Class CodeGen

java.lang.Object
org.jibx.schema.codegen.CodeGen

public class CodeGen extends Object
Code generator from schema definition. Although many of the methods in this class use public access, they are intended for use only by the JiBX developers and may change from one release to the next. To make use of this class from your own code, call the main(String[]) method with an appropriate argument list.
Author:
Dennis M. Sosnoski
  • Field Details

    • s_logger

      private static final Logger s_logger
      Logger for class.
    • DEFAULT_REPLACEMENTS

      private static final QName[] DEFAULT_REPLACEMENTS
      Default type replacements applied.
    • TYPE_DERIVE_MASK

      private static final long TYPE_DERIVE_MASK
      Mask for schema elements which derive from a type.
    • TYPE_DEFINE_MASK

      private static final long TYPE_DEFINE_MASK
      Mask for schema elements which define a type.
    • BLOCK_NAME_INHERIT_MASK

      private static final long BLOCK_NAME_INHERIT_MASK
      Mask for schema elements which block name inheritance downward.
    • m_global

      private final SchemasetCustom m_global
      Code generation customizations.
    • m_targetDir

      private final File m_targetDir
      Target directory for code generation.
    • m_validationContext

      private final ValidationContext m_validationContext
      Context for loading and processing schemas.
    • m_packageDirectory

      private PackageOrganizer m_packageDirectory
      Package directory for generated classes.
    • m_bindingDirectory

      private BindingOrganizer m_bindingDirectory
      Directory for constructed bindings.
    • m_rootHolder

      private BindingHolder m_rootHolder
      Root binding definition holder (set by writeBindings(String, String, List, ProblemHandler)).
  • Constructor Details

    • CodeGen

      public CodeGen(SchemasetCustom global, URL root, File target)
      Constructor.
      Parameters:
      global - schema customization root element
      root - URL for base of schema paths
      target - destination directory for code generation
    • CodeGen

      public CodeGen(SchemasetCustom custom, ValidationContext vctx)
      Constructor used by tests. This uses supplied schemas and skips writing to the file system.
      Parameters:
      custom -
      vctx -
  • Method Details

    • getSchemaValidationContext

      public ValidationContext getSchemaValidationContext()
      Get the validation context used for processing schemas.
      Returns:
      context
    • addDefaultSubstitutions

      private static void addDefaultSubstitutions(SchemasetCustom custom)
      Add default type substitutions to set currently defined.
      Parameters:
      custom -
    • findSchemaset

      public SchemasetCustom findSchemaset(SchemaElement schema, SchemasetCustom custom)
      Find the most specific schemaset owning a schema. If multiple matches are found which are not in line of containment the first match is returned and the conflict is reported as an error.
      Parameters:
      schema -
      custom - schema set customization
      Returns:
      owning schemaset, null if none
    • setDefaultPrefixes

      public void setDefaultPrefixes(Iterator iter)
      Scan schemas to find the default prefixes used for namespaces.
      Parameters:
      iter - schema iterator
    • customizeSchemas

      public boolean customizeSchemas(String pack, ProblemHandler handler)
      Validate and apply customizations to loaded schemas.
      Parameters:
      pack - package to be used by default for no-namespaced schemas (non-null)
      handler - validation problem handler
      Returns:
      true if successful, false if error
    • processExtensions

      private boolean processExtensions()
      Process substitutions and deletions defined by extensions. This builds the cross-reference information for the global definition components of the schemas while removing references to deleted components.
      Returns:
      true if any changes to the schemas, false if not
    • applyAndNormalize

      public void applyAndNormalize()
      Apply extensions and normalize all schemas. This may be a multipass process, since applying extensions may create the opportunity for further normalizations and vice versa.
    • pruneDefinitions

      public void pruneDefinitions()
      Processes the schemas to remove unused global definitions.
    • checkDirectName

      private String checkDirectName(Item item)
      Check if an item has an associated name. If the component associated with the item has a name, this just returns that name converted to base name form. The only exception is for inlined global type definitions, which are treated as unnamed.
      Parameters:
      item -
      Returns:
      name associated name, or null if none
    • deriveName

      private String deriveName(Item item, boolean force)
      Derive the base name for an item. If not forced, the only time a name will be returned is when the item is a reference to a non-type definition. If forced, this will try other alternatives for names including the text "Enumeration" for an enumeration group, the base type name for a type derivation, the schema type name for a value of a schema type, or finally the schema component element name.
      Parameters:
      item -
      force - name forced flag
      Returns:
      name (null if to use inherited name when force == false)
    • compactGroups

      private void compactGroups(GroupItem group)
      Compact group structures. This eliminates redundant groupings, in the form of groups with only one child, which child is a group referencing the same schema component as the parent group, from the data structure representation.
      Parameters:
      group -
    • assembleName

      private String assembleName(String prefix, String base)
      Assemble a name from a base name and an optional prefix. If the prefix is supplied, this first converts the base name to embedded form, then appends the prefix.
      Parameters:
      prefix -
      base -
      Returns:
      name
    • assignNames

      private void assignNames(String prefix, GroupItem group, boolean force)
      Set the basic names to be used for a structure of items. For named components of the schema definition the names used are simply the converted XML local names, for other components more complex rules apply (see deriveName(Item,boolean). This method calls itself recursively to handle nested groups.
      Parameters:
      prefix - text to be prefixed to names within inlined group (null if none)
      group - item group to be assigned
      force - force name derivation flag
    • computeComplexity

      private int computeComplexity(GroupItem group, int depth, List defs)
      Compute the complexity of a structure. In order to find the complexity of a structure all items of the structure must first be checked for inlining, which in turn requires checking their complexity. That makes this method mutually recursive with checkInline(DefinitionItem, int, List).
      Parameters:
      group -
      depth - nesting depth
      defs - list of generated definitions
      Returns:
      complexity (0, 1, or 2 for anything more than a single value)
    • isSimple

      private boolean isSimple(GroupItem group)
      Check if a group consists only of a single non-repeating item, which is not an enumeration.
      Parameters:
      group -
      Returns:
      true if simple group, false if repeated, multiple, or enumeration
    • convertToDefinitions

      private void convertToDefinitions(GroupItem group, List defs)
      Convert nested groups which are not inlined to freestanding definitions. This calls itself recursively to process nested groups, except those nested within groups converted to definitions.
      Parameters:
      group -
      defs - list of generated definitions
    • checkInline

      private void checkInline(DefinitionItem def, int depth, List defs)
      Check if a global definition structure is to be inlined. This method is mutually recursive with computeComplexity(GroupItem, int, List). The two methods together determine the inlining status of all items.
      Parameters:
      def -
      depth - nesting depth
      defs - list of generated definitions
    • setName

      private void setName(QName qname, MappingElementBase mapping, BindingHolder holder)
      Set the name and namespace URI for a concrete <mapping> binding component. This is the same logic as used in the StructureClassHolder equivalent.
      Parameters:
      qname - qualified name to be set (null if none)
      mapping - concrete mapping definition
      holder - binding containing the mapping
    • buildItemStructures

      private ArrayList buildItemStructures()
      Build the structure of items to be used in code generation for each global definition.
      Returns:
      constructed definition items
    • convertTypeIsomorphicElements

      private Map convertTypeIsomorphicElements(ArrayList items)
      Convert the item model used for global elements, if they're the only reference to a global type. This just prevents generating two separate classes, one for the type and one for the element.
      Parameters:
      items - global definition items
      Returns:
      map from base type definition to singleton element definition using that type
    • inlineReferences

      private ArrayList inlineReferences(ArrayList items)
      Build list of definitions to be generated. Where possible, references are converted to inline definitions. Where they can't be converted, new definitions are created for separate class generation.
      Parameters:
      items -
      Returns:
      definitions to be processed
    • checkNoNamespacedUsed

      private boolean checkNoNamespacedUsed()
      Check if no-namespace namespace is used in any of the schemas.
      Returns:
      true if no-namespace used, false if not
    • buildClassesAndBindings

      private void buildClassesAndBindings(ArrayList defs, Map typeinst)
      Build classes and bindings for all definitions, except those for singleton element definitions using a type.
      Parameters:
      defs - definitions to be generated
      typeinst - map from base type definition to singleton element definition using that type
    • initializeBindings

      private void initializeBindings()
      Initialize the bindings to be generated. This configures the binding directory, then creates the required bindings and sets their prefixes.
    • buildDataModel

      public String buildDataModel(boolean verbose, boolean usenns, Map elemmap, Map typemap)
      Generate the data model. This first builds a representation of all the data items from the schema definitions, then determines which items can be inlined and which need separate class representations, and finally builds the actual data model class and binding definitions.
      Parameters:
      verbose - verbose output flag
      usenns - no-namespace namespace used flag
      elemmap - map from qualified name of element to pregenerated mapping definition
      typemap - map from qualified name of type (or attributeGroup, or group) to pregenerated mapping definition
      Returns:
      root package for binding
    • getBindingDirectory

      public BindingOrganizer getBindingDirectory()
      Get the binding directory.
      Returns:
      directory
    • writeBindings

      public void writeBindings(String name, String pack, List pregens, ProblemHandler handler) throws JiBXException, IOException
      Write the binding definitions file(s). This method can only be used after buildDataModel(boolean, boolean, Map, Map) is called.
      Parameters:
      name - root binding definition file name (use customization, or default, if null)
      pack - target package for binding (null if unspecified)
      pregens - pregenerated bindings to be included in root binding
      handler - validation error and code generation problem handler
      Throws:
      JiBXException
      IOException
    • getRootBinding

      public BindingElement getRootBinding()
      Get the root binding definition. This is only allowed after the call to writeBindings(String, String, List, ProblemHandler).
      Returns:
      root binding element
    • getPackageDirectory

      public PackageOrganizer getPackageDirectory()
      Get the package directory used for code generation.
      Returns:
      directory
    • generate

      public boolean generate(boolean verbose, String usens, String dfltpkg, String bindname, List fileset, List inclpaths, File model, ProblemHandler handler) throws JiBXException, IOException
      Generate code from a list of schemas.
      Parameters:
      verbose - verbose output flag
      usens - namespace to be used when no schemas with namespaces are being generated (null if not specified)
      dfltpkg - default package for no-namespace schemas (null if not specified)
      bindname - name for root binding (null if not specified)
      fileset - list of resolvers for schemas to be generated
      inclpaths - list of paths for bindings to be used for matching schema definitions (empty if none)
      model - file to be used for dumping generated data model (null if none)
      handler - validation error and code generation problem handler
      Returns:
      true if successful, false if failure
      Throws:
      JiBXException
      IOException
    • listSchemas

      private static void listSchemas(SchemaElement[] schemas, ValidationContext vctx, ProblemHandler handler)
      List the schemas in use.
      Parameters:
      schemas -
      vctx -
      handler -
    • listGeneratedPackages

      private static void listGeneratedPackages(List packages, ProblemHandler handler)
      List the number of classes in each package, and the totals.
      Parameters:
      packages -
      handler -
    • buildClassData

      private static TypeData buildClassData(String cname, boolean simple)
      Build class data for pregenerated class.
      Parameters:
      cname - class name
      simple - simple value flag
      Returns:
      data
    • accumulateBindingDefinitions

      private static void accumulateBindingDefinitions(BindingElement binding, Map elemmap, Map typemap)
      Accumulate all format and mapping definitions, including those found in included bindings. For each abstract mapping or named format found, the type name is associated with the class data in the type map; for each concrete mapping found, the element name (and namespace) is associated with the class data in the element map. Included bindings are handled with recursive calls.
      Parameters:
      binding - binding definition root
      elemmap - map from element qualified name to class data
      typemap - map from type qualified name to class data
    • processPregeneratedBinding

      public static BindingElement processPregeneratedBinding(URL url, Map elemmap, Map typemap, ProblemHandler handler) throws JiBXException, IOException
      Load and validate binding and process all format and mapping definitions, including those in included bindings.
      Parameters:
      url - binding definition path
      elemmap - map from element qualified name to class data
      typemap - map from type qualified name to class data
      handler - validation error and problem handler
      Returns:
      binding
      Throws:
      JiBXException
      IOException
    • reportBindingProblems

      private static void reportBindingProblems(ValidationContext vctx, ProblemHandler handler)
      Report problems found in binding.
      Parameters:
      vctx -
      handler -
    • findPathSteps

      public static List findPathSteps(File file) throws IOException
      Find the steps in the canonical path to a file.
      Parameters:
      file -
      Returns:
      steps
      Throws:
      IOException
    • relativeFilePath

      public static String relativeFilePath(File dir, File file) throws IOException
      Construct a relative file path.
      Parameters:
      dir - start directory for path
      file - supplied file path
      Returns:
      relative file path
      Throws:
      IOException
    • checkNoNamespace

      public static boolean checkNoNamespace(BindingElement binding)
      Check if a binding definition uses the no-namespace namespace. This calls itself to recursively check on included bindings.
      Parameters:
      binding -
      Returns:
      true if no-namespace namespace used, false if not
    • main

      public static void main(String[] args) throws Exception
      Run the binding generation using command line parameters.
      Parameters:
      args -
      Throws:
      Exception