[infinispan-commits] Infinispan SVN: r560 - in trunk/tools/src/main/java/org/infinispan/tools: schema and 1 other directory.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Mon Jul 13 10:42:29 EDT 2009


Author: vblagojevic at jboss.com
Date: 2009-07-13 10:42:29 -0400 (Mon, 13 Jul 2009)
New Revision: 560

Added:
   trunk/tools/src/main/java/org/infinispan/tools/schema/
   trunk/tools/src/main/java/org/infinispan/tools/schema/SchemaGenerator.java
   trunk/tools/src/main/java/org/infinispan/tools/schema/SchemaGeneratorTreeWalker.java
   trunk/tools/src/main/java/org/infinispan/tools/schema/TreeNode.java
   trunk/tools/src/main/java/org/infinispan/tools/schema/TreeWalker.java
Log:
schema tool first cut

Added: trunk/tools/src/main/java/org/infinispan/tools/schema/SchemaGenerator.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/schema/SchemaGenerator.java	                        (rev 0)
+++ trunk/tools/src/main/java/org/infinispan/tools/schema/SchemaGenerator.java	2009-07-13 14:42:29 UTC (rev 560)
@@ -0,0 +1,171 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.tools.schema;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.infinispan.Version;
+import org.infinispan.config.AbstractConfigurationBean;
+import org.infinispan.config.ConfigurationElement;
+import org.infinispan.config.ConfigurationElements;
+import org.infinispan.util.ClassFinder;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class SchemaGenerator {
+   private final List<Class<?>> beans;
+   private final TreeNode root;
+   private final File fileToWrite;
+   
+   protected SchemaGenerator(File fileToWrite, String searchPath) throws Exception {
+      this.fileToWrite = fileToWrite;
+      List<Class<?>> infinispanClasses = null;
+      String pathUsed = ClassFinder.PATH;
+      if (searchPath == null || searchPath.length() == 0) {
+         infinispanClasses = ClassFinder.infinispanClasses();
+      } else {
+         pathUsed = searchPath;
+         infinispanClasses = ClassFinder.infinispanClasses(searchPath);
+      }
+      if (infinispanClasses == null || infinispanClasses.isEmpty())
+         throw new IllegalArgumentException("Could not find infinispan classes on your classpath "
+                  + pathUsed);
+
+      beans = ClassFinder.isAssignableFrom(infinispanClasses, AbstractConfigurationBean.class);
+      if (beans.isEmpty())
+         throw new IllegalStateException("Could not find AbstractConfigurationBean(s) on your classpath " 
+                  + pathUsed);
+      
+      root = tree(beans);
+   }
+   
+   private TreeNode findNode(TreeNode tn, String name, String parent){
+      TreeNode result = null;
+      if(tn.getName().equals(name) && tn.getParent() != null && tn.getParent().getName().equals(parent)){         
+         result = tn;
+      } else {
+         for (TreeNode child :tn.getChildren()){
+            result = findNode(child,name,parent);
+            if(result != null) break;
+         }
+      }
+      return result;
+   }
+   
+   private TreeNode tree(List<Class<?>>configBeans){
+      List<ConfigurationElement> lce = new ArrayList<ConfigurationElement>(7);
+      for (Class<?> clazz : configBeans) {
+         ConfigurationElement ces[] = null;
+         ConfigurationElements configurationElements = clazz.getAnnotation(ConfigurationElements.class);
+         ConfigurationElement configurationElement = clazz.getAnnotation(ConfigurationElement.class);
+
+         if (configurationElement != null && configurationElements == null) {
+            ces = new ConfigurationElement[]{configurationElement};
+         }
+         if (configurationElements != null && configurationElement == null) {
+            ces = configurationElements.elements();
+         }
+         if(ces != null){
+            lce.addAll(Arrays.asList(ces));
+         }
+      }
+      TreeNode root = new TreeNode("infinispan",new TreeNode());      
+      makeTree(lce,root);
+      return root;
+   }
+   
+   private void makeTree(List<ConfigurationElement> lce, TreeNode tn) {
+      for (ConfigurationElement ce : lce) {
+         if(ce.parent().equals(tn.getName())){
+            TreeNode child = new TreeNode(ce.name(),tn);
+            tn.getChildren().add(child);
+            makeTree(lce,child);
+         }
+      }
+   }
+   
+   public static void main(String[] args) throws Exception {
+      String outputDir = "./";
+
+      for (int i = 0; i < args.length; i++) {
+         String arg = args[i];
+         if ("-o".equals(arg)) {
+            outputDir = args[++i];
+            continue;
+         } else {
+            System.out.println("SchemaGenerator -o <path to newly created xsd schema file>");
+            return;
+         }
+      }
+
+      File f = new File(outputDir, "infinispan-config-" +Version.getMajorVersion() + ".xsd");
+      SchemaGenerator sg = new SchemaGenerator(f,null);
+      sg.generateSchema();
+   }
+
+   private void generateSchema() {
+      try {
+         FileWriter fw = new FileWriter(fileToWrite, false);
+         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+         DocumentBuilder builder = factory.newDocumentBuilder();
+         DOMImplementation impl = builder.getDOMImplementation();
+         Document xmldoc = impl.createDocument("http://www.w3.org/2001/XMLSchema", "xs:schema",null);
+         xmldoc.getDocumentElement().setAttribute("targetNamespace", "urn:infinispan:config:" + Version.getMajorVersion());
+         xmldoc.getDocumentElement().setAttribute("xmlns:tns","urn:infinispan:config:" + Version.getMajorVersion());
+         xmldoc.getDocumentElement().setAttribute("elementFormDefault", "qualified");
+        
+         Element xsElement = xmldoc.createElement("xs:element");       
+         xsElement.setAttribute("name", "infinispan");
+         xsElement.setAttribute("type", "tns:infinispanType");
+         xmldoc.getDocumentElement().appendChild(xsElement);
+
+         SchemaGeneratorTreeWalker tw = new SchemaGeneratorTreeWalker(xmldoc,beans);
+         root.acceptPreOrderTreeWalker(tw);
+
+         DOMSource domSource = new DOMSource(xmldoc);
+         StreamResult streamResult = new StreamResult(fw);
+         TransformerFactory tf = TransformerFactory.newInstance();
+         Transformer serializer = tf.newTransformer();
+         serializer.setOutputProperty(OutputKeys.METHOD, "xml");
+         serializer.setOutputProperty(OutputKeys.INDENT, "yes");
+         serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+         serializer.transform(domSource, streamResult);                 
+         fw.flush();
+         fw.close();
+      } catch (Exception e) {
+         e.printStackTrace();
+      }      
+   }
+}

