Juan Hernandez has uploaded a new change for review.

Change subject: codegen: Separate RSDL data management and code generation
......................................................................

codegen: Separate RSDL data management and code generation

Currently the "RsdlCodegen" class is responsible for loading and
managing the RSDL metadata and also for generating the code of the
broker entities. To make this class simpler this patch separates these
two resposibilities to two different classes.

Change-Id: Ic8b2f77228c4bd27157e7ffb6c54f73b7d0bfbfe
Signed-off-by: Juan Hernandez <[email protected]>
---
M generator/src/main/java/org/ovirt/engine/sdk/generator/Main.java
M generator/src/main/java/org/ovirt/engine/sdk/generator/rsdl/RsdlCodegen.java
A generator/src/main/java/org/ovirt/engine/sdk/generator/rsdl/RsdlData.java
M generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdCodegen.java
M generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdData.java
5 files changed, 209 insertions(+), 96 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine-sdk refs/changes/22/38222/1

diff --git a/generator/src/main/java/org/ovirt/engine/sdk/generator/Main.java 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/Main.java
index 53eb127..b1ac289 100644
--- a/generator/src/main/java/org/ovirt/engine/sdk/generator/Main.java
+++ b/generator/src/main/java/org/ovirt/engine/sdk/generator/Main.java
@@ -17,26 +17,29 @@
 package org.ovirt.engine.sdk.generator;
 
 import org.ovirt.engine.sdk.generator.rsdl.RsdlCodegen;
+import org.ovirt.engine.sdk.generator.rsdl.RsdlData;
 import org.ovirt.engine.sdk.generator.xsd.XsdData;
 import org.ovirt.engine.sdk.generator.xsd.XsdCodegen;
