Hi folks,

I found the format produced by the DirectoryGenerator somewhat
limited. I particular I missed the size attribute. 

Therefore I added the size attribute and additionally included
sorted output in different formats.

I'm still a Java neophyte, therefore please review my changes and
integrate them if you feel them appropiate. I've updated the
documentation accordingly.

Index: src/documentation/xdocs/userdocs/generators/directory-generator.xml
===================================================================
RCS file: 
/home/cvspublic/xml-cocoon2/src/documentation/xdocs/userdocs/generators/directory-generator.xml,v
retrieving revision 1.1
diff -u -r1.1 directory-generator.xml
--- src/documentation/xdocs/userdocs/generators/directory-generator.xml 3 Jan 2002 
12:31:04 -0000       1.1
+++ src/documentation/xdocs/userdocs/generators/directory-generator.xml 25 Apr 2002 
+07:40:59 -0000
@@ -24,12 +24,15 @@
         <li>name : the name of the file or directory</li>
         <li>lastModified : the time the file was last modified, measured as the 
number of
         milliseconds since the epoch (as in java.io.File.lastModified)</li>
+        <li>size : the file size in bytes (as returned by java.io.File.length)</li>
         <li>date (optional) : the time the file was last modified in human-readable 
form</li>
       </ul>
       <p>All generated elements have the namespace
         <code>http://apache.org/cocoon/directory/2.0</code>.
         The root <code>directory</code>
-        node has the attribute <code>requested</code> with the value 
<code>true</code>.
+        node has the attribute <code>requested</code> with the value 
+<code>true</code>. The sort
+        order is described by the attribute <code>sort</code>, which defaults to 
+sorting according
+        to <code>name</code>.
       </p>
       <ul>
         <li>Name : directory</li>
@@ -51,9 +54,16 @@
         <li>dateFormat (optional) :  Sets the format for the date attribute of each 
node, as
          described in java.text.SimpleDateFormat. If unset, the default
          format for the current locale will be used.</li>
-        <li>root (optional) : The root pattern</li>
-        <li>include (optional) : The include pattern</li>
-        <li>exclude (optional) : The exclude pattern</li>
+        <li>root (optional) : The root pattern. This is a regular expression as 
+described in
+          <link 
+href="http://jakarta.apache.org/regexp/apidocs/org/apache/regexp/RE.html";>
+          
+http://jakarta.apache.org/regexp/apidocs/org/apache/regexp/RE.html</link></li>
+        <li>include (optional) : The include pattern. Also a regular expression.</li>
+        <li>exclude (optional) : The exclude pattern. Also a regular expression.</li>
+        <li>sort (optional): This parameter determines the order, in which the 
+<code>file</code> 
+          and <code>directory</code> nodes are returned. Default sort order is by 
+name. 
+          Possible values are "name", "name-reverse", "size", "size-reverse", "time", 
+          "time-reverse" and "directory". "directory" is the same as "name", except 
+that directory
+          entries come first.</li>
       </ul>
     </s1>
     <s1 title="DTD">
@@ -67,13 +77,16 @@
     name         CDATA #REQUIRED
     lastModified CDATA #REQUIRED
     date         CDATA #IMPLIED
+    size        CDATA #IMPLIED
+    sort        CDATA #IMPLIED
     requested    CDATA #IMPLIED>
   
-  <!ELEMENt file #EMPTY>
+  <!ELEMENT file #EMPTY>
   <!ATTLIST file
     name         CDATA #REQUIRED
     lastModified CDATA #REQUIRED
-    date         CDATA #IMPLIED>
+    date         CDATA #IMPLIED
+    size        CDATA #IMPLIED>
 ]]></source>
     </s1>
     <s1 title="Example">
