View Javadoc

1   /*
2    * Copyright 2005 The Codehaus.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.codehaus.mojo.castor;
17  
18  import java.io.File;
19  import java.io.FileInputStream;
20  import java.io.FileNotFoundException;
21  import java.io.IOException;
22  import java.util.Properties;
23  
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugin.logging.Log;
26  import org.exolab.castor.builder.SourceGenerator;
27  import org.exolab.castor.builder.binding.ExtendedBinding;
28  import org.exolab.castor.builder.factory.FieldInfoFactory;
29  import org.exolab.castor.builder.info.CollectionInfo;
30  
31  /**
32   * Override Castor's SourceGenerator to inject exception handling. Code based on Castor XML code generator, release
33   * 1.1-M2
34   */
35  class CastorSourceGenerator
36      extends SourceGenerator
37  {
38      /**
39       * {@link Log} instance to use for any logging.
40       */
41      private Log log;
42  
43      /**
44       * {@link FieldInfoFactory} instance to be used during code generation. We need to save this in order to override
45       * its properties later since SourceGenerator doesn't give us access to this and the properties are only read during
46       * the constructor call
47       */
48      private FieldInfoFactory fieldInfoFactory;
49  
50      /**
51       * Indicates whether logging should be verbose. As base class does not provide access to this variable, we intercept
52       * setting it and store its value here
53       */
54      private boolean verbose;
55  
56      /**
57       * Creates a default {@link CastorSourceGenerator} instance.
58       */
59      public CastorSourceGenerator()
60      {
61          this( new FieldInfoFactory() );
62      }
63  
64      /**
65       * Creates an instance of {@link CastorSourceGenerator}, configured with a field info factory.
66       * 
67       * @param fieldInfoFactory {@link FieldInfoFactory} instance to be used during code generation.
68       */
69      public CastorSourceGenerator( FieldInfoFactory fieldInfoFactory )
70      {
71          super( fieldInfoFactory );
72          this.fieldInfoFactory = fieldInfoFactory;
73      }
74  
75      /**
76       * Creates an instance of {@link CastorSourceGenerator}, configured with a field info factory and a binding file.
77       * 
78       * @param fieldInfoFactory {@link FieldInfoFactory} instance to be used during code generation.
79       * @param extendedBinding Binding file to be used during code generation.
80       */
81      public CastorSourceGenerator( FieldInfoFactory fieldInfoFactory, ExtendedBinding extendedBinding )
82      {
83          super( fieldInfoFactory, extendedBinding );
84          this.fieldInfoFactory = fieldInfoFactory;
85      }
86  
87      /**
88       * Factory method to create a {@link CastorSourceGenerator} instance, preset with default values.
89       * 
90       * @param types A {@link FieldInfoFactory} type.
91       * @return a {@link CastorSourceGenerator} instance
92       * @throws MojoExecutionException To signal that an invalid type has been passed.
93       */
94      public static CastorSourceGenerator createSourceGenerator( String types )
95          throws MojoExecutionException
96      {
97          // Create Source Generator with appropriate type factory
98          CastorSourceGenerator sgen;
99          if ( types != null )
100         {
101             try
102             {
103                 String typ = "j2".equals( types ) ? "arraylist" : types;
104                 FieldInfoFactory factory = new FieldInfoFactory( typ );
105                 sgen = new CastorSourceGenerator( factory );
106             }
107             catch ( Exception e )
108             {
109                 try
110                 {
111                     sgen = new CastorSourceGenerator( (FieldInfoFactory) Class.forName( types ).newInstance() );
112                 }
113                 catch ( Exception e2 )
114                 {
115                     throw new MojoExecutionException( "Invalid types \"" + types + "\": " + e.getMessage() );
116                 }
117             }
118         }
119         else
120         {
121             sgen = new CastorSourceGenerator(); // default
122         }
123         return sgen;
124     }
125 
126     /**
127      * Sets the {@link Log} instance to use for logging.
128      * 
129      * @param log The {@link Log} instance to use for logging
130      */
131     public void setLog( Log log )
132     {
133         this.log = log;
134     }
135 
136     /**
137      * Returns the {@link Log} instance to use for logging.
138      * 
139      * @return The {@link Log} instance to use for logging.
140      */
141     public Log getLog()
142     {
143         return log;
144     }
145 
146     /**
147      * Helper method to output log statements.
148      * 
149      * @param msg The log message to be output.
150      */
151     public void log( String msg )
152     {
153         getLog().info( msg );
154     }
155 
156     /**
157      * Helper method to (conditionally) output a log statement.
158      * 
159      * @param msg The log message to be output.
160      */
161     public void verbose( String msg )
162     {
163         if ( verbose )
164         {
165             getLog().info( msg );
166         }
167     }
168 
169     /**
170      * Sets a user-specified line separator stype on the {@link CastorSourceGenerator}.
171      * 
172      * @param lineSeparator A user-specified line separator style.
173      * @throws MojoExecutionException If an invalid line separator stype has been specified.
174      */
175     public void setLineSeparatorStyle( String lineSeparator )
176         throws MojoExecutionException
177     {
178         // Set Line Separator
179         String lineSep = System.getProperty( "line.separator" );
180         if ( lineSeparator != null )
181         {
182             if ( "win".equals( lineSeparator ) )
183             {
184                 log( "Using Windows style line separation." );
185                 lineSep = "\r\n";
186             }
187             else if ( "unix".equals( lineSeparator ) )
188             {
189                 log( "Using UNIX style line separation." );
190                 lineSep = "\n";
191             }
192             else if ( "mac".equals( lineSeparator ) )
193             {
194                 log( "Using Macintosh style line separation." );
195                 lineSep = "\r";
196             }
197             else
198             {
199                 throw new MojoExecutionException( "Invalid value for lineseparator, must be win, unix, or mac." );
200             }
201         }
202         setLineSeparator( lineSep );
203     }
204 
205     /**
206      * Indicates whether source generation should be 'verbose'.
207      * 
208      * @param verbose True if source generation should be 'verbose'.
209      * @see org.exolab.castor.builder.SourceGenerator#setVerbose(boolean)
210      */
211     public void setVerbose( final boolean verbose )
212     {
213         this.verbose = verbose;
214         super.setVerbose( verbose );
215     }
216 
217     /**
218      * Sets a user-specific binding file to be used during code generation.
219      * 
220      * @param bindingFile A user-specified binding file.
221      */
222     public void setBindingFile( final File bindingFile )
223     {
224         setBinding( bindingFile.getAbsolutePath() );
225     }
226 
227     /**
228      * Sets user-specific code generator properties for the code generation process.
229      * 
230      * @param properties User-specific code generator properties.
231      * @throws MojoExecutionException Indicates that the user-specific properties cannot be accessed.
232      */
233     public void setBuilderProperties( File properties )
234         throws MojoExecutionException
235     {
236         // Set Builder Properties;
237         if ( properties != null )
238         {
239             String filePath = properties.getAbsolutePath();
240             Properties customProperties = new Properties();
241             try
242             {
243                 customProperties.load( new FileInputStream( filePath ) );
244             }
245             catch ( FileNotFoundException e )
246             {
247                 throw new MojoExecutionException( "Properties file \"" + filePath + "\" not found" );
248             }
249             catch ( IOException e )
250             {
251                 throw new MojoExecutionException( "Can't read properties file \"" + filePath + "\": " + e );
252             }
253             setDefaultProperties( customProperties );
254 
255             // these properties are read at contstruction time and copied into FieldInfoFactory
256             // se we set them directly in the fieldInfoFactory here.
257             if ( generateExtraCollectionMethods() )
258             {
259                 verbose( "Overriding default castorbuilder.properties and setting createExtraMethods to true" );
260                 fieldInfoFactory.setCreateExtraMethods( true );
261             }
262 
263             String suffix = getProperty( CollectionInfo.REFERENCE_SUFFIX_PROPERTY, null );
264             if ( suffix != null )
265             {
266                 verbose( "Overriding default castorbuilder.properties and " + "setting referenceSuffixProperty to "
267                     + suffix );
268             }
269             fieldInfoFactory.setReferenceMethodSuffix( suffix );
270 
271             if ( boundPropertiesEnabled() )
272             {
273                 verbose( "Overriding default castorbuilder.properties and setting boundProperties to true" );
274                 fieldInfoFactory.setBoundProperties( true );
275             }
276 
277         }
278     }
279 
280 }