+
+import java.io.File;
 
 public class Main {
     public static void main(String[] args) throws Exception {
         // Parse the command line parameters:
-        String xsdPath = null;
-        String rsdlPath = null;
+        File xsdFile = null;
+        File rsdlFile = null;
         for (int i = 0; i < args.length; i++) {
             switch (args[i]) {
             case "--xsd":
                 i++;
                 if (i < args.length) {
-                    xsdPath = args[i];
+                    xsdFile = new File(args[i]);
                 }
                 break;
             case "--rsdl":
                 i++;
                 if (i < args.length) {
-                    rsdlPath = args[i];
+                    rsdlFile = new File(args[i]);
                 }
                 break;
             default:
@@ -44,18 +47,19 @@
                 System.exit(1);
             }
         }
-        if (xsdPath == null || rsdlPath == null) {
+        if (xsdFile == null || rsdlFile == null) {
             System.err.println("Missing required parameters.");
             System.exit(1);
         }
 
-        // Build the class map:
-        XsdData.getInstance().load(xsdPath);
+        // Load the XML schema and the RSDL metadata:
+        XsdData.getInstance().load(xsdFile);
+        RsdlData.getInstance().load(rsdlFile);
 
         // Generate parameter classes:
-        new XsdCodegen().generate(xsdPath);
+        new XsdCodegen().generate();
 
         // Generate broker classes:
-        new RsdlCodegen().generate(rsdlPath);
+        new RsdlCodegen().generate();
     }
 }
diff --git 
a/generator/src/main/java/org/ovirt/engine/sdk/generator/rsdl/RsdlCodegen.java 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/rsdl/RsdlCodegen.java
index 0a533fb..076ebd4 100644
--- 
a/generator/src/main/java/org/ovirt/engine/sdk/generator/rsdl/RsdlCodegen.java
+++ 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/rsdl/RsdlCodegen.java
@@ -26,23 +26,14 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
 
 import org.apache.commons.io.FileUtils;
 import org.ovirt.engine.sdk.entities.DetailedLink;
-import org.ovirt.engine.sdk.entities.RSDL;
-import org.ovirt.engine.sdk.entities.Response;
 import org.ovirt.engine.sdk.generator.utils.Tree;
 
 /**
@@ -61,75 +52,19 @@
     );
 
     /**
-     * The root of the tree of locations.
-     */
-    private Tree<Location> root = new Tree<>();
-
-    /**
      * The keys of this map are the names of the broker types, and the content 
is the generated code.
      */
     private Map<String, CodeHolder> code = new LinkedHashMap<>();
 
-    public void generate(String rsdlPath) throws IOException {
-        // Load the RSDL document:
-        RSDL rsdl = loadRsdl(rsdlPath);
-
-        // The RSDL provided by the server doesn't include some links that are 
needed by the code generator, so we need
-        // to add them explicitly:
-        addMissingLinks(rsdl);
-
-        // Build the tree of URLs scanning all the links:
-        root.set(new Location());
-        for (DetailedLink link : rsdl.getLinks().getLinks()) {
-            List<String> path = Arrays.asList(link.getHref().split("/"));
-            Tree<Location> tree = root.getDescendant(path);
-            if (tree == null) {
-                tree = root.addDescendant(path);
-            }
-            Location location = tree.get();
-            if (location == null) {
-                location = new Location();
-                tree.set(location);
-            }
-            location.addLink(link);
-        }
-
-        // Get all the tree nodes:
-        List<Tree<Location>> locations = root.getDescendants();
-
-        // The previous process may have created intermediate nodes without a 
location object associated, and that may
-        // cause null pointer exceptions later, so to avoid that we need to 
make sure that all the nodes of the tree
-        // have a location, even if it is empty:
-        for (Tree<Location> tree : locations) {
-            Location location = tree.get();
-            if (location == null) {
-                location = new Location();
-                tree.set(location);
-            }
-        }
+    public void generate() throws IOException {
+        // Get the root of the tree of locations:
+        Tree<Location> root = RsdlData.getInstance().getRoot();
 
         // Generate the code:
-        locations.forEach(this::generateCode);
+        root.getDescendants().forEach(this::generateCode);
 
         // Store the generated code:
         persist();
-    }
-
-    private void addMissingLinks(RSDL rsdl) {
-        addMissingLink(rsdl, "users/{user:id}/roles/{role:id}", "Role");
-        addMissingLink(rsdl, 
"users/{user:id}/roles/{role:id}/permits/{permit:id}", "Permit");
-        addMissingLink(rsdl, "groups/{group:id}/roles/{role:id}", "Role");
-        addMissingLink(rsdl, 
"groups/{group:id}/roles/{role:id}/permits/{permit:id}", "Permit");
-    }
-
-    private void addMissingLink(RSDL rsdl, String href, String type) {
-        DetailedLink link = new DetailedLink();
-        link.setHref(href);
-        link.setRel("get");
-        Response response = new Response();
-        response.setType(type);
-        link.setResponse(response);
-        rsdl.getLinks().getLinks().add(link);
     }
 
     /**
@@ -375,19 +310,6 @@
             String updateMethod = SubResource.update(entityTree, link);
             holder.appendBody(updateMethod);
             break;
-        }
-    }
-
-    private RSDL loadRsdl(String rsdlPath) throws IOException {
-        try {
-            JAXBContext context = JAXBContext.newInstance(RSDL.class);
-            Unmarshaller unmarshaller = context.createUnmarshaller();
-            Source source = new StreamSource(new File(rsdlPath));
-            JAXBElement<RSDL> element = unmarshaller.unmarshal(source, 
RSDL.class);
-            return element.getValue();
-        }
-        catch (JAXBException exception) {
-            throw new IOException(exception);
         }
     }
 }
diff --git 
a/generator/src/main/java/org/ovirt/engine/sdk/generator/rsdl/RsdlData.java 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/rsdl/RsdlData.java
new file mode 100644
index 0000000..a5e1c6c
--- /dev/null
+++ b/generator/src/main/java/org/ovirt/engine/sdk/generator/rsdl/RsdlData.java
@@ -0,0 +1,159 @@
+//
+// Copyright (c) 2015 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.generator.rsdl;
+
+import org.ovirt.engine.sdk.entities.DetailedLink;
+import org.ovirt.engine.sdk.entities.RSDL;
+import org.ovirt.engine.sdk.entities.Response;
+import org.ovirt.engine.sdk.generator.utils.Tree;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This class contains the information extracted from the RSDL metadata.
+ */
+public class RsdlData {
+    /**
+     * This is a singleton, and this is the reference to the instance.
+     */
+    private static final RsdlData instance = new RsdlData();
+
+    /**
+     * Get the reference to the instance of this singleton.
+     */
+    public static RsdlData getInstance() {
+        return instance;
+    }
+
+    /**
+     * The file containing the RSDL metadata.
+     */
+    private File file;
+
+    /**
+     * The root of the tree of locations.
+     */
+    private Tree<Location> root = new Tree<>();
+
+    /**
+     * Returns the file that contains the RSDL metadata.
+     */
+    public File getFile() {
+        return file;
+    }
+
+    /**
+     * Returns the root of the tree of locations populated from the RSDL 
metadata. Note that the returned object is
+     * the one used internally, not a copy, so try to avoid modifying it.
+     */
+    public Tree<Location> getRoot() {
+        return root;
+    }
+
+    /**
+     * Loads the RSDL metadata from a file and extracts the information 
required to build the tree of locations.
+     *
+     * @param file the file that contains the RSDL metadata
+     * @throws IOException if something fails while loading the metadata or 
building the tree of locations
+     */
+    public void load(File file) throws IOException {
+        // Save the reference to the file:
+        this.file = file;
+
+        // Load the RSDL document:
+        RSDL rsdl = load();
+
+        // The RSDL provided by the server doesn't include some links that are 
needed by the code generator, so we need
+        // to add them explicitly:
+        addMissingLinks(rsdl);
+
+        // Build the tree of URLs scanning all the links:
+        root.set(new Location());
+        for (DetailedLink link : rsdl.getLinks().getLinks()) {
+            List<String> path = Arrays.asList(link.getHref().split("/"));
+            Tree<Location> tree = root.getDescendant(path);
+            if (tree == null) {
+                tree = root.addDescendant(path);
+            }
+            Location location = tree.get();
+            if (location == null) {
+                location = new Location();
+                tree.set(location);
+            }
+            location.addLink(link);
+        }
+
+        // Get all the tree nodes:
+        List<Tree<Location>> locations = root.getDescendants();
+
+        // The previous process may have created intermediate nodes without a 
location object associated, and that may
+        // cause null pointer exceptions later, so to avoid that we need to 
make sure that all the nodes of the tree
+        // have a location, even if it is empty:
+        for (Tree<Location> tree : locations) {
+            Location location = tree.get();
+            if (location == null) {
+                location = new Location();
+                tree.set(location);
+            }
+        }
+    }
+
+    private void addMissingLinks(RSDL rsdl) {
+        addMissingLink(rsdl, "users/{user:id}/roles/{role:id}", "Role");
+        addMissingLink(rsdl, 
"users/{user:id}/roles/{role:id}/permits/{permit:id}", "Permit");
+        addMissingLink(rsdl, "groups/{group:id}/roles/{role:id}", "Role");
+        addMissingLink(rsdl, 
"groups/{group:id}/roles/{role:id}/permits/{permit:id}", "Permit");
+    }
+
+    private void addMissingLink(RSDL rsdl, String href, String type) {
+        DetailedLink link = new DetailedLink();
+        link.setHref(href);
+        link.setRel("get");
+        Response response = new Response();
+        response.setType(type);
+        link.setResponse(response);
+        rsdl.getLinks().getLinks().add(link);
+    }
+
+    /**
+     * Loads the RSDL metadata from a file.
+     *
+     * @return the RSDL object populated with the data loaded from the file
+     * @throws IOException if something while loading the metadata
+     */
+    private RSDL load() throws IOException {
+        try {
+            JAXBContext context = JAXBContext.newInstance(RSDL.class);
+            Unmarshaller unmarshaller = context.createUnmarshaller();
+            Source source = new StreamSource(file);
+            JAXBElement<RSDL> element = unmarshaller.unmarshal(source, 
RSDL.class);
+            return element.getValue();
+        }
+        catch (JAXBException exception) {
+            throw new IOException(exception);
+        }
+    }
+}
diff --git 
a/generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdCodegen.java 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdCodegen.java
index 90f244a..15098aa 100644
--- a/generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdCodegen.java
+++ b/generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdCodegen.java
@@ -17,6 +17,7 @@
 package org.ovirt.engine.sdk.generator.xsd;
 
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -51,7 +52,7 @@
     /**
      * Generates parameter classes.
      */
-    public void generate(String xsdPath) throws IOException {
+    public void generate() throws IOException {
         // Check that the version of generateDS.py is correct:
         String version = runCommand("generateDS.py", "--version");
         if (!version.equals("generateDS.py version " + GENERATE_DS_VERSION)) {
@@ -60,8 +61,11 @@
             );
         }
 
+        // Get the location of the XML schemma file:
+        File xsdFile = XsdData.getInstance().getFile();
+
         // Run the generateDS.py program to generate the params.py file:
-        runCommand("generateDS.py", "-f", "-o", XSD_PARAMS_FILE, xsdPath);
+        runCommand("generateDS.py", "-f", "-o", XSD_PARAMS_FILE, 
xsdFile.getAbsolutePath());
 
         // Load all the lines of the params.py file in memory so that we can 
modify them easily:
         try (BufferedReader in = new BufferedReader(new 
FileReader(XSD_PARAMS_FILE))) {
diff --git 
a/generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdData.java 
b/generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdData.java
index ec756dc..0f8da22 100644
--- a/generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdData.java
+++ b/generator/src/main/java/org/ovirt/engine/sdk/generator/xsd/XsdData.java
@@ -40,11 +40,22 @@
 import org.w3c.dom.NodeList;
 
 public class XsdData {
+    /**
+     * This is a singleton, and this is the reference to the instance.
+     */
     private static final XsdData instance = new XsdData();
 
+    /**
+     * Get the reference to the instance of this singleton.
+     */
     public static XsdData getInstance() {
         return instance;
     }
+
+    /**
+     * The file containing the RSDL metadata.
+     */
+    private File file;
 
     /**
      * This maps stores the relationship between XML tag names and Python type 
names.
@@ -74,17 +85,30 @@
      */
     private XPath xpath;
 
-    private XsdData() {
+    /**
+     * Returns the file that contains the XML schema.
+     */
+    public File getFile() {
+        return file;
     }
 
-    public void load(String xsd) throws IOException {
+    /**
+     * Loads the XML schema from a file.
+     *
+     * @param file the file that contains the XML schema
+     * @throws IOException if something fails while loading the schema
+     */
+    public void load(File file) throws IOException {
+        // Save the reference to the file:
+        this.file = file;
+
         // Parse the XML schema document:
         Document schema;
         try {
             DocumentBuilderFactory factory = 
DocumentBuilderFactory.newInstance();
             factory.setNamespaceAware(true);
             DocumentBuilder parser = factory.newDocumentBuilder();
-            schema = parser.parse(new File(xsd));
+            schema = parser.parse(file);
         }
         catch (Exception exception) {
             throw new IOException("Can't parse XML schema.", exception);


-- 
To view, visit https://gerrit.ovirt.org/38222
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic8b2f77228c4bd27157e7ffb6c54f73b7d0bfbfe
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine-sdk
Gerrit-Branch: master
Gerrit-Owner: Juan Hernandez <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to