@@ -81,18 +94,20 @@
         The current directory generator may generate following xml:
       </p>
 <source><![CDATA[
-<directory xmlns="http://apache.org/cocoon/directory/2.0"; 
-  name="stylesheets" lastModified="999425490000" 
-  date="02.09.01 12:11" 
-  requested="true">
-  <directory name="sites" 
-    lastModified="999425490000" date="02.09.01 12:11"/>
-  <file name="dynamic-page2html.xsl" 
-    lastModified="999425490000" date="02.09.01 12:11"/>
-  <file name="simple-xml2html.xsl" 
-    lastModified="999425490000" date="02.09.01 12:11"/>
-</directory>
+<dir:directory xmlns:dir="http://apache.org/cocoon/directory/2.0";
+       name="stylesheets" lastModified="1019666489000" 
+       date="24.04.02 18:41" 
+       size="461" 
+       requested="true" 
+       sort="name">
+      <dir:directory name="sites" 
+       lastModified="1019666489000" date="24.04.02 18:41" size="118"/>
+      <dir:file name="dynamic-page2html.xsl" 
+       lastModified="1019666489000" date="24.04.02 18:41" size="1832"/>
+      <dir:file name="simple-xml2html.xsl" 
+       lastModified="1019666489000" date="24.04.02 18:41" size="12676"/>
+   </dir:directory>
 ]]></source>
     </s1>
-</body>
+</body>   
 </document>
Index: src/java/org/apache/cocoon/generation/DirectoryGenerator.java
===================================================================
RCS file: 
/home/cvspublic/xml-cocoon2/src/java/org/apache/cocoon/generation/DirectoryGenerator.java,v
retrieving revision 1.7
diff -u -r1.7 DirectoryGenerator.java
--- src/java/org/apache/cocoon/generation/DirectoryGenerator.java       22 Feb 2002 
07:03:51 -0000      1.7
+++ src/java/org/apache/cocoon/generation/DirectoryGenerator.java       25 Apr 2002 
+07:40:59 -0000
@@ -67,6 +67,8 @@
 import java.util.Date;
 import java.util.Map;
 import java.util.Stack;
