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