[infinispan-commits] Infinispan SVN: r1559 - in trunk/tools/src/main: java/org/infinispan/tools/schema and 1 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Tue Mar 2 14:44:44 EST 2010
Author: vblagojevic at jboss.com
Date: 2010-03-02 14:44:44 -0500 (Tue, 02 Mar 2010)
New Revision: 1559
Added:
trunk/tools/src/main/java/org/infinispan/tools/doclet/config/AbstractConfigHtmlGenerator.java
trunk/tools/src/main/resources/h1_hdr.png
Modified:
trunk/tools/src/main/java/org/infinispan/tools/doclet/config/ConfigHtmlGenerator.java
trunk/tools/src/main/java/org/infinispan/tools/doclet/config/XMLTreeOutputWalker.java
trunk/tools/src/main/java/org/infinispan/tools/schema/TreeNode.java
trunk/tools/src/main/java/org/infinispan/tools/schema/XSOMSchemaTreeWalker.java
trunk/tools/src/main/resources/stylesheet2.css
Log:
isolate configuration reference generation framework
Added: trunk/tools/src/main/java/org/infinispan/tools/doclet/config/AbstractConfigHtmlGenerator.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/doclet/config/AbstractConfigHtmlGenerator.java (rev 0)
+++ trunk/tools/src/main/java/org/infinispan/tools/doclet/config/AbstractConfigHtmlGenerator.java 2010-03-02 19:44:44 UTC (rev 1559)
@@ -0,0 +1,537 @@
+/*
+ * 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.doclet.config;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.Set;
+
+import org.infinispan.tools.doclet.html.HtmlGenerator;
+import org.infinispan.tools.schema.TreeNode;
+import org.infinispan.tools.schema.XSOMSchemaTreeWalker;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.FieldDoc;
+import com.sun.javadoc.RootDoc;
+import com.sun.javadoc.Tag;
+import com.sun.xml.xsom.XSAttributeDecl;
+import com.sun.xml.xsom.XSFacet;
+import com.sun.xml.xsom.XSRestrictionSimpleType;
+import com.sun.xml.xsom.XSSchemaSet;
+import com.sun.xml.xsom.parser.XSOMParser;
+
+ at SuppressWarnings("restriction")
+public abstract class AbstractConfigHtmlGenerator extends HtmlGenerator {
+
+ protected static final String CONFIG_REF = "configRef";
+
+ protected static final String CONFIG_REF_NAME_ATT= "name";
+ protected static final String CONFIG_REF_PARENT_NAME_ATT= "parentName";
+ protected static final String CONFIG_REF_DESC_ATT= "desc";
+
+
+ private static final int LEVEL_MULT = 3;
+ private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("infinispan.tools.configdoc.debug", "false"));
+
+ protected RootDoc rootDoc;
+ protected StringBuilder sb;
+
+ public AbstractConfigHtmlGenerator(String encoding, String title, String bottom, String footer,
+ String header, String metaDescription, List<String> metaKeywords) {
+ super(encoding, title, bottom, footer, header, metaDescription, metaKeywords);
+ sb = new StringBuilder();
+ }
+
+ /**
+ * Returns a list of classes inspected for configuration reference javadoc tags. Configuration
+ * reference tags are specified at class level and field level using <code>@configRef</code>
+ * javadoc tag.
+ *
+ * <p>
+ * Configuration class hierarchy should match configuration XML schema where each
+ * configuration class matches to one Java class and each property of XML element matches to a
+ * field of a class. On a class level <code>@configRef</code> javadoc tag should be placed on a
+ * class definition that matches the target XML element. On a field level <code>@configRef</code>
+ * javadoc tag should be placed on a field (anywhere in class hiearchy) that matches XML
+ * property.
+ *
+ * <p>
+ * <code>@configRef</code> has two key value property pairs: name and desc. Name specifies the
+ * name of the matching XML element in cases when <code>@configRef</code> decorates a class. If
+ * <code>@configRef</code> decorates a Java field then name attribute should match XML attribute.
+ *
+ * <p>
+ * Note that name property is optional in cases when <code>@configRef</code> decorates a Java
+ * field while it is mandatory in cases when <code>@configRef</code> decorates a configuration
+ * class.
+ *
+ *
+ *
+ * @return a list of configuration classes decorated with <code>@configRef</code> Javadoc tags.
+ * @throws Exception
+ */
+ protected abstract List<Class<?>> getConfigBeans() throws Exception;
+
+ /**
+ * Returns name of the schema file.
+ *
+ * <p>Note that schema file should be placed on a classpath.
+ *
+ * @return name of the schema file located on the classpath.
+ */
+ protected abstract String getSchemaFile();
+
+ /**
+ * Name of the root element in the schema
+ *
+ * @return name of the root element in the schema
+ */
+ protected abstract String getRootElementName();
+
+ /**
+ * Invoked prior to creation of XML tree table of contents for configuration elements in schema
+ *
+ * @param sw
+ * @param tw
+ */
+ protected void preXMLTableOfContentsCreate(XSOMSchemaTreeWalker sw, XMLTreeOutputWalker tw) {
+
+ }
+
+ /**
+ * Invoked after creation of XML tree table of contents for configuration elements in schema
+ *
+ * @param sw
+ * @param tw
+ */
+ protected void postXMLTableOfContentsCreate(XSOMSchemaTreeWalker w, XMLTreeOutputWalker tw) {
+
+ }
+
+ /**
+ * Callback invoked prior to visiting the specified node n.
+ *
+ * @param n
+ * @return true if the TreeNode n should be skipped for configuration reference creation, false otherwise
+ */
+ protected boolean preVisitNode(TreeNode n) {
+ return true;
+ }
+
+ /**
+ * Callback invoked after visiting the specified node n.
+ *
+ * @param n
+ * @return true if no more elements should be included in configuration reference creation, false otherwise
+ */
+ protected boolean postVisitNode(TreeNode n) {
+ return false;
+ }
+
+ protected String getTitle() {
+ return "<h2>Configuration reference</h2><br/>";
+ }
+
+ public RootDoc getRootDoc() {
+ return rootDoc;
+ }
+
+ public void setRootDoc(RootDoc rootDoc) {
+ this.rootDoc = rootDoc;
+ }
+
+ public InputStream lookupFile(String filename) {
+ InputStream is = filename == null || filename.length() == 0 ? null : getAsInputStreamFromClassLoader(filename);
+ if (is == null) {
+ try {
+ is = new FileInputStream(filename);
+ }
+ catch (FileNotFoundException e) {
+ return null;
+ }
+ }
+ return is;
+ }
+
+ protected InputStream getAsInputStreamFromClassLoader(String filename) {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ InputStream is = cl == null ? null : cl.getResourceAsStream(filename);
+ if (is == null) {
+ // check system class loader
+ is = getClass().getClassLoader().getResourceAsStream(filename);
+ }
+ return is;
+ }
+
+ protected StringBuilder getStringBuilder() {
+ return sb;
+ }
+
+ protected String generateContents() {
+ sb.append(getTitle());
+
+ List<Class<?>> configBeans;
+ try {
+ configBeans = getConfigBeans();
+
+ if (configBeans == null || configBeans.isEmpty())
+ throw new Exception("Configuration bean classes are not specified. Make sure that "
+ + "getConfigBeans() method returns a list of classes. Documentation creation aborted");
+
+ XMLTreeOutputWalker tw = new XMLTreeOutputWalker(sb);
+ String schemaFile = getSchemaFile();
+
+ if (schemaFile == null)
+ throw new Exception("Schema file name not specified. Documentation creation aborted");
+
+ InputStream file = lookupFile(schemaFile);
+
+ if (file == null)
+ throw new Exception("Schema file " + schemaFile
+ + " not found on classpath. Documentation creation aborted");
+
+ XSOMParser reader = new XSOMParser();
+ reader.parse(file);
+ XSSchemaSet xss = reader.getResult();
+ XSOMSchemaTreeWalker w = new XSOMSchemaTreeWalker(xss.getSchema(1), getRootElementName());
+ TreeNode root = w.getRoot();
+ associateBeansWithTreeNodes(configBeans, root);
+
+ preXMLTableOfContentsCreate(w, tw);
+
+ sb.append("<div class=\"" + "source" + "\"><pre>");
+ // print XMLTableOfContents into StringBuilder
+ tw.preOrderTraverse(root);
+ sb.append("</pre></div>");
+
+ postXMLTableOfContentsCreate(w, tw);
+
+
+ for (TreeNode n : root) {
+
+ boolean skip = preVisitNode(n);
+ //do not generate element for skipped element
+ if (skip)
+ continue;
+
+ debug("element = " + n.getName(), 0);
+
+ sb.append("<div class=\"section\">\n");
+ // Name, description, parent and child elements for node
+ generateHeaderForConfigurationElement(sb, tw, n);
+
+ //now attributes
+ if (!n.getAttributes().isEmpty()) {
+ generateAttributeTableRows(sb, n);
+ }
+
+ boolean breakLoop = postVisitNode(n);
+ sb.append("</div>\n");
+ if(breakLoop)
+ break;
+ }
+
+ } catch (Exception e) {
+ System.out.println("Exception while generating configuration reference " + e);
+ e.printStackTrace();
+ }
+ return sb.toString();
+ }
+
+ private void associateBeansWithTreeNodes(List<Class<?>> configBeans, TreeNode root) {
+ for (TreeNode n : root) {
+ if (n.getBeanClass() == null) {
+ for (Class<?> clazz : configBeans) {
+ ClassDoc classDoc = rootDoc.classNamed(clazz.getName());
+ if (classDoc != null) {
+ List<Tag> list = Arrays.asList(classDoc.tags(CONFIG_REF));
+ for (Tag tag : list) {
+ String text = tag.text().trim();
+ Map<String, String> p = parseTag(text);
+ String thisNode = p.get(CONFIG_REF_NAME_ATT);
+ String parentNode = p.get(CONFIG_REF_PARENT_NAME_ATT);
+ if (n.getName().equalsIgnoreCase(thisNode)) {
+ // parent specified
+ if (parentNode != null
+ && parentNode.equalsIgnoreCase(n.getParent().getName())) {
+ n.setBeanClass(clazz);
+ } else if (parentNode == null) {
+ n.setBeanClass(clazz);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void generateAttributeTableRows(StringBuilder sb, TreeNode n) {
+
+ sb.append("<table class=\"bodyTable\"> ");
+ sb.append("<tr class=\"a\"><th>Attribute</th><th>Type</th><th>Default</th><th>Description</th></tr>\n");
+
+ Class<?> bean = n.getBeanClass();
+ Object object = null;
+ try {
+ Constructor<?>[] constructors = bean.getDeclaredConstructors();
+ for (Constructor<?> c : constructors) {
+ if (c.getParameterTypes().length == 0) {
+ c.setAccessible(true);
+ object = c.newInstance();
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("Did not construct object " + bean);
+ }
+
+ Set<XSAttributeDecl> attributes = n.getAttributes();
+ for (XSAttributeDecl a : attributes) {
+ sb.append("<tr class=\"b\">");
+
+ //name, type...
+ sb.append("<td>").append("<code>" + a.getName() + "</code>").append("</td>\n");
+ sb.append("<td>").append("<code>" + a.getType().getName() + "</code>");
+
+ boolean isRestricted = false;
+ XSRestrictionSimpleType restriction = a.getType().asRestriction();
+ Collection<? extends XSFacet> declaredFacets = restriction.getDeclaredFacets();
+ for (XSFacet facet : declaredFacets) {
+ if (facet.getName().equalsIgnoreCase("enumeration")) {
+ isRestricted = true;
+ break;
+ }
+ }
+
+ debug ("attribute = " + a.getName() + "(restricted = " + isRestricted + ")", 1);
+
+ // restriction on type...
+ if (isRestricted) {
+ sb.append("* (");
+ for (XSFacet facet : declaredFacets) {
+ sb.append(facet.getValue().toString() + '|');
+ }
+ sb.deleteCharAt(sb.length() - 1);
+ sb.append(")</td>\n");
+ } else {
+ sb.append("</td>\n");
+ }
+
+ // if default value specified in annotation use it
+ if (a.getDefaultValue() != null) {
+ debug("annotation-defined default = " + a.getDefaultValue(), 2);
+ sb.append("<td>").append(a.getDefaultValue().toString()).append("</td>\n");
+ }
+
+ // otherwise reflect that field and read default value
+ else {
+ Field field = null;
+ Object defaultValue = null;
+ try {
+ field = findFieldRecursively(bean, a.getName());
+ defaultValue = fieldValue(field, object);
+ if (defaultValue != null) {
+ sb.append("<td>").append(defaultValue.toString()).append("</td>\n");
+ debug("field-defined default = " + defaultValue, 2);
+ } else {
+ debug("field-defined default is null!", 2);
+ sb.append("<td>").append("null").append("</td>\n");
+ }
+ } catch (Exception e) {
+ debug("Caught exception, bean is " + bean.getName() + ", looking for field " + a.getName() + ", field " + field, 2);
+ e.printStackTrace();
+ sb.append("<td>").append("N/A").append("</td>\n");
+ }
+ }
+
+ // and finally description
+ FieldDoc fieldDoc = findFieldDocRecursively(bean, a.getName(), CONFIG_REF);
+ if (fieldDoc != null) {
+ Tag[] tags = fieldDoc.tags(CONFIG_REF);
+ Map<String, String> p = parseTag(tags[0].text().trim());
+ sb.append("<td>").append(p.get(CONFIG_REF_DESC_ATT)).append("\n");
+ String packageDir = fieldDoc.containingPackage().toString().replace(".", "/").concat("/");
+ String htmlFile = fieldDoc.containingClass().typeName().concat(".html");
+ String field = fieldDoc.name();
+ sb.append(" (<a href=\"" +packageDir.concat(htmlFile).concat("#").concat(field) +"\">" + "Javadoc</a>)");
+ sb.append("</td>\n");
+
+ }
+ sb.append("</tr>\n");
+ }
+ sb.append("</table>\n");
+ }
+
+ private void debug(String s, int level) {
+ if (DEBUG) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < level * LEVEL_MULT; i++) sb.append(" ");
+ sb.append("> ").append(s);
+ System.out.println(sb.toString());
+ }
+ }
+
+ public Map<String, String> parseTag(String tag) {
+
+ //javadoc parser for our tags
+ Map<String, String> p = new HashMap<String, String>();
+ Scanner sc = new Scanner(tag);
+ Scanner sc2 = null;
+ sc.useDelimiter("\"\\s*,\\s*");
+ try {
+ while (sc.hasNext()) {
+ String keyValue = sc.next();
+ sc2 = new Scanner(keyValue);
+ sc2.useDelimiter("=\\s*\"");
+ String key = sc2.next();
+ String value = sc2.next().replace("\"", "");
+ p.put(key, value);
+ sc2.close();
+ }
+ sc.close();
+ } catch (Exception e) {
+ System.out.println("Invalid tag " + tag + " skipping...");
+ } finally {
+ sc.close();
+ sc2.close();
+ }
+ return p;
+ }
+
+ private void generateHeaderForConfigurationElement(StringBuilder sb, XMLTreeOutputWalker tw, TreeNode n) {
+ sb.append("<a name=\"").append("ce_" + n.getParent().getName() + "_" + n.getName() + "\">" + "</a>");
+ sb.append("<h3><a name=\"" + n.getName() + "\"></a>" + n.getName() + "</h3>");
+ sb.append("\n<p>");
+ Class<?> beanClass = n.getBeanClass();
+ //System.out.println("Generating " + n + " bean is " + beanClass);
+ ClassDoc classDoc = rootDoc.classNamed(beanClass.getName());
+ Tag[] tags = classDoc.tags(CONFIG_REF);
+
+ for (Tag tag : tags) {
+ String text = tag.text().trim();
+ Map<String, String> m = parseTag(text);
+ String name = m.get(CONFIG_REF_NAME_ATT);
+ if(n.getName().equals(name)) {
+ sb.append(m.get(CONFIG_REF_DESC_ATT));
+ }
+ }
+
+ sb.append("<BR/><BR />");
+
+ if (n.getParent().getParent() != null) {
+ sb.append("The parent element is " + "<a href=\"").append("#ce_" + n.getParent().getParent().getName()
+ + "_" + n.getParent().getName() + "\">" + "<" + n.getParent().getName() + ">" + "</a>. ");
+ }
+
+ if (!n.getChildren().isEmpty()) {
+ int childCount = n.getChildren().size();
+ int count = 1;
+ if (childCount == 1)
+ sb.append("The only child element is ");
+ else
+ sb.append("Child elements are ");
+ for (TreeNode tn : n.getChildren()) {
+ sb.append("<a href=\"").append("#ce_" + tn.getParent().getName() + "_"
+ + tn.getName() + "\">" + "<" + tn.getName() + ">" + "</a>");
+ if (count < childCount) {
+ sb.append(", ");
+ } else {
+ sb.append(".");
+ }
+ count++;
+ }
+ sb.append("\n");
+ }
+ sb.append("</p>");
+ }
+
+ private Field findFieldRecursively(Class<?> c, String fieldName) {
+ findFieldRecursively:
+ while (true) {
+ Field f = null;
+ try {
+ f = c.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException e) {
+ ClassDoc classDoc = rootDoc.classNamed(c.getName());
+ for (FieldDoc fd : classDoc.fields()) {
+ for (Tag t : fd.tags(CONFIG_REF)) {
+ Map<String, String> m = parseTag(t.text().trim());
+ String field = m.get(CONFIG_REF_NAME_ATT);
+ if (field != null && field.startsWith(fieldName)) {
+ fieldName = fd.name();
+ continue findFieldRecursively;
+ }
+ }
+ }
+ if (!c.equals(Object.class))
+ f = findFieldRecursively(c.getSuperclass(), fieldName);
+ }
+ return f;
+ }
+ }
+
+ private FieldDoc findFieldDocRecursively(Class<?> c, String fieldName, String tagName) {
+ while (true) {
+ ClassDoc classDoc = rootDoc.classNamed(c.getName());
+ for (FieldDoc fd : classDoc.fields()) {
+ if (fd.name().equalsIgnoreCase(fieldName)) {
+ return fd;
+ }
+ for (Tag t : fd.tags(tagName)) {
+ Map<String, String> m = parseTag(t.text().trim());
+ if (m.containsKey(CONFIG_REF_NAME_ATT)) {
+ String value = m.get(CONFIG_REF_NAME_ATT).trim();
+ if (fieldName.equalsIgnoreCase(value)) {
+ return fd;
+ }
+ }
+ }
+ }
+ if (c.getSuperclass() != null) {
+ c = c.getSuperclass();
+ continue;
+ }
+ return null;
+ }
+ }
+
+ private static Object fieldValue(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);
+ }
+ }
+}
Modified: trunk/tools/src/main/java/org/infinispan/tools/doclet/config/ConfigHtmlGenerator.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/doclet/config/ConfigHtmlGenerator.java 2010-02-26 18:24:37 UTC (rev 1558)
+++ trunk/tools/src/main/java/org/infinispan/tools/doclet/config/ConfigHtmlGenerator.java 2010-03-02 19:44:44 UTC (rev 1559)
@@ -1,36 +1,20 @@
package org.infinispan.tools.doclet.config;
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.FieldDoc;
-import com.sun.javadoc.RootDoc;
-import com.sun.javadoc.Tag;
-import com.sun.xml.xsom.XSAttributeDecl;
-import com.sun.xml.xsom.XSFacet;
-import com.sun.xml.xsom.XSRestrictionSimpleType;
-import com.sun.xml.xsom.XSSchemaSet;
-import com.sun.xml.xsom.parser.XSOMParser;
+import java.util.List;
+import java.util.Map;
+
import org.infinispan.Version;
import org.infinispan.config.AbstractConfigurationBean;
import org.infinispan.config.InfinispanConfiguration;
-import org.infinispan.tools.doclet.html.HtmlGenerator;
import org.infinispan.tools.schema.AbstractTreeWalker;
import org.infinispan.tools.schema.TreeNode;
import org.infinispan.tools.schema.XSOMSchemaTreeWalker;
import org.infinispan.util.ClassFinder;
-import org.infinispan.util.FileLookup;
import org.infinispan.util.TypedProperties;
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.Set;
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.FieldDoc;
+import com.sun.javadoc.Tag;
/**
* Infinispan configuration reference guide generator
@@ -38,18 +22,14 @@
* @author Vladimir Blagojevic
* @since 4.0
*/
+
@SuppressWarnings("restriction")
-public class ConfigHtmlGenerator extends HtmlGenerator {
+public class ConfigHtmlGenerator extends AbstractConfigHtmlGenerator {
- private static final String CONFIG_REF = "configRef";
- private static final String CONFIG_PROPERTY_REF = "configPropertyRef";
+ private static final String CONFIG_PROPERTY_REF = "configPropertyRef";
- private static final int LEVEL_MULT = 3;
- private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("infinispan.tools.configdoc.debug", "false"));
-
String classpath;
- RootDoc rootDoc;
-
+
public ConfigHtmlGenerator(String encoding, String title, String bottom, String footer,
String header, String metaDescription, List<String> metaKeywords, String classpath) {
super(encoding, title, bottom, footer, header, metaDescription, metaKeywords);
@@ -57,378 +37,83 @@
}
- public RootDoc getRootDoc() {
- return rootDoc;
- }
-
- public void setRootDoc(RootDoc rootDoc) {
- this.rootDoc = rootDoc;
- }
-
protected List<Class<?>> getConfigBeans() throws Exception {
- return ClassFinder.isAssignableFrom(ClassFinder.infinispanClasses(classpath),
+ List<Class<?>> list = ClassFinder.isAssignableFrom(ClassFinder.infinispanClasses(classpath),
AbstractConfigurationBean.class);
+
+ list.add(TypedProperties.class);
+ list.add(InfinispanConfiguration.class);
+ return list;
}
-
- protected String generateContents() {
-
- StringBuilder sb = new StringBuilder();
- // index of components
- sb.append("<h2>Infinispan configuration options " + Version.getMajorVersion() + " </h2><br/>");
- sb.append("<UL>");
-
- List<Class<?>> configBeans;
- try {
- configBeans = getConfigBeans();
- configBeans.add(TypedProperties.class);
- configBeans.add(InfinispanConfiguration.class);
-
- XMLTreeOutputWalker tw = new XMLTreeOutputWalker(sb);
- FileLookup fl = new FileLookup();
- InputStream file = fl.lookupFile("schema/infinispan-config-" + Version.getMajorVersion() + ".xsd");
- XSOMParser reader = new XSOMParser();
- reader.parse(file);
- XSSchemaSet xss = reader.getResult();
- XSOMSchemaTreeWalker w = new XSOMSchemaTreeWalker(xss.getSchema(1), "infinispan");
- TreeNode root = w.getRoot();
-
- associateBeansWithTreeNodes(configBeans, root);
-
- TreeNode node = tw.findNode(root, "namedCache", "infinispan");
- node.detach();
-
- PruneTreeWalker ptw = new PruneTreeWalker("property");
- ptw.postOrderTraverse(root);
-
- sb.append("<div class=\"" + "source" + "\"><pre>");
- // print xml tree into StringBuilder
- tw.preOrderTraverse(root);
- sb.append("</pre></div>");
-
-
- for (TreeNode n : root) {
-
- //do not generate element for properties element
- if (n.getName().equals("properties"))
- continue;
-
- debug("element = " + n.getName(), 0);
-
- // Name, description, parent and child elements node
- generateHeaderForConfigurationElement(sb, tw, n);
-
- //now attributes
- if (!n.getAttributes().isEmpty()) {
- generateAttributeTableRows(sb, n);
- }
-
- //and properties....
- if (n.hasChild("properties")) {
- generatePropertiesTableRows(sb, n);
- }
- }
-
- } catch (Exception e) {
- System.out.println("Exception while generating configuration reference " + e);
- System.out.println("Classpath is " + classpath);
- e.printStackTrace();
- }
- return sb.toString();
+
+ protected String getSchemaFile() {
+ return "schema/infinispan-config-" + Version.getMajorVersion() + ".xsd";
}
-
- private void associateBeansWithTreeNodes(List<Class<?>> configBeans, TreeNode root) {
- for (TreeNode n : root) {
- if (n.getBeanClass() == null) {
- for (Class<?> clazz : configBeans) {
- ClassDoc classDoc = rootDoc.classNamed(clazz.getName());
- if (classDoc != null) {
- List<Tag> list = Arrays.asList(classDoc.tags(CONFIG_REF));
- for (Tag tag : list) {
- String text = tag.text().trim();
- Map<String, String> p = parseTag(text);
- String thisNode = p.get("name");
- String parentNode = p.get("parentName");
- if (n.getName().equalsIgnoreCase(thisNode)) {
- // parent specified
- if (parentNode != null
- && parentNode.equalsIgnoreCase(n.getParent().getName())) {
- n.setBeanClass(clazz);
- } else if (parentNode == null) {
- n.setBeanClass(clazz);
- }
- }
- }
- }
- }
- }
- }
+
+ protected String getTitle() {
+ return "<h2>Infinispan configuration options " + Version.getMajorVersion() + " </h2><br/>";
}
-
- private void generatePropertiesTableRows(StringBuilder sb, TreeNode n) {
- FieldDoc fieldDoc = fieldDocWithTag(n.getBeanClass(), CONFIG_PROPERTY_REF);
- if (fieldDoc != null) {
- sb.append("\n<table class=\"bodyTable\"> ");
- sb.append("<tr class=\"a\"><th>Property</th><th>Description</th></tr>\n");
- Tag[] tags = fieldDoc.tags(CONFIG_PROPERTY_REF);
- for (Tag t : tags) {
- Map<String, String> m = parseTag(t.text().trim());
- sb.append("<tr class=\"b\">");
- sb.append("<td>").append(m.get("name")).append("</td>\n");
- sb.append("<td>").append(m.get("desc")).append("</td>\n");
- sb.append("</tr>\n");
- }
- sb.append("</table></div>");
- }
+
+ protected String getRootElementName() {
+ return "infinispan";
}
+
+ protected void preXMLTableOfContentsCreate(XSOMSchemaTreeWalker sw, XMLTreeOutputWalker tw) {
+
+ TreeNode root = sw.getRoot();
+ TreeNode node = tw.findNode(root, "namedCache", "infinispan");
+ node.detach();
- private void generateAttributeTableRows(StringBuilder sb, TreeNode n) {
-
- sb.append("<table class=\"bodyTable\"> ");
- sb.append("<tr class=\"a\"><th>Attribute</th><th>Type</th><th>Default</th><th>Description</th></tr>\n");
-
- Class<?> bean = n.getBeanClass();
- Object object = null;
- try {
- Constructor<?>[] constructors = bean.getDeclaredConstructors();
- for (Constructor<?> c : constructors) {
- if (c.getParameterTypes().length == 0) {
- c.setAccessible(true);
- object = c.newInstance();
- }
- }
- } catch (Exception e) {
- System.out.println("Did not construct object " + bean);
- }
-
- Set<XSAttributeDecl> attributes = n.getAttributes();
- for (XSAttributeDecl a : attributes) {
- sb.append("<tr class=\"b\">");
-
- //name, type...
- sb.append("<td>").append("<code>" + a.getName() + "</code>").append("</td>\n");
- sb.append("<td>").append("<code>" + a.getType().getName() + "</code>");
-
- boolean isRestricted = false;
- XSRestrictionSimpleType restriction = a.getType().asRestriction();
- Collection<? extends XSFacet> declaredFacets = restriction.getDeclaredFacets();
- for (XSFacet facet : declaredFacets) {
- if (facet.getName().equalsIgnoreCase("enumeration")) {
- isRestricted = true;
- break;
- }
- }
-
- debug ("attribute = " + a.getName() + "(restricted = " + isRestricted + ")", 1);
-
- // restriction on type...
- if (isRestricted) {
- sb.append("* (");
- for (XSFacet facet : declaredFacets) {
- sb.append(facet.getValue().toString() + '|');
- }
- sb.deleteCharAt(sb.length() - 1);
- sb.append(")</td>\n");
- } else {
- sb.append("</td>\n");
- }
-
- // if default value specified in annotation use it
- if (a.getDefaultValue() != null) {
- debug("annotation-defined default = " + a.getDefaultValue(), 2);
- sb.append("<td>").append(a.getDefaultValue().toString()).append("</td>\n");
- }
-
- // otherwise reflect that field and read default value
- else {
- Field field = null;
- Object defaultValue = null;
- try {
- field = findFieldRecursively(bean, a.getName());
- defaultValue = fieldValue(field, object);
- if (defaultValue != null) {
- sb.append("<td>").append(defaultValue.toString()).append("</td>\n");
- debug("field-defined default = " + defaultValue, 2);
- } else {
- debug("field-defined default is null!", 2);
- sb.append("<td>").append("null").append("</td>\n");
- }
- } catch (Exception e) {
- debug("Caught exception, bean is " + bean.getName() + ", looking for field " + a.getName() + ", field " + field, 2);
- e.printStackTrace();
- sb.append("<td>").append("N/A").append("</td>\n");
- }
- }
-
- // and finally description
- FieldDoc fieldDoc = findFieldDocRecursively(bean, a.getName(), CONFIG_REF);
- if (fieldDoc != null) {
- Tag[] tags = fieldDoc.tags(CONFIG_REF);
- Map<String, String> p = parseTag(tags[0].text().trim());
- sb.append("<td>").append(p.get("desc")).append("\n");
- String packageDir = fieldDoc.containingPackage().toString().replace(".", "/").concat("/");
- String htmlFile = fieldDoc.containingClass().typeName().concat(".html");
- String field = fieldDoc.name();
- sb.append(" (<a href=\"" +packageDir.concat(htmlFile).concat("#").concat(field) +"\">" + "Javadoc</a>)");
- sb.append("</td>\n");
-
- }
- sb.append("</tr>\n");
- }
- sb.append("</table></div>");
+ PruneTreeWalker ptw = new PruneTreeWalker("property");
+ ptw.postOrderTraverse(root);
}
-
- private void debug(String s, int level) {
- if (DEBUG) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < level * LEVEL_MULT; i++) sb.append(" ");
- sb.append("> ").append(s);
- System.out.println(sb.toString());
- }
+
+ protected boolean preVisitNode(TreeNode n) {
+ return n.getName().equals("properties");
}
-
- public Map<String, String> parseTag(String tag) {
-
- //javadoc parser for our tags
- Map<String, String> p = new HashMap<String, String>();
- Scanner sc = new Scanner(tag);
- Scanner sc2 = null;
- sc.useDelimiter("\"\\s*,\\s*");
- try {
- while (sc.hasNext()) {
- String keyValue = sc.next();
- sc2 = new Scanner(keyValue);
- sc2.useDelimiter("=\\s*\"");
- String key = sc2.next();
- String value = sc2.next().replace("\"", "");
- p.put(key, value);
- sc2.close();
- }
- sc.close();
- } catch (Exception e) {
- System.out.println("Invalid tag " + tag + " skipping...");
- } finally {
- sc.close();
- sc2.close();
- }
- return p;
+
+ protected boolean postVisitNode(TreeNode n) {
+ //generate table for properties as well
+ if (n.hasChild("properties")) {
+ generatePropertiesTableRows(getStringBuilder(), n);
+ }
+ return super.postVisitNode(n);
}
-
- private void generateHeaderForConfigurationElement(StringBuilder sb, XMLTreeOutputWalker tw, TreeNode n) {
- sb.append("\n<a name=\"").append("ce_" + n.getParent().getName() + "_" + n.getName() + "\">" + "</a>");
- sb.append("<div class=\"section\"><h3><a name=\"" + n.getName() + "\"></a>" + n.getName() + "</h3>");
- sb.append("\n<p>");
- Class<?> beanClass = n.getBeanClass();
- //System.out.println("Generating " + n + " bean is " + beanClass);
- ClassDoc classDoc = rootDoc.classNamed(beanClass.getName());
- Tag[] tags = classDoc.tags(CONFIG_REF);
- for (Tag tag : tags) {
- String text = tag.text().trim();
- Map<String, String> m = parseTag(text);
- sb.append(m.get("desc"));
- }
-
- sb.append("<BR/><BR />");
-
- if (n.getParent().getParent() != null) {
- sb.append("The parent element is " + "<a href=\"").append("#ce_" + n.getParent().getParent().getName()
- + "_" + n.getParent().getName() + "\">" + "<" + n.getParent().getName() + ">" + "</a>. ");
- }
-
- if (!n.getChildren().isEmpty()) {
- int childCount = n.getChildren().size();
- int count = 1;
- if (childCount == 1)
- sb.append("The only child element is ");
- else
- sb.append("Child elements are ");
- for (TreeNode tn : n.getChildren()) {
- sb.append("<a href=\"").append("#ce_" + tn.getParent().getName() + "_"
- + tn.getName() + "\">" + "<" + tn.getName() + ">" + "</a>");
- if (count < childCount) {
- sb.append(", ");
- } else {
- sb.append(".");
- }
- count++;
- }
- sb.append("\n");
- }
- sb.append("</p>");
- }
-
- private Field findFieldRecursively(Class<?> c, String fieldName) {
- findFieldRecursively:
- while (true) {
- Field f = null;
- try {
- f = c.getDeclaredField(fieldName);
- } catch (NoSuchFieldException e) {
- ClassDoc classDoc = rootDoc.classNamed(c.getName());
- for (FieldDoc fd : classDoc.fields()) {
- for (Tag t : fd.tags(CONFIG_REF)) {
- Map<String, String> m = parseTag(t.text().trim());
- String field = m.get("name");
- if (field != null && field.startsWith(fieldName)) {
- fieldName = fd.name();
- continue findFieldRecursively;
- }
+
+ private void generatePropertiesTableRows(StringBuilder sb, TreeNode n) {
+ FieldDoc fieldDoc = fieldDocWithTag(n.getBeanClass(), CONFIG_PROPERTY_REF);
+ if (fieldDoc != null) {
+ sb.append("<table class=\"bodyTable\"> ");
+ sb.append("<tr class=\"a\"><th>Property</th><th>Description</th></tr>\n");
+ Tag[] tags = fieldDoc.tags(CONFIG_PROPERTY_REF);
+ for (Tag t : tags) {
+ Map<String, String> m = parseTag(t.text().trim());
+ sb.append("<tr class=\"b\">");
+ sb.append("<td>").append(m.get(CONFIG_REF_NAME_ATT)).append("</td>\n");
+ sb.append("<td>").append(m.get(CONFIG_REF_DESC_ATT)).append("</td>\n");
+ sb.append("</tr>\n");
+ }
+ sb.append("</table>\n");
+ }
+ }
+
+ private FieldDoc fieldDocWithTag(Class<?> c, String tagName) {
+ while (true) {
+ ClassDoc classDoc = rootDoc.classNamed(c.getName());
+ for (FieldDoc fd : classDoc.fields()) {
+ if (fd.tags(tagName).length > 0) {
+ return fd;
}
- }
- if (!c.equals(Object.class))
- f = findFieldRecursively(c.getSuperclass(), fieldName);
- }
- return f;
- }
- }
+ }
- private FieldDoc findFieldDocRecursively(Class<?> c, String fieldName, String tagName) {
- while (true) {
- ClassDoc classDoc = rootDoc.classNamed(c.getName());
- for (FieldDoc fd : classDoc.fields()) {
- if (fd.name().equalsIgnoreCase(fieldName)) {
- return fd;
- }
- for (Tag t : fd.tags(tagName)) {
- Map<String, String> m = parseTag(t.text().trim());
- if (m.containsKey("name")) {
- String value = m.get("name").trim();
- if (fieldName.equalsIgnoreCase(value)) {
- return fd;
- }
- }
- }
- }
- if (c.getSuperclass() != null) {
- c = c.getSuperclass();
- continue;
- }
- return null;
- }
+ if (c.getSuperclass() != null) {
+ c = c.getSuperclass();
+ continue;
+ }
+ return null;
+ }
}
- private FieldDoc fieldDocWithTag(Class<?> c, String tagName) {
- ClassDoc classDoc = rootDoc.classNamed(c.getName());
- for (FieldDoc fd : classDoc.fields()) {
- if (fd.tags(tagName).length > 0)
- return fd;
-
- }
- if (c.getSuperclass() != null)
- fieldDocWithTag(c.getSuperclass(), tagName);
- return null;
- }
-
- private static Object fieldValue(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);
- }
- }
-
private static class PruneTreeWalker extends AbstractTreeWalker {
private String pruneNodeName = "";
Modified: trunk/tools/src/main/java/org/infinispan/tools/doclet/config/XMLTreeOutputWalker.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/doclet/config/XMLTreeOutputWalker.java 2010-02-26 18:24:37 UTC (rev 1558)
+++ trunk/tools/src/main/java/org/infinispan/tools/doclet/config/XMLTreeOutputWalker.java 2010-03-02 19:44:44 UTC (rev 1559)
@@ -26,14 +26,15 @@
/**
* TreeWalker that generates XML pretty print of the configuration tree
- *
+ *
* @author Vladimir Blagojevic
* @see ConfigDoclet
* @since 4.0
*/
public class XMLTreeOutputWalker extends AbstractTreeWalker {
-
+
private final StringBuilder sb;
+ private static final String IDENT = " ";
public XMLTreeOutputWalker(StringBuilder sb) {
super();
@@ -41,27 +42,25 @@
}
public void visitNode(TreeNode treeNode) {
- String ident = "";
- for(int i = 0; i<=treeNode.getDepth();i++)
- ident += " ";
-
- String parentName = treeNode.getParent().getName();
- if(parentName.startsWith("namedCache")){
- parentName = "default";
- }
- sb.append(ident + "<<a href=\"" + "#ce_" + parentName
- + "_" + treeNode.getName() + "\">" + treeNode.getName() + "</a>>" + "\n");
+ String ident = "";
+ for (int i = 0; i <= treeNode.getDepth(); i++)
+ ident += IDENT;
+ sb.append(ident + "<<a href=\"" + "#ce_" + treeNode.getParent().getName() + "_"
+ + treeNode.getName() + "\">" + treeNode.getName() + "</a>>" + "\n");
+
}
-
- public TreeNode findNode(TreeNode tn, String name, String parent){
+
+ public TreeNode findNode(TreeNode tn, String name, String parent) {
TreeNode result = null;
- if(tn.getName().equals(name) && tn.getParent() != null && tn.getParent().getName().equals(parent)){
+ 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;
+ for (TreeNode child : tn.getChildren()) {
+ result = findNode(child, name, parent);
+ if (result != null)
+ break;
}
}
return result;
Modified: trunk/tools/src/main/java/org/infinispan/tools/schema/TreeNode.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/schema/TreeNode.java 2010-02-26 18:24:37 UTC (rev 1558)
+++ trunk/tools/src/main/java/org/infinispan/tools/schema/TreeNode.java 2010-03-02 19:44:44 UTC (rev 1559)
@@ -37,7 +37,6 @@
* @author Vladimir Blagojevic
* @since 4.0
*/
- at SuppressWarnings("restriction")
public class TreeNode implements Iterable<TreeNode>, Comparable<TreeNode> {
private final String name;
private TreeNode parent;
Modified: trunk/tools/src/main/java/org/infinispan/tools/schema/XSOMSchemaTreeWalker.java
===================================================================
--- trunk/tools/src/main/java/org/infinispan/tools/schema/XSOMSchemaTreeWalker.java 2010-02-26 18:24:37 UTC (rev 1558)
+++ trunk/tools/src/main/java/org/infinispan/tools/schema/XSOMSchemaTreeWalker.java 2010-03-02 19:44:44 UTC (rev 1559)
@@ -57,8 +57,8 @@
*/
public class XSOMSchemaTreeWalker implements XSVisitor {
private XSSchema schema;
- TreeNode root;
- TreeNode currentNode;
+ private TreeNode root;
+ private TreeNode currentNode;
public XSOMSchemaTreeWalker(XSSchema schema, String rootName) {
super();
@@ -127,8 +127,7 @@
}
public void restrictionSimpleType(XSRestrictionSimpleType type) {
- XSSimpleType baseType = type.getSimpleBaseType();
- //System.out.println("Restriction " + type.getName() + " :" + baseType.getName());
+ //XSSimpleType baseType = type.getSimpleBaseType();
Iterator<?> itr = type.iterateDeclaredFacets();
while (itr.hasNext()) {
facet((XSFacet) itr.next());
Added: trunk/tools/src/main/resources/h1_hdr.png
===================================================================
(Binary files differ)
Property changes on: trunk/tools/src/main/resources/h1_hdr.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/tools/src/main/resources/stylesheet2.css
===================================================================
--- trunk/tools/src/main/resources/stylesheet2.css 2010-02-26 18:24:37 UTC (rev 1558)
+++ trunk/tools/src/main/resources/stylesheet2.css 2010-03-02 19:44:44 UTC (rev 1559)
@@ -17,17 +17,19 @@
under the License.
*/
body {
- background-color: #fff;
- font-family: Verdana, Helvetica, Arial, sans-serif;
- margin-left: auto;
- margin-right: auto;
- background-repeat: repeat-y;
- font-size: 13px;
- padding: 0px;
-}
+ background-color: #FFFFFF;
+ background-image:url(h1_hdr.png);
+ background-repeat: no-repeat;
+ margin:0 auto;
+ font-family:'Lucida Grande', Geneva, Verdana, Arial, sans-serif;
+ font-size:12px;
+ padding:0em 2em;
+ color:#333;
+ }
+
td, select, input, li {
- font-family: Verdana, Helvetica, Arial, sans-serif;
+ font-family:'Lucida Grande', Geneva, Verdana, Arial, sans-serif;
font-size: 12px;
color: #333333;
}
@@ -40,38 +42,10 @@
text-decoration: none;
}
-a:link {
- color: #47a;
-}
+a:link { color:#0066cc; }
+a:visited { color:#8b5caf; }
+a:hover { color:#6699cc; }
-a:visited {
- color: #68a;
-}
-
-a:active, a:hover {
- color: #990000;
-}
-
-#legend li.externalLink {
- background: url(../images/external.png) left top no-repeat;
- padding-left: 18px;
-}
-
-a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover {
- background: url(../images/external.png) right center no-repeat;
- padding-right: 18px;
-}
-
-#legend li.newWindow {
- background: url(../images/newwindow.png) left top no-repeat;
- padding-left: 18px;
-}
-
-a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover {
- background: url(../images/newwindow.png) right center no-repeat;
- padding-right: 18px;
-}
-
h2 {
font-size: 17px;
color: #333333;
@@ -83,9 +57,6 @@
background-color: #ccc;
font-weight: bold;
font-size: 14px;
- background-image: url(../images/h3.jpg);
- background-repeat: no-repeat;
- background-position: left bottom;
}
p {
@@ -94,42 +65,6 @@
color: #000;
}
-#breadcrumbs {
- height: 13px;
- background-image: url(../images/breadcrumbs.jpg);
- padding: 5px 10px 14px 20px;
-}
-
-* html #breadcrumbs {
- padding-bottom: 8px;
-}
-
-#leftColumn {
- margin: 10px 0 10px 0;
- border-top-color: #ccc;
- border-top-style: solid;
- border-top-width: 1px;
- border-right-color: #ccc;
- border-right-style: solid;
- border-right-width: 1px;
- border-bottom-color: #ccc;
- border-bottom-style: solid;
- border-bottom-width: 1px;
- padding-right: 5px;
- padding-left: 5px;
-}
-
-#navcolumn h5 {
- font-size: smaller;
- border-bottom: 1px solid #aaaaaa;
- padding-top: 2px;
- padding-left: 9px;
- color: #49635a;
- background-image: url(../images/h5.jpg);
- background-repeat: no-repeat;
- background-position: left bottom;
-}
-
table.bodyTable th {
color: white;
background-color: #bbb;
@@ -160,7 +95,6 @@
background-color: #ccc;
font-weight: bold;
font-size: 14px;
- background-image: url(../images/h3.jpg);
background-repeat: no-repeat;
background-position: left bottom;
}
@@ -184,11 +118,6 @@
color: #003300;
}
-#banner {
- height: 93px;
- background: url(../images/banner.jpg);
-}
-
#navcolumn ul {
margin: 5px 0 15px -0em;
}
@@ -223,22 +152,6 @@
color: #333333;
}
-.errormark, .warningmark, .donemark, .infomark {
- background: url(../images/icon_error_sml.gif) no-repeat;
-}
-
-.warningmark {
- background-image: url(../images/icon_warning_sml.gif);
-}
-
-.donemark {
- background-image: url(../images/icon_success_sml.gif);
-}
-
-.infomark {
- background-image: url(../images/icon_info_sml.gif);
-}
-
body {
margin: 0px;
padding: 0px;
@@ -274,15 +187,7 @@
display: none;
}
-#bannerLeft, #bannerRight {
- font-size: xx-large;
- font-weight: bold;
-}
-#bannerLeft img, #bannerRight img {
- margin: 0px;
-}
-
.xleft, #bannerLeft img {
float: left;
}
@@ -345,14 +250,7 @@
font-size: smaller;
}
-#navcolumn li.expanded {
- background-image: url(../images/expanded.gif);
-}
-#navcolumn li.collapsed {
- background-image: url(../images/collapsed.gif);
-}
-
#poweredBy {
text-align: center;
}
@@ -396,7 +294,7 @@
}
.section {
- padding: 4px;
+ padding: 4px;
}
#footer {
@@ -417,4 +315,4 @@
.source pre {
margin: 0px;
padding: 0px;
-}
+}
\ No newline at end of file
More information about the infinispan-commits
mailing list