View Javadoc
1   package org.apache.maven.doxia.parser;
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.File;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.Reader;
26  import java.io.StringReader;
27  
28  import java.util.Properties;
29  
30  import org.apache.maven.doxia.logging.Log;
31  import org.apache.maven.doxia.logging.SystemStreamLog;
32  import org.apache.maven.doxia.macro.Macro;
33  import org.apache.maven.doxia.macro.MacroExecutionException;
34  import org.apache.maven.doxia.macro.MacroRequest;
35  import org.apache.maven.doxia.macro.manager.MacroManager;
36  import org.apache.maven.doxia.macro.manager.MacroNotFoundException;
37  import org.apache.maven.doxia.sink.Sink;
38  import org.codehaus.plexus.component.annotations.Requirement;
39  
40  /**
41   * An abstract base class that defines some convenience methods for parsers.
42   * Provides a macro mechanism to give dynamic functionalities for the parsing.
43   *
44   * @author Jason van Zyl
45   * @since 1.0
46   */
47  public abstract class AbstractParser
48      implements Parser
49  {
50      /** Indicates that a second parsing is required. */
51      private boolean secondParsing = false;
52  
53      @Requirement
54      private MacroManager macroManager;
55  
56      /** Log instance. */
57      private Log logger;
58  
59      /**
60       * Emit Doxia comment events when parsing comments?
61       */
62      private boolean emitComments = true;
63  
64      private static final String DOXIA_VERSION;
65  
66      static
67      {
68          final Properties props = new Properties();
69          final InputStream is = AbstractParser.class.getResourceAsStream( "/build-info.properties" );
70  
71          if ( is == null )
72          {
73              props.setProperty( "version", "unknown" ); // should not happen
74          }
75          else
76          {
77              try
78              {
79                  props.load( is );
80              }
81              catch ( IOException ex )
82              {
83                  props.setProperty( "version", "unknown" ); // should not happen
84              }
85              finally
86              {
87                  try
88                  {
89                      is.close();
90                  }
91                  catch ( IOException ex )
92                  {
93                      // oh well...
94                  }
95              }
96          }
97  
98          DOXIA_VERSION = props.getProperty( "version" );
99      }
100 
101     /**
102      * {@inheritDoc}
103      *
104      * @return a int
105      */
106     public int getType()
107     {
108         return UNKNOWN_TYPE;
109     }
110 
111     /** {@inheritDoc} */
112     public void setEmitComments( boolean emitComments )
113     {
114         this.emitComments = emitComments;
115     }
116 
117     /**
118      * <p>isEmitComments.</p>
119      *
120      * @return a boolean
121      */
122     public boolean isEmitComments()
123     {
124         return emitComments;
125     }
126 
127     /**
128      * Execute a macro on the given sink.
129      *
130      * @param macroId an id to lookup the macro
131      * @param request the corresponding MacroRequest
132      * @param sink the sink to receive the events
133      * @throws org.apache.maven.doxia.macro.MacroExecutionException if an error occurred during execution
134      * @throws org.apache.maven.doxia.macro.manager.MacroNotFoundException if the macro could not be found
135      */
136     // Made public right now because of the structure of the APT parser and
137     // all its inner classes.
138     public void executeMacro( String macroId, MacroRequest request, Sink sink )
139         throws MacroExecutionException, MacroNotFoundException
140     {
141         Macro macro = getMacroManager().getMacro( macroId );
142 
143         macro.enableLogging( getLog() );
144 
145         macro.execute( sink, request );
146     }
147 
148     /**
149      * Returns the current base directory.
150      *
151      * @return the base directory
152      * @deprecated this does not work in multi-module builds, see DOXIA-373
153      */
154     protected File getBasedir()
155     {
156         // TODO: This is baaad, it should come in with the request.
157         // (this is only used for macro requests, see AptParser)
158 
159         String basedir = System.getProperty( "basedir" );
160 
161         if ( basedir != null )
162         {
163             return new File( basedir );
164         }
165 
166         return new File( new File( "" ).getAbsolutePath() );
167     }
168 
169     /**
170      * {@inheritDoc}
171      *
172      * Convenience method to parse an arbitrary string and emit events into the given sink.
173      *
174      * @param string a string that provides the source input
175      * @param sink a sink that consumes the Doxia events
176      * @throws org.apache.maven.doxia.parser.ParseException if the string could not be parsed
177      * @since 1.1
178      */
179     public void parse( String string, Sink sink )
180         throws ParseException
181     {
182         this.parse( string, sink, null );
183     }
184 
185     /**
186      * {@inheritDoc}
187      *
188      * Convenience method to parse an arbitrary string and emit events into the given sink.
189      *
190      * @param string a string that provides the source input
191      * @param sink a sink that consumes the Doxia events
192      * @param reference a string containing the reference to the source of the input string (e.g. filename)
193      * @throws org.apache.maven.doxia.parser.ParseException if the string could not be parsed
194      * @since 1.10
195      */
196     public void parse( String string, Sink sink, String reference )
197         throws ParseException
198     {
199         parse( new StringReader( string ), sink, reference );
200     }
201 
202     /** {@inheritDoc} */
203     @Override
204     public void parse( Reader source, Sink sink )
205         throws ParseException
206     {
207         parse( source, sink, null );
208     }
209 
210     /**
211      * Set <code>secondParsing</code> to true, if we need a second parsing.
212      *
213      * @param second true for second parsing
214      */
215     public void setSecondParsing( boolean second )
216     {
217         this.secondParsing = second;
218     }
219 
220     /**
221      * Indicates if we are currently parsing a second time.
222      *
223      * @return true if we are currently parsing a second time
224      * @since 1.1
225      */
226     protected boolean isSecondParsing()
227     {
228         return secondParsing;
229     }
230 
231     /** {@inheritDoc} */
232     public void enableLogging( Log log )
233     {
234         this.logger = log;
235     }
236 
237     /**
238      * Returns the current logger for this parser.
239      * If no logger has been configured yet, a new SystemStreamLog is returned.
240      *
241      * @return Log
242      * @since 1.1
243      */
244     protected Log getLog()
245     {
246         if ( logger == null )
247         {
248             logger = new SystemStreamLog();
249         }
250 
251         return logger;
252     }
253 
254     /**
255      * Gets the current {@link MacroManager}.
256      *
257      * @return the current {@link MacroManager}
258      * @since 1.1
259      */
260     protected MacroManager getMacroManager()
261     {
262         return macroManager;
263     }
264 
265     /**
266      * Initialize the parser. This is called first by
267      * {@link #parse(java.io.Reader, org.apache.maven.doxia.sink.Sink)} and can be used
268      * to set the parser into a clear state so it can be re-used.
269      *
270      * @since 1.1.2
271      */
272     protected void init()
273     {
274         // nop
275     }
276 
277     /**
278      * The current Doxia version.
279      *
280      * @return the current Doxia version as a String
281      * @since 1.2
282      */
283     protected static String doxiaVersion()
284     {
285         return DOXIA_VERSION;
286     }
287 }