Juan Hernandez has uploaded a new change for review. Change subject: codegen: Use XSD instead of classpath scanning ......................................................................
codegen: Use XSD instead of classpath scanning Currently the code generator scans the classpath to find the set of entity classes generated by the xjc compiler. This means that the generation has to be done in several steps: first generate the entities, then compile the result, then generate the decorators and the entry point, then compile again. These steps are currently managed by the generator itself, which calls Maven to do the intermediate compilation. To avoid this issue this patch changes the generator so that it extracts the set of entity classes from the XSD, using XSOM to parse it. Change-Id: Ia9c7146b477d421ad296cef376cef7c08d051ad8 Signed-off-by: Juan Hernandez <juan.hernan...@redhat.com> --- M ovirt-engine-sdk-java-codegen/pom.xml M ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/Main.java M ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/common/AbstractCodegen.java D ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/compile/CodeCompiler.java D ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/compile/ICompiler.java M ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/ApiCodegen.java M ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/RsdlCodegen.java D ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/utils/ReflectionHelper.java 8 files changed, 46 insertions(+), 296 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine-sdk-java refs/changes/92/22992/1 diff --git a/ovirt-engine-sdk-java-codegen/pom.xml b/ovirt-engine-sdk-java-codegen/pom.xml index 77ab14c..cfed472 100644 --- a/ovirt-engine-sdk-java-codegen/pom.xml +++ b/ovirt-engine-sdk-java-codegen/pom.xml @@ -44,9 +44,9 @@ </dependency> <dependency> - <groupId>org.apache.maven</groupId> - <artifactId>maven-embedder</artifactId> - <version>3.0.5</version> + <groupId>com.sun.xsom</groupId> + <artifactId>xsom</artifactId> + <version>20110809</version> </dependency> </dependencies> diff --git a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/Main.java b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/Main.java index dcd1a8a..d1ef967 100644 --- a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/Main.java +++ b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/Main.java @@ -59,7 +59,7 @@ new XsdCodegen(xsdPath).generate(); // #2 - generate api entities decorators by RSDL and SDK entry point - new RsdlCodegen(rsdlPath).generate(); + new RsdlCodegen(xsdPath, rsdlPath).generate(); // #3 - exit System.exit(0); diff --git a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/common/AbstractCodegen.java b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/common/AbstractCodegen.java index 5cc6de2..27cfe5c 100644 --- a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/common/AbstractCodegen.java +++ b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/common/AbstractCodegen.java @@ -16,12 +16,10 @@ package org.ovirt.engine.sdk.codegen.common; -import java.io.File; import java.io.IOException; import javax.xml.bind.JAXBException; -import org.ovirt.engine.sdk.codegen.compile.CodeCompiler; import org.ovirt.engine.sdk.codegen.utils.FileUtils; /** @@ -31,9 +29,6 @@ private final String distPath; - private final CodeCompiler codeCompiler; - private boolean dontCompile = false; - /** * @param distPath * path to generate the code in @@ -41,20 +36,6 @@ public AbstractCodegen(String distPath) { super(); this.distPath = distPath; - this.codeCompiler = new CodeCompiler(getPackagePath()); - } - - /** - * @param distPath - * path to generate the code in - * @param dontCompile - * disables compilation post gen() - */ - public AbstractCodegen(String distPath, boolean dontCompile) { - super(); - this.distPath = distPath; - this.codeCompiler = new CodeCompiler(getPackagePath()); - this.dontCompile = dontCompile; } /** @@ -67,24 +48,6 @@ public void generate() throws IOException, JAXBException { doCleanPackage(this.distPath); doGenerate(this.distPath); - doCompile(); - } - - /** - * Compiles generated code - */ - private void doCompile() { - if (!this.dontCompile) { - codeCompiler.compile(); - } - } - - /** - * @return root package path - */ - private String getPackagePath() { - String[] split = this.distPath.split(File.separator); - return split[0] + File.separator + split[1]; } /** @@ -106,13 +69,6 @@ */ protected void doCleanPackage(String dir) { FileUtils.deleteAllFiles(dir); - } - - /*** - * @return path to generate the code in - */ - protected String getDistinationPath() { - return distPath; } /** diff --git a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/compile/CodeCompiler.java b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/compile/CodeCompiler.java deleted file mode 100644 index 733801e..0000000 --- a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/compile/CodeCompiler.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright (c) 2012 Red Hat, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package org.ovirt.engine.sdk.codegen.compile; - -import org.apache.maven.cli.MavenCli; - -/** - * Provides compilation services - */ -public class CodeCompiler implements ICompiler { - - private static final String GOAL = "compile"; - - private final String path; - private final MavenCli mavenCli; - - public CodeCompiler(String path) { - super(); - this.path = path; - this.mavenCli = new MavenCli(); - } - - /** - * Compiles java code where default goal is compile. - * - * @return compilation status. - */ - @Override - public int compile() { - return compile(GOAL); - } - - /** - * Compiles java code - * - * @param goal - * compilation goal - * - * @return compilation status. - */ - public int compile(String goal) { - return this.mavenCli.doMain( - new String[] { goal }, - this.path, - System.out, - System.out); - } -} diff --git a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/compile/ICompiler.java b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/compile/ICompiler.java deleted file mode 100644 index b8fc6ee..0000000 --- a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/compile/ICompiler.java +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (c) 2012 Red Hat, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package org.ovirt.engine.sdk.codegen.compile; - -public interface ICompiler { - /** - * Compiles java code where default goal is compile. - * - * @return compilation status. - */ - public int compile(); -} diff --git a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/ApiCodegen.java b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/ApiCodegen.java index 363ccee..11b1930 100644 --- a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/ApiCodegen.java +++ b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/ApiCodegen.java @@ -62,7 +62,7 @@ public ApiCodegen(Map<String, CollectionHolder> collectionsHolder, VariableTemplate variableTemplate, CollectionGetterTemplate collectionGetterTemplate) { - super(getApiPath(), true); + super(getApiPath()); this.apiTemplate = new ApiTemplate(); this.rootResourceStaticTemplate = new RootResourceStaticTemplate(); this.rootResourceDynamicTemplate = new RootResourceDynamicTemplate(); diff --git a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/RsdlCodegen.java b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/RsdlCodegen.java index 523ce8e..5e882e6 100644 --- a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/RsdlCodegen.java +++ b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/rsdl/RsdlCodegen.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -30,6 +31,9 @@ import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; +import com.sun.xml.xsom.XSComplexType; +import com.sun.xml.xsom.XSSchemaSet; +import com.sun.xml.xsom.parser.XSOMParser; import org.ovirt.engine.sdk.codegen.common.AbstractCodegen; import org.ovirt.engine.sdk.codegen.documentation.DocsGen; import org.ovirt.engine.sdk.codegen.holders.CollectionHolder; @@ -50,14 +54,9 @@ import org.ovirt.engine.sdk.codegen.templates.UpdateMethodTemplate; import org.ovirt.engine.sdk.codegen.templates.VariableTemplate; import org.ovirt.engine.sdk.codegen.utils.OsUtil; -import org.ovirt.engine.sdk.codegen.utils.ReflectionHelper; import org.ovirt.engine.sdk.codegen.xsd.XsdCodegen; import org.ovirt.engine.sdk.entities.Capabilities; import org.ovirt.engine.sdk.entities.DetailedLink; -import org.ovirt.engine.sdk.entities.GlusterBrick; -import org.ovirt.engine.sdk.entities.GlusterBricks; -import org.ovirt.engine.sdk.entities.HostNIC; -import org.ovirt.engine.sdk.entities.HostNics; import org.ovirt.engine.sdk.entities.HttpMethod; import org.ovirt.engine.sdk.entities.RSDL; import org.ovirt.engine.sdk.entities.VersionCaps; @@ -69,11 +68,20 @@ */ public class RsdlCodegen extends AbstractCodegen { /** + * The location of the XSD file. + */ + private String xsdPath; + + /** * The location of the RSDL file. */ private String rsdlPath; - private Map<String, Class<?>> entitiesMap; + /** + * This maps contains the mapping between entities as described in the RSDL and the names of the Java classes that + * represent those entities. + */ + private Map<String, String> entitiesMap; private CollectionTemplate collectionTemplate; private ResourceTemplate resourceTemplate; @@ -100,7 +108,6 @@ private static final String WINDOWS_DECORATORS_PATH = "..\\ovirt-engine-sdk-java\\src\\main\\java\\org\\ovirt\\engine\\sdk\\decorators\\"; private static final String SLASH = "/"; - private static final String ENTITIES_PACKAGE = "org.ovirt.engine.sdk.entities"; private static final String DELETE_REL = "delete"; private static final String UPDATE_REL = "update"; private static final String ADD_REL = "add"; @@ -119,8 +126,9 @@ * * @param rsdlPath the path of the file containing the RSDL document */ - public RsdlCodegen(String rsdlPath) { + public RsdlCodegen(String xsdPath, String rsdlPath) { super(getDecoratorsPath()); + this.xsdPath = xsdPath; this.rsdlPath = rsdlPath; this.collectionTemplate = new CollectionTemplate(); @@ -146,25 +154,30 @@ } /** - * Maps entity to clazz.SimpleName + * Maps RSDL entity name to Java class name. * * @return EntitiesMap */ - private Map<String, Class<?>> getEntitiesMap() { - List<Class<?>> classes = new ArrayList<Class<?>>(); - Map<String, Class<?>> map = new HashMap<String, Class<?>>(); + private Map<String, String> getEntitiesMap() { + Map<String, String> map = new HashMap<>(); + + // Load the XML schema: + XSOMParser parser = new XSOMParser(); + XSSchemaSet schema; try { - classes = ReflectionHelper.getClasses(ENTITIES_PACKAGE); - } catch (ClassNotFoundException e) { - // TODO: Log error - e.printStackTrace(); - } catch (IOException e) { - // TODO: Log error - e.printStackTrace(); + parser.parse(new File(xsdPath)); + schema = parser.getResult(); + } + catch (Exception exception) { + throw new RuntimeException("Can't parse XML schema \"" + xsdPath + "\".", exception); } - for (Class<?> clazz : classes) { - map.put(clazz.getSimpleName().toLowerCase(), clazz); + // For each complex type add an entry to the entities map: + Iterator<XSComplexType> types = schema.iterateComplexTypes(); + while (types.hasNext()) { + XSComplexType type = types.next(); + String name = type.getName(); + map.put(name.toLowerCase(), name); } return addExceptions(map); @@ -178,13 +191,13 @@ * * @return updated map */ - private Map<String, Class<?>> addExceptions(Map<String, Class<?>> map) { + private Map<String, String> addExceptions(Map<String, String> map) { // FIXME: Fix this on server side or fond a way locating exceptions programatically - map.put("brick", GlusterBrick.class); - map.put("bricks", GlusterBricks.class); - map.put("hostnic", HostNIC.class); - map.put("hostnics", HostNics.class); + map.put("brick", "GlusterBrick"); + map.put("bricks", "GlusterBricks"); + map.put("hostnic", "HostNIC"); + map.put("hostnics", "HostNics"); return map; } @@ -907,7 +920,7 @@ */ private String getPublicCollection(String collectionName) { if (this.entitiesMap.containsKey(collectionName.toLowerCase())) { - return this.entitiesMap.get(collectionName.toLowerCase()).getSimpleName(); + return this.entitiesMap.get(collectionName.toLowerCase()); } return null; } @@ -935,7 +948,7 @@ */ private String getPublicEntity(String entityName) { if (this.entitiesMap.containsKey(entityName.toLowerCase())) { - return this.entitiesMap.get(entityName.toLowerCase()).getSimpleName(); + return this.entitiesMap.get(entityName.toLowerCase()); } throw new RuntimeException("Public entity \"" + entityName + "\" fetch has failed."); } diff --git a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/utils/ReflectionHelper.java b/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/utils/ReflectionHelper.java deleted file mode 100644 index 3bbab9a..0000000 --- a/ovirt-engine-sdk-java-codegen/src/main/java/org/ovirt/engine/sdk/codegen/utils/ReflectionHelper.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.ovirt.engine.sdk.codegen.utils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.URLDecoder; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; - -public class ReflectionHelper { - - /** - * Locate all directories in given package - * - * @param path - * @return Map<URL, File> - * @throws IOException - */ - public static List<URL> getDirectories(String path) throws IOException { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - assert classLoader != null; - Enumeration<URL> resources = classLoader.getResources(path); - List<URL> dirs = new ArrayList<URL>(); - while (resources.hasMoreElements()) { - dirs.add(resources.nextElement()); - } - return dirs; - } - - /** - * Locates all classes in given package - * - * @param packageName - * @return array of the classes - * @throws ClassNotFoundException - * @throws IOException - */ - public static List<Class<?>> getClasses(String packageName) throws ClassNotFoundException, - IOException { - String path = packageName.replace('.', '/'); - List<URL> dirs = getDirectories(path); - ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); - ClassLoader loader = URLClassLoader.newInstance(dirs.toArray(new URL[0]), - Thread.currentThread().getContextClassLoader()); - - for (URL directory : dirs) { - String resource = URLDecoder.decode(directory.getPath(), "UTF-8").replace("/" + path + "/", ""); - if (resource.endsWith(".jar")) { - classes.addAll(getClassNamesInJarPackage(loader, resource, packageName)); - } else { - classes.addAll(getClassNamesInPackage(new File(URLDecoder.decode(directory.getFile(), "UTF-8")), - packageName)); - } - } - return classes; - } - - /** - * Locates all classes in given package - * - * @param directory - * @param packageName - * @return List of classes - * @throws ClassNotFoundException - */ - private static List<Class<?>> getClassNamesInPackage(File directory, String packageName) - throws ClassNotFoundException { - List<Class<?>> classes = new ArrayList<Class<?>>(); - if (!directory.exists()) { - return classes; - } - File[] files = directory.listFiles(); - for (File file : files) { - if (file.isDirectory()) { - assert !file.getName().contains("."); - classes.addAll(getClassNamesInPackage(file, packageName + "." + file.getName())); - } else if (file.getName().endsWith(".class")) { - classes.add(Class.forName(packageName + '.' - + file.getName().substring(0, file.getName().length() - 6))); - } - } - return classes; - } - - /** - * Locates all classes in given jar package - * - * @param jarName - * @param url - * @param packageName - * @return List of classes - * @throws MalformedURLException - */ - static List<Class<?>> getClassNamesInJarPackage(ClassLoader loader, String jarName, String packageName) - throws MalformedURLException { - ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); - - packageName = packageName.replaceAll("\\.", "/"); - - JarInputStream jarFileInputStream = null; - try { - jarFileInputStream = new JarInputStream(new FileInputStream(jarName)); - JarEntry jarEntry; - while (true) { - jarEntry = jarFileInputStream.getNextJarEntry(); - if (jarEntry == null) - break; - if ((jarEntry.getName().startsWith(packageName)) && (jarEntry.getName().endsWith(".class"))) { - classes.add(loader.loadClass(jarEntry.getName().replaceAll("/", "\\.").replace(".class", ""))); - } - } - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (jarFileInputStream != null) { - jarFileInputStream.close(); - } - } catch (IOException e) { - // ignore - } - } - return classes; - } -} \ No newline at end of file -- To view, visit http://gerrit.ovirt.org/22992 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia9c7146b477d421ad296cef376cef7c08d051ad8 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine-sdk-java Gerrit-Branch: master Gerrit-Owner: Juan Hernandez <juan.hernan...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches