| Method from org.apache.cocoon.generation.DirectoryGenerator Detail: |
protected void addAncestorPath(File path,
Stack ancestors) throws SAXException {
if (ancestors.empty()) {
this.isRequestedDirectory = true;
addPath(path, depth);
} else {
startNode(DIR_NODE_NAME, (File)ancestors.pop());
addAncestorPath(path, ancestors);
endNode(DIR_NODE_NAME);
}
}
Adds recursively the path from the directory matched by the root pattern
down to the requested directory. |
protected void addPath(File path,
int depth) throws SAXException {
if (path.isDirectory()) {
startNode(DIR_NODE_NAME, path);
if (depth > 0) {
File contents[] = path.listFiles();
if (sort.equals("name")) {
Arrays.sort(contents, new Comparator() {
public int compare(Object o1, Object o2) {
if (reverse) {
return ((File)o2).getName().compareTo(((File)o1).getName());
}
return ((File)o1).getName().compareTo(((File)o2).getName());
}
});
} else if (sort.equals("size")) {
Arrays.sort(contents, new Comparator() {
public int compare(Object o1, Object o2) {
if (reverse) {
return new Long(((File)o2).length()).compareTo(
new Long(((File)o1).length()));
}
return new Long(((File)o1).length()).compareTo(
new Long(((File)o2).length()));
}
});
} else if (sort.equals("lastmodified")) {
Arrays.sort(contents, new Comparator() {
public int compare(Object o1, Object o2) {
if (reverse) {
return new Long(((File)o2).lastModified()).compareTo(
new Long(((File)o1).lastModified()));
}
return new Long(((File)o1).lastModified()).compareTo(
new Long(((File)o2).lastModified()));
}
});
} else if (sort.equals("directory")) {
Arrays.sort(contents, new Comparator() {
public int compare(Object o1, Object o2) {
File f1 = (File)o1;
File f2 = (File)o2;
if (reverse) {
if (f2.isDirectory() && f1.isFile())
return -1;
if (f2.isFile() && f1.isDirectory())
return 1;
return f2.getName().compareTo(f1.getName());
}
if (f2.isDirectory() && f1.isFile())
return 1;
if (f2.isFile() && f1.isDirectory())
return -1;
return f1.getName().compareTo(f2.getName());
}
});
}
for (int i = 0; i < contents.length; i++) {
if (isIncluded(contents[i]) && !isExcluded(contents[i])) {
addPath(contents[i], depth - 1);
}
}
}
endNode(DIR_NODE_NAME);
} else {
if (isIncluded(path) && !isExcluded(path)) {
startNode(FILE_NODE_NAME, path);
endNode(FILE_NODE_NAME);
}
}
}
Adds a single node to the generated document. If the path is a
directory, and depth is greater than zero, then recursive calls
are made to add nodes for the directory's children. |
protected void endNode(String nodeName) throws SAXException {
super.contentHandler.endElement(URI, nodeName, PREFIX + ':" + nodeName);
}
|
public void generate() throws SAXException, ProcessingException {
try {
String systemId = this.directorySource.getURI();
if (!systemId.startsWith(FILE)) {
throw new ResourceNotFoundException(systemId + " does not denote a directory");
}
// This relies on systemId being of the form "file://..."
File directoryFile = new File(new URL(systemId).getFile());
if (!directoryFile.isDirectory()) {
throw new ResourceNotFoundException(super.source + " is not a directory.");
}
this.contentHandler.startDocument();
this.contentHandler.startPrefixMapping(PREFIX, URI);
Stack ancestors = getAncestors(directoryFile);
addAncestorPath(directoryFile, ancestors);
this.contentHandler.endPrefixMapping(PREFIX);
this.contentHandler.endDocument();
} catch (IOException ioe) {
throw new ResourceNotFoundException("Could not read directory " + super.source, ioe);
}
}
|
protected Stack getAncestors(File path) {
File parent = path;
Stack ancestors = new Stack();
while ((parent != null) && !isRoot(parent)) {
parent = parent.getParentFile();
if (parent != null) {
ancestors.push(parent);
} else {
// no ancestor matched the root pattern
ancestors.clear();
}
}
return ancestors;
}
Creates a stack containing the ancestors of File up to specified directory. |
public Serializable getKey() {
StringBuffer buffer = new StringBuffer();
int len = this.cacheKeyParList.size();
for (int i = 0; i < len; i++) {
buffer.append((String)this.cacheKeyParList.get(i) + ":");
}
return buffer.toString();
}
|
public SourceValidity getValidity() {
if (this.validity == null) {
this.validity = new DirValidity(this.refreshDelay);
}
return this.validity;
}
Gets the source validity, using a deferred validity object. The validity
is initially empty since the files that define it are not known before
generation has occured. So the returned object is kept by the generator
and filled with each of the files that are traversed. |
protected boolean isExcluded(File path) {
return (this.excludeRE == null) ? false : this.excludeRE.match(path.getName());
}
Determines if a given File shall be excluded from viewing. |
protected boolean isIncluded(File path) {
return (this.includeRE == null) ? true : this.includeRE.match(path.getName());
}
Determines if a given File shall be visible. |
protected boolean isRoot(File path) {
return (this.rootRE == null) ? true : this.rootRE.match(path.getName());
}
Determines if a given File is the defined root. |
public void recycle() {
if ( this.resolver != null ) {
this.resolver.release(this.directorySource);
this.directorySource = null;
}
this.cacheKeyParList = null;
this.attributes = null;
this.dateFormatter = null;
this.rootRE = null;
this.includeRE = null;
this.excludeRE = null;
this.validity = null;
super.recycle();
}
|
protected void setNodeAttributes(File path) throws SAXException {
long lastModified = path.lastModified();
attributes.clear();
attributes.addAttribute("", FILENAME_ATTR_NAME, FILENAME_ATTR_NAME,
"CDATA", path.getName());
attributes.addAttribute("", LASTMOD_ATTR_NAME, LASTMOD_ATTR_NAME,
"CDATA", Long.toString(path.lastModified()));
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("", "sort", "sort", "CDATA", this.sort);
attributes.addAttribute("", "reverse", "reverse", "CDATA",
String.valueOf(this.reverse));
attributes.addAttribute("", "requested", "requested", "CDATA", "true");
this.isRequestedDirectory = false;
}
}
Sets the attributes for a given path. The default method sets attributes
for the name of thefile/directory and for the last modification time
of the path. |
public void setup(SourceResolver resolver,
Map objectModel,
String src,
Parameters par) throws IOException, SAXException, ProcessingException {
if (src == null) {
throw new ProcessingException("No src attribute pointing to a directory to be XMLized specified.");
}
super.setup(resolver, objectModel, src, par);
try {
this.directorySource = this.resolver.resolveURI(src);
} catch (SourceException se) {
throw SourceUtil.handle(se);
}
this.cacheKeyParList = new ArrayList();
this.cacheKeyParList.add(this.directorySource.getURI());
this.depth = par.getParameterAsInteger("depth", 1);
this.cacheKeyParList.add(String.valueOf(this.depth));
String dateFormatString = par.getParameter("dateFormat", null);
this.cacheKeyParList.add(dateFormatString);
if (dateFormatString != null) {
this.dateFormatter = new SimpleDateFormat(dateFormatString);
} else {
this.dateFormatter = new SimpleDateFormat();
}
this.sort = par.getParameter("sort", "name");
this.cacheKeyParList.add(this.sort);
this.reverse = par.getParameterAsBoolean("reverse", false);
this.cacheKeyParList.add(String.valueOf(this.reverse));
this.refreshDelay = par.getParameterAsLong("refreshDelay", 1L) * 1000L;
this.cacheKeyParList.add(String.valueOf(this.refreshDelay));
if (this.getLogger().isDebugEnabled()) {
this.getLogger().debug("depth: " + this.depth);
this.getLogger().debug("dateFormat: " + this.dateFormatter.toPattern());
this.getLogger().debug("sort: " + this.sort);
this.getLogger().debug("reverse: " + this.reverse);
this.getLogger().debug("refreshDelay: " + this.refreshDelay);
}
String rePattern = null;
try {
rePattern = par.getParameter("root", null);
this.cacheKeyParList.add(rePattern);
this.rootRE = (rePattern == null) ? null : new RE(rePattern);
if (this.getLogger().isDebugEnabled()) {
this.getLogger().debug("root pattern: " + rePattern);
}
rePattern = par.getParameter("include", null);
this.cacheKeyParList.add(rePattern);
this.includeRE = (rePattern == null) ? null : new RE(rePattern);
if (this.getLogger().isDebugEnabled()) {
this.getLogger().debug("include pattern: " + rePattern);
}
rePattern = par.getParameter("exclude", null);
this.cacheKeyParList.add(rePattern);
this.excludeRE = (rePattern == null) ? null : new RE(rePattern);
if (this.getLogger().isDebugEnabled()) {
this.getLogger().debug("exclude pattern: " + rePattern);
}
} catch (RESyntaxException rese) {
throw new ProcessingException("Syntax error in regexp pattern '"
+ rePattern + "'", rese);
}
this.isRequestedDirectory = false;
this.attributes = new AttributesImpl();
}
Set the request parameters. Must be called before the generate method. |
protected void startNode(String nodeName,
File path) throws SAXException {
if (this.validity != null) {
this.validity.addFile(path);
}
setNodeAttributes(path);
super.contentHandler.startElement(URI, nodeName, PREFIX + ':" + nodeName, attributes);
}
Begins a named node and calls setNodeAttributes to set its attributes. |