Package org.geotools.maven.xmlcodegen

Source Code of org.geotools.maven.xmlcodegen.AbstractGeneratorMojo

package org.geotools.maven.xmlcodegen;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.project.MavenProject;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.util.XSDSchemaLocationResolver;
import org.eclipse.xsd.util.XSDSchemaLocator;
import org.geotools.xml.Schemas;
import org.geotools.xml.XSD;

/**
* Generates the bindings and utility classes used to parse xml documents
* for a particular schema.
*
* @author Justin Deoliveira, The Open Planning Project
*
*/
public abstract class AbstractGeneratorMojo extends AbstractMojo {

  /**
   * The .xsd file defining the schema to generate bindings for.
   *
   * @parameter
   * @required
   */
  protected File schemaLocation;
 
  /**
   * Directory containing xml schemas, default is ${basedir}/src/main/xsd.
   *
   * @parameter expression="${basedir}/src/main/xsd"
   */
  protected File schemaSourceDirectory;
 
  /**
   * Additional directories used to locate included and imported schemas.
   *
   * @parameter
   */
  protected File[] schemaLookupDirectories;
 
  /**
   * The destination package of the generated source files in the standard dot-seperated
   * naming format.
   *
   * @parameter
   */
  protected String destinationPackage;
 
  /**
   * Directory to output generated files to. Default is ${project.build.sourceDirectory}
   * <p>
   * {@link Deprecated}, use one of {@link #sourceOutputDirectory} or {@link #testOutputDirectory}
   * </p>
   * @parameter expression="${project.build.sourceDirectory}"
   */
  protected File outputDirectory;
 
  /**
     * Directory to output generated source files to. Default is
     * ${project.build.sourceDirectory}
     *
     * @parameter expression="${project.build.sourceDirectory}"
     */
  protected File sourceOutputDirectory;
  /**
     * Directory to output generated test files to. Default is
     * ${project.build.testDirectory}
     *
     * @parameter expression="${project.build.testSourceDirectory}"
     */
  protected File testOutputDirectory;
  /**
   * Flag controlling wether files should overide files that already
   * exist with the same name. False by default.
   *
   * @param expression="false"
   */
  protected boolean overwriteExistingFiles;
 
  /**
     * List of names of attributes, elements, and types to include, if unset all will
     * be generated.
     *
     * @parameter
     */
    protected String[] includes;
    /**
     * The prefix to use for the targetNamespace.
     *
     * @parameter
     */
    protected String targetPrefix;
 
  /**
     * The currently executing project
     *
     * @parameter expression="${project}"
     */
    MavenProject project;
   
    /**
     * The local maven repository
     *
     * @parameter expression="${localRepository}"
     */
    ArtifactRepository localRepository;
   
    /**
     * Remote maven repositories
     * 
     * @parameter expression="${project.remoteArtifactRepositories}"
     */
    List remoteRepositories;
   
    /**
     * @component
     */
    ArtifactFactory artifactFactory;
   
    /**
     * @component
     */
    ArtifactResolver artifactResolver;
   
    /**
     * @component
     */
    ArtifactMetadataSource artifactMetadataSource;
   
    /**
     * The classpath elements of the project.
     *
     * @parameter expression="${project.runtimeClasspathElements}"
     * @required
     * @readonly
     */
    List classpathElements;
   
    /**
     * Flag to control whether to include GML libraries on classpath when running.
     * @parameter expression="true"
     */
    boolean includeGML;
   
    /**
     * Treat all relative schema references (include and import) as relative to the schema (XSD)
     * resource in which they are found, rather than looking for them in compiled classes or
     * schemaLookupDirectories. This requires all included/imported schemas to be present in the
     * expected relative filesystem location. The main advantage of this approach is that it
     * supports schema files that have cyclic dependencies (e.g. GML 3.2).
     *
     * @parameter expression="false"
     */
    boolean relativeSchemaReference;
   
