001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.pipeline.config;
019
020 import java.io.File;
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.net.URL;
024 import java.util.ArrayList;
025 import java.util.Iterator;
026 import java.util.List;
027 import org.apache.commons.digester.Digester;
028 import org.apache.commons.digester.RuleSet;
029 import org.apache.commons.pipeline.PipelineCreationException;
030 import org.apache.commons.pipeline.Pipeline;
031 import org.xml.sax.SAXException;
032
033
034 /**
035 * This factory is designed to simplify creating a pipeline using Digester.
036 * @see PipelineRuleSet for additional information on the format of the
037 * XML configuration file.
038 */
039 public class DigesterPipelineFactory implements org.apache.commons.pipeline.PipelineFactory {
040
041 /** Digester rule sets used to configure the Digester instance. */
042 private List<RuleSet> ruleSets = new ArrayList<RuleSet>();
043
044 /**
045 * Factory will create a pipeline from the specified Digester configuration file
046 * if this filename is not null.
047 */
048 private URL confURL;
049
050 /**
051 * A factory created by this constructor will create a pipeline from the specified
052 * XML configuration file.
053 * @param configFile the XML file containing pipeline configuration information
054 */
055 public DigesterPipelineFactory(URL confURL) {
056 if (confURL == null) throw new IllegalArgumentException("Configuration file URL may not be null.");
057 this.confURL = confURL;
058
059 //PipelineRuleSet needs a reference to {@link org.apache.commons.digester.RuleSet RuleSet}s
060 //used to parse the configuration file in case configuration is split up between multiple
061 //files.
062 ruleSets.add(new PipelineRuleSet(ruleSets));
063 }
064
065 /**
066 * Creates a new pipeline based upon the configuration of this factory instance.
067 * @throws org.apache.commons.pipeline.PipelineCreationException Thrown if an error is encountered parsing the configuration file.
068 * @return The newly created pipeline instance
069 */
070 public Pipeline createPipeline() throws PipelineCreationException {
071 try {
072 Digester digester = new Digester();
073 this.initDigester(digester);
074
075 InputStream in = confURL.openStream();
076 try {
077 return (Pipeline) digester.parse(in);
078 } finally {
079 in.close();
080 }
081 } catch (IOException e) {
082 throw new PipelineCreationException("An IOException occurred reading the configuration file: " + e.getMessage(), e);
083 } catch (SAXException e) {
084 throw new PipelineCreationException("A formatting error exists in the configuration file: " + e.getMessage(), e);
085 }
086 }
087
088 /**
089 * Initialize a Digester instance with the rule sets provided to this factory.
090 * @param digester The digester instance to be initialized
091 */
092 public void initDigester(Digester digester) {
093 for (Iterator iter = ruleSets.iterator(); iter.hasNext();) {
094 digester.addRuleSet((RuleSet) iter.next());
095 }
096 }
097
098 /**
099 * Adds a RuleSet to the list of rules available to Digester for parsing
100 * the configuration file.
101 * @param ruleSet The rule set to be added to the Digester
102 */
103 public void addRuleSet(RuleSet ruleSet) {
104 this.ruleSets.add(ruleSet);
105 }
106
107 /**
108 * The simplest possible main method that creates a pipeline from a configuration file,
109 * then runs the pipeline processing from start to finish.
110 *
111 * When run from the command line, the only argument to this method should be
112 * the path to the configuration file.
113 *
114 * @param argv the command line arguments
115 */
116 public static void main(String[] argv) {
117 try {
118 File configFile = new File(argv[0]);
119
120 DigesterPipelineFactory factory = new DigesterPipelineFactory(configFile.toURL());
121 Pipeline pipeline = factory.createPipeline();
122 for (int i = 1; i < argv.length; i++) {
123 pipeline.getSourceFeeder().feed(argv[i]);
124 }
125
126 System.out.println("Pipeline created, about to begin processing...");
127
128 pipeline.start();
129 pipeline.finish();
130
131 System.out.println("Pipeline successfully finished processing. See logs for details.");
132 } catch (Exception e) {
133 e.printStackTrace(System.err);
134 }
135 }
136 }