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