1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.pipeline.config;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.URL;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27 import org.apache.commons.digester.Digester;
28 import org.apache.commons.digester.RuleSet;
29 import org.apache.commons.pipeline.PipelineCreationException;
30 import org.apache.commons.pipeline.Pipeline;
31 import org.xml.sax.SAXException;
32
33
34 /**
35 * This factory is designed to simplify creating a pipeline using Digester.
36 * @see PipelineRuleSet for additional information on the format of the
37 * XML configuration file.
38 */
39 public class DigesterPipelineFactory implements org.apache.commons.pipeline.PipelineFactory {
40
41 /** Digester rule sets used to configure the Digester instance. */
42 private List<RuleSet> ruleSets = new ArrayList<RuleSet>();
43
44 /**
45 * Factory will create a pipeline from the specified Digester configuration file
46 * if this filename is not null.
47 */
48 private URL confURL;
49
50 /**
51 * A factory created by this constructor will create a pipeline from the specified
52 * XML configuration file.
53 * @param configFile the XML file containing pipeline configuration information
54 */
55 public DigesterPipelineFactory(URL confURL) {
56 if (confURL == null) throw new IllegalArgumentException("Configuration file URL may not be null.");
57 this.confURL = confURL;
58
59 //PipelineRuleSet needs a reference to {@link org.apache.commons.digester.RuleSet RuleSet}s
60 //used to parse the configuration file in case configuration is split up between multiple
61 //files.
62 ruleSets.add(new PipelineRuleSet(ruleSets));
63 }
64
65 /**
66 * Creates a new pipeline based upon the configuration of this factory instance.
67 * @throws org.apache.commons.pipeline.PipelineCreationException Thrown if an error is encountered parsing the configuration file.
68 * @return The newly created pipeline instance
69 */
70 public Pipeline createPipeline() throws PipelineCreationException {
71 try {
72 Digester digester = new Digester();
73 this.initDigester(digester);
74
75 InputStream in = confURL.openStream();
76 try {
77 return (Pipeline) digester.parse(in);
78 } finally {
79 in.close();
80 }
81 } catch (IOException e) {
82 throw new PipelineCreationException("An IOException occurred reading the configuration file: " + e.getMessage(), e);
83 } catch (SAXException e) {
84 throw new PipelineCreationException("A formatting error exists in the configuration file: " + e.getMessage(), e);
85 }
86 }
87
88 /**
89 * Initialize a Digester instance with the rule sets provided to this factory.
90 * @param digester The digester instance to be initialized
91 */
92 public void initDigester(Digester digester) {
93 for (Iterator iter = ruleSets.iterator(); iter.hasNext();) {
94 digester.addRuleSet((RuleSet) iter.next());
95 }
96 }
97
98 /**
99 * 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 }