upayavira 2003/09/15 04:26:04
Modified: src/java/org/apache/cocoon/bean CocoonBean.java Target.java Log: Moving destination URI arithmetic into Target class. Revision Changes Path 1.24 +45 -106 cocoon-2.1/src/java/org/apache/cocoon/bean/CocoonBean.java Index: CocoonBean.java =================================================================== RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/bean/CocoonBean.java,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- CocoonBean.java 13 Sep 2003 10:20:09 -0000 1.23 +++ CocoonBean.java 15 Sep 2003 11:26:04 -0000 1.24 @@ -71,7 +71,6 @@ import java.io.PrintStream; import java.util.Map; import java.util.HashMap; -import java.util.TreeMap; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -186,17 +185,24 @@ String sourceURI, String destURI) throws IllegalArgumentException { - targets.add(new Target(type, root, sourceURI, destURI)); + Target target = new Target(type, root, sourceURI, destURI); + target.setDefaultFilename(this.defaultFilename); + targets.add(target); + } public void addTarget(String type, String sourceURI, String destURI) throws IllegalArgumentException { - targets.add(new Target(type, sourceURI, destURI)); + Target target = new Target(type, sourceURI, destURI); + target.setDefaultFilename(this.defaultFilename); + targets.add(target); } public void addTarget(String sourceURI, String destURI) throws IllegalArgumentException { - targets.add(new Target(sourceURI, destURI)); + Target target = new Target(sourceURI, destURI); + target.setDefaultFilename(this.defaultFilename); + targets.add(target); } public void addTargets(List uris, String destURI) @@ -204,6 +210,7 @@ Iterator i = uris.iterator(); while (i.hasNext()) { Target target = new Target((String) i.next(), destURI); + target.setDefaultFilename(this.defaultFilename); targets.add(target); } } @@ -367,30 +374,20 @@ int linkCount = 0; - String destinationURI; if (confirmExtension) { - destinationURI = (String) allTranslatedLinks.get(target.getSourceURI()); - if (destinationURI == null) { - destinationURI = mangle(target.getSourceURI()); - final String type = getType(target.getDeparameterizedSourceURI(), target.getParameters()); - final String ext = NetUtils.getExtension(destinationURI); - final String defaultExt = MIMEUtils.getDefaultExtension(type); - if (defaultExt != null) { - if ((ext == null) || (!ext.equals(defaultExt))) { - destinationURI += defaultExt; - } - } - allTranslatedLinks.put(target.getSourceURI(), destinationURI); + if (null == allTranslatedLinks.get(target.getSourceURI())) { + final String mimeType = getType(target.getDeparameterizedSourceURI(), target.getParameters()); + target.setMimeType(mimeType); + allTranslatedLinks.put(target.getSourceURI(), target.getDestinationURI()); } - } else { - destinationURI = target.getSourceURI(); } // Store processed URI list to avoid eternal loop allProcessedLinks.put(target, target); - if ("".equals(destinationURI)) { - return new ArrayList(); - } + // IS THIS STILL NEEDED? + //if ("".equals(destinationURI)) { + // return new ArrayList(); + //} // Process links final HashMap translatedLinks = new HashMap(); @@ -415,31 +412,23 @@ continue; } - String linkDestinationURI = - (String) allTranslatedLinks.get(linkTarget.getSourceURI()); - if (linkDestinationURI == null) { + if (null == allTranslatedLinks.get(linkTarget.getSourceURI())) { try { - linkDestinationURI = - this.translateURI(linkTarget.getSourceURI()); + final String mimeType = + getType(target.getDeparameterizedSourceURI(), target.getParameters()); + target.setMimeType(mimeType); + allTranslatedLinks.put(target.getSourceURI(), target.getDestinationURI()); log.info(" Link translated: " + linkTarget.getSourceURI()); - allTranslatedLinks.put( - linkTarget.getSourceURI(), - linkDestinationURI); + targets.add(linkTarget); } catch (ProcessingException pe) { this.sendBrokenLinkWarning(linkTarget.getSourceURI(), pe.getMessage()); + if (this.brokenLinkGenerate) { + targets.add(linkTarget); + } } } - // AllTranslatedLinks is for preventing retranslation - // translartedLinks is for use by the LinkTranslator - final String translatedRelativeLink = - NetUtils.relativize(target.getPath(), linkDestinationURI); - translatedLinks.put(linkTarget.getOriginalSourceURI(), translatedRelativeLink); - - // I have to add also broken links to the absolute links - // to be able to generate the "broken link" page - // @TODO@ Only do this if broken page generation is required - targets.add(linkTarget); + translatedLinks.put(linkTarget.getOriginalSourceURI(), linkTarget.getTranslatedURI(target.getPath())); } linkCount = translatedLinks.size(); @@ -452,7 +441,7 @@ status = getPage( target.getDeparameterizedSourceURI(), - getLastModified(target, destinationURI), + getLastModified(target), target.getParameters(), confirmExtension ? translatedLinks : null, gatheredLinks, @@ -487,14 +476,13 @@ } catch (ProcessingException pe) { output.close(); output = null; - this.resourceUnavailable(target, target.getSourceURI(), destinationURI); - this.sendBrokenLinkWarning( - destinationURI, + this.resourceUnavailable(target); + this.sendBrokenLinkWarning(target.getSourceURI(), DefaultNotifyingBuilder.getRootCause(pe).getMessage()); } finally { if (output != null && status != -1) { - ModifiableSource source = getSource(target, destinationURI); + ModifiableSource source = getSource(target); try { OutputStream stream = source.getOutputStream(); @@ -522,46 +510,19 @@ } /** - * Translate an URI into a file name. - * - * @param uri a <code>String</code> value to map - * @return a <code>String</code> vlaue for the file - * @exception Exception if an error occurs - */ - private String translateURI(String uri) throws Exception { - if (null == uri || "".equals(uri)) { - log.warn("cannot translate empty uri"); - if (verbose) sendMessage("cannot translate empty uri"); - return ""; - } - HashMap parameters = new HashMap(); - String deparameterizedURI = NetUtils.deparameterize(uri, parameters); - - String destinationURI = mangle(uri); - String type = getType(deparameterizedURI, parameters); - String ext = NetUtils.getExtension(destinationURI); - String defaultExt = MIMEUtils.getDefaultExtension(type); - if (defaultExt != null) { - if ((ext == null) || (!ext.equals(defaultExt))) { - destinationURI += defaultExt; - } - } - - return destinationURI; - } - - /** * Generate a <code>resourceUnavailable</code> message. * * @param target being unavailable * @exception IOException if an error occurs */ - private void resourceUnavailable(Target target, String uri, String destinationURI) + private void resourceUnavailable(Target target) throws IOException, ProcessingException { if (brokenLinkGenerate) { - String brokenFile = NetUtils.decodePath(destinationURI); + //Why decode this URI now? + //String brokenFile = NetUtils.decodePath(destinationURI); + if (brokenLinkExtension != null) { - brokenFile = brokenFile + brokenLinkExtension; + target.setExtension(brokenLinkExtension); } SimpleNotifyingBean n = new SimpleNotifyingBean(this); n.setType("resource-not-found"); @@ -569,10 +530,10 @@ n.setSource("Cocoon commandline (Main.java)"); n.setMessage("Page Not Available."); n.setDescription("The requested resource couldn't be found."); - n.addExtraDescription(Notifying.EXTRA_REQUESTURI, uri); - n.addExtraDescription("missing-file", uri); + n.addExtraDescription(Notifying.EXTRA_REQUESTURI, target.getSourceURI()); + n.addExtraDescription("missing-file", target.getSourceURI()); - ModifiableSource source = getSource(target, destinationURI); + ModifiableSource source = getSource(target); try { OutputStream stream = source.getOutputStream(); @@ -585,32 +546,10 @@ } } } - - /** - * Mangle a URI. - * - * @param uri a URI to mangle - * @return a mangled URI - */ - private String mangle(String uri) { - if (log.isDebugEnabled()) { - log.debug("mangle(\"" + uri + "\")"); - } - if (uri.charAt(uri.length() - 1) == '/') { - uri += defaultFilename; - } - uri = uri.replace('"', '\''); - uri = uri.replace('?', '_'); - uri = uri.replace(':', '_'); - if (log.isDebugEnabled()) { - log.debug(uri); - } - return uri; - } - public ModifiableSource getSource(Target target, String destinationURI) + public ModifiableSource getSource(Target target) throws IOException, ProcessingException { - final String finalDestinationURI = target.getDestinationURI(destinationURI); + final String finalDestinationURI = target.getDestinationURI(); Source src = sourceResolver.resolveURI(finalDestinationURI); if (!(src instanceof ModifiableSource)) { sourceResolver.release(src); @@ -620,8 +559,8 @@ return (ModifiableSource) src; } - public long getLastModified(Target target, String destinationURI) throws IOException, ProcessingException { - Source src = getSource(target, destinationURI); + public long getLastModified(Target target) throws IOException, ProcessingException { + Source src = getSource(target); long lastModified = src.getLastModified(); this.releaseSource(src); return lastModified; 1.4 +145 -27 cocoon-2.1/src/java/org/apache/cocoon/bean/Target.java Index: Target.java =================================================================== RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/bean/Target.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- Target.java 13 Sep 2003 10:20:09 -0000 1.3 +++ Target.java 15 Sep 2003 11:26:04 -0000 1.4 @@ -52,6 +52,8 @@ import java.util.TreeMap; +import org.apache.cocoon.Constants; +import org.apache.cocoon.util.MIMEUtils; import org.apache.cocoon.util.NetUtils; import org.apache.cocoon.ProcessingException; @@ -77,8 +79,12 @@ private final String deparameterizedSourceURI; private final TreeMap parameters; - private String originalURI; - + private String originalURI = null; + private String mimeType = null; + private String defaultFilename = Constants.INDEX_URI; + private String finalDestinationURI = null; + private String extension = null; + private transient int _hashCode; private transient String _toString; @@ -147,6 +153,50 @@ } /** + * Sets the mime type for the resource referenced by this target. + * If a mime type is specified, the file extension of the + * destination URI will be checked to see that it matches the + * default extension for the specified mime type. If it doesn't, + * the default extension will be appended to the destination URI. + * + * This URI change will be taken into account in pages that link + * to the current page. + * + * If the mime type is not specified (and thus null), no extension + * checking will take place. + */ + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + this.finalDestinationURI = null; + } + + /** + * Sets a file extension to be appended to the end of the destination + * URI. The main use of this is to create broken link error files that + * stand out, within the file structure of the generated site, by, for + * example, adding '.error' to the end of the filename. + */ + public void setExtension(String extension) { + this.extension = extension; + this.finalDestinationURI = null; + } + /** + * Sets the default filename. This filename is appended to URIs + * that refer to a directory, i.e. end with a slash, as resources + * referred to by such a URI cannot be written to a file system + * without a filename. + * + * This URI change will be taken into account in pages that link + * to the current page. + * + * If no default is specified, the Cocoon constants value will + * be used. + */ + public void setDefaultFilename(String filename) { + this.defaultFilename = filename; + } + + /** * Gets the filename from the source URI, without the path. * This is used to fill out relative URIs that have * parameters but no filename such as ?page=123 @@ -174,35 +224,86 @@ * Calculates the destination URI - the URI to which the generated * page should be written. This will be a URI that, when resolved * by a SourceResolver, will return a modifiableSource. + * + * This calculation is only done once per target. It is therefore + * necessary to ensure that the mime type has been set (if required) + * before this method is called. */ - public String getDestinationURI(String actualSourceURI) + public String getDestinationURI() throws ProcessingException { - if (!actualSourceURI.startsWith(root)) { - throw new ProcessingException( - "Derived target does not share same root: " - + actualSourceURI); - } - actualSourceURI = actualSourceURI.substring(root.length()); - - if (APPEND_TYPE.equals(this.type)) { - return destURI + actualSourceURI; - } else if (REPLACE_TYPE.equals(this.type)) { - return destURI; - } else if (INSERT_TYPE.equals(this.type)) { - int starPos = destURI.indexOf("*"); - if (starPos == -1) { - throw new ProcessingException("Missing * in replace mapper uri"); - } else if (starPos == destURI.length() - 1) { - return destURI.substring(0, starPos) + actualSourceURI; + + if (this.finalDestinationURI == null) { + + String actualSourceURI = this.sourceURI; + if (!actualSourceURI.startsWith(root)) { + throw new ProcessingException( + "Derived target does not share same root: " + + actualSourceURI); + } + actualSourceURI = actualSourceURI.substring(root.length()); + actualSourceURI = mangle(actualSourceURI); + + String destinationURI; + if (APPEND_TYPE.equals(this.type)) { + destinationURI = destURI + actualSourceURI; + } else if (REPLACE_TYPE.equals(this.type)) { + destinationURI = destURI; + } else if (INSERT_TYPE.equals(this.type)) { + int starPos = destURI.indexOf("*"); + if (starPos == -1) { + throw new ProcessingException("Missing * in replace mapper uri"); + } else if (starPos == destURI.length() - 1) { + destinationURI = destURI.substring(0, starPos) + actualSourceURI; + } else { + destinationURI = destURI.substring(0, starPos) + + actualSourceURI + + destURI.substring(starPos + 1); + } } else { - return destURI.substring(0, starPos) - + actualSourceURI - + destURI.substring(starPos + 1); - } - } else { - throw new ProcessingException( - "Unknown mapper type: " + this.type); + throw new ProcessingException( + "Unknown mapper type: " + this.type); + } + if (mimeType != null) { + final String ext = NetUtils.getExtension(destinationURI); + final String defaultExt = MIMEUtils.getDefaultExtension(mimeType); + if (defaultExt != null) { + if ((ext == null) || (!ext.equals(defaultExt))) { + destinationURI += defaultExt; + } + } + } + if (this.extension != null) { + destinationURI += this.extension; + } + this.finalDestinationURI = destinationURI; } + return this.finalDestinationURI; + } + + /** + * Gets a translated version of a link, ready for insertion + * into another page as a link. This link needs to be + * relative to the original page. + */ + public String getTranslatedURI(String path) + throws ProcessingException { + + String actualSourceURI = this.sourceURI; + if (!actualSourceURI.startsWith(root)) { + return actualSourceURI; + } + actualSourceURI = mangle(actualSourceURI); + + if (mimeType != null) { + final String ext = NetUtils.getExtension(actualSourceURI); + final String defaultExt = MIMEUtils.getDefaultExtension(mimeType); + if (defaultExt != null) { + if ((ext == null) || (!ext.equals(defaultExt))) { + actualSourceURI += defaultExt; + } + } + } + return NetUtils.relativize(path, actualSourceURI); } /** @@ -243,6 +344,23 @@ */ public TreeMap getParameters() { return this.parameters; + } + + /** + * Mangle a URI. + * + * @param uri a URI to mangle + * @return a mangled URI + */ + private String mangle(String uri) { + if (uri.charAt(uri.length() - 1) == '/') { + uri += defaultFilename; + } + uri = uri.replace('"', '\''); + uri = uri.replace('?', '_'); + uri = uri.replace(':', '_'); + + return uri; } public boolean equals(Object o) {