001    package com.saelist.stx.xpath;
002    
003    import org.apache.log4j.Logger;
004    
005    import org.jaxen.XPath;
006    import org.jaxen.DefaultNavigator;
007    import org.jaxen.FunctionCallException;
008    import org.jaxen.UnsupportedAxisException;
009    
010    import org.jaxen.util.SingleObjectIterator;
011    
012    
013    import org.saxpath.SAXPathException;
014    
015    import java.util.*;
016    import java.net.URL;
017    import java.io.File;
018    
019    import com.saelist.util.*;
020    import com.saelist.stx.parser.*;
021    
022    /** Interface for navigating around the File object model.
023     *
024     *  <p>
025     *  This class is not intended for direct usage, but is
026     *  used by the Jaxen engine during evaluation.
027     *  </p>
028     *
029     *  @see XPath
030     *
031     *  @author <a href="mailto:thor@peersoft.de">Thor Kristmundsson</a>
032     *
033     *  Derived from {@link org.jaxen.jdom.DocumentNavigator}.
034     */
035    public class FileNavigator extends DefaultNavigator {
036    
037      public static Logger logger = Logger.getLogger(FileNavigator.class.getName());
038    
039        /** Singleton implementation.
040         */
041        private static class Singleton {
042          /** Singleton instance.
043           */
044          private static FileNavigator instance = new FileNavigator();
045        }
046    
047        public static FileNavigator getInstance() {
048          return Singleton.instance;
049        }
050    
051        public boolean isElement(Object obj) {
052          return obj instanceof File;
053        }
054    
055        public boolean isComment(Object obj) { return false; }
056    
057        public boolean isText(Object obj) { return false; }
058    
059        public boolean isAttribute(Object obj) {
060          return obj instanceof FileAttribute;
061        }
062    
063        public boolean isProcessingInstruction(Object obj) { return false; }
064    
065        public boolean isDocument(Object obj) {
066          throw new UnsupportedOperationException("");
067          /* logger.info("isDocument() : obj=" + Strings.cutDown("" + obj, 30, "..."));
068          return obj == ((Element) obj).getRoot();  */
069        }
070    
071        public boolean isNamespace(Object obj) { return false; }
072    
073        public String getElementName(Object obj) {
074          logger.info("getElementName() : obj=" + Strings.cutDown("" + obj, 30, "...") + ", class=" + obj.getClass().getName());
075          return ((File) obj).getName();
076        }
077    
078        public String getElementNamespaceUri(Object obj) {   return null; }
079    
080        public String getAttributeName(Object obj) {
081          return ((FileAttribute) obj).name;
082        }
083    
084        public String getAttributeNamespaceUri(Object obj) {
085          return null;
086        }
087    
088        public Iterator getChildAxisIterator(Object contextNode) {
089          logger.info("getChildAxisIterator() : contextNode=" + Strings.cutDown("" + contextNode, 30, "..."));
090          File file = (File) contextNode;
091          if(! file.isDirectory())
092            return null;
093          File[] files = file.listFiles();
094          return Arrays.asList(files).iterator();
095        }
096    
097        public Iterator getNamespaceAxisIterator(Object contextNode) throws UnsupportedAxisException { throw new UnsupportedAxisException(""); }
098    
099        public Iterator getParentAxisIterator(Object contextNode) {
100          logger.info("getParentAxisIterator() : contextNode=" + Strings.cutDown("" + contextNode, 30, "..."));
101          File file = (File) contextNode;
102          File parent = file.getParentFile();
103          if(parent != null)
104            return new SingleObjectIterator(parent);
105          return null;
106        }
107    
108        public Iterator getAttributeAxisIterator(Object contextNode) {
109          return new FileAttributeAxisIterator((File) contextNode);
110        }
111    
112        /** Returns a parsed form of the given xpath string, which will be suitable
113         *  for queries on JDOM documents.
114         */
115        public XPath parseXPath (String xpath) throws SAXPathException {
116          return new FileXPath(xpath);
117        }
118    
119        public Object getDocumentNode(Object contextNode) {
120          logger.info("getDocumentNode() : contextNode=" + Strings.cutDown("" + contextNode, 30, "..."));
121          return null;
122        }
123    
124        public String getElementQName(Object obj) {
125          logger.info("getElementQName() : obj=" + Strings.cutDown("" + obj, 30, "..."));
126          return ((File) obj).getName();
127        }
128    
129        public String getAttributeQName(Object obj) {
130          return ((FileAttribute) obj).name;
131        }
132    
133        public String getNamespaceStringValue(Object obj) { throw new UnsupportedOperationException(""); }
134    
135        public String getNamespacePrefix(Object obj) { throw new UnsupportedOperationException(""); }
136    
137        public String getTextStringValue(Object obj) { throw new UnsupportedOperationException(""); }
138    
139        public String getAttributeStringValue(Object obj) {
140          return ((FileAttribute) obj).toString();
141        }
142    
143        public String getElementStringValue(Object obj) {
144          return "";
145        }
146    
147        public String getProcessingInstructionTarget(Object obj) { throw new UnsupportedOperationException(""); }
148    
149        public String getProcessingInstructionData(Object obj) { throw new UnsupportedOperationException(""); }
150    
151        public String getCommentStringValue(Object obj) { throw new UnsupportedOperationException(""); }
152    
153        public String translateNamespacePrefixToUri(String prefix, Object context) { throw new UnsupportedOperationException(""); }
154    
155        public Object getDocument(String url) throws FunctionCallException  {
156          logger.info("getDocument() : url=" + Strings.cutDown("" + url, 30, "..."));
157          throw new UnsupportedOperationException("");
158          /* try {
159            return Parser.parse(Net.loadFromURL(new URL(url)));
160          } catch (Exception e) {
161             throw new FunctionCallException( e.getMessage() );
162          } */
163        }
164    
165      public static class FileAttribute {
166        File parent;
167        String name;
168        String value;
169        public FileAttribute(File parent, String name, String value) {
170          this.parent = parent;
171          this.name = name;
172          this.value = value;
173        }
174        public String toString() {
175          return value;
176        }
177      }
178    
179      public static class FileAttributeAxisIterator implements Iterator {
180        File file;
181        List list;
182        Iterator iterator;
183        public FileAttributeAxisIterator(File file) {
184          this.file = file;
185          list = new ArrayList(7);
186          list.add(new FileAttribute(file, "readable", "" + file.canRead()));
187          list.add(new FileAttribute(file, "writable", "" + file.canWrite()));
188          list.add(new FileAttribute(file, "modified", "" + file.lastModified()));
189          list.add(new FileAttribute(file, "created", "" + file.canRead()));
190          list.add(new FileAttribute(file, "type", "" + (file.isFile() ? "file" : "directory")));
191          list.add(new FileAttribute(file, "hidden", "" + file.isHidden()));
192          list.add(new FileAttribute(file, "length", "" + file.length()));
193          list.add(new FileAttribute(file, "name", "" + file.getName()));
194          list.add(new FileAttribute(file, "path", "" + file.getPath()));
195          iterator = list.iterator();
196        }
197    
198        public boolean hasNext() { return iterator.hasNext(); }
199        public Object next() { return iterator.next(); }
200        public void remove() { throw new UnsupportedOperationException(); }
201      }
202    }