package org.geotools.maven.xmlcodegen; import java.io.File; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; import java.util.HashMap; 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.resolver.ArtifactResolutionResult; import org.apache.maven.model.Dependency; import org.apache.maven.model.Resource; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.eclipse.xsd.XSDSchema; import org.geotools.xml.XSD; /** * Generates the bindings and utility classes used to parse xml documents * for a particular schema. * * @goal generate * * @author Justin Deoliveira, The Open Planning Project * */ public class BindingGeneratorMojo extends AbstractGeneratorMojo { /** * Flag controlling wether a parser configuration ( {@link org.geotools.xml.Configuration} ) * the default is true. * * @parameter expression="true" */ boolean generateConfiguration; /** * Flag controlling wether an xsd ({@link XSD} subclass should be generated. * * @parameter expression="true" */ boolean generateXsd; /** * Flag controlling wether bindings for attributes should be generated, default is * false. * * @parameter expression="false" */ boolean generateAttributeBindings; /** * Flag controlling wether bindings for eleements should be generated, default is * false. * * @parameter expression="false" */ boolean generateElementBindings; /** * Flag controlling wether bindings for types should be generated, default is * true. * * @parameter expression="true" */ boolean generateTypeBindings; /** * Flag controlling wether test for bindings should be generated, default is * false. * * @parameter expression="false" */ boolean generateTests; /** * List of constructor arguments that should be supplied to generated bindings. * Each argument is a 'name','type','mode' triplet. 'name' and 'type' declare * the name and class of the argument respectivley. 'mode' can be set to * "member", or "parent". If set to "member" the argument will be set to a * member of the binding. If set to "parent" the argument will passed through * to the call to the super constructor. The default is "member" * * @parameter */ BindingConstructorArgument[] bindingConstructorArguments; /** * The base class for complex bindings. If unspecified {@link org.geotools.xml.AbstractComplexBinding} * is used. * * @parameter expression="org.geotools.xml.AbstractComplexBinding" * */ String complexBindingBaseClass; /** * The base class for simple bindings. If unspecified {@link org.geotools.xml.AbstractSimpleBinding} * is used. * * @parameter expression="org.geotools.xml.AbstractSimpleBinding" */ String simpleBindingBaseClass; public void execute() throws MojoExecutionException, MojoFailureException { XSDSchema xsdSchema = schema(); if ( xsdSchema == null ) { return; } BindingGenerator generator = new BindingGenerator(); generator.setGenerateAttributes( generateAttributeBindings ); generator.setGenerateElements( generateElementBindings ); generator.setGenerateTypes( generateTypeBindings ); generator.setGenerateConfiguration( generateConfiguration ); generator.setGenerateXsd(generateXsd); generator.setGenerateTests(generateTests); generator.setOverwriting( overwriteExistingFiles ); //generator.setLocation( outputDirectory.getAbsolutePath() ); generator.setSourceLocation(sourceOutputDirectory.getAbsolutePath()); generator.setTestLocation(testOutputDirectory.getAbsolutePath()); generator.setResourceLocation(((Resource)project.getBuild().getResources().get( 0 )).getDirectory()); generator.setSchemaSourceDirectory(schemaSourceDirectory); try { Class c = Class.forName(complexBindingBaseClass); generator.setComplexBindingBaseClass(c); } catch( ClassNotFoundException e ) { getLog().error("Could not load class: " + complexBindingBaseClass); return; } try { Class c = Class.forName(simpleBindingBaseClass); generator.setSimpleBindingBaseClass(c); } catch( ClassNotFoundException e ) { getLog().error("Could not load class: " + simpleBindingBaseClass); return; } if ( schemaLookupDirectories != null ) { generator.setSchemaLookupDirectories(schemaLookupDirectories); } if ( destinationPackage != null ) { generator.setPackageBase( destinationPackage ); } //list of urls to use as class loading locations Set urls = new HashSet(); try { //get the ones from the project List l = project.getCompileClasspathElements(); for ( Iterator i = l.iterator(); i.hasNext(); ) { String element = (String) i.next(); File d = new File( element ); if ( d.exists() && d.isDirectory() ) { urls.add( d.toURI().toURL() ); } } //get the ones from project dependencies List d = project.getDependencies(); for ( Iterator i = d.iterator(); i.hasNext(); ) { Dependency dep = (Dependency) i.next(); if ( "jar".equals( dep.getType() ) ) { Artifact artifact = artifactFactory.createArtifact( dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), dep.getScope(), dep.getType() ); Set artifacts = project.createArtifacts( artifactFactory, null, null); ArtifactResolutionResult result = artifactResolver.resolveTransitively(artifacts, artifact, remoteRepositories, localRepository, artifactMetadataSource); artifacts = result.getArtifacts(); for ( Iterator a = artifacts.iterator(); a.hasNext(); ) { Artifact dartifact = (Artifact) a.next(); urls.add(dartifact.getFile().toURI().toURL()); } } } } catch (Exception e) { getLog().error( e ); return; } ClassLoader cl = new URLClassLoader( (URL[]) urls.toArray( new URL[ urls.size() ] ) ); if ( bindingConstructorArguments != null ) { HashMap map = new HashMap(); for ( int i = 0; i < bindingConstructorArguments.length; i++) { String name = bindingConstructorArguments[i].getName(); String type = bindingConstructorArguments[i].getType(); try { bindingConstructorArguments[i].clazz = cl.loadClass( type ); } catch (ClassNotFoundException e) { getLog().error( "Could not locate class:" + type ); return; } } generator.setBindingConstructorArguments( bindingConstructorArguments ); } if ( includes != null && includes.length > 0 ) { HashSet included = new HashSet( Arrays.asList( includes ) ); getLog().info( "Including: " + included ); generator.setIncluded( included ); } getLog().info( "Generating bindings..."); generator.generate( xsdSchema ); } }