    protected XSDSchema schema() {
   
      getLog().info( artifactFactory.toString() );
     
      //check schema source
    if ( !schemaSourceDirectory.exists() ) {
      getLog().error( schemaSourceDirectory.getAbsolutePath() + " does not exist" );
      return null;
    }
   
    //check schema
    if ( !schemaLocation.exists() ) {
      //check relative to schemaSourceDirectory
      schemaLocation = new File( schemaSourceDirectory, schemaLocation.getName() );
      if ( !schemaLocation.exists() ) {
        getLog().error( "Could not locate schema: " + schemaLocation.getName() );
        return null;
      }
    }
   
    //build an "extended" classloader for "well-known
    List artifacts = new ArrayList();
    if (includeGML) {
            artifacts.add(
              artifactFactory.createArtifact(
                "org.geotools", "gt2-xml-gml2", "2.7-SNAPSHOT", "compile", "jar"
       
                    )
            );
            artifacts.add(
              artifactFactory.createArtifact(
                "org.geotools", "gt2-xml-gml3", "2.7-SNAPSHOT", "compile", "jar"
              )
            );
            artifacts.add(
              artifactFactory.createArtifact(
                "org.geotools", "gt2-xml-filter", "2.7-SNAPSHOT", "compile", "jar"
              )
            );
            artifacts.add(
              artifactFactory.createArtifact(
                "org.geotools", "gt2-xml-sld","2.7-SNAPSHOT", "compile", "jar"
              )
            );
    }
 
    Set urls = new HashSet();
    for ( Iterator a = artifacts.iterator(); a.hasNext(); ) {
      Artifact artifact = (Artifact) a.next();
      getLog().debug("Attempting to dynamically resolve: " + artifact);
      try {
          Set resolvedArtifacts = project.createArtifacts( artifactFactory, null, null);
          //artifactResolver.resolve( artifact, remoteRepositories, localRepository );
        ArtifactResolutionResult result = artifactResolver.resolveTransitively(resolvedArtifacts, artifact, remoteRepositories, localRepository, artifactMetadataSource);
        resolvedArtifacts = result.getArtifacts();
       
        for ( Iterator ra = resolvedArtifacts.iterator(); ra.hasNext(); ) {
            Artifact resolvedArtifact = (Artifact) ra.next();
            urls.add( resolvedArtifact.getFile().toURI().toURL() );   
        }
       
      }
      catch( Exception e ) {
        getLog().warn( "Unable to resolve " + artifact.getId(), e );
      }
    }
   
    ClassLoader ext =
      new URLClassLoader( (URL[]) urls.toArray( new URL[ urls.size() ] ), getClass().getClassLoader() );
    StringBuffer sb = new StringBuffer();
    sb.append( "Using following classpath for XSD lookup: ");
    for ( Iterator u = urls.iterator(); u.hasNext(); ) {
        sb.append( u.next().toString() );
    }
    getLog().debug(sb.toString());
   
    //use extended classloader to load up configuration classes to load schema files
    // with
    final List xsds = new ArrayList();
                xsds.add( "org.geotools.xml.XML" );
                xsds.add( "org.geotools.xlink.XLINK" );
               
                if (includeGML) {
                    xsds.add( "org.geotools.gml2.GML" );
                    xsds.add( "org.geotools.gml3.GML" );
                    xsds.add( "org.geotools.filter.v1_0.OGC" );
                    xsds.add( "org.geotools.filter.v1_1.OGC" );
                }
   
    for ( int i = 0; i < xsds.size(); i++ ) {
      String className = (String) xsds.get( i );
      try {
        Class clazz = ext.loadClass( className );
        Method m = clazz.getMethod("getInstance", null);
        Object xsd = m.invoke(null, null);
        xsds.set( i, xsd );
      }
      catch (Exception e) {
        getLog().warn( "Unable to load " + className);
        getLog().debug(e);
        xsds.set( i , null );
      }
    }
   
    //add a schema locator which uses the xsd objects to get at the schemas
    XSDSchemaLocator locator = new XSDSchemaLocator() {

            public XSDSchema locateSchema(XSDSchema schema, String namespaceURI,
                String rawSchemaLocationURI, String resolvedSchemaLocationURI) {
               
                for ( Iterator x = xsds.iterator(); x.hasNext(); ) {
                    XSD xsd = (XSD) x.next();
                    if ( xsd == null ) {
                        continue;
                    }
                    if ( xsd.getNamespaceURI().equals( namespaceURI ) ) {
                        try {
                            return xsd.getSchema();
                        }
                        catch (IOException e) {
                            getLog().warn("Error occured locating schema: " + namespaceURI, e);
                        }
                    }
                }
            
                getLog().warn( "Could not locate schema for: " + namespaceURI );
                return null;
            }
       
    };
   
    //add a location resolver which checks the schema source directory
    XSDSchemaLocationResolver locationResolver = new XSDSchemaLocationResolver() {

      public String resolveSchemaLocation(
        XSDSchema schema, String namespaceURI, String schemaLocation
      ) {
     
                                if ( schemaLocation == null ) {
                                   getLog().warn("Null location for " + namespaceURI );
                                   return null;
                                }
                               
        //check location directlry
        File file = new File( schemaLocation )
        if ( file.exists() ) {
          getLog().debug( "Resolving " + schemaLocation + " to " + schemaLocation );
          return schemaLocation;
        }
       
        String fileName = new File( schemaLocation ).getName();
       
        //check under teh schema source directory
        file = new File( schemaSourceDirectory, fileName );
        if ( file.exists() ) {
          getLog().debug( "Resolving " + schemaLocation + " to " + file.getAbsolutePath() );
          return file.getAbsolutePath();
        }
       
        //check hte lookup directories
        if ( schemaLookupDirectories != null ) {
          for ( int i = 0; i < schemaLookupDirectories.length; i++ ) {
            File schemaLookupDirectory = schemaLookupDirectories[ i ];
            file = new File( schemaLookupDirectory, fileName );
            if ( file.exists() ) {
              getLog().debug( "Resolving " + schemaLocation + " to " + file.getAbsolutePath() );
              return file.getAbsolutePath();
            }
             
          }
        }
       
        getLog().warn( "Could not resolve location for: " + fileName );
        return null;
      }
     
    };
   
    //parse the schema
    XSDSchema xsdSchema = null;
    try {
      getLog().info("Parsing schema: " + schemaLocation);
      if (relativeSchemaReference) {
        xsdSchema = Schemas.parse(schemaLocation.getAbsolutePath(), Collections.EMPTY_LIST,
            Collections.singletonList(new XSDSchemaLocationResolver() {
              public String resolveSchemaLocation(XSDSchema xsdSchema,
                  String namespaceURI, String schemaLocationURI) {
                try {
                  URI contextUri = new URI(xsdSchema.getSchemaLocation());
                  if (contextUri.isOpaque()) {
                    // probably a jar:file: URL, which is opaque and thus not
                    // supported by URI.resolve()
                    URL contextUrl = new URL(xsdSchema.getSchemaLocation());
                    return (new URL(contextUrl, schemaLocationURI)).toString();
                  } else {
                    return contextUri.resolve(schemaLocationURI).toString();
                  }
                } catch (URISyntaxException e) {
                  throw new RuntimeException(e);
                } catch (MalformedURLException e) {
                  throw new RuntimeException(e);
                }
              }
            }));
      } else {
        xsdSchema = Schemas.parse(schemaLocation.getAbsolutePath(),
            new XSDSchemaLocator[] { locator },
            new XSDSchemaLocationResolver[] { locationResolver });
      }
     
      if ( xsdSchema == null ) {
        throw new NullPointerException();
      }
    }
    catch (Exception e) {
      getLog().error( "Failed to parse schema");
      getLog().error( e );
      return null;
   
   
    //set the target prefix if set
        if (targetPrefix != null) {
            xsdSchema.getQNamePrefixToNamespaceMap().put(targetPrefix,xsdSchema.getTargetNamespace());
        }
       
        //do some sanity checks on the schema
        if ( Schemas.getTargetPrefix(xsdSchema) == null ) {
            String msg = "Unable to determine a prefix for the target namespace " +
                "of the schema Either  include a mapping in the schema or manually " +
                "specify one with the 'targetPrefix' parameter.";
            throw new RuntimeException(msg);
        }
   
    return xsdSchema;
    }
   
}
TOP

Related Classes of org.geotools.maven.xmlcodegen.AbstractGeneratorMojo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.