You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by up...@apache.org on 2003/06/27 15:50:38 UTC

cvs commit: cocoon-2.1/src/java/org/apache/cocoon/bean BeanListener.java CocoonBean.java

upayavira    2003/06/27 06:50:38

  Modified:    src/java/org/apache/cocoon Main.java
               src/java/org/apache/cocoon/bean CocoonBean.java
  Added:       src/java/org/apache/cocoon/bean BeanListener.java
  Log:
  Added 'BeanListener' interface for CocoonBean to report back to caller.
  Added class to Main that implements BeanListener.
  Moved broken link reporting to Main. Main can then report them as it wants.
  Reordered some methods in CocoonBean.
  Removed all references to System.out from CocoonBean - gets it closer to being
  ThreadSafe.
  
  This changes the interface to the CocoonBean, but leaves the CLI interface as is.
  I think we need to consider the CLI interface stable, but the Bean one unstable for
  the time being.
  
  Upayavira
  
  Revision  Changes    Path
  1.8       +100 -12   cocoon-2.1/src/java/org/apache/cocoon/Main.java
  
  Index: Main.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/java/org/apache/cocoon/Main.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Main.java	24 Jun 2003 16:59:24 -0000	1.7
  +++ Main.java	27 Jun 2003 13:50:37 -0000	1.8
  @@ -50,12 +50,11 @@
   */
   package org.apache.cocoon;
   
  -import java.io.BufferedReader;
  -import java.io.FileReader;
  -import java.io.File;
  +import java.io.*;
   import java.util.List;
   import java.util.ArrayList;
   import java.util.Arrays;
  +import java.util.Iterator;
   import javax.xml.parsers.DocumentBuilderFactory;
   import javax.xml.parsers.DocumentBuilder;
   
  @@ -72,6 +71,7 @@
   
   import org.apache.cocoon.Constants;
   import org.apache.cocoon.bean.CocoonBean;
  +import org.apache.cocoon.bean.BeanListener;
   
   /**
    * Command line entry point. Parses command line, create Cocoon bean and invokes it
  @@ -80,7 +80,7 @@
    * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
    * @author <a href="mailto:nicolaken@apache.org">Nicola Ken Barozzi</a>
    * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
  - * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a> 
  + * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
    * @version CVS $Id$
    */
   public class Main {
  @@ -165,6 +165,9 @@
       private static final String ATTR_URI_DESTURI = "dest";
   
       private static Options options;
  +    private static List brokenLinks = new ArrayList();
  +    private static String brokenLinkReportFile = null;
  +    private static String brokenLinkReportType = "text";
   
       private static void setOptions() {
           options = new Options();
  @@ -289,7 +292,9 @@
   
           Main.setOptions();
           CommandLine line = new PosixParser().parse( options, args );
  +        CLIListener listener = new Main.CLIListener();
           CocoonBean cocoon = new CocoonBean();
  +        cocoon.addListener(listener);
   
           if (line.hasOption(HELP_OPT)) {
                printUsage();
  @@ -341,7 +346,7 @@
               cocoon.setDefaultFilename(line.getOptionValue(DEFAULT_FILENAME_OPT));
           }
           if (line.hasOption(BROKEN_LINK_FILE_OPT)) {
  -            cocoon.setBrokenLinkReportFile(line.getOptionValue(BROKEN_LINK_FILE_OPT));
  +            brokenLinkReportFile = line.getOptionValue(BROKEN_LINK_FILE_OPT);
           }
           if (line.hasOption(URI_FILE_OPT)) {
               cocoon.addTargets(processURIFile(line.getOptionValue(URI_FILE_OPT)), destDir);
  @@ -359,11 +364,13 @@
           cocoon.addTargets(line.getArgList(), destDir);
   
           System.out.println(getProlog());
  -        
  +
           cocoon.initialize();
           cocoon.process();
           cocoon.dispose();
   
  +        listener.outputBrokenLinks();
  +
           long duration = System.currentTimeMillis() - startTimeMillis;
           System.out.println("Total time: " + (duration / 60000) + " minutes " + (duration % 60000)/1000 + " seconds");
           System.exit(0);
  @@ -508,10 +515,10 @@
   
       private static void parseBrokenLinkNode(CocoonBean cocoon, Node node) throws IllegalArgumentException {
           if (Main.hasAttribute(node, ATTR_BROKEN_LINK_REPORT_FILE)) {
  -            cocoon.setBrokenLinkReportFile(Main.getAttributeValue(node, ATTR_BROKEN_LINK_REPORT_FILE));
  +            brokenLinkReportFile = Main.getAttributeValue(node, ATTR_BROKEN_LINK_REPORT_FILE);
           }
           if (Main.hasAttribute(node, ATTR_BROKEN_LINK_REPORT_TYPE)) {
  -            cocoon.setBrokenLinkReportType(Main.getAttributeValue(node, ATTR_BROKEN_LINK_REPORT_TYPE));
  +            brokenLinkReportType = Main.getAttributeValue(node, ATTR_BROKEN_LINK_REPORT_TYPE);
           }
           if (Main.hasAttribute(node, ATTR_BROKEN_LINK_GENERATE)) {
           cocoon.setBrokenLinkGenerate(Main.getBooleanAttributeValue(node, ATTR_BROKEN_LINK_GENERATE));
  @@ -641,7 +648,7 @@
           msg.append("------------------------------------------------------------------------ ").append(lSep).append(lSep);
           return msg.toString();
       }
  -         
  +
       /**
        * Print the usage message and exit
        */
  @@ -654,12 +661,93 @@
                               "Note: the context directory defaults to '"+ Constants.DEFAULT_CONTEXT_DIR + "'");
           System.exit(0);
       }
  -    
  +
       /**
        * Print the version string and exit
        */
       private static void printVersion() {
           System.out.println(Constants.VERSION);
           System.exit(0);
  -    }    
  +    }
  +    public static class CLIListener implements BeanListener {
  +        public void pageGenerated(String uri, int linksInPage, int pagesRemaining) {
  +            if (linksInPage == -1) {
  +                this.print("* " + uri);
  +            } else {
  +                this.print("* ["+linksInPage + "] "+uri);
  +            }
  +        }
  +        public void messageGenerated(String msg) {
  +            this.print(msg);
  +        }
  +
  +        public void warningGenerated(String uri, String warning) {
  +            this.print("Warning: "+warning + " when generating " + uri);
  +        }
  +
  +        public void brokenLinkFound(String uri, String message) {
  +            brokenLinks.add(uri + "\t" + message);
  +        }
  +
  +        public void outputBrokenLinks() {
  +            if (brokenLinkReportFile == null) {
  +                return;
  +            } else if ("text".equalsIgnoreCase(brokenLinkReportType)) {
  +                outputBrokenLinksAsText();
  +            } else if ("xml".equalsIgnoreCase(brokenLinkReportType)) {
  +                outputBrokenLinksAsXML();
  +            }
  +        }
  +        private void outputBrokenLinksAsText() {
  +            PrintWriter writer;
  +            try {
  +                writer =
  +                        new PrintWriter(
  +                                new FileWriter(new File(brokenLinkReportFile)),
  +                                true);
  +                for (Iterator i = brokenLinks.iterator(); i.hasNext();) {
  +                    writer.println((String) i.next());
  +                }
  +                writer.close();
  +            } catch (IOException ioe) {
  +                this.print("Broken link file does not exist: " + brokenLinkReportFile);
  +            }
  +        }
  +        private void outputBrokenLinksAsXML() {
  +            PrintWriter writer;
  +            try {
  +                writer =
  +                        new PrintWriter(
  +                                new FileWriter(new File(brokenLinkReportFile)),
  +                                true);
  +                writer.println("<broken-links>");
  +                for (Iterator i = brokenLinks.iterator(); i.hasNext();) {
  +                    String linkMsg = (String) i.next();
  +                    String uri = linkMsg.substring(0,linkMsg.indexOf('\t'));
  +                    String msg = linkMsg.substring(linkMsg.indexOf('\t')+1);
  +                    writer.println("  <link message=\"" + msg + "\">" + uri + "</link>");
  +                }
  +                writer.println("</broken-links>");
  +                writer.close();
  +            } catch (IOException ioe) {
  +                this.print("Could not create broken link file: " + brokenLinkReportFile);
  +            }
  +        }
  +        private void print(String message) {
  +            int screenWidth = 67;
  +            int messageWidth = screenWidth - 6;
  +
  +            int messageLength = message.length(), currentStart = -messageWidth, currentEnd = 0;
  +            do {
  +                currentStart += messageWidth;
  +                currentEnd   += messageWidth;
  +
  +                if (currentEnd>messageLength) {
  +                    currentEnd=messageLength;
  +                }
  +
  +                System.out.println(message.substring(currentStart, currentEnd));
  +            } while(currentEnd < messageLength);
  +        }
  +    }
   }
  
  
  
  1.13      +129 -240  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.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- CocoonBean.java	24 Jun 2003 16:44:35 -0000	1.12
  +++ CocoonBean.java	27 Jun 2003 13:50:38 -0000	1.13
  @@ -83,11 +83,9 @@
   import org.apache.log.Logger;
   
   import java.io.File;
  -import java.io.PrintWriter;
   import java.io.IOException;
   import java.io.FileNotFoundException;
   import java.io.FileInputStream;
  -import java.io.FileWriter;
   import java.io.OutputStream;
   import java.io.PrintStream;
   import java.util.Map;
  @@ -118,8 +116,6 @@
       private String contextDir = Constants.DEFAULT_CONTEXT_DIR;
       private String configFile = null;
   
  -    private String brokenLinkReportFile = null;
  -    private String brokenLinkReportType = "text";
       private boolean brokenLinkGenerate = false;
       private String brokenLinkExtension = "";
   
  @@ -133,7 +129,6 @@
       private boolean precompileOnly = false;
       private boolean confirmExtension = true;
       private List classList = new ArrayList();
  -    private List brokenLinks = null;
       private List targets = new ArrayList();
   
       // Objects used alongside User Supplied Parameters
  @@ -151,6 +146,7 @@
       private Map allTranslatedLinks;
       private boolean initialized;
       private boolean verbose;
  +    private List listeners = new ArrayList();
       SourceResolver sourceResolver;
       //
       // INITIALISATION METHOD
  @@ -167,23 +163,20 @@
               String error =
                   "Careful, you must specify a configuration file when using the -c/--contextDir argument";
               log.fatalError(error);
  -            System.out.println(error);
  -            System.exit(1);
  +            throw new ProcessingException(error);
           }
   
           if (workDir.equals("")) {
               String error =
                   "Careful, you must specify a destination dir when using the -w/--workDir argument";
               log.fatalError(error);
  -            System.out.println(error);
  -            System.exit(1);
  +            throw new ProcessingException(error);
           }
   
           if (targets.size() == 0 && !precompileOnly) {
               String error = "Please, specify at least one starting URI.";
               log.fatalError(error);
  -            System.out.println(error);
  -            System.exit(1);
  +            throw new ProcessingException(error);
           }
           setLogLevel("ERROR");
           this.context = getDir(this.contextDir, "context");
  @@ -243,14 +236,6 @@
               cocoon.setLogKitManager(logKitManager);
               ContainerUtil.initialize(cocoon);
   
  -            // I don't understand why not having an error file (on startup) is an error (JT)
  -            //if (brokenLinkReportFile!=null && !(new File(brokenLinkReportFile).exists())) {
  -            //  log.error("Broken Link Report File does not exist: " + brokenLinkReportFile);
  -            //}
  -
  -            if (brokenLinkReportFile != null) {
  -                brokenLinks = new ArrayList();
  -            }
               this.sourceResolver =
                   (SourceResolver) cocoon.getComponentManager().lookup(
                       SourceResolver.ROLE);
  @@ -449,14 +434,6 @@
           this.confirmExtension = confirmExtension;
       }
   
  -    public void setBrokenLinkReportFile(String filename) {
  -        this.brokenLinkReportFile = filename;
  -    }
  -
  -    public void setBrokenLinkReportType(String brokenLinkReportType) {
  -        this.brokenLinkReportType = brokenLinkReportType;
  -    }
  -
       public void setBrokenLinkGenerate(boolean brokenLinkGenerate) {
           this.brokenLinkGenerate = brokenLinkGenerate;
       }
  @@ -518,6 +495,41 @@
           }
       }
   
  +    public void addListener(BeanListener listener) {
  +        this.listeners.add(listener);
  +    }
  +
  +    public void pageGenerated(String uri, int linksInPage, int pagesRemaining) {
  +        Iterator i = listeners.iterator();
  +        while (i.hasNext()) {
  +            BeanListener l = (BeanListener) i.next();
  +            l.pageGenerated(uri, linksInPage, pagesRemaining);
  +        }
  +    }
  +
  +    public void sendMessage(String msg) {
  +        Iterator i = listeners.iterator();
  +        while (i.hasNext()) {
  +            BeanListener l = (BeanListener) i.next();
  +            l.messageGenerated(msg);
  +        }
  +    }
  +
  +    public void sendWarning(String uri, String warning) {
  +        Iterator i = listeners.iterator();
  +        while (i.hasNext()) {
  +            BeanListener l = (BeanListener) i.next();
  +            l.warningGenerated(uri, warning);
  +        }
  +    }
  +
  +    public void sendBrokenLinkWarning(String uri, String warning) {
  +        Iterator i = listeners.iterator();
  +        while (i.hasNext()) {
  +            BeanListener l = (BeanListener) i.next();
  +            l.brokenLinkFound(uri, warning);
  +        }
  +    }
       /**
        * Process single URI into given output stream.
        *
  @@ -633,7 +645,7 @@
                       }
                   }
               } catch (ResourceNotFoundException rnfe) {
  -                printBroken(target.getSourceURI(), rnfe.getMessage());
  +                this.sendBrokenLinkWarning(target.getSourceURI(), rnfe.getMessage());
               }
   
               targetMap.remove(target);
  @@ -657,79 +669,6 @@
           if (nCount == 0) {
               recursivelyPrecompile(context, context);
           }
  -        outputBrokenLinks();
  -    }
  -
  -    /**
  -     * Recurse the directory hierarchy and process the XSP's.
  -     * @param contextDir a <code>File</code> value for the context directory
  -     * @param file a <code>File</code> value for a single XSP file or a directory to scan recursively
  -     */
  -    private void recursivelyPrecompile(File contextDir, File file) {
  -        if (file.isDirectory()) {
  -            String entries[] = file.list();
  -            for (int i = 0; i < entries.length; i++) {
  -                recursivelyPrecompile(contextDir, new File(file, entries[i]));
  -            }
  -        } else if (file.getName().toLowerCase().endsWith(".xmap")) {
  -            try {
  -                this.processXMAP(
  -                    IOUtils.getContextFilePath(
  -                        contextDir.getCanonicalPath(),
  -                        file.getCanonicalPath()));
  -            } catch (Exception e) {
  -                //Ignore for now.
  -            }
  -        } else if (file.getName().toLowerCase().endsWith(".xsp")) {
  -            try {
  -                this.processXSP(
  -                    IOUtils.getContextFilePath(
  -                        contextDir.getCanonicalPath(),
  -                        file.getCanonicalPath()));
  -            } catch (Exception e) {
  -                //Ignore for now.
  -            }
  -        }
  -    }
  -
  -    /**
  -     * Process a single XSP file
  -     *
  -     * @param uri a <code>String</code> pointing to an xsp URI
  -     * @exception Exception if an error occurs
  -     */
  -    private void processXSP(String uri) throws Exception {
  -        String markupLanguage = "xsp";
  -        String programmingLanguage = "java";
  -        Environment env =
  -            new LinkSamplingEnvironment(
  -                "/",
  -                context,
  -                attributes,
  -                null,
  -                cliContext,
  -                new LogKitLogger(log));
  -        this.cocoon.precompile(uri, env, markupLanguage, programmingLanguage);
  -    }
  -
  -    /**
  -     * Process a single XMAP file
  -     *
  -     * @param uri a <code>String</code> pointing to an xmap URI
  -     * @exception Exception if an error occurs
  -     */
  -    private void processXMAP(String uri) throws Exception {
  -        String markupLanguage = "sitemap";
  -        String programmingLanguage = "java";
  -        Environment env =
  -            new LinkSamplingEnvironment(
  -                "/",
  -                context,
  -                attributes,
  -                null,
  -                cliContext,
  -                new LogKitLogger(log));
  -        this.cocoon.precompile(uri, env, markupLanguage, programmingLanguage);
       }
   
       /**
  @@ -767,9 +706,9 @@
        * @exception Exception if an error occurs
        */
       private Collection processTarget(Target target) throws Exception {
  -        System.out.print(" * ");
   
           String uri = target.getSourceURI();
  +        int linkCount = 0;
   
           // Get parameters, deparameterized URI and path from URI
           final TreeMap parameters = new TreeMap();
  @@ -853,7 +792,7 @@
                               translatedAbsoluteLink);
                           absoluteLinks.add(absoluteLink);
                       } catch (ProcessingException pe) {
  -                        printBroken(absoluteLink, pe.getMessage());
  +                        this.sendBrokenLinkWarning(absoluteLink, pe.getMessage());
                       }
                   }
   
  @@ -865,7 +804,7 @@
                   translatedLinks.put(link, translatedRelativeLink);
               }
   
  -            printInfo("[" + translatedLinks.size() + "] ");
  +            linkCount = translatedLinks.size();
           }
   
           try {
  @@ -904,21 +843,15 @@
                           }
                           absoluteLinks.add(absoluteLink);
                       }
  -                    printInfo("[" + gatheredLinks.size() + "] ");
  +                    linkCount = gatheredLinks.size();
                   }
   
  -                printlnInfo(uri); // (can also output type returned by getPage)
  +                pageGenerated(uri, linkCount, 0); // @todo@ get the number of pages remaining here
               } catch (ProcessingException pe) {
                   output.close();
                   output = null;
  -                if (brokenLinkGenerate) {
  -                    String brokenFile = NetUtils.decodePath(filename);
  -                    if (brokenLinkExtension != null) {
  -                        brokenFile = brokenFile + brokenLinkExtension;
  -                    }
  -                    resourceUnavailable(target, uri);
  -                }
  -                printBroken(
  +                this.resourceUnavailable(target, uri, filename);
  +                this.sendBrokenLinkWarning(
                       filename,
                       DefaultNotifyingBuilder.getRootCause(pe).getMessage());
               } finally {
  @@ -942,11 +875,8 @@
                   }
               }
           } catch (Exception rnfe) {
  -            System.out.println("XXX" + rnfe);
               log.warn("Could not process URI: " + deparameterizedURI);
  -            if (verbose)
  -                System.out.println(
  -                    "Could not process URI: " + deparameterizedURI);
  +            this.sendBrokenLinkWarning(deparameterizedURI, "URI not found");
           }
   
           List targets = new ArrayList();
  @@ -961,6 +891,60 @@
       }
   
       /**
  +     * Recurse the directory hierarchy and process the XSP's.
  +     * @param contextDir a <code>File</code> value for the context directory
  +     * @param file a <code>File</code> value for a single XSP file or a directory to scan recursively
  +     */
  +    private void recursivelyPrecompile(File contextDir, File file) {
  +        if (file.isDirectory()) {
  +            String entries[] = file.list();
  +            for (int i = 0; i < entries.length; i++) {
  +                recursivelyPrecompile(contextDir, new File(file, entries[i]));
  +            }
  +        } else if (file.getName().toLowerCase().endsWith(".xmap")) {
  +            try {
  +                this.processXMAP(IOUtils.getContextFilePath(contextDir.getCanonicalPath(),file.getCanonicalPath()));
  +            } catch (Exception e){
  +                //Ignore for now.
  +            }
  +        } else if (file.getName().toLowerCase().endsWith(".xsp")) {
  +            try {
  +                this.processXSP(IOUtils.getContextFilePath(contextDir.getCanonicalPath(),file.getCanonicalPath()));
  +            } catch (Exception e){
  +                //Ignore for now.
  +            }
  +        }
  +    }
  +
  +    /**
  +     * Process a single XSP file
  +     *
  +     * @param uri a <code>String</code> pointing to an xsp URI
  +     * @exception Exception if an error occurs
  +     */
  +    private void processXSP(String uri) throws Exception {
  +        String markupLanguage = "xsp";
  +        String programmingLanguage = "java";
  +        Environment env = new LinkSamplingEnvironment("/", context, attributes, null, cliContext,
  +                                                      new LogKitLogger(log));
  +        cocoon.precompile(uri, env, markupLanguage, programmingLanguage);
  +    }
  +
  +    /**
  +     * Process a single XMAP file
  +     *
  +     * @param uri a <code>String</code> pointing to an xmap URI
  +     * @exception Exception if an error occurs
  +     */
  +    private void processXMAP(String uri) throws Exception {
  +        String markupLanguage = "sitemap";
  +        String programmingLanguage = "java";
  +        Environment env = new LinkSamplingEnvironment("/", context, attributes, null, cliContext,
  +                                                      new LogKitLogger(log));
  +        cocoon.precompile(uri, env, markupLanguage, programmingLanguage);
  +    }
  +
  +    /**
        * Translate an URI into a file name.
        *
        * @param uri a <code>String</code> value to map
  @@ -969,9 +953,8 @@
        */
       private String translateURI(String uri) throws Exception {
           if (null == uri || "".equals(uri)) {
  -            log.warn("translate empty uri");
  -            if (verbose)
  -                System.out.println("translate empty uri");
  +            log.warn("cannot translate empty uri");
  +            if (verbose) sendMessage("cannot translate empty uri");
               return "";
           }
           HashMap parameters = new HashMap();
  @@ -995,135 +978,41 @@
       }
   
       /**
  -      * Print the message of a broken link.
  -      *
  -      * @param url the <code>URL</code> of the broken link
  -      * @param cause of the broken link
  -      */
  -    private void printBroken(String url, String cause) {
  -        int screenWidth = 67;
  -        int causeWidth = screenWidth - 6;
  -
  -        printlnInfo("");
  -        printlnInfo("-> [broken page] " + url + " <- ");
  -        printlnInfo("");
  -        printInfo("     ");
  -
  -        int causeLength = cause.length(),
  -            currentStart = -causeWidth,
  -            currentEnd = 0;
  -        do {
  -            currentStart += causeWidth;
  -            currentEnd += causeWidth;
  -
  -            if (currentEnd > causeLength) {
  -                currentEnd = causeLength;
  -            }
  -
  -            printlnInfo(cause.substring(currentStart, currentEnd));
  -            printInfo("     ");
  -        } while (currentEnd < causeLength);
  -
  -        printlnInfo("");
  -
  -        if (null != this.brokenLinks) {
  -            brokenLinks.add(url);
  -        }
  -    }
  -
  -    /**
  -     * Print an info message.
  -     *
  -     * @param message the message to print
  -     */
  -    private void printlnInfo(String message) {
  -        log.info(message);
  -        if (verbose)
  -            System.out.println(message);
  -    }
  -
  -    /**
  -     * Print an info message.
  -     *
  -     * @param message the message to print
  -     */
  -    private void printInfo(String message) {
  -        log.info(message);
  -        if (verbose)
  -            System.out.print(message);
  -    }
  -
  -    /**
        * Generate a <code>resourceUnavailable</code> message.
        *
        * @param target being unavailable
        * @exception IOException if an error occurs
        */
  -    private void resourceUnavailable(Target target, String uri)
  +    private void resourceUnavailable(Target target, String uri, String filename)
           throws IOException, ProcessingException {
  -        SimpleNotifyingBean n = new SimpleNotifyingBean(this);
  -        n.setType("resource-not-found");
  -        n.setTitle("Resource not Found");
  -        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);
  +        if (brokenLinkGenerate) {
  +            String brokenFile = NetUtils.decodePath(filename);
  +            if (brokenLinkExtension != null) {
  +                brokenFile = brokenFile + brokenLinkExtension;
  +            }
  +            SimpleNotifyingBean n = new SimpleNotifyingBean(this);
  +            n.setType("resource-not-found");
  +            n.setTitle("Resource not Found");
  +            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);
   
  -        ModifiableSource source = target.getSource(uri);
  -        try {
  -            OutputStream stream = source.getOutputStream();
  +            ModifiableSource source = target.getSource(filename);
  +            try {
  +                OutputStream stream = source.getOutputStream();
   
  -            PrintStream out = new PrintStream(stream);
  -            Notifier.notify(n, out, "text/html");
  -            out.flush();
  -            out.close();
  -        } finally {
  -            target.releaseSource(source);
  +                PrintStream out = new PrintStream(stream);
  +                Notifier.notify(n, out, "text/html");
  +                out.flush();
  +                out.close();
  +            } finally {
  +                target.releaseSource(source);
  +            }
           }
       }
   
  -    private void outputBrokenLinks() {
  -        if (brokenLinkReportFile == null) {
  -            return;
  -        } else if ("text".equalsIgnoreCase(brokenLinkReportType)) {
  -            outputBrokenLinksAsText();
  -        } else if ("xml".equalsIgnoreCase(brokenLinkReportType)) {
  -            outputBrokenLinksAsXML();
  -        }
  -    }
  -    private void outputBrokenLinksAsText() {
  -        PrintWriter writer;
  -        try {
  -            writer =
  -                new PrintWriter(
  -                    new FileWriter(new File(brokenLinkReportFile)),
  -                    true);
  -            for (Iterator i = brokenLinks.iterator(); i.hasNext();) {
  -                writer.println((String) i.next());
  -            }
  -            writer.close();
  -        } catch (IOException ioe) {
  -            log.error("File does not exist: " + brokenLinkReportFile);
  -        }
  -    }
  -    private void outputBrokenLinksAsXML() {
  -        PrintWriter writer;
  -        try {
  -            writer =
  -                new PrintWriter(
  -                    new FileWriter(new File(brokenLinkReportFile)),
  -                    true);
  -            writer.println("<broken-links>");
  -            for (Iterator i = brokenLinks.iterator(); i.hasNext();) {
  -                writer.println("  <link>" + (String) i.next() + "</link>");
  -            }
  -            writer.println("</broken-links>");
  -            writer.close();
  -        } catch (IOException ioe) {
  -            log.error("File does not exist: " + brokenLinkReportFile);
  -        }
  -    }
       /**
        * Mangle a URI.
        *
  
  
  
  1.1                  cocoon-2.1/src/java/org/apache/cocoon/bean/BeanListener.java
  
  Index: BeanListener.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <st...@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.bean;
  
  /**
   * Interface allowing caller to install a listener so that it can be informed
   * as the bean makes progress through the links to be called.
   *
   * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
   * @version CVS $Id: BeanListener.java,v 1.1 2003/06/27 13:50:38 upayavira Exp $
   */
  public interface BeanListener {
  
      /**
       * Report a page as successfully generated
       * @param uri            URI of page that has been generated
       * @param linksInPage    Number of links found in this page
       * @param pagesRemaining Number of pages still to be generated
       */
      public void pageGenerated(String uri, int linksInPage, int pagesRemaining);
  
      /**
       * Report a general message about operation of the bean
       * @param msg            The message to be reported
       */
      public void messageGenerated(String msg);
  
      /**
       * Report a warning about something non-fatal that happened within
       * the bean.
       * @param uri            The page being generated when warning was triggered
       * @param warning        The warning to be reported
       */
      public void warningGenerated(String uri, String warning);
  
      /**
       * Report a broken link
       * @param uri            The URI that failed to be generated
       * @param message        A reason why the link was not generated
       */
      public void brokenLinkFound(String uri, String message);
  }