diff --git a/x4o-driver/src/main/java/org/x4o/xml/io/XMLConstants.java b/x4o-driver/src/main/java/org/x4o/xml/io/XMLConstants.java index 4336713..7b8ce21 100644 --- a/x4o-driver/src/main/java/org/x4o/xml/io/XMLConstants.java +++ b/x4o-driver/src/main/java/org/x4o/xml/io/XMLConstants.java @@ -314,6 +314,20 @@ public final class XMLConstants { StringBuffer result = new StringBuffer(length); for (int i=0;i0) { + if (charEntityAllowed(entity)) { + result.append(entity); + continue; // contine to next i char. + } else { + i = iOrg; // continue normal escape. + } + } + } if (escapeXMLValue(c,result)) { continue; } @@ -322,6 +336,66 @@ public final class XMLConstants { return result.toString(); } + // TODO: make it loaded and xml and html version aware for correctness. + static private boolean charEntityAllowed(String entity) { + + // Hex code points + if (entity.startsWith("&#")) { + String hex = entity.substring(2,entity.length()-1); + if (hex.startsWith("x")) { + hex = hex.substring(1); + } + int codePoint = Integer.parseInt(hex, 16); + return codePoint > 0; // TODO: check if code point is valid. + } + + // XML + if ("<".equals(entity)) { return true; } + if (">".equals(entity)) { return true; } + if ("&".equals(entity)) { return true; } + if (""e;".equals(entity)) { return true; } + if ("'".equals(entity)) { return true; } + + // HTML + if ("´".equals(entity)) { return true; } + if ("ℵ".equals(entity)) { return true; } + if ("≈".equals(entity)) { return true; } + if ("∠".equals(entity)) { return true; } + if ("∗".equals(entity)) { return true; } + if ("♣".equals(entity)) { return true; } + if ("♦".equals(entity)) { return true; } + if ("♥".equals(entity)) { return true; } + if ("♠".equals(entity)) { return true; } + // TODO: etc/etc + if ("ÿ".equals(entity)) { return true; } + if ("ý".equals(entity)) { return true; } + if ("ù".equals(entity)) { return true; } + if ("ü".equals(entity)) { return true; } + if ("û".equals(entity)) { return true; } + if ("ú".equals(entity)) { return true; } + + if ("÷".equals(entity)) { return true; } + if (" ".equals(entity)) { return true; } + if ("®".equals(entity)) { return true; } + if ("™".equals(entity)) { return true; } + if ("©".equals(entity)) { return true; } + return false; + } + + static private int charEntityLookup(int iStart,String value,StringBuffer buf) { + StringBuffer result = new StringBuffer(); + int iMax = 10; + for (int i=iStart;i)value).getName(); - } - if (value instanceof List) { - StringBuffer buf = new StringBuffer(100); - buf.append("[L: "); - List l = (List)value; - if (l.isEmpty()) { - buf.append("Empty"); - } - for (Object o:l) { - buf.append(""+o); - buf.append(" "); - } - buf.append("]"); - return buf.toString(); - } - if (value instanceof Object[]) { - StringBuffer buf = new StringBuffer(100); - buf.append("[A: "); - Object[] l = (Object[])value; - if (l.length==0) { - buf.append("Empty"); - } - for (Object o:l) { - buf.append(""+o); - buf.append(" "); - } - buf.append("]"); - return buf.toString(); - } - - return value.toString(); - } - - @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementBindingHandler.class}) - public void writeElementBindingHandlerBeanProperties(ApiDocWriteEvent event) throws SAXException { - printBeanProperties(event.getWriter(),event.getEvent().getUserData()); - } - - @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementConfigurator.class}) - public void writeElementConfiguratorBeanProperties(ApiDocWriteEvent event) throws SAXException { - printBeanProperties(event.getWriter(),event.getEvent().getUserData()); + private String getLanguageNameUpperCase() { + return context.getLanguage().getLanguageName().toUpperCase(); } } diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterElementClass.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterElementClass.java index a1b45fc..930ade5 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterElementClass.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterElementClass.java @@ -22,17 +22,21 @@ */ package org.x4o.xml.eld.doc; -import java.lang.reflect.Method; import java.util.List; import org.x4o.xml.eld.doc.EldDocXTreePageWriter.TreeNode; +import org.x4o.xml.eld.doc.api.AbstractApiDocWriter; import org.x4o.xml.eld.doc.api.ApiDocContentWriter; +import org.x4o.xml.eld.doc.api.ApiDocNodeDataConfiguratorMethod; import org.x4o.xml.eld.doc.api.ApiDocNodeWriterMethod; +import org.x4o.xml.eld.doc.api.dom.ApiDoc; import org.x4o.xml.eld.doc.api.dom.ApiDocNode; import org.x4o.xml.eld.doc.api.dom.ApiDocNodeBody; +import org.x4o.xml.eld.doc.api.dom.ApiDocNodeData; import org.x4o.xml.eld.doc.api.dom.ApiDocWriteEvent; import org.x4o.xml.element.ElementClass; import org.x4o.xml.element.ElementClassAttribute; +import org.x4o.xml.element.ElementConfigurator; import org.x4o.xml.element.ElementNamespaceContext; import org.x4o.xml.io.sax.ext.ContentWriterHtml.Tag; import org.x4o.xml.lang.X4OLanguageContext; @@ -45,85 +49,71 @@ import org.xml.sax.SAXException; * @author Willem Cazander * @version 1.0 May 29, 2013 */ -public class EldDocWriterElementClass { +public class EldDocWriterElementClass extends AbstractApiDocWriter { - private String printList(List list) { - StringBuffer buf = new StringBuffer(40); - buf.append("[L: "); + @ApiDocNodeDataConfiguratorMethod(targetClasses={ElementClass.class}) + public void configNavBar(ApiDoc doc,ApiDocNode node,ApiDocNodeData data) { + /* + ElementClass ec = (ElementClass)node.getUserData(); + Collection list = ec.getElementClassAttributes(); if (list.isEmpty()) { - buf.append("Empty."); + clearHrefContentGroupAlways(doc,"summary","attribute"); } - for (String s:list) { - buf.append(s); - buf.append(' '); - } - buf.append("]"); - return buf.toString(); + */ + clearHrefContentGroup(doc,node,"summary","attribute",ElementClassAttribute.class); + clearHrefContentGroup(doc,node,"summary","configurator",ElementConfigurator.class); } - @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementClass.class}) + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementClass.class},nodeBodyOrders={1},contentGroup="element",contentGroupType="summary") public void writeElementX4OSummary(ApiDocWriteEvent event) throws SAXException { - ApiDocContentWriter writer = event.getWriter(); - ElementClass ec = (ElementClass)event.getEvent().getUserData(); - writer.docTableStart("Element X4O Properties", "Element X4O Property Overview"); - writer.docTableHeader("Name", "Value"); - writer.docTableRow("id",""+ec.getId()); - writer.docTableRow("objectClass",""+ec.getObjectClass()); - writer.docTableRow("elementClass",""+ec.getElementClass()); - writer.docTableRow("autoAttributes",""+ec.getAutoAttributes()); - writer.docTableRow("skipPhases",printList(ec.getSkipPhases())); - writer.docTableRow("schemaContentBase",""+ec.getSchemaContentBase()); - writer.docTableRow("schemaContentComplex",""+ec.getSchemaContentComplex()); - writer.docTableRow("schemaContentMixed",""+ec.getSchemaContentMixed()); - writer.docTableEnd(); + printApiTableBean(event, "Element", "class","id","description"); } - @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementClass.class}) + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementClass.class},nodeBodyOrders={2},contentGroup="attribute",contentGroupType="summary") + public void writeElementClassAttribute(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Element Class Attribute Summary",ElementClassAttribute.class); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementClass.class},nodeBodyOrders={3},contentGroup="configurator",contentGroupType="summary") + public void writeElementConfigurator(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Element Configurator Summary",ElementConfigurator.class); + } + + /* + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementClass.class},nodeBodyOrders={2},contentGroup="attribute",contentGroupType="summary") public void writeElementX4OAttributeSummary(ApiDocWriteEvent event) throws SAXException { + ElementClass ec = (ElementClass)event.getEventObject().getUserData(); + Collection list = ec.getElementClassAttributes(); + if (list.isEmpty()) { + return; + } ApiDocContentWriter writer = event.getWriter(); - ElementClass ec = (ElementClass)event.getEvent().getUserData(); - writer.docTableStart("Element X4O Attributes", "All Element X4O Attributes Overview"); + writer.docTableStart("Element X4O Attributes", "All Element X4O Attributes Overview",ApiDocContentCss.overviewSummary); writer.docTableHeader("URI", "Name"); - for (ElementClassAttribute attr:ec.getElementClassAttributes()) { + for (ElementClassAttribute attr:list) { writer.docTableRow(attr.getId(),attr.getDescription()); } writer.docTableEnd(); } + */ - @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementClass.class}) + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementClass.class},nodeBodyOrders={10},contentGroup="bean",contentGroupType="summary") public void writeElementObjectPropertiesSummary(ApiDocWriteEvent event) throws SAXException { - ApiDocContentWriter writer = event.getWriter(); - ElementClass ec = (ElementClass)event.getEvent().getUserData(); - Class beanClass = ec.getElementClass(); + ElementClass ec = (ElementClass)event.getEventObject().getUserData(); + Class beanClass = ec.getObjectClass(); if (beanClass==null) { return; } - writer.docTableStart("Class Properties", "Bean class properties overview."); - writer.docTableHeader("Name", "Value"); - for (Method m:beanClass.getMethods()) { - if (m.getName().startsWith("set")) { - String n = m.getName().substring(3); - if (m.getParameterTypes().length==0) { - continue; // set without parameters - } - if (n.length()<2) { - continue; - } - n = n.substring(0,1).toLowerCase()+n.substring(1,n.length()); - Class type = m.getParameterTypes()[0]; // TODO make full list for auto attribute type resolving. - writer.docTableRow(n,""+type); - } - } - writer.docTableEnd(); + printApiTableBeanClass(event, beanClass, "Object"); } @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.DESCRIPTION_LINKS,targetClasses={ElementClass.class}) public void writeElementRelationLinks(ApiDocWriteEvent event) throws SAXException { ApiDocContentWriter writer = event.getWriter(); - ElementClass ec = (ElementClass)event.getEvent().getUserData(); - ElementNamespaceContext ns = (ElementNamespaceContext)event.getEvent().getParent().getUserData(); - X4OLanguageModule mod = (X4OLanguageModule)event.getEvent().getParent().getParent().getUserData(); - X4OLanguageContext context = (X4OLanguageContext)event.getEvent().getParent().getParent().getParent().getUserData(); + ElementClass ec = (ElementClass)event.getEventObject().getUserData(); + ElementNamespaceContext ns = (ElementNamespaceContext)event.getEventObject().getParent().getUserData(); + X4OLanguageModule mod = (X4OLanguageModule)event.getEventObject().getParent().getParent().getUserData(); + X4OLanguageContext context = (X4OLanguageContext)event.getEventObject().getParent().getParent().getParent().getUserData(); // TODO: this is hacky EldDocXTreePageWriter xtree = (EldDocXTreePageWriter)event.getDoc().findDocPageById("overview-xtree").getPageWriters().get(0); @@ -138,7 +128,7 @@ public class EldDocWriterElementClass { List parents = xtree.findParents(node); writer.printTagStart(Tag.dl); - writer.printTagCharacters(Tag.dt,"Element Parents:"); + writer.printTagCharacters(Tag.dt,"All Element Parents:"); writer.printTagStart(Tag.dd); if (parents.isEmpty()) { writer.characters("No parent."); @@ -148,7 +138,7 @@ public class EldDocWriterElementClass { String uri = toElementUri(pathPrefix, n.module, n.namespace, n.elementClass); writer.printHref(uri, n.namespace.getId()+":"+n.elementClass.getId()); if (i childs = xtree.findChilderen(node); writer.printTagStart(Tag.dl); - writer.printTagCharacters(Tag.dt,"Element Childeren:"); + writer.printTagCharacters(Tag.dt,"All Element Childeren:"); writer.printTagStart(Tag.dd); if (childs.isEmpty()) { writer.characters("No childeren."); @@ -166,7 +156,7 @@ public class EldDocWriterElementClass { String uri = toElementUri(pathPrefix, n.module, n.namespace, n.elementClass); writer.printHref(uri, n.namespace.getId()+":"+n.elementClass.getId()); if (i event) throws SAXException { + printApiTableBean(event,"Interface","description"); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementInterface.class},nodeBodyOrders={2},contentGroup="attribute",contentGroupType="summary") + public void writeElementClassAttribute(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Element Class Attribute Summary",ElementClassAttribute.class); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementInterface.class},nodeBodyOrders={3},contentGroup="binding",contentGroupType="summary") + public void writeElementBindingHandler(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Element Binding Handler Summary",ElementBindingHandler.class); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementInterface.class},nodeBodyOrders={4},contentGroup="configurator",contentGroupType="summary") + public void writeElementConfigurator(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Element Configurator Summary",ElementConfigurator.class); + } +} diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterElementNamespace.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterElementNamespace.java new file mode 100644 index 0000000..05472ca --- /dev/null +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterElementNamespace.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2004-2013, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.x4o.xml.eld.doc; + +import org.x4o.xml.eld.doc.api.AbstractApiDocWriter; +import org.x4o.xml.eld.doc.api.ApiDocNodeDataConfiguratorMethod; +import org.x4o.xml.eld.doc.api.ApiDocNodeWriterMethod; +import org.x4o.xml.eld.doc.api.dom.ApiDoc; +import org.x4o.xml.eld.doc.api.dom.ApiDocNode; +import org.x4o.xml.eld.doc.api.dom.ApiDocNodeBody; +import org.x4o.xml.eld.doc.api.dom.ApiDocNodeData; +import org.x4o.xml.eld.doc.api.dom.ApiDocWriteEvent; +import org.x4o.xml.element.ElementClass; +import org.x4o.xml.element.ElementNamespaceContext; +import org.xml.sax.SAXException; + +/** + * EldDocWriterElementNamespace writers all content parts for the x4o element namespace context. + * + * @author Willem Cazander + * @version 1.0 Aug 14, 2013 + */ +public class EldDocWriterElementNamespace extends AbstractApiDocWriter { + + @ApiDocNodeDataConfiguratorMethod(targetClasses={ElementNamespaceContext.class}) + public void configNavBar(ApiDoc doc,ApiDocNode node,ApiDocNodeData data) { + clearHrefContentGroup(doc,node,"summary","element",ElementClass.class); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementNamespaceContext.class},nodeBodyOrders={1},contentGroup="namespace",contentGroupType="summary") + public void writeElementNamespaceBeanProperties(ApiDocWriteEvent event) throws SAXException { + printApiTableBean(event,"Namespace","description","elementClasses","elementNamespaceInstanceProvider","prefixMapping"); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementNamespaceContext.class},nodeBodyOrders={2},contentGroup="element",contentGroupType="summary") + public void writeElementNamespaceElements(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Element Summary",ElementClass.class); + } + + //@ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementNamespaceContext.class},nodeBodyOrders={2}) + //public void writeElementNamespaceAttributes(ApiDocWriteEvent event) throws SAXException { + // printApiTable(event,"Element Summary",ElementClass.class); + //} +} diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterLanguage.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterLanguage.java index bfffb33..febbafe 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterLanguage.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterLanguage.java @@ -22,11 +22,16 @@ */ package org.x4o.xml.eld.doc; +import org.x4o.xml.eld.doc.api.AbstractApiDocWriter; +import org.x4o.xml.eld.doc.api.ApiDocContentCss; import org.x4o.xml.eld.doc.api.ApiDocContentWriter; import org.x4o.xml.eld.doc.api.ApiDocNodeWriterMethod; import org.x4o.xml.eld.doc.api.dom.ApiDocNode; import org.x4o.xml.eld.doc.api.dom.ApiDocNodeBody; import org.x4o.xml.eld.doc.api.dom.ApiDocWriteEvent; +import org.x4o.xml.element.ElementBindingHandler; +import org.x4o.xml.element.ElementClassAttribute; +import org.x4o.xml.element.ElementConfigurator; import org.x4o.xml.element.ElementNamespaceContext; import org.x4o.xml.lang.X4OLanguageContext; import org.x4o.xml.lang.X4OLanguageModule; @@ -38,12 +43,31 @@ import org.xml.sax.SAXException; * @author Willem Cazander * @version 1.0 May 29, 2013 */ -public class EldDocWriterLanguage { +public class EldDocWriterLanguage extends AbstractApiDocWriter { - @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={X4OLanguageContext.class}) + // TODO move + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementBindingHandler.class}) + public void writeElementBindingHandlerBean(ApiDocWriteEvent event) throws SAXException { + printApiTableBean(event,"BindingHandler","description"); + } + + // TODO move + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementConfigurator.class}) + public void writeElementConfiguratorBean(ApiDocWriteEvent event) throws SAXException { + printApiTableBean(event,"Configurator","description"); + } + + // TODO move + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementClassAttribute.class}) + public void writeElementClassAttributeBean(ApiDocWriteEvent event) throws SAXException { + printApiTableBean(event,"Element Class Attribute","description"); + } + + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={X4OLanguageContext.class},nodeBodyOrders={1}) public void writeLanguageSummary(ApiDocWriteEvent event) throws SAXException { ApiDocContentWriter writer = event.getWriter(); - ApiDocNode node = event.getEvent(); + ApiDocNode node = event.getEventObject(); X4OLanguageContext context = (X4OLanguageContext)node.getUserData(); int attrHandlers = 0; int bindHandlers = 0; @@ -61,7 +85,7 @@ public class EldDocWriterLanguage { elements += ns.getElementClasses().size(); } } - writer.docTableStart("Language Summary", "Language Stats Summary."); + writer.docTableStart("Language Summary", "Language Stats Summary.",ApiDocContentCss.overviewSummary); writer.docTableHeader("Name", "Value"); writer.docTableRow("LanguageName:", ""+context.getLanguage().getLanguageName(), null); writer.docTableRow("LanguageVersion:",""+context.getLanguage().getLanguageVersion(),null); @@ -75,32 +99,21 @@ public class EldDocWriterLanguage { writer.docTableEnd(); } - @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={X4OLanguageContext.class}) + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={X4OLanguageContext.class},nodeBodyOrders={2}) public void writeModulesSummary(ApiDocWriteEvent event) throws SAXException { - ApiDocContentWriter writer = event.getWriter(); - ApiDocNode node = event.getEvent(); - writer.docTableStart("Modules Summary", "All modules."); - writer.docTableHeader("Name", "Description"); - for (ApiDocNode child:node.getNodes()) { - String link = ApiDocContentWriter.toSafeUri(child.getId())+"/index.html"; - if (node.getParent()==null) { - link = ApiDocContentWriter.toSafeUri(node.getId())+"/"+link; // root node - } - writer.docTableRowHref(link,child.getName(),child.getDescription(),null); - } - writer.docTableEnd(); + printApiTable(event,"Module Summary",X4OLanguageModule.class); } - @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={X4OLanguageContext.class}) + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={X4OLanguageContext.class},nodeBodyOrders={3}) public void writeNamespaceSummary(ApiDocWriteEvent event) throws SAXException { ApiDocContentWriter writer = event.getWriter(); - ApiDocNode node = event.getEvent(); + ApiDocNode node = event.getEventObject(); X4OLanguageContext context = (X4OLanguageContext)node.getUserData(); - writer.docTableStart("Namespace Summary", "All Language Namespaces Overview"); + writer.docTableStart("Namespace Summary", "All Language Namespaces Overview",ApiDocContentCss.overviewSummary); writer.docTableHeader("ID", "URI"); for (X4OLanguageModule mod:context.getLanguage().getLanguageModules()) { for (ElementNamespaceContext ns:mod.getElementNamespaceContexts()) { - writer.docTableRowHref("language/"+ApiDocContentWriter.toSafeUri(mod.getId())+"/"+ApiDocContentWriter.toSafeUri(ns.getId())+"/index.html",ns.getId(),ns.getUri(),null); + writer.docTableRowLink("language/"+ApiDocContentWriter.toSafeUri(mod.getId())+"/"+ApiDocContentWriter.toSafeUri(ns.getId())+"/index.html",ns.getId(),ns.getUri()); } } writer.docTableEnd(); diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterLanguageModule.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterLanguageModule.java new file mode 100644 index 0000000..e3627ea --- /dev/null +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/EldDocWriterLanguageModule.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2004-2013, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.x4o.xml.eld.doc; + +import org.x4o.xml.eld.doc.api.AbstractApiDocWriter; +import org.x4o.xml.eld.doc.api.ApiDocNodeDataConfiguratorMethod; +import org.x4o.xml.eld.doc.api.ApiDocNodeWriterMethod; +import org.x4o.xml.eld.doc.api.dom.ApiDoc; +import org.x4o.xml.eld.doc.api.dom.ApiDocNode; +import org.x4o.xml.eld.doc.api.dom.ApiDocNodeBody; +import org.x4o.xml.eld.doc.api.dom.ApiDocNodeData; +import org.x4o.xml.eld.doc.api.dom.ApiDocWriteEvent; +import org.x4o.xml.element.ElementAttributeHandler; +import org.x4o.xml.element.ElementBindingHandler; +import org.x4o.xml.element.ElementConfigurator; +import org.x4o.xml.element.ElementInterface; +import org.x4o.xml.element.ElementNamespaceContext; +import org.x4o.xml.lang.X4OLanguageModule; +import org.xml.sax.SAXException; + +/** + * EldDocWriterLanguageModukle writers all content parts for the x4o language module. + * + * @author Willem Cazander + * @version 1.0 Aug 10, 2013 + */ +public class EldDocWriterLanguageModule extends AbstractApiDocWriter { + + @ApiDocNodeDataConfiguratorMethod(targetClasses={X4OLanguageModule.class}) + public void configNavBar(ApiDoc doc,ApiDocNode node,ApiDocNodeData data) { + clearHrefContentGroup(doc,node,"summary","interface",ElementInterface.class); + clearHrefContentGroup(doc,node,"summary","binding",ElementBindingHandler.class); + clearHrefContentGroup(doc,node,"summary","attribute",ElementAttributeHandler.class); + clearHrefContentGroup(doc,node,"summary","configurator",ElementConfigurator.class); + clearHrefContentGroup(doc,node,"summary","namespace",ElementNamespaceContext.class); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={X4OLanguageModule.class},nodeBodyOrders={1},contentGroup="interface",contentGroupType="summary") + public void writeInterfaceSummary(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Interface Summary",ElementInterface.class); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={X4OLanguageModule.class},nodeBodyOrders={2},contentGroup="binding",contentGroupType="summary") + public void writeBindingSummary(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Binding Summary",ElementBindingHandler.class); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={X4OLanguageModule.class},nodeBodyOrders={3},contentGroup="attribute",contentGroupType="summary") + public void writeAttributeSummary(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Attribute Summary",ElementAttributeHandler.class); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={X4OLanguageModule.class},nodeBodyOrders={4},contentGroup="configurator",contentGroupType="summary") + public void writeConfigutorSummary(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Configurator Summary",ElementConfigurator.class); + } + + @ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={X4OLanguageModule.class},nodeBodyOrders={5},contentGroup="namespace",contentGroupType="summary") + public void writeNamespaceSummary(ApiDocWriteEvent event) throws SAXException { + printApiTable(event,"Namespace Summary",ElementNamespaceContext.class); + } +} diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/AbstractApiDocWriter.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/AbstractApiDocWriter.java new file mode 100644 index 0000000..62540b8 --- /dev/null +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/AbstractApiDocWriter.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2004-2013, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.x4o.xml.eld.doc.api; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import org.x4o.xml.eld.doc.api.dom.ApiDoc; +import org.x4o.xml.eld.doc.api.dom.ApiDocNavLink; +import org.x4o.xml.eld.doc.api.dom.ApiDocNode; +import org.x4o.xml.eld.doc.api.dom.ApiDocRemoteClass; +import org.x4o.xml.eld.doc.api.dom.ApiDocWriteEvent; +import org.xml.sax.SAXException; + +/** + * AbstractApiDocNodeWriter has some handy writer method for printing api doc html stuctures. + * + * @author Willem Cazander + * @version 1.0 Aug 11, 2013 + */ +public abstract class AbstractApiDocWriter { + + public void clearHrefContentGroup(ApiDoc doc,ApiDocNode node,String groupType,String group,Class filterClass) { + boolean doClear = filterUserDataClassType(node,filterClass).isEmpty(); + if (doClear==false) { + return; + } + clearHrefContentGroupAlways(doc,groupType,group); + } + + public void clearHrefContentGroupAlways(ApiDoc doc,String groupType,String group) { + ApiDocNavLink link = doc.getNodeData().getGroupTypeLink(groupType,group); + if (link==null) { + return; + } + link.setHref(null); + } + + + public void printApiTable(ApiDocWriteEvent event,String name,Class interfaceClass) throws SAXException { + printApiTable( + event.getEventObject(), + filterUserDataClassType(event.getEventObject(),interfaceClass), + event.getWriter(), + name + ); + } + + public void printApiTable(ApiDocNode parent,List nodes,ApiDocContentWriter writer,String name) throws SAXException { + if (nodes.isEmpty()) { + return; + } + writer.docTableStart(name, "All childeren in "+name,ApiDocContentCss.overviewSummary); + writer.docTableHeader("Name", "Description"); + for (ApiDocNode child:nodes) { + String link = ApiDocContentWriter.toSafeUri(child.getId())+"/index.html"; + if (parent.getParent()==null) { + link = ApiDocContentWriter.toSafeUri(parent.getId())+"/"+link; // root node + } + writer.docTableRowLink(link,child.getName(),child.getDescription()); + } + writer.docTableEnd(); + } + + private List filterUserDataClassType(ApiDocNode filterNode,Class interfaceClass) { + List result = new ArrayList(filterNode.getNodes().size()/2); + for (ApiDocNode node:filterNode.getNodes()) { + if (interfaceClass.isAssignableFrom(node.getUserData().getClass())) { + result.add(node); + } + } + return result; + } + + public void printApiTableBean(ApiDocWriteEvent event,String name,String...skipProperties) throws SAXException { + printApiTableBean(event, event.getEventObject().getUserData(), name, skipProperties); + } + + public void printApiTableBean(ApiDocWriteEvent event,Object bean,String name,String...skipProperties) throws SAXException { + printApiTableBean(event.getDoc(), event.getWriter(), bean, name, skipProperties); + } + + public void printApiTableBean(ApiDoc doc,ApiDocContentWriter writer,Object bean,String name,String...skipProperties) throws SAXException { + printApiTableBeanClass(doc, writer, bean, bean.getClass(), name, skipProperties); + } + + public void printApiTableBeanClass(ApiDocWriteEvent event,Class beanClass,String name,String...skipProperties) throws SAXException { + printApiTableBeanClass(event.getDoc(), event.getWriter(), null,beanClass, name, skipProperties); + } + + private void printApiTableBeanClass(ApiDoc doc,ApiDocContentWriter writer,Object bean,Class beanClass,String name,String...skipProperties) throws SAXException { + writer.docTableStart(name+" Properties", name+" properties overview.",ApiDocContentCss.overviewSummary); + writer.docTableHeader("Name", "Value"); + for (Method m:beanClass.getMethods()) { + if (m.getName().startsWith("get")) { + String n = m.getName().substring(3); + if (m.getParameterTypes().length!=0) { + continue; // set without parameters + } + if (n.length()<2) { + continue; + } + n = n.substring(0,1).toLowerCase()+n.substring(1,n.length()); + boolean skipNext = false; + for (String skip:skipProperties) { + if (n.equals(skip)) { + skipNext = true; + break; + } + } + if (skipNext) { + continue; + } + + Object value = null; + if (bean!=null) { + try { + value = m.invoke(bean, new Object[] {}); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } else { + value = m.getReturnType(); + } + //writer.docTableRow(n,); + writer.docTableRowLastStart(n, null); + String c = printValue(doc,writer,value); + if (c!=null) { + writer.characters(c); + } + writer.docTableRowLastEnd(); + } + } + writer.docTableEnd(); + } + + private String printValue(ApiDoc doc,ApiDocContentWriter writer,Object value) throws SAXException { + if (value==null) { + return "null"; + } + if (value instanceof String) { + return (String)value; + } + if (value instanceof Class) { + Class cls = (Class)value; + + for (ApiDocRemoteClass rc:doc.getRemoteClasses()) { + String remoteUrl = rc.getRemoteUrl(cls); + if (remoteUrl==null) { + continue; + } + writer.printHref(remoteUrl, cls.getName(), cls.getSimpleName()); + return null; + } + + return "class "+cls.getName(); + } + if (value instanceof List) { + StringBuffer buf = new StringBuffer(100); + buf.append("[L: "); + List l = (List)value; + if (l.isEmpty()) { + buf.append("Empty"); + } + for (Object o:l) { + buf.append(""+o); + buf.append(" "); + } + buf.append("]"); + return buf.toString(); + } + if (value instanceof Object[]) { + StringBuffer buf = new StringBuffer(100); + buf.append("[A: "); + Object[] l = (Object[])value; + if (l.length==0) { + buf.append("Empty"); + } + for (Object o:l) { + buf.append(""+o); + buf.append(" "); + } + buf.append("]"); + return buf.toString(); + } + + return value.toString(); + } +} diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocContentCss.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocContentCss.java index e07fc28..b54526f 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocContentCss.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocContentCss.java @@ -59,6 +59,7 @@ public enum ApiDocContentCss { docSummary, contentContainer, packageSummary, + overviewSummary, colOne, colFirst, diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocContentWriter.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocContentWriter.java index 2f926c5..724340d 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocContentWriter.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocContentWriter.java @@ -23,11 +23,8 @@ package org.x4o.xml.eld.doc.api; import java.io.Writer; -import java.util.ArrayList; import java.util.Date; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.x4o.xml.io.sax.ext.ContentWriterHtml; import org.xml.sax.SAXException; @@ -51,7 +48,7 @@ public class ApiDocContentWriter extends ContentWriterHtml { comment("Generated by "+ApiDocContentWriter.class.getSimpleName()+" on "+new Date()); } - public void docHtmlStart(NavBarConfig conf,String title,List keywords) throws SAXException { + public void docHtmlStart(String title,List keywords,String pathPrefix) throws SAXException { printDocType(DocType.HTML_4_TRANSITIONAL); comment("NewPage"); printHtmlStart("en"); @@ -65,7 +62,7 @@ public class ApiDocContentWriter extends ContentWriterHtml { for (String keyword:keywords) { printHeadMeta("keywords",keyword); } - printHeadLinkCss(conf.pathPrefix+"resources/stylesheet.css"); + printHeadLinkCss(pathPrefix+"resources/stylesheet.css"); printTagEnd(Tag.head); // ======= Write body @@ -78,233 +75,36 @@ public class ApiDocContentWriter extends ContentWriterHtml { script.append("\t}\n"); printScriptInline(script.toString()); printScriptNoDiv(); - - docNavBar(conf,true); } - public void docHtmlEnd(NavBarConfig conf,String copyright) throws SAXException { - docNavBar(conf,false); + public void docHtmlEnd(String copyright,String statsJS) throws SAXException { printTagStart(Tag.p,ApiDocContentCss.legalCopy); printTagStart(Tag.small); - charactersRaw(copyright); + characters(copyright); printTagEnd(Tag.small); printTagEnd(Tag.p); - if (conf.statsJS!=null) { - printScriptInline(conf.statsJS); + if (statsJS!=null) { + printScriptInline(statsJS); } printTagEnd(Tag.body); printHtmlEnd(); } - class NavBarConfig { - String navSelected = null; - List navList = new ArrayList(10); - Map navLinks = new HashMap(10); - Map navNames = new HashMap(10); - Map navTitles = new HashMap(10); - String pathPrefix; - String prev; - String next; - String frame; - String aboutLanguage; - String statsJS; - boolean linkDetails = false; - boolean linkFields = false; - boolean linkConstructors = false; - boolean linkMethods = false; - String linkFieldName = "Field"; - String linkConstructorName = "Constr"; - String linkMethodName = "Method"; - String noFrameAllName; - String noFrameAllLink; - String noFrameAllTopJS = - "\nallClassesLink = document.getElementById(\"allclasses_navbar_top\");\n"+ - "if(window==top) {\n\tallClassesLink.style.display = \"block\";\n} else {\n\tallClassesLink.style.display = \"none\";\n}\n"; - String noFrameAllBottomJS = - "\nallClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n"+ - "if(window==top) {\n\tallClassesLink.style.display = \"block\";\n} else {\n\tallClassesLink.style.display = \"none\";\n}\n"; - - public NavBarConfig() {} - public NavBarConfig(String pathPrefix,String prev,String next,String frame,String aboutLanguage) { - this.pathPrefix=pathPrefix; - this.prev=prev; - this.next=next; - this.frame=frame; - this.aboutLanguage=aboutLanguage; + public void docNavBarAbout(String about) throws SAXException { + printTagStart(Tag.div,ApiDocContentCss.aboutLanguage); // Print about language + printTagStart(Tag.em); + printTagStart(Tag.strong); + String[] lines = about.split("\n"); + for (int i=0;i> targetClasses = null; + + public ApiDocNodeDataConfiguratorBean() { + targetClasses = new ArrayList>(5); + } + + public ApiDocNodeDataConfiguratorBean(Object bean,String method,Class...classes) { + this(); + setBean(bean); + setMethod(method); + for (Class cl:classes) { + addtargetClass(cl); + } + } + + public static void addAnnotatedNodeDataConfigurators(ApiDoc doc,Object bean) { + if (doc==null) { + throw new NullPointerException("Can't add to null ApiDoc."); + } + if (bean==null) { + throw new NullPointerException("Can't scan null bean."); + } + for (Method method:bean.getClass().getMethods()) { + ApiDocNodeDataConfiguratorMethod ammo = method.getAnnotation(ApiDocNodeDataConfiguratorMethod.class); + if (ammo==null) { + continue; + } + if (ammo.targetClasses().length==0) { + throw new IllegalArgumentException("Can't configure writer bean with empty 'targetClasses' parameter."); + } + ApiDocNodeDataConfiguratorBean methodConfig = new ApiDocNodeDataConfiguratorBean(bean, method.getName(), ammo.targetClasses()); + doc.addDataConfigurator(methodConfig); + } + } + + public void configNodeData(ApiDoc doc, ApiDocNode node,ApiDocNodeData data) { + Class beanClass = getBean().getClass(); + try { + Method methodBean = beanClass.getMethod(getMethod(), new Class[]{ApiDoc.class,ApiDocNode.class,ApiDocNodeData.class}); + methodBean.invoke(getBean(), new Object[]{doc,node,data}); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + public void addtargetClass(Class targetClass) { + targetClasses.add(targetClass); + } + + public void removetargetClass(Class targetClass) { + targetClasses.remove(targetClasses); + } + + public List> getTargetClasses() { + return targetClasses; + } + + /** + * @return the bean + */ + public Object getBean() { + return bean; + } + + /** + * @param bean the bean to set + */ + public void setBean(Object bean) { + this.bean = bean; + } + + /** + * @return the method + */ + public String getMethod() { + return method; + } + + /** + * @param method the method to set + */ + public void setMethod(String method) { + this.method = method; + } +} diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocNodeDataConfiguratorMethod.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocNodeDataConfiguratorMethod.java new file mode 100644 index 0000000..0837181 --- /dev/null +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocNodeDataConfiguratorMethod.java @@ -0,0 +1,41 @@ +/* + * Copyright 2007-2012 forwardfire.net All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.x4o.xml.eld.doc.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ApiDocNodeDataConfiguratorMethod wraps the node data config api to a method. + * + * @author Willem Cazander + * @version 1.0 Aug 11, 2013 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface ApiDocNodeDataConfiguratorMethod { + + Class[] targetClasses(); +} \ No newline at end of file diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocWriter.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocWriter.java index 0c0ef9f..5e79f53 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocWriter.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/ApiDocWriter.java @@ -39,11 +39,13 @@ import java.util.Comparator; import java.util.Iterator; import java.util.List; -import org.x4o.xml.eld.doc.api.ApiDocContentWriter.NavBarConfig; import org.x4o.xml.eld.doc.api.dom.ApiDoc; import org.x4o.xml.eld.doc.api.dom.ApiDocConcept; +import org.x4o.xml.eld.doc.api.dom.ApiDocNavLink; import org.x4o.xml.eld.doc.api.dom.ApiDocNode; import org.x4o.xml.eld.doc.api.dom.ApiDocNodeBody; +import org.x4o.xml.eld.doc.api.dom.ApiDocNodeData; +import org.x4o.xml.eld.doc.api.dom.ApiDocNodeDataConfigurator; import org.x4o.xml.eld.doc.api.dom.ApiDocWriteEvent; import org.x4o.xml.eld.doc.api.dom.ApiDocNodeWriter; import org.x4o.xml.eld.doc.api.dom.ApiDocPage; @@ -61,7 +63,7 @@ import org.xml.sax.helpers.AttributesImpl; * @author Willem Cazander * @version 1.0 May 1, 2013 */ -public class ApiDocWriter { +public class ApiDocWriter extends AbstractApiDocWriter { private ApiDoc doc = null; private File basePath = null; @@ -80,6 +82,7 @@ public class ApiDocWriter { if (basePath==null) { throw new NullPointerException("Can't write with null basePath."); } + doc.checkModel(); this.doc=doc; this.basePath=basePath; @@ -100,10 +103,12 @@ public class ApiDocWriter { } private void writeNode(ApiDocNode node) throws SAXException { - ApiDocConcept concept = findConceptByClass(node.getUserData().getClass()); + ApiDocConcept concept = doc.findConceptByClass(node.getUserData().getClass()); if (concept==null) { - //System.out.println("----- no concept found for: "+node.getId()+" data: "+node.getUserData()); - return; + concept = doc.findConceptChildByNode(node); + } + if (concept==null) { + throw new IllegalStateException("No concept found for: "+node.getId()+" data: "+node.getUserData()); } List path = new ArrayList(10); buildParentPath(node,path); @@ -119,30 +124,61 @@ public class ApiDocWriter { } File outputFile = createOutputPathFile(basePath,path.toArray(new String[]{})); ApiDocContentWriter writer = createContentWriter(outputFile); - NavBarConfig config = createNavBarConfig(pathPrefix, outputFile, writer); - config.navSelected=concept.getId(); - configActiveNavConceptLinks(config,node,concept,"/.."); - configNextPrevLinks(config,node); + doc.getNodeData().clearGroupTypeLinks(); + doc.getNodeData().setNavSelected(concept.getId()); + configNodeData(pathPrefix,outputFile); + configActiveNavConceptLinks(node,concept,"/.."); + configNextPrevLinks(node); + configSubNavLinks(node); + configData(node); ApiDocWriteEvent bodyEvent = new ApiDocWriteEvent(doc,writer,node); - String title = node.getId(); - String titleSub = null; + String titleNode = node.getName(); + String titleNodeSub = null; if (node.getParent()!=null) { - titleSub = node.getParent().getId()+":"+node.getId(); + titleNodeSub = node.getParent().getId()+":"+node.getId(); + } + boolean isNodePageMode = isNodePageMode(node); + String titleContent = titleNode; + if (doc.isPrintConceptTitle()) { + String conceptTitle = concept.getName(); + ApiDocConcept childConcept = doc.findConceptChildByNode(node); + if (childConcept!=null) { + conceptTitle = childConcept.getName(); + } + titleContent = conceptTitle +" "+titleNode; + } + String titleHtml = titleNode; + if (doc.getDocPageSubTitle()!=null) { + titleHtml = titleNode+" ("+doc.getDocPageSubTitle()+")"; + if (node.getParent()==null) { + titleContent = doc.getDocPageSubTitle(); + titleHtml = "Overview ("+doc.getDocPageSubTitle()+")"; + } } // Write node file - writer.docHtmlStart(config,title, doc.getDocKeywords()); - writer.docPageClassStart(title, titleSub); + writer.docHtmlStart(titleHtml, doc.getDocKeywords(),doc.getNodeData().getPrefixPath()); + docNavBar(writer,true,concept,node); + if (isNodePageMode) { + writer.docPageClassStart(titleContent, null,Tag.h1); + } else { + writer.docPageClassStart(titleContent, titleNodeSub,Tag.h2); + } + writer.docPageContentStart(); - writeNodeTreePath(bodyEvent); - writeNodeDescription(bodyEvent); - writeNodeSummary(bodyEvent); + if (!isNodePageMode) { + writeNodeTreePath(bodyEvent); + } + writeNodeDescription(bodyEvent,isNodePageMode); + writeNodeSummary(bodyEvent,true); // print without div and block lists + writeNodeSummary(bodyEvent,false); writeNodeDetails(bodyEvent); writer.docPageContentEnd(); writer.docPageClassEnd(); - writer.docHtmlEnd(config,doc.getDocCopyright()); + docNavBar(writer,false,concept,node); + writer.docHtmlEnd(doc.getDocCopyright(),doc.getDocStatsJS()); writer.closeWriterSafe(); // Writer other files @@ -152,10 +188,19 @@ public class ApiDocWriter { } } + private boolean isNodePageMode(ApiDocNode node) { + for (Class pageModeClass:doc.getTreeNodePageModeClasses()) { + if (pageModeClass.isAssignableFrom(node.getUserData().getClass())) { + return true; + } + } + return false; + } + private void writeNodeTreePath(ApiDocWriteEvent event) throws SAXException { - List bodyWriterTreePath = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.TREE_PATH); + List bodyWriterTreePath = findNodeBodyWriters(event.getEventObject(),ApiDocNodeBody.TREE_PATH); if (bodyWriterTreePath.isEmpty()) { - defaultWriteTreePath(event.getEvent(),event.getWriter()); + defaultWriteTreePath(event.getEventObject(),event.getWriter()); } for (int i=0;i event) throws SAXException { - event.getWriter().characters(event.getEvent().getDescription()); + event.getWriter().characters(event.getEventObject().getDescription()); } - private void writeNodeDescription(ApiDocWriteEvent event) throws SAXException { + private void writeNodeDescription(ApiDocWriteEvent event,boolean isPageMode) throws SAXException { ApiDocContentWriter writer = event.getWriter(); - List bodyWriterDescriptionLinks = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.DESCRIPTION_LINKS); - List bodyWriterDescriptionNode = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.DESCRIPTION_NODE); + List bodyWriterDescriptionLinks = findNodeBodyWriters(event.getEventObject(),ApiDocNodeBody.DESCRIPTION_LINKS); + List bodyWriterDescriptionNode = findNodeBodyWriters(event.getEventObject(),ApiDocNodeBody.DESCRIPTION_NODE); writer.printTagStart(Tag.div, ApiDocContentCss.description); writer.docPageBlockStart(); - if (bodyWriterDescriptionLinks.isEmpty()) { - //defaultWriteTreePath(node,writer); + if (isPageMode==false) { + if (bodyWriterDescriptionLinks.isEmpty()) { + //defaultWriteTreePath(node,writer); + } + for (int i=0;i event) throws SAXException { + private void writeNodeSummary(ApiDocWriteEvent event,boolean isPage) throws SAXException { ApiDocContentWriter writer = event.getWriter(); - List bodyWriterSummary = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.SUMMARY); - writer.printTagStart(Tag.div, ApiDocContentCss.summary); + List bodyWriterSummary = null; + List bodyWriterSummaryPage = findNodeBodyWriters(event.getEventObject(),ApiDocNodeBody.SUMMARY_PAGE); + List bodyWriterSummaryNormal = findNodeBodyWriters(event.getEventObject(),ApiDocNodeBody.SUMMARY); + if (isPage) { + bodyWriterSummary = bodyWriterSummaryPage; + } else { + bodyWriterSummary = bodyWriterSummaryNormal; + } + if (!isPage) { + writer.printTagStart(Tag.div, ApiDocContentCss.summary); writer.docPageBlockStart(); - if (bodyWriterSummary.isEmpty()) { + } + if (bodyWriterSummary.isEmpty() && !isPage && bodyWriterSummaryPage.isEmpty()) { writer.docPageBlockStart(); - defaultWriteSummary(event.getEvent(),writer); + defaultWriteSummary(event.getEventObject(),writer); writer.docPageBlockEnd(); } for (int i=0;i event,ApiDocNodeWriter writer) throws SAXException { + String group = writer.getContentGroup(); + String groupTypeKey = writer.getContentGroupType(); + if (group==null | groupTypeKey==null) { + return; + } + event.getWriter().printHrefNamed(groupTypeKey+"_"+group); } private void writeNodeDetails(ApiDocWriteEvent event) throws SAXException { ApiDocContentWriter writer = event.getWriter(); - List bodyWriterDetail = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.DETAIL); + List bodyWriterDetail = findNodeBodyWriters(event.getEventObject(),ApiDocNodeBody.DETAIL); if (bodyWriterDetail.isEmpty()) { return;// no default .. } @@ -228,9 +297,10 @@ public class ApiDocWriter { // writer.docPageBlockEnd(); //} for (int i=0;i pathClean = new ArrayList(10); - buildParentPath(node,pathClean); + protected void configNodeData(String prefixPath,File frame) throws SAXException { + ApiDocNodeData conf = doc.getNodeData(); + String framePath = null; + try { + String rootPath = new File(frame.getParentFile().getPath()+File.separatorChar+prefixPath).getCanonicalPath(); + framePath = frame.getPath().substring(rootPath.length()+1); + } catch (IOException e) { + throw new SAXException(e); + } + conf.setPrefixPath(prefixPath); + conf.setFramePath(framePath); - if (concept.getParent()!=null && !concept.getParent().getId().equals(doc.getRootNode().getId())) { - ApiDocConcept conceptParent = concept.getParent(); - conf.navLinks.put(conceptParent.getId(), ApiDocContentWriter.toSafeUri(pathClean)+prefix+"/index.html"); - conf.navTitles.put(conceptParent.getId(), conceptParent.getDescriptionName()); - configActiveNavConceptLinks(conf,node,concept.getParent(),prefix+"/.."); + // Reset hrefs + for (ApiDocNavLink link:doc.getNodeData().getNavLinks()) { + if (link.isResetHref()) { + link.setHref(null); + } } } - private void configNextPrevLinks(NavBarConfig conf,ApiDocNode node) { + + private void configActiveNavConceptLinks(ApiDocNode node,ApiDocConcept concept,String prefix) { + List pathClean = new ArrayList(10); + buildParentPath(node,pathClean); + if (concept.getParent()!=null && !concept.getParent().getId().equals(doc.getRootNode().getId())) { + ApiDocConcept conceptParent = concept.getParent(); + ApiDocNavLink link = doc.getNodeData().getNavLinkById(conceptParent.getId()); + + link.setHref(ApiDocContentWriter.toSafeUri(pathClean)+prefix+"/index.html"); + link.setTitle(node.getParent().getId()); + configActiveNavConceptLinks(node,concept.getParent(),prefix+"/.."); + } + } + + private void configNextPrevLinks(ApiDocNode node) { + doc.getNodeData().setPrevLink(null); + doc.getNodeData().setNextLink(null); if (node.getParent()==null) { return; } @@ -262,7 +356,7 @@ public class ApiDocWriter { ApiDocNode prevNode = pn.get(nodeIdx-1); if (node.getUserData().getClass().equals(prevNode.getUserData().getClass())) { buildParentPath(prevNode,pathClean); - conf.prev = ApiDocContentWriter.toSafeUri(pathClean)+"/index.html"; + doc.getNodeData().setPrevLink(ApiDocContentWriter.toSafeUri(pathClean)+"/index.html"); } } if ((nodeIdx+1) result) { if (node.getParent()!=null) { defaultWriteTreePathBuildPath(node.getParent(),result); + } else if (doc.isSkipRootTreePathNode()) { + return; } result.add(node); } @@ -354,44 +472,11 @@ public class ApiDocWriter { } } - protected NavBarConfig createNavBarConfig(String pathPrefix,File frame,ApiDocContentWriter writer) throws SAXException { - return createNavBarConfig(pathPrefix, null, null, frame, writer); - } - - protected NavBarConfig createNavBarConfig(String pathPrefix,String prev,String next,File frame,ApiDocContentWriter writer) throws SAXException { - String framePath = null; - try { - String rootPath = new File(frame.getParentFile().getPath()+File.separatorChar+pathPrefix).getCanonicalPath(); - framePath = frame.getPath().substring(rootPath.length()+1); - } catch (IOException e) { - throw new SAXException(e); - } - NavBarConfig conf = writer.new NavBarConfig(pathPrefix,prev,next,framePath,doc.getDocAbout()); - conf.noFrameAllLink="allelements-noframe.html"; - conf.noFrameAllName="All Elements"; - conf.linkConstructorName="Tag"; - conf.linkFieldName="Attributes"; - conf.linkMethodName="Config"; - - for (ApiDocConcept concept:doc.getConcepts()) { - String navLink = "overview-"+concept.getId()+".html"; - if (concept.getParent()!=null) { - navLink = null; - } - conf.addNavItem(concept.getId(), navLink, concept.getName()); - } - for (ApiDocPage page:doc.getDocPages()) { - String navLink = page.getId()+".html"; - conf.addNavItem(page.getId(), navLink, page.getName()); - } - return conf; - } - private List findNodeBodyWriters(ApiDocNode node,ApiDocNodeBody nodeBody) { List result = new ArrayList(); final Class objClass = node.getUserData().getClass(); for (ApiDocNodeWriter writer:doc.getNodeBodyWriters()) { - if (!nodeBody.equals(writer.getNodeBody())) { + if (nodeBody!=null && !nodeBody.equals(writer.getNodeBody())) { continue; } for (Class c:writer.getTargetClasses()) { @@ -441,20 +526,20 @@ public class ApiDocWriter { }); return result; } - - private ApiDocConcept findConceptByClass(Class objClass) { - for (ApiDocConcept concept:doc.getConcepts()) { - if (concept.getConceptClass().isAssignableFrom(objClass)) { - return concept; - } - for (Class c:concept.getConceptChildClasses()) { + + private List findDataConfigurators(ApiDocNode node) { + List result = new ArrayList(); + final Class objClass = node.getUserData().getClass(); + for (ApiDocNodeDataConfigurator conf:doc.getDataConfigurators()) { + for (Class c:conf.getTargetClasses()) { if (c.isAssignableFrom(objClass)) { - return concept; + result.add(conf); } } } - return null; + return result; } + private void buildParentPath(ApiDocNode node,List path) { if (node.getParent()==null) { @@ -535,7 +620,7 @@ public class ApiDocWriter { atts.addAttribute ("", "onload", "", "", "top.loadFrames()"); writer.printTagStart(Tag.frameset, atts); - ApiDocConcept rootConcept = findConceptByClass(doc.getFrameNavConceptClass()); + ApiDocConcept navConcept = doc.findConceptByClass(doc.getFrameNavConceptClass()); atts = new AttributesImpl(); atts.addAttribute ("", "rows", "", "", "30%,70%"); atts.addAttribute ("", "title", "", "", "Left frames"); @@ -548,7 +633,7 @@ public class ApiDocWriter { writer.printTagStart(Tag.frame, atts); writer.printTagEnd(Tag.frame); atts = new AttributesImpl(); - atts.addAttribute ("", "src", "", "", "all"+rootConcept.getId()+"-frame.html"); + atts.addAttribute ("", "src", "", "", "all"+navConcept.getId()+"-frame.html"); atts.addAttribute ("", "title", "", "", "All Elements"); atts.addAttribute ("", "name", "", "", ApiDocContentCss.frameNavDetail.name()); writer.printTagStart(Tag.frame, atts); @@ -592,7 +677,7 @@ public class ApiDocWriter { } public void writeOverviewFrame() throws SAXException { - ApiDocConcept concept = findConceptByClass(doc.getFrameNavConceptClass()); + ApiDocConcept concept = doc.findConceptByClass(doc.getFrameNavConceptClass()); ApiDocConcept conceptParent = concept.getParent(); List nodes = new ArrayList(50); findNodeByUserDataClass(doc.getRootNode(),conceptParent.getConceptClass(),nodes); @@ -640,7 +725,7 @@ public class ApiDocWriter { } public void writeAllFrameNav(boolean isFrame) throws SAXException { - ApiDocConcept concept = findConceptByClass(doc.getFrameNavConceptClass()); + ApiDocConcept concept = doc.findConceptByClass(doc.getFrameNavConceptClass()); if (isFrame) { writeAllFrameNav("",true,null,"all"+concept.getId()+"-frame.html"); } else { @@ -649,7 +734,7 @@ public class ApiDocWriter { } private void writeAllFrameNavNode(ApiDocNode node) throws SAXException { - ApiDocConcept concept = findConceptByClass(doc.getFrameNavConceptClass()); + ApiDocConcept concept = doc.findConceptByClass(doc.getFrameNavConceptClass()); ApiDocConcept conceptParent = concept.getParent(); if (!conceptParent.getConceptClass().isAssignableFrom(node.getUserData().getClass())) { return; // only frame nav nodes. @@ -665,7 +750,7 @@ public class ApiDocWriter { } private void writeAllFrameNav(String pathPrefix,boolean isFrame,ApiDocNode searchNode,String...fileName) throws SAXException { - ApiDocConcept concept = findConceptByClass(doc.getFrameNavConceptClass()); + ApiDocConcept concept = doc.findConceptByClass(doc.getFrameNavConceptClass()); //ApiDocConcept conceptParent = concept.getParent(); List nodes = new ArrayList(50); findNodeByUserDataClass(doc.getRootNode(),concept.getConceptClass(),nodes); @@ -755,11 +840,12 @@ public class ApiDocWriter { ApiDocContentWriter writer = createContentWriter(outputFile); String pathPrefix = ""; try { - NavBarConfig conf = createNavBarConfig(pathPrefix, outputFile, writer); - conf.navSelected=page.getId(); + configNodeData(pathPrefix,outputFile); + doc.getNodeData().setNavSelected(page.getId()); String title = page.getName(); - writer.docHtmlStart(conf,title, doc.getDocKeywords()); - writer.docPageClassStart(title, page.getDescription()); + writer.docHtmlStart(title, doc.getDocKeywords(),doc.getNodeData().getPrefixPath()); + docNavBar(writer,true,null,null); + writer.docPageClassStart(title, page.getDescription(),Tag.h1); ApiDocWriteEvent e = new ApiDocWriteEvent(doc,writer,page); @@ -770,7 +856,8 @@ public class ApiDocWriter { //writer.docPageContentEnd(); writer.docPageClassEnd(); - writer.docHtmlEnd(conf, doc.getDocCopyright()); + docNavBar(writer,false,null,null); + writer.docHtmlEnd(doc.getDocCopyright(),doc.getDocStatsJS()); } finally { writer.closeWriterSafe(); } @@ -849,4 +936,147 @@ public class ApiDocWriter { //System.out.println("Creating file: "+outputFile); return outputFile; } + + private void docNavBar(ApiDocContentWriter writer,boolean isTop,ApiDocConcept concept,ApiDocNode node) throws SAXException { + ApiDocNodeData conf = doc.getNodeData(); + String pathPrefix = conf.getPrefixPath(); + String barComment = "TOP"; + String barCssDiv = "topNav"; + String barId = "navbar_top"; + if (isTop==false) { + barComment = "BOTTOM"; + barCssDiv = "bottomNav"; + barId = "navbar_bottom"; + } + writer.comment("========= START OF "+barComment+" NAVBAR ======="); + + writer.printTagStart(Tag.div,barCssDiv); + writer.printHrefNamed(barId); // Print named link navigation + AttributesImpl atts = new AttributesImpl(); + atts.addAttribute ("", "href", "", "", "#skip-"+barId); + atts.addAttribute ("", "title", "", "", "Skip navigation links"); + writer.startElement("", "a", "", atts); + writer.endElement("", "a", ""); + writer.printHrefNamed(barId+"_firstrow"); + + atts = new AttributesImpl();// Print nav bar + atts.addAttribute ("", "class", "", "", "navList"); + atts.addAttribute ("", "title", "", "", "Navigation"); + writer.startElement("", "ul", "", atts); + + for (ApiDocNavLink navLink:conf.getNavLinks()) { + String selectedCss = null; + String href = navLink.getHref(); + if (navLink.getId().equals(conf.getNavSelected())) { + selectedCss = "navBarCell1Rev"; + href = null; // disables link + } + String navTitle = navLink.getTitle(); + if (navTitle==null) { + navTitle = navLink.getText(); + } + if (href==null) { + writer.printTagCharacters(Tag.li, navLink.getText(), selectedCss); + } else { + docNavBarListItemHref(writer,pathPrefix+href,navTitle,navLink.getText(),selectedCss,null,null); + } + } + writer.endElement("", "ul", ""); + + writer.docNavBarAbout(doc.getDocAbout()); + + writer.printTagEnd(Tag.div); // end barCssDiv + + writer.printTagStart(Tag.div,ApiDocContentCss.subNav); + writer.printTagStart(Tag.ul,ApiDocContentCss.navList); + String postFix = ""; + if (concept!=null && doc.isPrintConceptPrevNext()) { + String conceptTitle = concept.getName(); + ApiDocConcept childConcept = doc.findConceptChildByNode(node); + if (childConcept!=null) { + conceptTitle = childConcept.getName(); + } + postFix = " "+conceptTitle; + } + if (conf.getPrevLink()==null) { + writer.printTagCharacters(Tag.li, "Prev"); + } else { + docNavBarListItemHref(writer,pathPrefix+conf.getPrevLink(),"Previous Item","Prev"+postFix,null,"strong",null); + } + if (conf.getNextLink()==null) { + writer.printTagCharacters(Tag.li, "Next"); + } else { + docNavBarListItemHref(writer,pathPrefix+conf.getNextLink(),"Next Item","Next"+postFix,null,"strong",null); + } + writer.printTagEnd(Tag.ul); + if (conf.getFramePath()!=null) { + writer.printTagStart(Tag.ul,ApiDocContentCss.navList); + writer.printTagStart(Tag.li); + writer.printHrefTarget(pathPrefix+"index.html?"+conf.getFramePath(), "Frames", "_top"); + writer.printTagEnd(Tag.li); + writer.printTagStart(Tag.li); + writer.printHrefTarget(pathPrefix+conf.getFramePath(), "No Frames", "_top"); + writer.printTagEnd(Tag.li); + writer.printTagEnd(Tag.ul); + } + if (doc.getNoFrameAllName()!=null && doc.getNoFrameAllLink()!=null) { + writer.printTagStart(Tag.ul,ApiDocContentCss.navList,"allclasses_"+barId); + docNavBarListItemHref(writer,pathPrefix+doc.getNoFrameAllLink(),doc.getNoFrameAllName(),doc.getNoFrameAllName(),null,null,null); + writer.printTagEnd(Tag.ul); + writer.printTagStart(Tag.div); + if (isTop) { + writer.printScriptInline(doc.getNoFrameAllTopJS()); + } else { + writer.printScriptInline(doc.getNoFrameAllBottomJS()); + } + writer.printTagEnd(Tag.div); + } + + String tabSpace = " | "; + List groupKeys = conf.getGroupTypeKeys(); + boolean printLink = groupKeys.isEmpty()==false; + if (printLink) { + writer.printTagStart(Tag.div); + writer.printTagStart(Tag.ul,ApiDocContentCss.subNavList); + for (int i=0;i links = conf.getGroupTypeLinks(groupKey); + if (links.isEmpty()==false) { + writer.printTagStart(Tag.li);writer.characters(groupName+": ");writer.printTagEnd(Tag.li); + for (int l=0;l e) throws SAXException { ApiDoc doc = e.getDoc(); - ApiDocPage page = e.getEvent(); + ApiDocPage page = e.getEventObject(); ApiDocContentWriter writer = e.getWriter(); //writer.docPagePackageTitle(title, "Overview Tree"); writer.docPageContentStart(); @@ -69,8 +69,13 @@ public class DefaultPageWriterTree implements ApiDocPageWriter { } } + StringBuffer buf = new StringBuffer(); + if (!doc.getRootNode().equals(node)) { + buildParentPath(node,buf); + } + buf.append("index.html"); - String href = ApiDocContentWriter.toSafeUri("todo");// toElementUri(pathPrefix,node.module,node.namespace,node.elementClass); + String href = buf.toString(); writer.printTagStart(Tag.ul); writer.printTagStart(Tag.li,"",null,"circle"); @@ -86,4 +91,15 @@ public class DefaultPageWriterTree implements ApiDocPageWriter { } writer.printTagEnd(Tag.ul); } + + private void buildParentPath(ApiDocNode node,StringBuffer buf) { + if (node.getParent()==null) { + buf.append(ApiDocContentWriter.toSafeUri(node.getId())); + buf.append('/'); + return; + } + buildParentPath(node.getParent(),buf); + buf.append(ApiDocContentWriter.toSafeUri(node.getId())); + buf.append('/'); + } } diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDoc.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDoc.java index 2d03755..e36cf5a 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDoc.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDoc.java @@ -22,10 +22,16 @@ */ package org.x4o.xml.eld.doc.api.dom; +import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; + +import org.x4o.xml.eld.doc.api.ApiDocNodeDataConfiguratorBean; +import org.x4o.xml.eld.doc.api.ApiDocNodeWriterBean; /** * ApiDoc holds all config and data to write a full api doc structure. @@ -51,6 +57,22 @@ public class ApiDoc { private Boolean frameNavPrintParent = null; private Boolean frameNavPrintParentParent = null; private List> treeNodeClassExcludes = null; + private List> treeNodePageModeClass = null; + private List dataConfigurators = null; + private List> annotatedClasses = null; + private ApiDocNodeData nodeData = null; + private String docStatsJS = null; + private String noFrameAllName = null; + private String noFrameAllLink = null; + private String noFrameAllTopJS = null; + private String noFrameAllBottomJS = null; + private boolean fillOnce = false; + private List remoteClasses = null; + private boolean skipRootTreePathNode = true; + private boolean printConceptTitle = true; + private boolean printConceptPrevNext = true; + private Map groupTypeNames = null; + private String docPageSubTitle = null; public ApiDoc() { nodeBodyWriters = new ArrayList(20); @@ -58,6 +80,11 @@ public class ApiDoc { docKeywords = new ArrayList(5); docPages = new ArrayList(5); treeNodeClassExcludes = new ArrayList>(5); + treeNodePageModeClass = new ArrayList>(5); + dataConfigurators = new ArrayList(5); + annotatedClasses = new ArrayList>(5); + remoteClasses = new ArrayList(5); + groupTypeNames = new HashMap(3); } public void checkModel() throws NullPointerException,IllegalArgumentException { @@ -67,12 +94,11 @@ public class ApiDoc { checkNull(docCopyright,"docCopyright"); checkNull(rootNode,"rootNode"); checkNull(frameNavConceptClass,"frameNavConceptClass"); + checkNull(noFrameAllName,"noFrameAllName"); + if (concepts.isEmpty()) { throw new IllegalStateException("Can't work with empty concepts"); } - if (nodeBodyWriters.isEmpty()) { - throw new IllegalStateException("Can't work with empty nodeBodyWriters"); - } if (frameNavOverviewPrintParent==null) { setFrameNavOverviewPrintParent(false); } @@ -85,6 +111,69 @@ public class ApiDoc { if (frameNavPrintParentId==null) { setFrameNavPrintParentId(false); } + + if (noFrameAllTopJS==null) { + noFrameAllTopJS = "\nallClassesLink = document.getElementById(\"allclasses_navbar_top\");\n"+ + "if(window==top) {\n\tallClassesLink.style.display = \"block\";\n} else {\n\tallClassesLink.style.display = \"none\";\n}\n"; + } + if (noFrameAllBottomJS==null) { + noFrameAllBottomJS = "\nallClassesLink = document.getElementById(\"allclasses_navbar_bottom\");\n"+ + "if(window==top) {\n\tallClassesLink.style.display = \"block\";\n} else {\n\tallClassesLink.style.display = \"none\";\n}\n"; + } + if (noFrameAllLink==null) { + ApiDocConcept navConcept = findConceptByClass(getFrameNavConceptClass()); + setNoFrameAllLink("all"+navConcept.getId()+"-noframe.html"); + } + + fillRuntimeData(); + + if (nodeBodyWriters.isEmpty()) { + fillOnce = false; + dataConfigurators.clear(); + throw new IllegalStateException("Can't work with empty nodeBodyWriters"); + } + } + + private void fillRuntimeData() { + if (fillOnce) { + return; + } + setNodeData(new ApiDocNodeData()); + try { + for (Class annoClass:getAnnotatedClasses()) { + Object bean = annoClass.newInstance(); + ApiDocNodeWriterBean.addAnnotatedNodeContentWriters(this,bean); + ApiDocNodeDataConfiguratorBean.addAnnotatedNodeDataConfigurators(this, bean); + } + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + for (ApiDocConcept concept:getConcepts()) { + String navLink = "overview-"+concept.getId()+".html"; + boolean resetHref = true; + if (concept.getParent()==null) { + resetHref = false; // don't reset root node + } else { + navLink = null; // rest start with null href's + } + ApiDocNavLink link = new ApiDocNavLink(concept.getId(), navLink, concept.getName(),concept.getName(),resetHref); + getNodeData().addNavLink(link); + } + for (ApiDocPage page:getDocPages()) { + String navLink = page.getId()+".html"; + ApiDocNavLink link = new ApiDocNavLink(page.getId(), navLink, page.getName(),page.getName(),false); + getNodeData().addNavLink(link); + } + for (ApiDocRemoteClass rc:getRemoteClasses()) { + try { + rc.parseRemotePackageList(); + } catch (IOException e) { + throw new IllegalStateException("While parsing: "+rc.getDocUrl()+" got: "+e.getMessage(),e); + } + } + fillOnce = true; } private void checkNull(Object obj,String objName) { @@ -93,6 +182,75 @@ public class ApiDoc { } } + public ApiDocConcept findConceptByClass(Class objClass) { + for (ApiDocConcept concept:getConcepts()) { + if (concept.getConceptClass().isAssignableFrom(objClass)) { + return concept; + } + for (ApiDocConcept c:concept.getChildConcepts()) { + if (c.getConceptClass().isAssignableFrom(objClass)) { + return concept; + } + } + } + return null; + } + + public ApiDocConcept findConceptChildByNode(ApiDocNode node) { + Class objClass = node.getUserData().getClass(); + Class parentClass = null; + if (node.getParent()!=null) { + parentClass = node.getParent().getUserData().getClass(); + } + for (ApiDocConcept concept:getConcepts()) { + if (parentClass!=null && concept.getConceptClass().isAssignableFrom(parentClass)==false) { + continue; + } + for (ApiDocConcept c:concept.getChildConcepts()) { + if (c.getConceptClass().isAssignableFrom(objClass)) { + return c; + } + } + } + return null; + } + + public List getRemoteClasses() { + return remoteClasses; + } + + public void addRemoteClass(ApiDocRemoteClass remoteClass) { + remoteClasses.add(remoteClass); + } + + public void removeRemoteClass(ApiDocRemoteClass remoteClass) { + remoteClasses.add(remoteClass); + } + + public List> getAnnotatedClasses() { + return annotatedClasses; + } + + public void removeAnnotatedClasses(Class annotatedClass) { + annotatedClasses.remove(annotatedClass); + } + + public void addAnnotatedClasses(Class annotatedClass) { + annotatedClasses.add(annotatedClass); + } + + public List getDataConfigurators() { + return dataConfigurators; + } + + public void removeDataConfigurator(ApiDocNodeDataConfigurator conf) { + dataConfigurators.remove(conf); + } + + public void addDataConfigurator(ApiDocNodeDataConfigurator conf) { + dataConfigurators.add(conf); + } + public ApiDocNodeWriter addNodeBodyWriter(ApiDocNodeWriter writer) { nodeBodyWriters.add(writer); return writer; @@ -217,6 +375,19 @@ public class ApiDoc { return treeNodeClassExcludes; } + public Class addTreeNodePageModeClass(Class pageModeClass) { + treeNodePageModeClass.add(pageModeClass); + return pageModeClass; + } + + public boolean removeTreeNodePageModeClass(Class pageModeClass) { + return treeNodePageModeClass.remove(pageModeClass); + } + + public List> getTreeNodePageModeClasses() { + return treeNodePageModeClass; + } + /** * @return the name */ @@ -342,4 +513,156 @@ public class ApiDoc { public void setFrameNavPrintParentId(Boolean frameNavPrintParentId) { this.frameNavPrintParentId = frameNavPrintParentId; } + + /** + * @return the nodeData + */ + public ApiDocNodeData getNodeData() { + return nodeData; + } + + /** + * @param nodeData the nodeData to set + */ + public void setNodeData(ApiDocNodeData nodeData) { + this.nodeData = nodeData; + } + + /** + * @return the docStatsJS + */ + public String getDocStatsJS() { + return docStatsJS; + } + + /** + * @param docStatsJS the docStatsJS to set + */ + public void setDocStatsJS(String docStatsJS) { + this.docStatsJS = docStatsJS; + } + + /** + * @return the noFrameAllName + */ + public String getNoFrameAllName() { + return noFrameAllName; + } + + /** + * @param noFrameAllName the noFrameAllName to set + */ + public void setNoFrameAllName(String noFrameAllName) { + this.noFrameAllName = noFrameAllName; + } + + /** + * @return the noFrameAllLink + */ + public String getNoFrameAllLink() { + return noFrameAllLink; + } + + /** + * @param noFrameAllLink the noFrameAllLink to set + */ + public void setNoFrameAllLink(String noFrameAllLink) { + this.noFrameAllLink = noFrameAllLink; + } + + /** + * @return the noFrameAllTopJS + */ + public String getNoFrameAllTopJS() { + return noFrameAllTopJS; + } + + /** + * @param noFrameAllTopJS the noFrameAllTopJS to set + */ + public void setNoFrameAllTopJS(String noFrameAllTopJS) { + this.noFrameAllTopJS = noFrameAllTopJS; + } + + /** + * @return the noFrameAllBottomJS + */ + public String getNoFrameAllBottomJS() { + return noFrameAllBottomJS; + } + + /** + * @param noFrameAllBottomJS the noFrameAllBottomJS to set + */ + public void setNoFrameAllBottomJS(String noFrameAllBottomJS) { + this.noFrameAllBottomJS = noFrameAllBottomJS; + } + + /** + * @return the skipRootTreePathNode + */ + public boolean isSkipRootTreePathNode() { + return skipRootTreePathNode; + } + + /** + * @param skipRootTreePathNode the skipRootTreePathNode to set + */ + public void setSkipRootTreePathNode(boolean skipRootTreePathNode) { + this.skipRootTreePathNode = skipRootTreePathNode; + } + + /** + * @return the printConceptTitle + */ + public boolean isPrintConceptTitle() { + return printConceptTitle; + } + + /** + * @param printConceptTitle the printConceptTitle to set + */ + public void setPrintConceptTitle(boolean printConceptTitle) { + this.printConceptTitle = printConceptTitle; + } + + /** + * @return the printConceptPrevNext + */ + public boolean isPrintConceptPrevNext() { + return printConceptPrevNext; + } + + /** + * @param printConceptPrevNext the printConceptPrevNext to set + */ + public void setPrintConceptPrevNext(boolean printConceptPrevNext) { + this.printConceptPrevNext = printConceptPrevNext; + } + + public String getGroupTypeName(String groupTypeKey) { + String result = groupTypeNames.get(groupTypeKey); + if (result==null) { + result = groupTypeKey; + } + return result; + } + + public void setGroupTypeName(String groupTypeKey,String name) { + groupTypeNames.put(groupTypeKey,name); + } + + /** + * @return the docPageSubTitle + */ + public String getDocPageSubTitle() { + return docPageSubTitle; + } + + /** + * @param docPageSubTitle the docPageSubTitle to set + */ + public void setDocPageSubTitle(String docPageSubTitle) { + this.docPageSubTitle = docPageSubTitle; + } } diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocConcept.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocConcept.java index ccc9bcd..836b4e9 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocConcept.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocConcept.java @@ -39,10 +39,10 @@ public class ApiDocConcept { private String descriptionHelp = null; private ApiDocConcept parent = null; private Class conceptClass = null; - private List> conceptChildClasses = null; + private List childConcepts = null; public ApiDocConcept() { - conceptChildClasses = new ArrayList>(5); + childConcepts = new ArrayList(5); } public ApiDocConcept(ApiDocConcept parent,String id,Class conceptClass) { @@ -52,18 +52,15 @@ public class ApiDocConcept { setParent(parent); } - public ApiDocConcept(ApiDocConcept parent,String[] text,Class conceptClass,Class...classes) { - this(parent,text[0],text[1],text[2],text[3],conceptClass,classes); + public ApiDocConcept(ApiDocConcept parent,String[] text,Class conceptClass) { + this(parent,text[0],text[1],text[2],text[3],conceptClass); } - public ApiDocConcept(ApiDocConcept parent,String id,String name,String descriptionName,String descriptionHelp,Class conceptClass,Class...classes) { + public ApiDocConcept(ApiDocConcept parent,String id,String name,String descriptionName,String descriptionHelp,Class conceptClass) { this(parent,id,conceptClass); setName(name); setDescriptionName(descriptionName); setDescriptionHelp(descriptionHelp); - for (Class cl:classes) { - addConceptChildClass(cl); - } } /** @@ -136,16 +133,16 @@ public class ApiDocConcept { this.conceptClass = conceptClass; } - public void addConceptChildClass(Class targetClass) { - conceptChildClasses.add(targetClass); + public void addChildConcepts(ApiDocConcept childConcept) { + childConcepts.add(childConcept); } - public void removeConceptChildClass(Class targetClass) { - conceptChildClasses.remove(conceptChildClasses); + public void removeChildConcept(ApiDocConcept childConcept) { + childConcepts.remove(childConcept); } - public List> getConceptChildClasses() { - return conceptChildClasses; + public List getChildConcepts() { + return childConcepts; } /** diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNavLink.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNavLink.java new file mode 100644 index 0000000..717aa81 --- /dev/null +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNavLink.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2004-2013, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.x4o.xml.eld.doc.api.dom; + +/** + * ApiDocNavLink holds all fields of an navigation link. + * + * @author Willem Cazander + * @version 1.0 Aug 11, 2013 + */ +public class ApiDocNavLink { + + private String id = null; + private String href = null; + private String title = null; + private String text = null; + private boolean resetHref = false; + + public ApiDocNavLink() { + } + + public ApiDocNavLink(String id,String href,String title,String text,boolean resetHref) { + setId(id); + setHref(href); + setTitle(title); + setText(text); + } + + /** + * @return the id + */ + public String getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(String id) { + this.id = id; + } + + /** + * @return the href + */ + public String getHref() { + return href; + } + + /** + * @param href the href to set + */ + public void setHref(String href) { + this.href = href; + } + + /** + * @return the title + */ + public String getTitle() { + return title; + } + + /** + * @param title the title to set + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return the text + */ + public String getText() { + return text; + } + + /** + * @param text the text to set + */ + public void setText(String text) { + this.text = text; + } + + /** + * @return the resetHref + */ + public boolean isResetHref() { + return resetHref; + } + + /** + * @param resetHref the resetHref to set + */ + public void setResetHref(boolean resetHref) { + this.resetHref = resetHref; + } +} diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeBody.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeBody.java index 7f98803..a2214e8 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeBody.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeBody.java @@ -34,5 +34,10 @@ public enum ApiDocNodeBody { DESCRIPTION_LINKS, DESCRIPTION_NODE, SUMMARY, - DETAIL + DETAIL, + + /** + * Summary page blocks had no div and no block lists around content. + */ + SUMMARY_PAGE } diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeData.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeData.java new file mode 100644 index 0000000..c88d071 --- /dev/null +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeData.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2004-2013, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.x4o.xml.eld.doc.api.dom; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * ApiDocNodeData holds all data the is configed per node page. + * + * @author Willem Cazander + * @version 1.0 Aug 11, 2013 + */ +public class ApiDocNodeData { + + private String prefixPath; + private String navSelected = null; + private List groupTypeKeys = null; + private Map> groupTypeLinks = null; + private String prevLink = null; + private String nextLink = null; + private String framePath = null;; + private List navLinks = null; + + public ApiDocNodeData() { + navLinks = new ArrayList(12); + groupTypeKeys = new ArrayList(navLinks.size()/3); + groupTypeLinks = new HashMap>(groupTypeKeys.size()); + } + + public void addGroupTypeKey(String groupTypeKey) { + groupTypeKeys.add(groupTypeKey); + } + + public List getGroupTypeKeys() { + return groupTypeKeys; + } + + public void addGroupTypeLink(String groupTypeKey,ApiDocNavLink link) { + List result = groupTypeLinks.get(groupTypeKey); + if (result==null) { + result = new ArrayList(10); + groupTypeLinks.put(groupTypeKey, result); + } + result.add(link); + } + + public List getGroupTypeLinks(String groupTypeKey) { + List result = groupTypeLinks.get(groupTypeKey); + if (result==null) { + result = new ArrayList(0); + } + return result; + } + + public ApiDocNavLink getGroupTypeLink(String groupTypeKey,String group) { + List links = getGroupTypeLinks(groupTypeKey); + for (ApiDocNavLink link:links) { + if (link.getId().equals(group)) { + return link; + } + } + return null; + } + + public void clearGroupTypeLinks() { + groupTypeLinks.clear(); + } + + public List getNavLinks() { + return navLinks; + } + + public ApiDocNavLink getNavLinkById(String id) { + for (ApiDocNavLink link:navLinks) { + if (link.getId().equals(id)) { + return link; + } + } + return null; + } + + public void addNavLink(ApiDocNavLink link) { + navLinks.add(link); + } + + public void removeNavLink(ApiDocNavLink link) { + navLinks.remove(link); + } + + /** + * @return the prefixPath + */ + public String getPrefixPath() { + return prefixPath; + } + + /** + * @param prefixPath the prefixPath to set + */ + public void setPrefixPath(String prefixPath) { + this.prefixPath = prefixPath; + } + + /** + * @return the navSelected + */ + public String getNavSelected() { + return navSelected; + } + + /** + * @param navSelected the navSelected to set + */ + public void setNavSelected(String navSelected) { + this.navSelected = navSelected; + } + + /** + * @return the prevLink + */ + public String getPrevLink() { + return prevLink; + } + + /** + * @param prevLink the prevLink to set + */ + public void setPrevLink(String prevLink) { + this.prevLink = prevLink; + } + + /** + * @return the nextLink + */ + public String getNextLink() { + return nextLink; + } + + /** + * @param nextLink the nextLink to set + */ + public void setNextLink(String nextLink) { + this.nextLink = nextLink; + } + + /** + * @return the framePath + */ + public String getFramePath() { + return framePath; + } + + /** + * @param framePath the framePath to set + */ + public void setFramePath(String framePath) { + this.framePath = framePath; + } +} diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeDataConfigurator.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeDataConfigurator.java new file mode 100644 index 0000000..d1dd369 --- /dev/null +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeDataConfigurator.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2004-2013, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.x4o.xml.eld.doc.api.dom; + +import java.util.List; + +/** + * ApiDocNodeDataConfigurator is for per node config of data. + * + * @author Willem Cazander + * @version 1.0 Aug 11, 2013 + */ +public interface ApiDocNodeDataConfigurator { + + List> getTargetClasses(); + + void configNodeData(ApiDoc doc,ApiDocNode node,ApiDocNodeData data); +} diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeWriter.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeWriter.java index fa668f0..fd220ca 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeWriter.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocNodeWriter.java @@ -37,6 +37,8 @@ public interface ApiDocNodeWriter { ApiDocNodeBody getNodeBody(); List> getTargetClasses(); List getNodeBodyOrders(); + String getContentGroup(); + String getContentGroupType(); void writeNodeContent(ApiDocWriteEvent e) throws SAXException; } diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocRemoteClass.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocRemoteClass.java new file mode 100644 index 0000000..89a1d66 --- /dev/null +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocRemoteClass.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2004-2013, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.x4o.xml.eld.doc.api.dom; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +/** + * ApiDocRemoteUrl defines the javadoc package-list remote url. + * + * @author Willem Cazander + * @version 1.0 Aug 15, 2013 + */ +public class ApiDocRemoteClass { + + public final static String REMOTE_FILE = "package-list"; + private Logger logger = Logger.getLogger(ApiDocRemoteClass.class.getName()); + private String docUrl = null; + private String packageListUrl = null; + private List packageList = null; + + private ApiDocRemoteClass() { + packageList = new ArrayList(100); + } + + public ApiDocRemoteClass(String docUrl) { + this(); + setDocUrl(docUrl); + } + + public ApiDocRemoteClass(String docUrl,String packageListUrl) { + this(docUrl); + setPackageListUrl(packageListUrl); + } + + /** + * Returns remote url for a class or null if no remote package excists for the class. + * @param cls The class to get the remote url for. + * @return The remote url of the class requested or null if none if found. + */ + public String getRemoteUrl(Class cls) { + if (cls==null) { + return null; + } + if (cls.isArray()) { + return null; + } + if (cls.getPackage()==null) { + return null; + } + String packageName = cls.getPackage().getName(); + logger.fine("Search "+packageName+" in "+packageList.size()+" of "+docUrl); + if (packageList.contains(packageName)) { + String baseUrl = getDocUrlClean(); + String packagePath = packageName.replaceAll("\\.", "/"); + String fullUrl = baseUrl+packagePath+"/"+cls.getSimpleName()+".html"; + return fullUrl; + } + return null; + } + + private String getDocUrlClean() { + String baseUrl = getDocUrl(); + if (baseUrl.endsWith("/")==false) { + baseUrl += "/"; + } + return baseUrl; + } + + public void parseRemotePackageList() throws IOException { + packageList.clear(); + String baseUrl = getDocUrlClean(); + baseUrl += REMOTE_FILE; + URL url = new URL(baseUrl); + URLConnection conn = url.openConnection(); + conn.setConnectTimeout(2000); + conn.setReadTimeout(2000); + parseRemoteFile(conn.getInputStream(), conn.getContentEncoding()); + } + + private void parseRemoteFile(InputStream in,String enc) throws IOException { + if (enc==null) { + enc = "UTF-8"; + } + BufferedReader br = new BufferedReader(new InputStreamReader(in,Charset.forName(enc))); + try { + String line = null; + while ((line = br.readLine()) != null) { + String lineClean = line.trim(); + packageList.add(lineClean); + logger.finer("Adding remote package: '"+lineClean+"'"); + } + } finally { + br.close(); + } + } + + /** + * @return the docUrl + */ + public String getDocUrl() { + return docUrl; + } + + /** + * @param docUrl the docUrl to set + */ + public void setDocUrl(String docUrl) { + this.docUrl = docUrl; + } + + /** + * @return the packageListUrl + */ + public String getPackageListUrl() { + return packageListUrl; + } + + /** + * @param packageListUrl the packageListUrl to set + */ + public void setPackageListUrl(String packageListUrl) { + this.packageListUrl = packageListUrl; + } + + /** + * @return the packageList + */ + public List getPackageList() { + return packageList; + } +} diff --git a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocWriteEvent.java b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocWriteEvent.java index 9b88f3b..f22bd11 100644 --- a/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocWriteEvent.java +++ b/x4o-eld-doc/src/main/java/org/x4o/xml/eld/doc/api/dom/ApiDocWriteEvent.java @@ -33,7 +33,7 @@ import org.x4o.xml.eld.doc.api.ApiDocContentWriter; public class ApiDocWriteEvent { private ApiDoc doc = null; - private T event = null; + private T eventObject = null; private ApiDocContentWriter writer = null; /** @@ -42,10 +42,10 @@ public class ApiDocWriteEvent { * @param writer The content writer to write to. * @param event The event we are firing this event for. */ - public ApiDocWriteEvent(ApiDoc doc,ApiDocContentWriter writer,T event) { + public ApiDocWriteEvent(ApiDoc doc,ApiDocContentWriter writer,T eventObject) { this.doc=doc; this.writer=writer; - this.event=event; + this.eventObject=eventObject; } /** @@ -58,8 +58,8 @@ public class ApiDocWriteEvent { /** * @return the event */ - public T getEvent() { - return event; + public T getEventObject() { + return eventObject; } /**