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