KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > transformation > ParserTransformer


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.cocoon.transformation;
18
19 import net.sourceforge.chaperon.build.ParserAutomatonBuilder;
20 import net.sourceforge.chaperon.model.grammar.Grammar;
21 import net.sourceforge.chaperon.model.grammar.GrammarFactory;
22 import net.sourceforge.chaperon.process.ParserAutomaton;
23 import net.sourceforge.chaperon.process.ParserProcessor;
24
25 import org.apache.avalon.excalibur.pool.Recyclable;
26 import org.apache.avalon.framework.activity.Disposable;
27 import org.apache.avalon.framework.logger.LogEnabled;
28 import org.apache.avalon.framework.logger.Logger;
29 import org.apache.avalon.framework.parameters.ParameterException;
30 import org.apache.avalon.framework.parameters.Parameterizable;
31 import org.apache.avalon.framework.parameters.Parameters;
32 import org.apache.avalon.framework.service.ServiceException;
33 import org.apache.avalon.framework.service.ServiceManager;
34 import org.apache.avalon.framework.service.Serviceable;
35
36 import org.apache.cocoon.ProcessingException;
37 import org.apache.cocoon.caching.CacheableProcessingComponent;
38 import org.apache.cocoon.components.source.SourceUtil;
39 import org.apache.cocoon.environment.SourceResolver;
40 import org.apache.cocoon.xml.XMLConsumer;
41
42 import org.apache.excalibur.source.Source;
43 import org.apache.excalibur.source.SourceException;
44 import org.apache.excalibur.source.SourceValidity;
45 import org.apache.excalibur.store.Store;
46
47 import org.xml.sax.SAXException JavaDoc;
48
49 import java.io.IOException JavaDoc;
50 import java.io.Serializable JavaDoc;
51
52 import java.util.Map JavaDoc;
53
54 /**
55  * This transfomer transforms lexical tokens in a XML file into a XML hirachy by using a grammar
56  * file.
57  *
58  * <p>
59  * Input:
60  * </p>
61  * <pre>
62  * &lt;lexemes xmlns="http://chaperon.sourceforge.net/schema/lexemes/1.0"&gt;
63  * &lt;lexeme symbol="word" text="Text"/&gt;
64  * &lt;lexeme symbol="number" text="123"/&gt;
65  * &lt;lexeme symbol="word" text="bla"/&gt;
66  * &lt;/lexemes&gt;
67  * </pre>
68  *
69  * <p>
70  * were transform into the following output:
71  * </p>
72  * <pre>
73  * &lt;sentence xmlns="http://chaperon.sourceforge.net/schema/syntaxtree/1.0"&gt;
74  * &lt;word&gt;Text&lt;/word&gt;
75  * &lt;number&gt;123&lt;/number&gt;
76  * &lt;word&gt;bla&lt;/word&gt;
77  * &lt;/sentence&gt;
78  * </pre>
79  *
80  * @author <a HREF="mailto:stephan@apache.org">Stephan Michels </a>
81  * @version CVS $Id: ParserTransformer.java 124685 2005-01-08 22:20:56Z antonio $
82  */