Added: trunk/tools/src/main/java/org/infinispan/tools/schema/SchemaGeneratorTreeWalker.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/schema/SchemaGeneratorTreeWalker.java	                        (rev 0)
+++ trunk/tools/src/main/java/org/infinispan/tools/schema/SchemaGeneratorTreeWalker.java	2009-07-13 14:42:29 UTC (rev 560)
@@ -0,0 +1,137 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.tools.schema;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.List;
+import java.util.Set;
+
+import org.infinispan.config.ConfigurationAttribute;
+import org.infinispan.config.ConfigurationElement;
+import org.infinispan.config.ConfigurationElements;
+import org.infinispan.config.ConfigurationException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class SchemaGeneratorTreeWalker implements TreeWalker {
+   
+   Document xmldoc;
+   private List<Class<?>> beans;
+
+   public SchemaGeneratorTreeWalker(Document xmldoc, List<Class<?>> beans) {
+      super();
+      this.xmldoc = xmldoc;
+      this.beans = beans;
+   }
+
+   public void visitNode(TreeNode treeNode) {
+      
+      Element complexType = xmldoc.createElement("xs:complexType");
+      complexType.setAttribute("name", treeNode.getName() + "Type");
+      if(treeNode.hasChildren()) {
+         Element all = xmldoc.createElement("xs:all");
+         complexType.appendChild(all);
+         Set<TreeNode> children = treeNode.getChildren();
+         for (TreeNode child : children) {
+            Element childElement = xmldoc.createElement("xs:element");
+            childElement.setAttribute("name", child.getName());
+            childElement.setAttribute("type", "tns:" + child.getName() + "Type");
+            //childElement.setAttribute("minOccurs", "0");
+            //childElement.setAttribute("maxOccurs", "1");            
+            all.appendChild(childElement);
+         }
+      } else { 
+         Class <?> bean = findBean(beans, treeNode.getName(), treeNode.getParent().getName());
+         for (Method m : bean.getMethods()) {
+            ConfigurationAttribute a = m.getAnnotation(ConfigurationAttribute.class);
+            boolean childElement = a != null && a.containingElement().equals(treeNode.getName());           
+            if (childElement) {
+               String type = "";
+               if (isSetterMethod(m)) {
+                  type = m.getParameterTypes()[0].getSimpleName();
+                  type = type.toLowerCase();
+               }                            
+               Element att = xmldoc.createElement("xs:attribute");
+               att.setAttribute("name", a.name());
+               att.setAttribute("type", "xs:" + type);
+               complexType.appendChild(att);
+            }
+         }         
+      }
+      xmldoc.getDocumentElement().appendChild(complexType);
+   }
+   
+   private Class<?> findBean(List<Class<?>> b, String name, String parentName) throws ConfigurationException {
+      
+      if (parentName.equals("namedCache"))
+         parentName = "default";
+      for (Class<?> clazz : b) {
+         ConfigurationElements elements = clazz.getAnnotation(ConfigurationElements.class);
+         try {
+            if (elements != null) {
+               for (ConfigurationElement ce : elements.elements()) {
+                  if (ce.name().equals(name) && ce.parent().equals(parentName)) {
+                     return clazz;
+                  }
+               }
+            } else {
+               ConfigurationElement ce = clazz.getAnnotation(ConfigurationElement.class);
+               if (ce != null && (ce.name().equals(name) && ce.parent().equals(parentName))) {
+                  return clazz;
+               }
+            }
+         } catch (Exception e1) {
+            throw new ConfigurationException("Could not instantiate class " + clazz, e1);
+         }
+      }
+      return null;
+   }
+   
+   
+   private boolean isSetterMethod(Method m) {
+      return m.getName().startsWith("set") && m.getParameterTypes().length == 1;
+   }
+
+   private Object matchingFieldValue(Method m) throws Exception {
+      String name = m.getName();
+      if (!name.startsWith("set")) throw new IllegalArgumentException("Not a setter method");
+
+      String fieldName = name.substring(name.indexOf("set") + 3);
+      fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
+      Field f = m.getDeclaringClass().getDeclaredField(fieldName);
+      return getField(f, m.getDeclaringClass().newInstance());
+   }
+   
+   private static Object getField(Field field, Object target) {
+      if (!Modifier.isPublic(field.getModifiers())) {
+         field.setAccessible(true);
+      }
+      try {
+         return field.get(target);
+      }
+      catch (IllegalAccessException iae) {
+         throw new IllegalArgumentException("Could not get field " + field, iae);
+      }
+   }
+}

