Index: ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/SchemaOutputFormat.java =================================================================== --- ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/SchemaOutputFormat.java Fri Mar 12 17:47:15 EST 2010 +++ ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/SchemaOutputFormat.java Fri Mar 12 17:47:15 EST 2010 @@ -0,0 +1,8 @@ +package com.sun.enterprise.admin.cli.schemadoc; + +import org.jvnet.hk2.annotations.Contract; + +@Contract +public interface SchemaOutputFormat { + void output(Context context); +} \ No newline at end of file Index: ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/HtmlFormat.java =================================================================== --- ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/HtmlFormat.java Mon Mar 15 11:53:33 EDT 2010 +++ ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/HtmlFormat.java Mon Mar 15 11:53:33 EDT 2010 @@ -0,0 +1,210 @@ +package com.sun.enterprise.admin.cli.schemadoc; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.glassfish.api.admin.config.PropertyDesc; +import org.jvnet.hk2.annotations.Contract; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.config.Attribute; +import org.jvnet.hk2.config.types.Property; + +@Service(name = "html") +public class HtmlFormat implements SchemaOutputFormat, Comparable { + private PrintWriter tocWriter; + private PrintWriter detail; + private Set toc = new HashSet(); + private File dir; + private Map defs; + + @SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"}) + @Override + public void output(Context context) { + dir = context.getDocDir(); + defs = context.getClassDefs(); + try { + try { + tocWriter = new PrintWriter(new FileWriter(new File(dir, "toc.HTML"))); + detail = new PrintWriter(new FileWriter(new File(dir, "detail.HTML"))); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + println(tocWriter, + ""); + println(detail, + ""); + copyResources(); + buildToc(defs.get(context.getRootClassName())); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } finally { + println(tocWriter, ""); + footer(tocWriter); + footer(detail); + if (tocWriter != null) { + tocWriter.close(); + } + if (detail != null) { + detail.close(); + } + } + } + + private void buildDetail(ClassDef def) { + println(detail, "

"); + println(detail, ""); + println(detail, String.format(""); + println(detail, ""); + printHeaderRow(detail, "attribute", "type", "default", "required"); + final Map map = def.getAttributes(); + if (map != null) { + for (Entry entry : map.entrySet()) { + println(detail, String.format("", entry.getKey())); + printAttributeData(entry.getValue()); + } + } + println(detail, "
%s%s", + def.isDeprecated() ? "deprecated" : "", + def.getXmlName(), def.isDeprecated() ? " - DEPRECATED" : "")); + println(detail, "
%s
"); + printPropertyData(def); + } + + private void println(final PrintWriter writer, final String text) { + writer.println(text); + writer.flush(); + } + + private void printAttributeData(final Attribute annotation) { + printKeyValue(detail, annotation != null ? annotation.dataType().getName() : null); + printKeyValue(detail, annotation != null ? annotation.defaultValue() : null); + printKeyValue(detail, annotation != null && annotation.required()); + } + + private void printPropertyData(final ClassDef def) { + final Set properties = def.getProperties(); + if (properties != null && !properties.isEmpty()) { + println(detail, ""); + println(detail, ""); + println(detail, ""); + println(detail, ""); + println(detail, ""); + println(detail, ""); + println(detail, ""); + println(detail, ""); + println(detail, ""); + println(detail, ""); + println(detail, ""); + for (PropertyDesc property : properties) { + println(detail, ""); + println(detail, String.format("", property.name())); + println(detail, String.format("", property.defaultValue())); + println(detail, String.format("", + property.values().length == 0 ? "" : Arrays.toString(property.values()))); + println(detail, String.format("", property.description())); + println(detail, ""); + } + println(detail, "
Properties
namedefaultvaluesdescription
%s%s%s%s
"); + println(detail, ""); + } + } + + private void buildToc(final ClassDef def) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + if (def != null/* && !"Named".equals(def.getSimpleName())*/) { + if (!toc.contains(def)) { + buildDetail(def); + } + toc.add(def); + println(tocWriter, "

"); + } + } + + private String link(final ClassDef def) { + return String.format("%s", + def.isDeprecated() ? "class=\"deprecated\"" : "", def.getXmlName(), def.getXmlName()); + } + + private void footer(final PrintWriter writer) { + writer.println(""); + writer.flush(); + writer.close(); + } + + private void copyResources() throws IOException { + copy("/schemadoc.css"); + copy("/index.html"); + } + + @SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"}) + private void copy(final String resource) throws IOException { + InputStreamReader reader = null; + PrintWriter writer = null; + try { + System.out.println("HtmlFormat.copy: resource = " + resource); + InputStream stream = getClass().getResourceAsStream(resource); + reader = new InputStreamReader(stream); + writer = new PrintWriter(new File(dir, resource)); + char[] bytes = new char[8192]; + int read; + while ((read = reader.read(bytes)) != -1) { + writer.write(bytes, 0, read); + } + } finally { + if (reader != null) { + reader.close(); + } + if (writer != null) { + writer.close(); + } + } + } + + private void printKeyValue(final PrintWriter writer, Object value) { + println(writer, ""); + if (value != null) { + if (value instanceof Class) { + println(writer, ((Class) value).getSimpleName()); + } else { + println(writer, value.toString().trim()); + } + } + println(writer, ""); + } + + private void printHeaderRow(final PrintWriter writer, final String... values) { + writer.println(""); + for (String value : values) { + writer.println(String.format("%s", value != null ? value.trim() : " ")); + } + writer.println(""); + } + + @Override + public int compareTo(final HtmlFormat o) { + return 0; + } +} \ No newline at end of file Index: ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/DocClassVisitor.java =================================================================== --- ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/DocClassVisitor.java Wed Mar 10 19:48:35 EST 2010 +++ ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/DocClassVisitor.java Wed Mar 10 19:48:35 EST 2010 @@ -0,0 +1,104 @@ +package com.sun.enterprise.admin.cli.schemadoc; + +import java.util.ArrayList; +import java.util.List; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Attribute; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public class DocClassVisitor implements ClassVisitor { + private boolean hasConfiguredAnnotation = false; + private String className; + private List interfaces; + private ClassDef classDef; + private boolean showDeprecated; + + public DocClassVisitor(final boolean showDep) { + showDeprecated = showDep; + } + + public void visit(int version, int access, String name, String signature, String superName, String[] intfs) { + className = CreateDocumentation.toClassName(name); + interfaces = new ArrayList(); + for (String intf : intfs) { + interfaces.add(CreateDocumentation.toClassName(intf)); + } + classDef = new ClassDef(className, interfaces); + } + + public List getInterfaces() { + return interfaces; + } + + public void visitSource(String source, String debug) { + } + + public void visitOuterClass(String owner, String name, String desc) { + } + + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + hasConfiguredAnnotation |= "Lorg/jvnet/hk2/config/Configured;".equals(desc); + if ("Ljava/lang/Deprecated;".equals(desc)) { + classDef.setDeprecated(true); + } + return null; + } + + public void visitAttribute(Attribute attr) { + } + + public void visitInnerClass(String name, String outerName, String innerName, int access) { + } + + public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { + return null; + } + + public MethodVisitor visitMethod(int access, String name, String desc, String signature, + String[] exceptions) { + String type = null; + try { + if (showDeprecated || ((access & Opcodes.ACC_DEPRECATED) != Opcodes.ACC_DEPRECATED)) { + if (hasConfiguredAnnotation) { + if (signature != null) { + type = CreateDocumentation.toClassName( + signature.substring(signature.indexOf("<") + 1, signature.lastIndexOf(">") - 1)); + } else { + type = CreateDocumentation.toClassName(desc); + } + } + } + } catch (StringIndexOutOfBoundsException e) { + throw new RuntimeException(e.getMessage()); + } + return name.startsWith("get") && type != null ? new AttributeMethodVisitor(classDef, name, type) + : null; + } + + /** + * Visits the end of the class. This method, which is the last one to be called, is used to inform the visitor that + * all the fields and methods of the class have been visited. + */ + public void visitEnd() { + } + + public boolean isConfigured() { + return hasConfiguredAnnotation; + } + + public ClassDef getClassDef() { + return hasConfiguredAnnotation ? classDef : null; + } + + @Override + public String toString() { + return "DocClassVisitor{" + + "className='" + className + '\'' + + ", hasConfiguredAnnotation=" + hasConfiguredAnnotation + + '}'; + } +} Index: ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/AttributeMethodVisitor.java =================================================================== --- ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/AttributeMethodVisitor.java Fri Mar 12 16:39:09 EST 2010 +++ ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/AttributeMethodVisitor.java Fri Mar 12 16:39:09 EST 2010 @@ -0,0 +1,83 @@ +package com.sun.enterprise.admin.cli.schemadoc; + +import org.objectweb.asm.AnnotationVisitor; +import org.glassfish.api.admin.config.PropertiesDesc; +import org.glassfish.api.admin.config.PropertyDesc; +import org.jvnet.hk2.config.Attribute; + +public class AttributeMethodVisitor extends EmptyVisitor { + private ClassDef def; + private String name; + private String type; + private boolean duckTyped; + + public AttributeMethodVisitor(ClassDef classDef, String method, String aggType) { + def = classDef; + name = method; + type = aggType; + def.addAttribute(name, null); + } + + @Override + public String toString() { + return "AttributeMethodVisitor{" + + "def=" + def + + ", name='" + name + '\'' + + ", type='" + type + '\'' + + ", duckTyped=" + duckTyped + + '}'; + } + + /** + * Visits an annotation of this method. + * + * @param desc the class descriptor of the annotation class. + * @param visible true if the annotation is visible at runtime. + * + * @return a visitor to visit the annotation values, or null if this visitor is not interested in visiting + * this annotation. + */ + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + duckTyped |= "Lorg/jvnet/hk2/config/DuckTyped;".equals(desc); + AnnotationVisitor visitor = null; + if ("Lorg/jvnet/hk2/config/Attribute;".equals(desc) || "Lorg/jvnet/hk2/config/Element;".equals(desc)) { + try { + final Class configurable = Thread.currentThread().getContextClassLoader().loadClass(def.getDef()); + final Attribute annotation = configurable.getMethod(name).getAnnotation(Attribute.class); + def.addAttribute(name, annotation); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + + } else if ("Lorg/glassfish/api/admin/config/PropertiesDesc;".equals(desc)) { + try { + final Class configurable = Thread.currentThread().getContextClassLoader().loadClass(def.getDef()); + final PropertiesDesc annotation = configurable.getMethod(name).getAnnotation(PropertiesDesc.class); + final PropertyDesc[] propertyDescs = annotation.props(); + for (PropertyDesc prop : propertyDescs) { + def.addProperty(prop); + } + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + return visitor; + } + + @Override + public void visitEnd() { + if (!duckTyped) { + if (!isSimpleType(type)) { + def.addAggregatedType(name, type); + def.removeAttribute(name); + } + } else { + def.removeAttribute(name); + } + } + + private boolean isSimpleType(String type) { + return type.startsWith("java"); + } +} \ No newline at end of file Index: ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/Context.java =================================================================== --- ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/Context.java Mon Mar 15 11:57:56 EDT 2010 +++ ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/Context.java Mon Mar 15 11:57:56 EDT 2010 @@ -0,0 +1,42 @@ +package com.sun.enterprise.admin.cli.schemadoc; + +import java.util.Map; +import java.util.HashMap; +import java.io.File; + +public class Context { + private Boolean showSubclasses; + private Boolean showDeprecated; + private File docDir; + private Map classDefs = new HashMap(); + private String rootClassName; + + public Context(Map classDefs, File docDir, Boolean showDeprecated, + Boolean showSubclasses, String className) { + this.classDefs = classDefs; + this.docDir = docDir; + this.showDeprecated = showDeprecated; + this.showSubclasses = showSubclasses; + rootClassName = className; + } + + public Map getClassDefs() { + return classDefs; + } + + public File getDocDir() { + return docDir; + } + + public Boolean getShowDeprecated() { + return showDeprecated; + } + + public Boolean getShowSubclasses() { + return showSubclasses; + } + + public String getRootClassName() { + return rootClassName; + } +} Index: ../admin/cli/src/main/resources/index.html =================================================================== --- ../admin/cli/src/main/resources/index.html Wed Mar 10 18:00:46 EST 2010 +++ ../admin/cli/src/main/resources/index.html Wed Mar 10 18:00:46 EST 2010 @@ -0,0 +1,11 @@ + + + + GlassFish domain.xml Schema Documentation + + + + + + + Index: ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/CreateDocumentation.java =================================================================== --- ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/CreateDocumentation.java Mon Mar 15 11:53:33 EDT 2010 +++ ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/CreateDocumentation.java Mon Mar 15 11:53:33 EDT 2010 @@ -0,0 +1,133 @@ +package com.sun.enterprise.admin.cli.schemadoc; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import com.sun.enterprise.config.serverbeans.Domain; +import org.glassfish.api.Param; +import org.glassfish.api.admin.AdminCommand; +import org.glassfish.api.admin.AdminCommandContext; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.Habitat; +import org.jvnet.hk2.component.PerLookup; +import org.objectweb.asm.ClassReader; + +@Service(name = "create-documentation") +@Scoped(PerLookup.class) +public class CreateDocumentation implements AdminCommand { + @Inject + private Domain domain; + @Inject + private Habitat habitat; + @Param(name = "format", defaultValue = "html", optional = true) + private String format; + File docDir; + private Map classDefs = new HashMap(); + @Param(name = "showSubclasses", defaultValue = "false", optional = true) + private Boolean showSubclasses; + @Param(name = "showDeprecated", defaultValue = "false", optional = true) + private Boolean showDeprecated; + + public void execute(final AdminCommandContext context) { + try { + URI uri = new URI(System.getProperty("com.sun.aas.instanceRootURI")); + docDir = new File(new File(uri), "config"); + findClasses(classDefs, locateJarFiles(System.getProperty("com.sun.aas.installRoot") + "/modules")); + + getFormat().output(new Context(classDefs, docDir, Boolean.valueOf(showDeprecated), + Boolean.valueOf(showSubclasses), Domain.class.getName())); + context.getActionReport().setMessage("Finished generating " + format + " documentation in " + docDir); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage(), e); + } + } + + private SchemaOutputFormat getFormat() throws IllegalAccessException, InstantiationException { + return habitat.getComponent(SchemaOutputFormat.class, format); +/* + for (final SchemaOutputFormat formatter : list) { + String name = formatter.getClass().getSimpleName(); + if (name.endsWith("Format")) { + name = name.substring(0, name.indexOf("Format")); + } + if (format.equals(name.toLowerCase())) { + return formatter.getClass().newInstance(); + } + } + return null; +*/ + } + + private List locateJarFiles(final String modulesDir) throws IOException { + List result = new ArrayList(); + final File[] files = new File(modulesDir).listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.endsWith(".jar"); + } + }); + for (File f : files) { + result.add(new JarFile(f)); + } + return result; + } + + private void findClasses(final Map classDefs, final List jarFiles) throws IOException { + for (JarFile jf : jarFiles) { + for (Enumeration entries = jf.entries(); entries.hasMoreElements();) { + JarEntry entry = entries.nextElement(); + if (entry.getName().endsWith(".class")) { + ClassDef def = parse(jf.getInputStream(entry)); + if (def != null) { + classDefs.put(def.getDef(), def); + for (String intf : def.getInterfaces()) { + final ClassDef parent = classDefs.get(intf); + if (parent != null) { + parent.addSubclass(def); + } + } + } + } + } + } + if (showSubclasses) { + for (ClassDef def : classDefs.values()) { + for (String anInterface : def.getInterfaces()) { + final ClassDef parent = classDefs.get(anInterface); + if (parent != null) { + parent.addSubclass(def); + } + } + } + } + } + + private ClassDef parse(final InputStream is) throws IOException { + DocClassVisitor visitor = new DocClassVisitor(Boolean.valueOf(showDeprecated)); + new ClassReader(is).accept(visitor, 0); + return visitor.isConfigured() ? visitor.getClassDef() : null; + } + + public static String toClassName(final String value) { + int start = value.startsWith("()") ? 2 : 0; + start = value.substring(start).startsWith("L") ? start + 1 : start; + final int end = value.endsWith(";") ? value.length() - 1 : value.length(); + return value + .substring(start, end) + .replace('/', '.'); + } +} \ No newline at end of file Index: ../admin/cli/pom.xml =================================================================== --- ../admin/cli/pom.xml (revision 34733) +++ ../admin/cli/pom.xml Mon Mar 15 11:48:54 EDT 2010 @@ -106,6 +106,8 @@ src/main/resources + **/*.css + **/*.html **/*.xml **/*.1 **/*.1m @@ -207,6 +209,11 @@ + org.glassfish.external + asm-all-repackaged + ${project.parent.version} + + org.glassfish.core glassfish ${project.parent.version} Index: ../admin/cli/osgi.bundle =================================================================== --- ../admin/cli/osgi.bundle (revision 30322) +++ ../admin/cli/osgi.bundle Fri Mar 12 17:34:44 EST 2010 @@ -1,5 +1,6 @@ -exportcontents: \ com.sun.enterprise.admin.cli; \ com.sun.enterprise.admin.cli.remote; \ + com.sun.enterprise.admin.cli.schemadoc; \ com.sun.enterprise.admin.cli.util; \ org.glassfish.admin.cli.resources; version=${project.osgi.version} Index: ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/EmptyVisitor.java =================================================================== --- ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/EmptyVisitor.java Fri Mar 12 16:39:09 EST 2010 +++ ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/EmptyVisitor.java Fri Mar 12 16:39:09 EST 2010 @@ -0,0 +1,156 @@ +package com.sun.enterprise.admin.cli.schemadoc; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Attribute; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; + +public class EmptyVisitor implements ClassVisitor, FieldVisitor, MethodVisitor, AnnotationVisitor { + @Override + public void visit(int i, int i1, String s, String s1, String s2, + String[] strings) { + } + + @Override + public void visitSource(String s, String s1) { + } + + @Override + public void visitOuterClass(String s, String s1, String s2) { + } + + @Override + public AnnotationVisitor visitAnnotation(String s, boolean b) { + return null; + } + + @Override + public void visitAttribute(Attribute attribute) { + } + + @Override + public void visitInnerClass(String s, String s1, String s2, int i) { + } + + @Override + public FieldVisitor visitField(int i, String s, String s1, String s2, Object o) { + return null; + } + + @Override + public MethodVisitor visitMethod(int i, String s, String s1, String s2, + String[] strings) { + return null; + } + + @Override + public void visitEnd() { + } + + @Override + public void visit(String s, Object o) { + } + + @Override + public void visitEnum(String s, String s1, String s2) { + } + + @Override + public AnnotationVisitor visitAnnotation(String s, String s1) { + return null; + } + + @Override + public AnnotationVisitor visitArray(String s) { + return null; + } + + @Override + public AnnotationVisitor visitAnnotationDefault() { + return null; + } + + @Override + public AnnotationVisitor visitParameterAnnotation(int i, String s, boolean b) { + return null; + } + + @Override + public void visitCode() { + } + + @Override + public void visitFrame(int i, int i1, Object[] objects, int i2, Object[] objects1) { + } + + @Override + public void visitInsn(int i) { + } + + @Override + public void visitIntInsn(int i, int i1) { + } + + @Override + public void visitVarInsn(int i, int i1) { + } + + @Override + public void visitTypeInsn(int i, String s) { + } + + @Override + public void visitFieldInsn(int i, String s, String s1, String s2) { + } + + @Override + public void visitMethodInsn(int i, String s, String s1, String s2) { + } + + @Override + public void visitJumpInsn(int i, Label label) { + } + + @Override + public void visitLabel(Label label) { + } + + @Override + public void visitLdcInsn(Object o) { + } + + @Override + public void visitIincInsn(int i, int i1) { + } + + @Override + public void visitTableSwitchInsn(int i, int i1, Label label, Label[] labels) { + } + + @Override + public void visitLookupSwitchInsn(Label label, int[] ints, Label[] labels) { + } + + @Override + public void visitMultiANewArrayInsn(String s, int i) { + } + + @Override + public void visitTryCatchBlock(Label label, Label label1, Label label2, String s) { + } + + @Override + public void visitLocalVariable(String s, String s1, String s2, Label label, + Label label1, int i) { + } + + @Override + public void visitLineNumber(int i, Label label) { + } + + @Override + public void visitMaxs(int i, int i1) { + } +} Index: ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/ClassDef.java =================================================================== --- ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/ClassDef.java Wed Mar 10 19:48:35 EST 2010 +++ ../admin/cli/src/main/java/com/sun/enterprise/admin/cli/schemadoc/ClassDef.java Wed Mar 10 19:48:35 EST 2010 @@ -0,0 +1,128 @@ +package com.sun.enterprise.admin.cli.schemadoc; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.Comparator; +import java.util.List; +import java.lang.annotation.Annotation; + +import org.jvnet.hk2.config.Dom; +import org.jvnet.hk2.config.Attribute; +import org.glassfish.api.admin.config.PropertyDesc; + +/** + * Contains metadata information about a class + */ +public class ClassDef { + private final String def; + private List interfaces; + private Set subclasses = new HashSet(); + private Map types = new HashMap(); + private Map attributes = new TreeMap(); + private Map validators = new TreeMap(); + private boolean deprecated; + private Set properties = new TreeSet(new Comparator() { + @Override + public int compare(final PropertyDesc left, final PropertyDesc right) { + return left.name().compareTo(right.name()); + } + }); + + public ClassDef(final String def, final List intfs) { + this.def = def; + interfaces = intfs; + } + + public String getDef() { + return def; + } + + public List getInterfaces() { + return interfaces; + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + final ClassDef classDef = (ClassDef) o; + if (def != null ? !def.equals(classDef.def) : classDef.def != null) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return def != null ? def.hashCode() : 0; + } + + public void addSubclass(final ClassDef classDef) { + subclasses.add(classDef); + } + + public Set getSubclasses() { + return subclasses; + } + + public void addAggregatedType(final String name, final String type) { + types.put(name, type); + } + + public String getAggregatedType(final String name) { + return types.get(name); + } + + public Map getAggregatedTypes() { + return types; + } + + @Override + public String toString() { + return def; + } + + public String getSimpleName() { + return Dom.convertName(def); + } + + public Map getAttributes() { + return attributes; + } + + public void addAttribute(String attrName, Attribute annotation) { + attributes.put(Dom.convertName(attrName), annotation); + } + + public void removeAttribute(final String name) { + attributes.remove(Dom.convertName(name)); + } + + public boolean isDeprecated() { + return deprecated; + } + + public void setDeprecated(final boolean deprecated) { + this.deprecated = deprecated; + } + + public Set getProperties() { + return properties; + } + + public void addProperty(final PropertyDesc prop) { + properties.add(prop); + } + + public String getXmlName() { + return Dom.convertName(def.substring(def.lastIndexOf(".")+1)); + } +} \ No newline at end of file Index: ../admin/cli/src/main/resources/schemadoc.css =================================================================== --- ../admin/cli/src/main/resources/schemadoc.css Wed Mar 10 18:00:28 EST 2010 +++ ../admin/cli/src/main/resources/schemadoc.css Wed Mar 10 18:00:28 EST 2010 @@ -0,0 +1,70 @@ +body { + background-color: #FFFFFF; + color: #000000; +} + +h1 { + font-size: 145% +} + +li { + list-style: none; +} + +ul { + margin-left: 0; + padding-left: 1.5em; + border-left: 1px dashed lightgray; +} + +table { + width: 100%; + border-collapse: collapse; + empty-cells: show; + /*border: 1px solid black;*/ +} + +th { + padding-left: 0.25em; + padding-right: 0.25em; + border: 1px solid black; + empty-cells: show; +} + +th.entity { + font-size: x-large; + font-weight: bolder; + empty-cells: show; + background-color: #4444FF; +} + +td { + padding-left: 0.25em; + padding-right: 0.25em; + border: 1px solid black; + empty-cells: show; +} + +.deprecated { + text-decoration:line-through; +} + +/* Table colors */ +.TableHeadingColor { + background: #CCCCFF; + color: #000000; + white-space: nowrap; + /*border: 1px solid black;*/ +} + +.nobreak { + white-space: nowrap; +} + +/* Dark mauve */ +.TableSubHeadingColor { + background: #EEEEFF; + color: #000000; + /*border: 1px solid black;*/ + white-space: nowrap; +} \ No newline at end of file