Coverage Report - org.deduced.generator.java.JavaGeneratorUtilities
 
Classes in this File Line Coverage Branch Coverage Complexity
JavaGeneratorUtilities
95%
88/92
87%
14/16
1.75
 
 1  
 /**
 2  
  *    Copyright 2005-2011 Steve McDuff d-duff@users.sourceforge.net
 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.deduced.generator.java;
 17  
 
 18  
 import java.io.ByteArrayOutputStream;
 19  
 import java.io.IOException;
 20  
 import java.util.List;
 21  
 import java.util.logging.Level;
 22  
 import java.util.logging.Logger;
 23  
 
 24  
 import org.apache.commons.lang.StringUtils;
 25  
 import org.deduced.DeducedModelLayer;
 26  
 import org.deduced.DeducedSchemaLayer;
 27  
 import org.deduced.DeducedUtilities;
 28  
 import org.deduced.OrderedPropertyListType;
 29  
 import org.deduced.PropertyCollection;
 30  
 import org.deduced.PropertyCollectionType;
 31  
 import org.deduced.framework.DeducedModelLayerExtensionImplementation;
 32  
 import org.deduced.framework.FrameworkUtilities;
 33  
 import org.deduced.generator.VelocityGenerator;
 34  
 import org.deduced.utilities.FileUtilities;
 35  
 import org.deduced.xml.XmlFileParser;
 36  
 import org.deduced.xml.XmlFileParserImplementation;
 37  
 
 38  
 /**
 39  
  * Class used to generate a java interface based on a property collection type.
 40  
  * 
 41  
  * @author Steve McDuff
 42  
  */
 43  2
 public class JavaGeneratorUtilities
 44  
 {
 45  
 
 46  
         /**
 47  
          * Logger
 48  
          */
 49  1
         private static final Logger LOGGER = Logger
 50  
                 .getLogger(JavaGeneratorUtilities.class.getName());
 51  
 
 52  
         /** XML file parser to use */
 53  1
         private static XmlFileParser XML_PARSER = new XmlFileParserImplementation();
 54  
 
 55  
         /**
 56  
          * file name used to generate Java Interfaces
 57  
          */
 58  
         public static final String JAVA_INTERFACE_TEMPLATE =
 59  
                 "org/deduced/generator/java/JavaInterface.vm";
 60  
 
 61  
         /**
 62  
          * file name used to generate Java Implementations
 63  
          */
 64  
         public static final String JAVA_IMPLEMENTATION_TEMPLATE =
 65  
                 "org/deduced/generator/java/JavaImplementation.vm";
 66  
 
 67  
         /**
 68  
          * file name used to generate Java Schema
 69  
          */
 70  
         public static final String JAVA_FRAMEWORK_TEMPLATE =
 71  
                 "org/deduced/generator/java/JavaFramework.vm";
 72  
 
 73  
         /**
 74  
          * file name used to generate Java ordered property list interfaces
 75  
          */
 76  
         private static final String JAVA_ORDERED_PROPERTY_LIST_INTERFACE_TEMPLATE =
 77  
                 "org/deduced/generator/java/JavaOrderedPropertyListInterface.vm";
 78  
 
 79  
         /**
 80  
          * file name used to generate Java ordered property list implementation
 81  
          */
 82  
         private static final String JAVA_ORDERED_PROPERTY_LIST_IMPLEMENTATION_TEMPLATE =
 83  
                 "org/deduced/generator/java/JavaOrderedPropertyListImplementation.vm";
 84  
 
 85  
         /**
 86  
          * method used to generate a java implementation for a property collection
 87  
          * type
 88  
          * 
 89  
          * @param type the property collection type
 90  
          * @param outputFolderName the output folder name to use
 91  
          * @throws IOException any exception that occurs while attempting to write
 92  
          *             the file
 93  
          */
 94  
         public static void generateImplementationForType(
 95  
                 PropertyCollection<?, ?> type, String outputFolderName)
 96  
                 throws IOException
 97  
         {
 98  12
                 validateTypePackageName(type);
 99  12
                 String implementationFileName =
 100  
                         JavaNamingUtilities.getImplementationFileName(type);
 101  12
                 String implementationFolderName =
 102  
                         JavaNamingUtilities.getImplementationFolderName(type);
 103  
 
 104  12
                 String folderName =
 105  
                         FileUtilities.mergeFolderName(outputFolderName,
 106  
                                 implementationFolderName);
 107  
 
 108  12
                 String javaImplementationTemplate = JAVA_IMPLEMENTATION_TEMPLATE;
 109  
 
 110  12
                 boolean isOrderedPropertyListType = isOrderedPropertyListType(type);
 111  
 
 112  12
                 if (isOrderedPropertyListType)
 113  
                 {
 114  0
                         javaImplementationTemplate =
 115  
                                 JAVA_ORDERED_PROPERTY_LIST_IMPLEMENTATION_TEMPLATE;
 116  
                 }
 117  
 
 118  12
                 generateType(type, javaImplementationTemplate, folderName,
 119  
                         implementationFileName);
 120  12
         }
 121  
 
 122  
         /**
 123  
          * utility method to generate an output based on a property collection type
 124  
          * and a velocity template
 125  
          * 
 126  
          * @param type the property collection type
 127  
          * @param template the velocity template file name to use
 128  
          * @param folderName the folder name in which to output the files
 129  
          * @param fileName the file name that will be created
 130  
          * @throws IOException any exception that occurs while attempting to write
 131  
          *             the file
 132  
          */
 133  
         private static void generateType(
 134  
                 PropertyCollection<?, ?> type, String template, String folderName,
 135  
                 String fileName) throws IOException
 136  
         {
 137  24
                 if (LOGGER.isLoggable(Level.FINE))
 138  
                 {
 139  8
                         LOGGER.log(Level.FINE,
 140  
                                 "Generating : " + DeducedUtilities.getCollectionName(type)
 141  
                                         + " using template : " + template);
 142  
                 }
 143  
 
 144  24
                 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
 145  
 
 146  24
                 VelocityGenerator generator = new VelocityGenerator();
 147  24
                 generator.setOutputStream(outStream);
 148  24
                 generator.setTemplateName(template);
 149  24
                 generator.getContext().put("type", type);
 150  24
                 fillCommonGeneratorContext(generator);
 151  
 
 152  24
                 generator.generate();
 153  
 
 154  24
                 FileUtilities.forceCreateDirectory(folderName);
 155  24
                 String output = FileUtilities.mergeFolderName(folderName, fileName);
 156  
 
 157  24
                 FileUtilities.writeFileContent(output, outStream.toByteArray());
 158  
 
 159  24
                 outStream.close();
 160  24
         }
 161  
 
 162  
         /**
 163  
          * generate the framework class used to initialize a schema
 164  
          * 
 165  
          * @param model the model hosting the schema. Used to extract dependent
 166  
          *            schemas.
 167  
          * @param schema the schema which will be used to generate the factory
 168  
          * @param outputFolderName the output folder name.
 169  
          * @throws IOException any exception that occurs while attempting to write
 170  
          *             the file
 171  
          */
 172  
         public static void generateFrameworkForSchema(
 173  
                 PropertyCollection<?, ?> model, PropertyCollection<?, ?> schema,
 174  
                 String outputFolderName) throws IOException
 175  
         {
 176  14
                 String template = JAVA_FRAMEWORK_TEMPLATE;
 177  14
                 String schemaName = DeducedUtilities.getCollectionName(schema);
 178  14
                 String frameworkFileName =
 179  
                         JavaNamingUtilities.getSchemaClassName(schemaName) + ".java";
 180  
 
 181  14
                 String frameworkFolderName =
 182  
                         JavaNamingUtilities.getSchemaFolderName(schemaName);
 183  
 
 184  14
                 String folderName =
 185  
                         FileUtilities
 186  
                                 .mergeFolderName(outputFolderName, frameworkFolderName);
 187  
 
 188  14
                 if (LOGGER.isLoggable(Level.FINE))
 189  
                 {
 190  5
                         LOGGER.log(Level.FINE, "Generating : " + schemaName
 191  
                                 + " using template : " + template);
 192  
                 }
 193  
 
 194  14
                 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
 195  
 
 196  14
                 VelocityGenerator generator = new VelocityGenerator();
 197  14
                 generator.setOutputStream(outStream);
 198  14
                 generator.setTemplateName(template);
 199  14
                 generator.getContext().put("schema", schema);
 200  14
                 generator.getContext().put("model", model);
 201  14
                 fillCommonGeneratorContext(generator);
 202  
 
 203  14
                 generator.generate();
 204  
 
 205  14
                 FileUtilities.forceCreateDirectory(folderName);
 206  14
                 String output =
 207  
                         FileUtilities.mergeFolderName(folderName, frameworkFileName);
 208  
 
 209  14
                 FileUtilities.writeFileContent(output, outStream.toByteArray());
 210  
 
 211  14
                 outStream.close();
 212  14
         }
 213  
 
 214  
         /**
 215  
          * method used to generate a java interface for a property collection type
 216  
          * 
 217  
          * @param type the property collection type
 218  
          * @param outputFolderName the output folder name
 219  
          * @throws IOException any exception that occurs while attempting to write
 220  
          *             the file
 221  
          */
 222  
         public static void generateInterfaceForType(
 223  
                 PropertyCollection<?, ?> type, String outputFolderName)
 224  
                 throws IOException
 225  
         {
 226  12
                 validateTypePackageName(type);
 227  12
                 String interfaceFileName =
 228  
                         JavaNamingUtilities.getInterfaceFileName(type);
 229  12
                 String interfaceFolderName =
 230  
                         JavaNamingUtilities.getInterfaceFolderName(type);
 231  
 
 232  12
                 String folderName =
 233  
                         FileUtilities
 234  
                                 .mergeFolderName(outputFolderName, interfaceFolderName);
 235  
 
 236  12
                 String javaInterfaceTemplate = JAVA_INTERFACE_TEMPLATE;
 237  
 
 238  12
                 boolean isOrderedPropertyListType = isOrderedPropertyListType(type);
 239  
 
 240  12
                 if (isOrderedPropertyListType)
 241  
                 {
 242  0
                         javaInterfaceTemplate =
 243  
                                 JAVA_ORDERED_PROPERTY_LIST_INTERFACE_TEMPLATE;
 244  
                 }
 245  
 
 246  12
                 generateType(type, javaInterfaceTemplate, folderName, interfaceFileName);
 247  12
         }
 248  
 
 249  
         /**
 250  
          * is Ordered Property List Type
 251  
          * 
 252  
          * @param type the type to test
 253  
          * @return true if the type of the specified type is an ordered property
 254  
          *         list type.
 255  
          */
 256  
         public static boolean isOrderedPropertyListType(
 257  
                 PropertyCollection<?, ?> type)
 258  
         {
 259  24
                 PropertyCollectionType orderedPropertyListType =
 260  
                         OrderedPropertyListType.ORDERED_PROPERTY_LIST_TYPE_TYPE
 261  
                                 .getPropertyCollectionType();
 262  
 
 263  24
                 PropertyCollection<?, ?> typeOfTheCurrentType = type.type();
 264  
 
 265  24
                 boolean isOrderedPropertyListType =
 266  
                         DeducedUtilities.isInstanceOf(typeOfTheCurrentType,
 267  
                                 orderedPropertyListType);
 268  24
                 return isOrderedPropertyListType;
 269  
         }
 270  
 
 271  
         /**
 272  
          * test if the package name is valid for a type
 273  
          * 
 274  
          * @param type the type to test
 275  
          */
 276  
         public static void validateTypePackageName(
 277  
                 PropertyCollection<?, ?> type)
 278  
         {
 279  36
                 String interfacePackageName =
 280  
                         JavaNamingUtilities.getInterfacePackageName(type);
 281  36
                 if (StringUtils.isEmpty(interfacePackageName))
 282  
                 {
 283  8
                         throw new IllegalArgumentException(
 284  
                                 "Invalid empty package name for type : "
 285  
                                         + DeducedUtilities.getCollectionName(type));
 286  
                 }
 287  28
         }
 288  
 
 289  
         /**
 290  
          * Utility method to fill the velocity generation context with common
 291  
          * variables
 292  
          * 
 293  
          * @param generator the velocity generator to use
 294  
          */
 295  
         private static void fillCommonGeneratorContext(
 296  
                 VelocityGenerator generator)
 297  
         {
 298  38
                 generator.getContext().put("javaNamingUtilities",
 299  
                         JavaNamingUtilities.DEFAULT);
 300  38
                 generator.getContext().put("deducedUtilities", new DeducedUtilities());
 301  38
         }
 302  
 
 303  
         /**
 304  
          * generate all the files required to use the specified schema. This method
 305  
          * will generate the framework, all the interfaces and implementations of
 306  
          * types within the schema.
 307  
          * 
 308  
          * @param model the model hosting the schema
 309  
          * @param schema the schema to generate
 310  
          * @param outputFolderName the output folder to use
 311  
          * @throws IOException any exception that occurs while attempting to write
 312  
          *             the file
 313  
          */
 314  
         public static void generateFilesForSchema(
 315  
                 PropertyCollection<?, ?> model, PropertyCollection<?, ?> schema,
 316  
                 String outputFolderName) throws IOException
 317  
         {
 318  10
                 List<PropertyCollection<?, ?>> propertyCollectionTypeListFromSchema =
 319  
                         JavaNamingUtilities.getPropertyCollectionTypeListFromSchema(schema);
 320  
 
 321  10
                 generateFrameworkForSchema(model, schema, outputFolderName);
 322  
 
 323  10
                 for (PropertyCollection<?, ?> currentType : propertyCollectionTypeListFromSchema)
 324  
                 {
 325  8
                         generateImplementationForType(currentType, outputFolderName);
 326  8
                         generateInterfaceForType(currentType, outputFolderName);
 327  
                 }
 328  10
         }
 329  
 
 330  
         /**
 331  
          * generate the Java Schema files from a DeducedModelLayer. Any schema
 332  
          * contained in the base property collection list on the model will be
 333  
          * generated
 334  
          * 
 335  
          * @param outputFolderName the folder where Java files will be created
 336  
          * @param schemaModelToGenerate the DeducedModelLayer containing some
 337  
          *            DeducedSchemaLayer objects
 338  
          * @throws IOException any error that occurs while writing the files
 339  
          */
 340  
         public static void generateSchemaFromModel(
 341  
                 String outputFolderName, PropertyCollection<?, ?> schemaModelToGenerate)
 342  
                 throws IOException
 343  
         {
 344  6
                 PropertyCollection<?, ?> collectionList =
 345  
                         (PropertyCollection<?, ?>) schemaModelToGenerate
 346  
                                 .getPropertyValue(DeducedModelLayer.COLLECTION_LIST_INSTANCE
 347  
                                         .getKey());
 348  
 
 349  6
                 List<?> schemaValueList = collectionList.asValueList();
 350  6
                 for (Object object : schemaValueList)
 351  
                 {
 352  10
                         PropertyCollection<?, ?> possibleSchema =
 353  
                                 (PropertyCollection<?, ?>) object;
 354  
 
 355  10
                         if (DeducedUtilities.isInstanceOf(possibleSchema.type(),
 356  
                                 DeducedSchemaLayer.DEDUCED_SCHEMA_LAYER_TYPE
 357  
                                         .getPropertyCollectionType()))
 358  
                         {
 359  8
                                 JavaGeneratorUtilities.generateFilesForSchema(
 360  
                                         schemaModelToGenerate, possibleSchema, outputFolderName);
 361  
                         }
 362  10
                 }
 363  6
         }
 364  
 
 365  
         /**
 366  
          * Load a model layer from a XML file and add it to the application hub for
 367  
          * future reference. Note that if errors occur, the loaded model will only
 368  
          * contain a partially loaded file.
 369  
          * 
 370  
          * @param xmlFileName the XML file name to load
 371  
          * @param generatorApplicationModel the application model to use while
 372  
          *            loading
 373  
          * @param ignoreXmlErrors if set to true, any non-fatal error encountered
 374  
          *            while reading the xml file will not throw an exception and the
 375  
          *            resulting partially loaded model is returned
 376  
          * @return the loaded schema model layer
 377  
          * @throws Exception any error that occurs while decoding the XML file.
 378  
          */
 379  
         @SuppressWarnings("unchecked")
 380  
         public static PropertyCollection<?, ?> loadModelFromXmlFile(
 381  
                 String xmlFileName, PropertyCollection<?, ?> generatorApplicationModel,
 382  
                 boolean ignoreXmlErrors) throws Exception
 383  
         {
 384  19
                 DeducedModelLayerExtensionImplementation newSchemaModel =
 385  
                         FrameworkUtilities.createDynamicModelLayer();
 386  
 
 387  19
                 XmlFileParser xmlParser = getXmlParser();
 388  
 
 389  19
                 xmlParser.readModelLayer(xmlFileName, newSchemaModel,
 390  
                         generatorApplicationModel, ignoreXmlErrors);
 391  
 
 392  9
                 Object collectionListKey =
 393  
                         DeducedModelLayer.COLLECTION_LIST_INSTANCE.getKey();
 394  
 
 395  9
                 PropertyCollection collectionList =
 396  
                         (PropertyCollection) generatorApplicationModel
 397  
                                 .getPropertyValue(collectionListKey);
 398  
 
 399  9
                 collectionList.addProperty(null, null, newSchemaModel);
 400  
 
 401  9
                 return newSchemaModel;
 402  
         }
 403  
 
 404  
         /**
 405  
          * @param setXmlParser the xml parser to set
 406  
          */
 407  
         public static void setXmlParser(
 408  
                 XmlFileParser setXmlParser)
 409  
         {
 410  0
                 XML_PARSER = setXmlParser;
 411  0
         }
 412  
 
 413  
         /**
 414  
          * @return the xml parser
 415  
          */
 416  
         public static XmlFileParser getXmlParser()
 417  
         {
 418  19
                 return XML_PARSER;
 419  
         }
 420  
 
 421  
 }