Added: trunk/tools/src/main/java/org/infinispan/tools/schema/TreeNode.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/schema/TreeNode.java	                        (rev 0)
+++ trunk/tools/src/main/java/org/infinispan/tools/schema/TreeNode.java	2009-07-13 14:42:29 UTC (rev 560)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.tools.schema;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class TreeNode {
+   private final String name;
+   private final TreeNode parent;
+   private final Set<TreeNode> children = new HashSet<TreeNode>();
+   
+   public TreeNode(String name, TreeNode parent) {
+      this.name = name;
+      this.parent = parent;
+   }   
+   
+   public TreeNode() {
+      this.name="";
+      this.parent=null;
+   }
+
+   public String getName() {
+      return name;
+   }
+   
+   public boolean hasChildren(){
+      return !children.isEmpty();
+   }
+
+   public TreeNode getParent() {
+      return parent;
+   }
+   
+   public Set<TreeNode> getChildren() {
+      return children;
+   }
+   
+   public void acceptPreOrderTreeWalker(TreeWalker tw) {
+      tw.visitNode(this);         
+      for (TreeNode child : children)
+         child.acceptPreOrderTreeWalker(tw);         
+   }
+
+   public boolean equals(Object other) {
+      if (other == this)
+         return true;
+      if (!(other instanceof TreeNode))
+         return false;
+      TreeNode tn = (TreeNode) other;
+      return this.parent.name != null && tn.parent != null
+               && this.parent.name.equals(tn.parent.name) && this.name.equals(tn.name);
+   }  
+
+   public int hashCode() {
+      int result = 17;
+      result = 31 * result + name.hashCode();
+      result = 31 * result
+               + ((parent != null && parent.name != null) ? parent.name.hashCode() : 0);
+      return result;
+   }
+   
+   public String toString() {
+      return name;
+   }
+}
\ No newline at end of file

Added: trunk/tools/src/main/java/org/infinispan/tools/schema/TreeWalker.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/schema/TreeWalker.java	                        (rev 0)
+++ trunk/tools/src/main/java/org/infinispan/tools/schema/TreeWalker.java	2009-07-13 14:42:29 UTC (rev 560)
@@ -0,0 +1,30 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.tools.schema;
+
+import org.infinispan.tools.schema.TreeNode;
+
+public interface TreeWalker {
+
+   void visitNode(TreeNode treeNode);
+
+}




More information about the infinispan-commits mailing list