[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