View Javadoc

1   package org.astrogrid.portal.myspace.transformation;
2   
3   import org.apache.avalon.framework.parameters.Parameters;
4   
5   import org.apache.cocoon.ProcessingException;
6   import org.apache.cocoon.environment.SourceResolver;
7   import org.apache.cocoon.transformation.AbstractDOMTransformer;
8   import org.apache.cocoon.util.jxpath.DOMFactory;
9   import org.apache.cocoon.xml.XMLUtils;
10  import org.apache.commons.jxpath.JXPathContext;
11  import org.apache.commons.jxpath.Pointer;
12  
13  import org.w3c.dom.Document;
14  import org.w3c.dom.Element;
15  import org.w3c.dom.Node;
16  
17  import org.xml.sax.SAXException;
18  
19  import java.io.File;
20  import java.io.IOException;
21  
22  import java.util.Iterator;
23  import java.util.Map;
24  
25  import javax.xml.parsers.DocumentBuilder;
26  import javax.xml.parsers.DocumentBuilderFactory;
27  
28  public class MySpaceHoldingsTransformer
29      extends AbstractDOMTransformer {
30        
31    public static void main(String[] args) {
32      try {
33        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
34        DocumentBuilder builder = builderFactory.newDocumentBuilder();
35        Document sourceDoc = builder.parse(new File(args[0]));
36        
37        MySpaceHoldingsTransformer transformer = new MySpaceHoldingsTransformer();
38        Document transDoc = transformer.transform(sourceDoc);
39        
40        String result = XMLUtils.serializeNodeToXML(transDoc);
41        System.out.print(result);
42      }
43      catch(Exception e) {
44        e.printStackTrace();
45      }
46    }
47    
48    /* (non-Javadoc)
49     * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
50     */
51    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters params)
52        throws ProcessingException, SAXException, IOException {
53      super.setup(resolver, objectModel, src, params);
54    }
55  
56    /* (non-Javadoc)
57     * @see org.apache.cocoon.transformation.AbstractDOMTransformer#transform(org.w3c.dom.Document)
58     */
59    protected Document transform(Document doc) {
60      Document result = doc;
61      
62      JXPathContext context = JXPathContext.newContext(doc);
63      Iterator recordPointerIt = context.iteratePointers("//dataItemRecord");
64      
65      try {
66        // Create a new document with the myspace-tree root.
67        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
68        DocumentBuilder builder = builderFactory.newDocumentBuilder();
69        Document transDoc = builder.newDocument();
70        
71        Element rootElement = transDoc.createElement("myspace-tree");
72        transDoc.appendChild(rootElement);
73        
74        // Create a new JXPath context that can create new DOM elements.
75        JXPathContext transContext = JXPathContext.newContext(transDoc);
76        transContext.setFactory(new DOMFactory());
77  
78        // Add all data item records as myspace-item nodes.
79        boolean success = false;
80        Pointer recordPointer = null;
81        MySpaceRecord record = null;
82        Element recordElement = null;
83        while(recordPointerIt.hasNext()) {
84          recordPointer = (Pointer) recordPointerIt.next();
85          record = new MySpaceRecord(context, recordPointer);
86          record.addElement("myspace-tree", transDoc, transContext);
87          
88          success = true;
89        }
90  
91        if(success) {
92          result = transDoc;
93        }
94      }
95      catch(Exception e) {
96        // Do nothing.
97        e.printStackTrace();
98      }
99      
100     return result;
101   }
102   
103   private static class MySpaceRecord {
104     private String fullName;
105     private String safeName;
106     private String parentName;
107     private String itemName;
108       
109     private String id;
110     private String ownerID;
111     private String creationDate;
112     private String expiryDate;
113     private String size;
114     private String type;
115     private String permissionsMask;
116     private String dataHolderURI;
117     
118     public MySpaceRecord(JXPathContext context, Pointer recordPointer) {
119       String path = recordPointer.asPath();
120       
121       fullName = (String) context.getValue(path + "/dataItemName");
122       id = (String) context.getValue(path + "/dataItemID");
123       ownerID = (String) context.getValue(path + "/ownerID");
124       creationDate = (String) context.getValue(path + "/creationDate");
125       expiryDate = (String) context.getValue(path + "/expiryDate");
126       size = (String) context.getValue(path + "/size");
127       type = (String) context.getValue(path + "/type");
128       permissionsMask = (String) context.getValue(path + "/permissionsMask");
129       dataHolderURI = (String) context.getValue(path + "/dataHolderURI");
130       
131       separatePaths();
132     }
133     
134     public String toString() {
135       StringBuffer result = new StringBuffer();
136       
137       result.append('[');
138       
139       result.append("[safeName, ").append(safeName).append("]");
140       result.append("[fullName, ").append(fullName).append("]");
141       result.append("[parentName, ").append(parentName).append("]");
142       result.append("[itemName, ").append(itemName).append("]");
143       result.append("[id, ").append(id).append("]");
144       result.append("[ownerID, ").append(ownerID).append("]");
145       result.append("[creationDate, ").append(creationDate).append("]");
146       result.append("[expiryDate, ").append(expiryDate).append("]");
147       result.append("[size, ").append(size).append("]");
148       result.append("[type, ").append(type).append("]");
149       result.append("[permissionsMask, ").append(permissionsMask).append("]");
150       result.append("[dataHolderURI, ").append(dataHolderURI).append("]");
151       
152       result.append(']');
153       
154       return result.toString();
155     }
156     
157     public void addElement(String root, Document doc, JXPathContext context) {
158       // Search for the parent node.
159       Pointer parentPointer = context.getPointer("/descendant::myspace-item[@full-name = '" + parentName + "']");
160       
161       // If there is no parent node, set the root node as the parent.
162       JXPathContext insertionContext = null;
163       if(parentPointer == null || "null()".equals(parentPointer.asPath())) {
164         parentPointer = context.getPointer("/myspace-tree");
165       }
166       
167       // Create a new node for this record in the document.
168       Element itemElement = doc.createElement("myspace-item");
169       
170       itemElement.setAttribute("full-name", "ag-insert");
171       Node parentNode = (Node) parentPointer.getNode();
172       parentNode.appendChild(itemElement);
173       
174       // Get the insertion context for this new node.
175       Pointer insertionPoint =
176           context.getRelativeContext(parentPointer)
177                  .getPointer("myspace-item[@full-name = 'ag-insert']");
178       insertionContext = context.getRelativeContext(insertionPoint);
179 
180       // Now that we have the new node's insertion context, create the attributes under it.
181       insertionContext.createPathAndSetValue("attribute::safe-name", safeName);
182       insertionContext.createPathAndSetValue("attribute::full-name", fullName);
183       insertionContext.createPathAndSetValue("attribute::parent-name", parentName);
184       insertionContext.createPathAndSetValue("attribute::item-name", itemName);
185       insertionContext.createPathAndSetValue("attribute::id", id);
186       insertionContext.createPathAndSetValue("attribute::owner-id", ownerID);
187       insertionContext.createPathAndSetValue("attribute::creation-date", creationDate);
188       insertionContext.createPathAndSetValue("attribute::expiry-date", expiryDate);
189       insertionContext.createPathAndSetValue("attribute::size", size);
190       insertionContext.createPathAndSetValue("attribute::type", type);
191       insertionContext.createPathAndSetValue("attribute::permission-mask", permissionsMask);
192       insertionContext.createPathAndSetValue("attribute::data-holder-uri", dataHolderURI);
193     }
194     
195     private void separatePaths() {
196       if(fullName != null && fullName.length() > 0) {
197         int index = fullName.lastIndexOf('/');
198         
199         if(index > -1) {
200           parentName = fullName.substring(0, index);
201           itemName = fullName.substring(index + 1);
202         }
203         
204         safeName = escapeName();
205       }
206     }
207     
208     private String escapeName() {
209       StringBuffer result = new StringBuffer();
210       
211       char character = 0;
212       for(int cIndex = 0; cIndex < fullName.length(); cIndex++) {
213         character = fullName.charAt(cIndex);
214         switch(character) {
215           case '/':
216           case '@':
217           case ' ':
218             result.append('_');
219             break;
220 
221           default:
222             result.append(character);
223             break;
224         }
225       }
226       
227       return result.toString();
228     }
229   }
230 }