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