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$
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 }