+import java.util.Arrays;
+import java.util.Comparator;
 
 /**
  * Generates an XML directory listing.
@@ -82,6 +84,8 @@
  *   <dt> lastModified
  *   <dd> the time the file was last modified, measured as the number of
  *   milliseconds since the epoch (as in java.io.File.lastModified)
+ *   <dt> size
+ *   <dd> the file size in bytes (as returned by java.io.File.length)
  *   <dt> date (optional)
  *   <dd> the time the file was last modified in human-readable form
  *   </dl>
@@ -93,6 +97,11 @@
  * <dd> Sets how deep DirectoryGenerator should delve into the
  * directory structure. If set to 1 (the default), only the starting
  * directory's immediate contents will be returned.
+ * <dt> <i>sort</i>
+ * <dd> Sort order in which the nodes are returned. Default is name.
+ *     Possible values are name, name-reverse, size, size-reverse, 
+ *     time, time-reverse and directory. directory is the same as 
+ *     name, except that the directory entries are listed first.
  * <dt> <i>dateFormat</i> (optional)
  * <dd> Sets the format for the date attribute of each node, as
  * described in java.text.SimpleDateFormat. If unset, the default
@@ -122,6 +131,7 @@
     protected static final String FILENAME_ATTR_NAME    = "name";
     protected static final String LASTMOD_ATTR_NAME     = "lastModified";
     protected static final String DATE_ATTR_NAME        = "date";
+    protected static final String SIZE_ATTR_NAME        = "size";
 
     /*
      * Variables set per-request
@@ -131,6 +141,7 @@
     protected int depth;
     protected AttributesImpl attributes = new AttributesImpl();
     protected SimpleDateFormat dateFormatter;
+    protected String sort;
 
     protected RE rootRE;
     protected RE includeRE;
@@ -166,6 +177,9 @@
         this.depth = par.getParameterAsInteger("depth", 1);
         getLogger().debug("depth: " + this.depth);
 
+        this.sort = par.getParameter("sort", "name");
+        getLogger().debug("sort: " + this.sort);
+
         String rePattern = par.getParameter("root", null);
         try {
             getLogger().debug("root pattern: " + rePattern);
@@ -288,6 +302,27 @@
             startNode(DIR_NODE_NAME, path);
             if (depth>0) {
                 File contents[] = path.listFiles();
+                if (sort.equals("name")) {
+                    Arrays.sort(contents, new SortByName());
+                }
+                if (sort.equals("name-reverse")) {
+                    Arrays.sort(contents, new SortByName(true));
+                }
+                if (sort.equals("size")) {
+                    Arrays.sort(contents, new SortBySize());
+                }
+                if (sort.equals("size-reverse")) {
+                    Arrays.sort(contents, new SortBySize(true));
+                }
+                if (sort.equals("lastmodified")) {
+                    Arrays.sort(contents, new SortByLastmodified());
+                }
+                if (sort.equals("lastmodified-reverse")) {
+                    Arrays.sort(contents, new SortByLastmodified(true));
+                }
+                if (sort.equals("directory")) {
+                    Arrays.sort(contents, new SortByDirectory());
+                }
                 for (int i=0; i<contents.length; i++) {
                     if (isIncluded(contents[i]) && !isExcluded(contents[i])) {
                         addPath(contents[i], depth-1);
@@ -346,10 +381,15 @@
         attributes.addAttribute("", DATE_ATTR_NAME,
                     DATE_ATTR_NAME, "CDATA",
                     dateFormatter.format(new Date(lastModified)));
+        attributes.addAttribute("", SIZE_ATTR_NAME,
+                    SIZE_ATTR_NAME, "CDATA",
+                    Long.toString(path.length()));
 
         if (this.isRequestedDirectory) {
             attributes.addAttribute("", "requested", "requested", "CDATA",
                     "true");
+            attributes.addAttribute("", "sort", "sort", "CDATA",
+                    this.sort);
             this.isRequestedDirectory = false;
         }
     }
@@ -434,3 +474,86 @@
 
     }
 }
+
+class SortByName implements Comparator {
+    boolean sortReverse = false;
+    
+    SortByName () {
+    }
+    
+    SortByName(boolean order) {
+        this.sortReverse = order;
+    }
+    
+    public int compare (Object o1, Object o2) {
+        File f1 = (File) o1;
+        File f2 = (File) o2;
+        
+        if (sortReverse) {
+            return f2.getName().compareTo(f1.getName());
+        }  else {
+            return f1.getName().compareTo(f2.getName());
+        }
+    }
+}
+
+class SortByDirectory implements Comparator {
+
+    public int compare (Object o1, Object o2) {
+        File f1 = (File) o1;
+        File f2 = (File) o2;
+        
+        if (f1.isDirectory() && f2.isFile()) {
+            return -1;
+        } else if (f1.isFile() && f2.isDirectory()) {
+            return 1;
+        } else {
+            return f1.getName().compareTo(f2.getName());
+        }
+    }
+}
+
+class SortBySize implements Comparator {
+    boolean sortReverse = false;
+    
+    SortBySize() {
+    }
+    
+    SortBySize(boolean order) {
+        this.sortReverse = order;
+    }
+    
+    public int compare (Object o1, Object o2) {
+        Long s1 = new Long(((File)o1).length());
+        Long s2 = new Long(((File)o2).length());
+        
+        if (sortReverse) {
+            return s2.compareTo(s1);
+        } else {
+            return s1.compareTo(s2);
+        }
+    }
+}
+
+class SortByLastmodified implements Comparator {
+    boolean sortReverse = false;
+    
+    SortByLastmodified() {
+    }
+    
+    SortByLastmodified(boolean order) {
+        this.sortReverse = order;
+    }
+    
+    public int compare (Object o1, Object o2) {
+        Long s1 = new Long(((File)o1).lastModified());
+        Long s2 = new Long(((File)o2).lastModified());
+        
+        if (sortReverse) {
+            return s2.compareTo(s1);
+        } else {
+            return s1.compareTo(s2);
+        }
+    }
+}
+


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to