83 public class ParserTransformer extends ParserProcessor
84         implements Transformer, LogEnabled, Serviceable, Parameterizable,
85                    Recyclable, Disposable, CacheableProcessingComponent
86 {
87   private String JavaDoc grammar = null;
88   private Source grammarSource = null;
89   private Logger logger = null;
90   private ServiceManager manager = null;
91   private SourceResolver resolver = null;
92
93   /**
94    * Provide component with a logger.
95    *
96    * @param logger the logger
97    */

98   public void enableLogging(Logger logger)
99   {
100     this.logger = logger;
101
102     // TODO: check if the loglevel is correct LogKitLogger -> Logger
103
// setLog(new AvalonLogger(logger));
104
//setLog(new ConsoleLog());
105
}
106
107   /**
108    * Pass the ServiceManager to the object. The Serviceable implementation should use the
109    * specified ServiceManager to acquire the services it needs for execution.
110    *
111    * @param manager The ServiceManager which this Serviceable uses.
112    */

113   public void service(ServiceManager manager)
114   {
115     this.manager = manager;
116   }
117
118   /**
119    * Provide component with parameters.
120    *
121    * @param parameters the parameters
122    *
123    * @throws ParameterException if parameters are invalid
124    */

125   public void parameterize(Parameters parameters) throws ParameterException
126   {
127     setFlatten(parameters.getParameterAsBoolean("flatten", false));
128
129     //setRecovery(parameters.getParameterAsBoolean("recovery", false));
130
setLocalizable(parameters.getParameterAsBoolean("localizable", false));
131   }
132
133   /**
134    * Set the <code>XMLConsumer</code> that will receive XML data.
135    *
136    * @param consumer
137    */

138   public void setConsumer(XMLConsumer consumer)
139   {
140     setContentHandler(consumer);
141     setLexicalHandler(consumer);
142   }
143
144   /**
145    * Set the SourceResolver, objectModel Map, the source and sitemap Parameters used to process the
146    * request.
147    *
148    * @param resolver Source resolver
149    * @param objectmodel Object model
150    * @param src Source
151    * @param parameters Parameters
152    *
153    * @throws IOException
154    * @throws ProcessingException
155    * @throws SAXException
156    */

157   public void setup(SourceResolver resolver, Map JavaDoc objectmodel, String JavaDoc src, Parameters parameters)
158     throws ProcessingException, SAXException JavaDoc, IOException JavaDoc
159   {
160     this.resolver = resolver;
161
162     setFailSafe(parameters.getParameterAsBoolean("failsafe", false));
163
164     Store store = null;
165     try
166     {
167       this.grammar = src;
168
169       this.grammarSource = resolver.resolveURI(this.grammar);
170
171       // Retrieve the parser automaton from the transient store
172
store = (Store)this.manager.lookup(Store.TRANSIENT_STORE);
173
174       ParserAutomatonEntry entry = (ParserAutomatonEntry)store.get(this.grammarSource.getURI());
175
176       // If the parser automaton has changed, rebuild the parser automaton
177
if ((entry==null) || (entry.getValidity()==null) ||
178           ((entry.getValidity().isValid(this.grammarSource.getValidity()))<=0))
179       {
180         this.logger.info("(Re)building the automaton from '"+this.grammarSource.getURI()+"'");
181
182         //SAXConfigurationHandler confighandler = new SAXConfigurationHandler();
183
if (this.grammarSource.getInputStream()==null)
184           throw new ProcessingException("Source '"+this.grammarSource.getURI()+"' not found");
185
186         GrammarFactory factory = new GrammarFactory();
187         SourceUtil.toSAX(this.manager, this.grammarSource, null, factory);
188
189         //Configuration config = confighandler.getConfiguration();
190
//Grammar grammar = GrammarFactory.createGrammar(config);
191
Grammar grammar = factory.getGrammar();
192
193         if (grammar==null)
194           throw new ProcessingException("Error while reading the grammar from "+src);
195
196         ParserAutomatonBuilder builder =
197           new ParserAutomatonBuilder(grammar /*, new AvalonLogger(logger)*/);
198
199         ParserAutomaton automaton = builder.getParserAutomaton();
200         setParserAutomaton(builder.getParserAutomaton());
201
202         this.logger.info("Store automaton into store for '"+this.grammarSource.getURI()+"'");
203         store.store(this.grammarSource.getURI(),
204                     new ParserAutomatonEntry(automaton, this.grammarSource.getValidity()));
205       }
206       else
207       {
208         this.logger.info("Getting automaton from store for '"+this.grammarSource.getURI()+"'");
209         setParserAutomaton(entry.getParserAutomaton());
210       }
211     }
212     catch (SourceException se)
213     {
214       throw new ProcessingException("Error during resolving of '"+src+"'.", se);
215     }
216     catch (ServiceException se)
217     {
218       throw new ProcessingException("Could not lookup for service", se);
219     }
220     finally
221     {
222       if (store!=null)
223         this.manager.release(store);
224     }
225   }
226
227   /**
228    * Generate the unique key. This key must be unique inside the space of this component.
229    *
230    * @return The generated key hashes the src
231    */

232   public Serializable JavaDoc getKey()
233   {
234     return this.grammarSource.getURI();
235   }
236
237   /**
238    * Generate the validity object.
239    *
240    * @return The generated validity object or <code>null</code> if the component is currently not
241    * cacheable.
242    */

243   public SourceValidity getValidity()
244   {
245     return this.grammarSource.getValidity();
246   }
247
248   /**
249    * Recycle this component. All instance variables are set to <code>null</code>.
250    */

251   public void recycle()
252   {
253     if ((this.resolver!=null) && (this.grammarSource!=null))
254     {
255       this.resolver.release(this.grammarSource);
256       this.grammarSource = null;
257     }
258   }
259
260   /**
261    * The dispose operation is called at the end of a components lifecycle.
262    */

263   public void dispose()
264   {
265     if ((this.resolver!=null) && (this.grammarSource!=null))
266     {
267       this.resolver.release(this.grammarSource);
268       this.grammarSource = null;
269     }
270
271     this.manager = null;
272   }
273
274   /**
275    * This class represent a entry in a store to cache the parser automaton.
276    */

277   public static class ParserAutomatonEntry implements Serializable JavaDoc {
278     private SourceValidity validity = null;
279     private ParserAutomaton automaton = null;
280
281     /**
282      * Create a new entry.
283      *
284      * @param automaton Parser automaton.
285      * @param validity Validity for the grammar file.
286      */

287     public ParserAutomatonEntry(ParserAutomaton automaton, SourceValidity validity)
288     {
289       this.automaton = automaton;
290       this.validity = validity;
291     }
292
293     /**
294      * Return the validity of the grammar file.
295      *
296      * @return Validity of the grammar file.
297      */

298     public SourceValidity getValidity()
299     {
300       return this.validity;
301     }
302
303     /**
304      * Return the parser automaton.
305      *
306      * @return Parser automaton.
307      */

308     public ParserAutomaton getParserAutomaton()
309     {
310       return this.automaton;
311     }
312
313     private void writeObject(java.io.ObjectOutputStream JavaDoc out)
314       throws IOException JavaDoc
315     {
316       out.writeObject(validity);
317       out.writeObject(automaton);
318     }
319
320     private void readObject(java.io.ObjectInputStream JavaDoc in)
321       throws IOException JavaDoc, ClassNotFoundException JavaDoc
322     {
323       validity = (SourceValidity)in.readObject();
324       automaton = (ParserAutomaton)in.readObject();
325     }
326   }
327 }
328
Popular Tags