View Javadoc

1   package org.apache.velocity.site.doxia.renderer;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.Reader;
23  import java.io.StringReader;
24  import java.lang.reflect.Method;
25  
26  import org.apache.maven.doxia.parser.AbstractParser;
27  import org.apache.maven.doxia.parser.ParseException;
28  import org.apache.maven.doxia.parser.Parser;
29  import org.apache.maven.doxia.sink.Sink;
30  import org.apache.velocity.site.doxia.plugin.DoxiaVelocityRendererPlugin;
31  import org.apache.velocity.site.doxia.runner.DefaultVelocityRunner;
32  import org.apache.velocity.site.doxia.runner.VelocityRunner;
33  import org.apache.velocity.site.plexus.PlexusKludgeException;
34  import org.apache.velocity.site.plexus.PlexusKludgeUtils;
35  import org.codehaus.plexus.PlexusConstants;
36  import org.codehaus.plexus.PlexusContainer;
37  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
38  import org.codehaus.plexus.context.Context;
39  import org.codehaus.plexus.context.ContextException;
40  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
41  
42  /**
43   * <p>
44   * This is the base class for the various parsers. This does not run inside the
45   * Mojo API and the plugin cycle but gets instantiated by Plexus itself.
46   * </p>
47   *
48   * <p>
49   * <b>NOTE:</b> This parser could be so much easier if it were possible to
50   * inject the ParserManager. Then only one instance would be needed and the
51   * class could decide whether the supplied input was XDoc or APT or something
52   * else. However, Plexus chokes on cyclic definitions (The Parsers are injected
53   * into the ParserManager which in turn should be injected into one Parser).
54   * Maybe the Plexus authors should do less Spring bashing (Spring gets this
55   * right) and fix their injectors...
56   * </p>
57   *
58   * @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
59   * @version $Revision: 526751 $
60   */
61  public abstract class AbstractVelocityRenderer extends AbstractParser implements Contextualizable
62  
63  {
64      protected PlexusContainer container = null;
65  
66      private final String roleHint;
67  
68      /**
69       * Creates a new AbstractVelocityRenderer object.
70       */
71      protected AbstractVelocityRenderer(final String roleHint)
72      {
73          this.roleHint = roleHint;
74      }
75  
76      public void contextualize(final Context context) throws ContextException
77      {
78          this.container = (PlexusContainer) context.get(PlexusConstants.PLEXUS_KEY);
79      }
80  
81      /**
82       * Returns the actual Parser (currently only Apt and Xdoc) must be injected
83       * into an instance of this component. This is where the Xdoc and the Apt
84       * parser differ.
85       *
86       * @return A {@link Parser} instance that is the actual parser for this
87       *         document type once Velocity processed the template.
88       */
89      protected Parser getParser() throws ComponentLookupException
90      {
91          return (Parser) container.lookup(Parser.ROLE, roleHint);
92      }
93  
94      /**
95       * This is the actual parsing stage. We fetch the Runner object from the
96       * doxia-renderer plugin and execute the parse method on it.
97       *
98       * @param reader
99       *            The reader which returns the actual template data.
100      * @param sink
101      *            The Doxia Sink to send our information to.
102      *
103      * @throws parseException
104      *             When Velocity can not load or process the template.
105      */
106     public final synchronized void parse(final Reader reader, final Sink sink) throws ParseException
107     {
108         try
109         {
110             Object runner = getVelocityRunner();
111             Method parseVelocity = runner.getClass().getMethod(VelocityRunner.PARSE_METHOD, VelocityRunner.PARSE_METHOD_SIGNATURE);
112             String result = (String) parseVelocity.invoke(runner, new Object[] { reader });
113 
114             StringReader strReader = new StringReader(result);
115 
116             getParser().parse(strReader, sink);
117         }
118         catch (RuntimeException re)
119         {
120             throw re;
121         }
122         catch (Exception e)
123         {
124             throw new ParseException(e);
125         }
126     }
127 
128     /**
129      * Returns the Velocity Context factory which contains the values set by the
130      * Plugin for the Velocity renderer.
131      *
132      * It must be injected into an instance of this component.
133      *
134      * @return A {@link DoxiaVelocityContextFactory} instance that generates
135      *         {@link VelocityContext} objects for the render process.
136      */
137     private Object getVelocityRunner() throws ComponentLookupException
138     {
139         try
140         {
141             PlexusContainer velocityContainer = PlexusKludgeUtils.lookupContainer(container,
142                     DoxiaVelocityRendererPlugin.CONTAINER_LOOKUP_NAME);
143             return velocityContainer.lookup(DefaultVelocityRunner.ROLE);
144         }
145         catch (PlexusKludgeException pke)
146         {
147             throw new ComponentLookupException("While retrieving Velocity runner: ", pke);
148         }
149     }
150 }