Added more ApiDoc methods and made eld api doc writers more complete.

This commit is contained in:
Willem Cazander 2013-08-17 17:41:25 +02:00
parent d4f80f338a
commit 024865084a
27 changed files with 2119 additions and 567 deletions

View file

@ -314,6 +314,20 @@ public final class XMLConstants {
StringBuffer result = new StringBuffer(length);
for (int i=0;i<length;i++) {
char c = value.charAt(i);
if (c=='&') {
StringBuffer buf = new StringBuffer(length);
int iOrg = i;
i = charEntityLookup(i,value,buf);
String entity = buf.toString();
if (entity.length()>0) {
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 ("&lt;".equals(entity)) { return true; }
if ("&gt;".equals(entity)) { return true; }
if ("&amp;".equals(entity)) { return true; }
if ("&quote;".equals(entity)) { return true; }
if ("&apos;".equals(entity)) { return true; }
// HTML
if ("&acute;".equals(entity)) { return true; }
if ("&alefsym;".equals(entity)) { return true; }
if ("&asymp;".equals(entity)) { return true; }
if ("&ang;".equals(entity)) { return true; }
if ("&lowast;".equals(entity)) { return true; }
if ("&clubs;".equals(entity)) { return true; }
if ("&diams;".equals(entity)) { return true; }
if ("&hearts;".equals(entity)) { return true; }
if ("&spades;".equals(entity)) { return true; }
// TODO: etc/etc
if ("&yuml;".equals(entity)) { return true; }
if ("&yacute;".equals(entity)) { return true; }
if ("&ugrave;".equals(entity)) { return true; }
if ("&uuml;".equals(entity)) { return true; }
if ("&ucirc;".equals(entity)) { return true; }
if ("&uacute;".equals(entity)) { return true; }
if ("&divide;".equals(entity)) { return true; }
if ("&nbsp;".equals(entity)) { return true; }
if ("&reg;".equals(entity)) { return true; }
if ("&trade;".equals(entity)) { return true; }
if ("&copy;".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.length() && i<(iStart+iMax);i++) {
char c = value.charAt(i);
result.append(c);
if (c==';') {
buf.append(result);
return i;
}
}
return iStart; // not found continue escaping.
}
static public String escapeCharactersCdata(String value,String replaceCdataStart,String replaceCdataEnd) {
value = value.replaceAll(CDATA_START_REGEX, replaceCdataStart);
value = value.replaceAll(CDATA_END_REGEX, replaceCdataEnd);

View file

@ -367,7 +367,7 @@ public class AbstractContentWriterHandler implements ContentHandler {
}
// move or remove ?
public void charactersRaw(String text) throws SAXException {
protected void charactersRaw(String text) throws SAXException {
if (text==null) {
return;
}

View file

@ -27,7 +27,6 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;

View file

@ -24,15 +24,10 @@ package org.x4o.xml.eld.doc;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import org.x4o.xml.eld.doc.api.ApiDocContentWriter;
import org.x4o.xml.eld.doc.api.ApiDocNodeWriterBean;
import org.x4o.xml.eld.doc.api.ApiDocNodeWriterMethod;
import org.x4o.xml.eld.doc.api.ApiDocWriter;
import org.x4o.xml.eld.doc.api.DefaultPageWriterHelp;
import org.x4o.xml.eld.doc.api.DefaultPageWriterIndexAll;
@ -40,12 +35,12 @@ import org.x4o.xml.eld.doc.api.DefaultPageWriterTree;
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.ApiDocNode;
import org.x4o.xml.eld.doc.api.dom.ApiDocNodeBody;
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.ElementClass;
import org.x4o.xml.element.ElementClassAttribute;
import org.x4o.xml.element.ElementConfigurator;
import org.x4o.xml.element.ElementConfiguratorGlobal;
import org.x4o.xml.element.ElementInterface;
import org.x4o.xml.element.ElementException;
import org.x4o.xml.element.ElementNamespaceContext;
@ -61,12 +56,23 @@ import org.xml.sax.SAXException;
*/
public class EldDocWriter {
// The context to write doc over.
private X4OLanguageContext context = null;
// Core concepts
private static final String[] C_CONTEXT = {"language","Overview","All language modules.","The loaded language modules.."};
private static final String[] C_MODULE = {"module","Module","The Language Modules.","The language is build by the modules and provides the namespaces."};
private static final String[] C_INTERFACE = {"interface","Interface","The element interface.","The element interface."};
private static final String[] C_NAMESPACE = {"namespace","Namespace","The Language Namespace.","The language namespace holds all the xml elements."};
private static final String[] C_ELEMENT = {"element","Element","The Language Element.","The xml language element description."};
// Child concepts
private static final String[] CC_ATTRIBUTE_H = {"attribute-handler","Attribute Handler","The attribute handler.","The attribute handler."};
private static final String[] CC_ATTRIBUTE = {"attribute","Attribute","The attribute config.","The attribute config."};
private static final String[] CC_CONFIGURATOR = {"configurator","Configurator","The element configurator.","The element configurator."};
private static final String[] CC_CONFIGURATOR_G = {"configurator-global","ConfiguratorGlobal","The global configurator.","The global configurator."};
private static final String[] CC_BINDING = {"binding","Binding","The element binding.","The element binding."};
/**
* Creates an EldDocGenerator for this langauge context.
* @param context The language context to generate doc for.
@ -84,7 +90,6 @@ public class EldDocWriter {
try {
ApiDocWriter writer = new ApiDocWriter();
ApiDoc doc = buildLanguageDoc();
doc.checkModel();
writer.write(doc, basePath);
} catch (SAXException e) {
throw new ElementException(e);
@ -99,37 +104,65 @@ public class EldDocWriter {
doc.setDescription("X4O Meta Language Description");
doc.setDocAbout(createLanguageAbout());
doc.setDocCopyright(createLanguageCopyright());
doc.setDocPageSubTitle(createPageSubTitle());
doc.addDocKeywordAll(createLanguageKeywords());
doc.setNoFrameAllName("All Elements");
doc.setFrameNavPrintParent(true);
doc.setFrameNavPrintParentId(true);
doc.setGroupTypeName("summary", "Summary");
doc.setGroupTypeName("overview", "Overview");
// TODO: add config bean to task launcher
//doc.addRemoteClass(new ApiDocRemoteClass("file:///home/willemc/devv/git/x4o/x4o-driver/target/apidocs"));
//doc.addRemoteClass(new ApiDocRemoteClass("http://docs.oracle.com/javase/7/docs/api/"));
doc.setFrameNavConceptClass(ElementClass.class);
ApiDocNodeWriterBean.addAnnotatedNodeContentWriters(doc,new EldDocWriterLanguage());
ApiDocNodeWriterBean.addAnnotatedNodeContentWriters(doc,new EldDocWriterElementClass());
ApiDocNodeWriterBean.addAnnotatedNodeContentWriters(doc,this);
ApiDocConcept adc1 = doc.addConcept(new ApiDocConcept(null,C_CONTEXT,X4OLanguageContext.class));
ApiDocConcept adc2 = doc.addConcept(new ApiDocConcept(adc1,C_MODULE,X4OLanguageModule.class,
ElementAttributeHandler.class,ElementConfigurator.class,ElementInterface.class,ElementBindingHandler.class));
ApiDocConcept adc3 = doc.addConcept(new ApiDocConcept(adc2,C_NAMESPACE,ElementNamespaceContext.class));
doc.addConcept(new ApiDocConcept(adc3,C_ELEMENT,ElementClass.class));
doc.addTreeNodePageModeClass(X4OLanguageContext.class);
doc.addTreeNodePageModeClass(X4OLanguageModule.class);
doc.addTreeNodePageModeClass(ElementInterface.class);
doc.addTreeNodePageModeClass(ElementNamespaceContext.class);
doc.addAnnotatedClasses(EldDocWriterLanguage.class);
doc.addAnnotatedClasses(EldDocWriterLanguageModule.class);
doc.addAnnotatedClasses(EldDocWriterElementClass.class);
doc.addAnnotatedClasses(EldDocWriterElementNamespace.class);
doc.addAnnotatedClasses(EldDocWriterElementInterface.class);
ApiDocConcept adcRoot = doc.addConcept(new ApiDocConcept(null,C_CONTEXT,X4OLanguageContext.class));
ApiDocConcept adcMod = doc.addConcept(new ApiDocConcept(adcRoot,C_MODULE,X4OLanguageModule.class));
ApiDocConcept adcIface = doc.addConcept(new ApiDocConcept(adcMod,C_INTERFACE,ElementInterface.class));
ApiDocConcept adcNs = doc.addConcept(new ApiDocConcept(adcMod,C_NAMESPACE,ElementNamespaceContext.class));
ApiDocConcept adcEc = doc.addConcept(new ApiDocConcept(adcNs,C_ELEMENT,ElementClass.class));
// mm maybe redo something here
adcMod.addChildConcepts(new ApiDocConcept(adcMod,CC_ATTRIBUTE_H,ElementAttributeHandler.class));
adcMod.addChildConcepts(new ApiDocConcept(adcMod,CC_CONFIGURATOR_G,ElementConfiguratorGlobal.class));
adcMod.addChildConcepts(new ApiDocConcept(adcMod,CC_BINDING,ElementBindingHandler.class));
adcIface.addChildConcepts(new ApiDocConcept(adcMod,CC_ATTRIBUTE,ElementClassAttribute.class));
adcIface.addChildConcepts(new ApiDocConcept(adcMod,CC_CONFIGURATOR,ElementConfigurator.class));
adcIface.addChildConcepts(new ApiDocConcept(adcMod,CC_BINDING,ElementBindingHandler.class));
adcEc.addChildConcepts(new ApiDocConcept(adcEc,CC_CONFIGURATOR,ElementConfigurator.class));
adcEc.addChildConcepts(new ApiDocConcept(adcEc,CC_ATTRIBUTE,ElementClassAttribute.class));
doc.addDocPage(EldDocXTreePageWriter.createDocPage());
doc.addDocPage(DefaultPageWriterTree.createDocPage());
doc.addDocPage(DefaultPageWriterIndexAll.createDocPage());
doc.addDocPage(DefaultPageWriterHelp.createDocPage());
ApiDocNode rootNode = new ApiDocNode(context,"language","Language","The X4O Language");
ApiDocNode rootNode = new ApiDocNode(context,"language",getLanguageNameUpperCase()+" Language","The X4O "+getLanguageNameUpperCase()+" Language");
doc.setRootNode(rootNode);
for (X4OLanguageModule mod:context.getLanguage().getLanguageModules()) { ApiDocNode modNode = rootNode.addNode(createNodeLanguageModule(mod));
for (ElementBindingHandler bind:mod.getElementBindingHandlers()) { modNode.addNode(createNodeElementBindingHandler(bind)); }
for (ElementAttributeHandler attr:mod.getElementAttributeHandlers()) { modNode.addNode(createNodeElementAttributeHandler(attr)); }
for (ElementConfigurator conf:mod.getElementConfiguratorGlobals()) { modNode.addNode(createNodeElementConfigurator(conf)); }
for (ElementConfiguratorGlobal conf:mod.getElementConfiguratorGlobals()) { modNode.addNode(createNodeElementConfiguratorGlobal(conf)); }
for (ElementInterface iface:mod.getElementInterfaces()) { ApiDocNode ifaceNode = modNode.addNode(createNodeElementInterface(iface));
for (ElementClassAttribute eca:iface.getElementClassAttributes()) { ifaceNode.addNode(createNodeElementClassAttribute(eca)); }
for (ElementBindingHandler bind:iface.getElementBindingHandlers()) { ifaceNode.addNode(createNodeElementBindingHandler(bind)); }
for (ElementConfigurator conf:iface.getElementConfigurators()) { ifaceNode.addNode(createNodeElementConfigurator(conf)); } }
for (ElementNamespaceContext ns:mod.getElementNamespaceContexts()) { ApiDocNode nsNode = modNode.addNode(createNodeElementNamespaceContext(ns));
for (ElementClass ec:ns.getElementClasses()) { ApiDocNode ecNode = nsNode.addNode(createNodeElementClass(ec));
for (ElementClassAttribute eca:ec.getElementClassAttributes()) { ecNode.addNode(createNodeElementClassAttribute(eca)); }
for (ElementConfigurator conf:ec.getElementConfigurators()) { ecNode.addNode(createNodeElementConfigurator(conf)); } } }
}
return doc;
@ -141,6 +174,9 @@ public class EldDocWriter {
private ApiDocNode createNodeElementAttributeHandler(ElementAttributeHandler attr) {
return new ApiDocNode(attr,attr.getId(),attr.getId(),attr.getDescription());
}
private ApiDocNode createNodeElementConfiguratorGlobal(ElementConfiguratorGlobal conf) {
return new ApiDocNode(conf,conf.getId(),conf.getId(),conf.getDescription());
}
private ApiDocNode createNodeElementConfigurator(ElementConfigurator conf) {
return new ApiDocNode(conf,conf.getId(),conf.getId(),conf.getDescription());
}
@ -156,6 +192,18 @@ public class EldDocWriter {
private ApiDocNode createNodeElementClass(ElementClass ec) {
return new ApiDocNode(ec,ec.getId(),ec.getId(),ec.getDescription());
}
private ApiDocNode createNodeElementClassAttribute(ElementClassAttribute eca) {
return new ApiDocNode(eca,eca.getId(),eca.getId(),eca.getDescription());
}
private String createPageSubTitle() {
StringBuffer buf = new StringBuffer(100);
buf.append(context.getLanguage().getLanguageName());
buf.append(" ");// note use real space as 'html/header/title' will not always escape entities. TODO: add to html writer
buf.append(context.getLanguage().getLanguageVersion());
buf.append(" API");
return buf.toString();
}
private String createLanguageAbout() {
StringBuffer buf = new StringBuffer(100);
@ -172,7 +220,7 @@ public class EldDocWriter {
buf.append("Copyright&nbsp;&#x00a9;&nbsp;");
buf.append(calendar.get(Calendar.YEAR));
buf.append("&nbsp;");
buf.append(context.getLanguage().getLanguageName().toUpperCase());
buf.append(getLanguageNameUpperCase());
buf.append("&nbsp;");
buf.append("All Rights Reserved.");
return buf.toString();
@ -188,84 +236,7 @@ public class EldDocWriter {
return keywords;
}
private void printBeanProperties(ApiDocContentWriter writer,Object bean) throws SAXException {
writer.docTableStart("Bean Properties", "Bean properties overview.");
writer.docTableHeader("Name", "Value");
for (Method m:bean.getClass().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());
Object value = null;
try {
value = m.invoke(bean, new Object[] {});
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
writer.docTableRow(n,printValue(value));
}
}
writer.docTableEnd();
}
private String printValue(Object value) {
if (value==null) {
return "null";
}
if (value instanceof String) {
return (String)value;
}
if (value instanceof Class) {
return "class "+((Class<?>)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<ApiDocNode> event) throws SAXException {
printBeanProperties(event.getWriter(),event.getEvent().getUserData());
}
@ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementConfigurator.class})
public void writeElementConfiguratorBeanProperties(ApiDocWriteEvent<ApiDocNode> event) throws SAXException {
printBeanProperties(event.getWriter(),event.getEvent().getUserData());
private String getLanguageNameUpperCase() {
return context.getLanguage().getLanguageName().toUpperCase();
}
}

View file

@ -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<String> 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<ElementClassAttribute> 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<ApiDocNode> 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<ApiDocNode> 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<ApiDocNode> 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<ApiDocNode> event) throws SAXException {
ElementClass ec = (ElementClass)event.getEventObject().getUserData();
Collection<ElementClassAttribute> 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<ApiDocNode> 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<ApiDocNode> 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<TreeNode> 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<parents.size()-1) {
writer.charactersRaw(",&nbsp;");
writer.characters(",&nbsp;");
}
}
writer.printTagEnd(Tag.dd);
@ -156,7 +146,7 @@ public class EldDocWriterElementClass {
List<TreeNode> 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<childs.size()-1) {
writer.charactersRaw(",&nbsp;");
writer.characters(",&nbsp;");
}
}
writer.printTagEnd(Tag.dd);

View file

@ -0,0 +1,74 @@
/*
* 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.ElementBindingHandler;
import org.x4o.xml.element.ElementClassAttribute;
import org.x4o.xml.element.ElementConfigurator;
import org.x4o.xml.element.ElementInterface;
import org.xml.sax.SAXException;
/**
* EldDocWriterElementInterface writers all content parts for the x4o element interface.
*
* @author Willem Cazander
* @version 1.0 Aug 17, 2013
*/
public class EldDocWriterElementInterface extends AbstractApiDocWriter {
@ApiDocNodeDataConfiguratorMethod(targetClasses={ElementInterface.class})
public void configNavBar(ApiDoc doc,ApiDocNode node,ApiDocNodeData data) {
clearHrefContentGroup(doc,node,"summary","attribute",ElementClassAttribute.class);
clearHrefContentGroup(doc,node,"summary","binding",ElementBindingHandler.class);
clearHrefContentGroup(doc,node,"summary","configurator",ElementConfigurator.class);
}
@ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementInterface.class},nodeBodyOrders={1},contentGroup="interface",contentGroupType="summary")
public void writeElementNamespaceBeanProperties(ApiDocWriteEvent<ApiDocNode> 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<ApiDocNode> 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<ApiDocNode> 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<ApiDocNode> event) throws SAXException {
printApiTable(event,"Element Configurator Summary",ElementConfigurator.class);
}
}

View file

@ -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<ApiDocNode> 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<ApiDocNode> event) throws SAXException {
printApiTable(event,"Element Summary",ElementClass.class);
}
//@ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={ElementNamespaceContext.class},nodeBodyOrders={2})
//public void writeElementNamespaceAttributes(ApiDocWriteEvent<ApiDocNode> event) throws SAXException {
// printApiTable(event,"Element Summary",ElementClass.class);
//}
}

View file

@ -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<ApiDocNode> event) throws SAXException {
printApiTableBean(event,"BindingHandler","description");
}
// TODO move
@ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementConfigurator.class})
public void writeElementConfiguratorBean(ApiDocWriteEvent<ApiDocNode> event) throws SAXException {
printApiTableBean(event,"Configurator","description");
}
// TODO move
@ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY,targetClasses={ElementClassAttribute.class})
public void writeElementClassAttributeBean(ApiDocWriteEvent<ApiDocNode> event) throws SAXException {
printApiTableBean(event,"Element Class Attribute","description");
}
@ApiDocNodeWriterMethod(nodeBody=ApiDocNodeBody.SUMMARY_PAGE,targetClasses={X4OLanguageContext.class},nodeBodyOrders={1})
public void writeLanguageSummary(ApiDocWriteEvent<ApiDocNode> 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<ApiDocNode> 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<ApiDocNode> 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();

View file

@ -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<ApiDocNode> 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<ApiDocNode> 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<ApiDocNode> 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<ApiDocNode> 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<ApiDocNode> event) throws SAXException {
printApiTable(event,"Namespace Summary",ElementNamespaceContext.class);
}
}

View file

@ -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<ApiDocNode> event,String name,Class<?> interfaceClass) throws SAXException {
printApiTable(
event.getEventObject(),
filterUserDataClassType(event.getEventObject(),interfaceClass),
event.getWriter(),
name
);
}
public void printApiTable(ApiDocNode parent,List<ApiDocNode> 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<ApiDocNode> filterUserDataClassType(ApiDocNode filterNode,Class<?> interfaceClass) {
List<ApiDocNode> result = new ArrayList<ApiDocNode>(filterNode.getNodes().size()/2);
for (ApiDocNode node:filterNode.getNodes()) {
if (interfaceClass.isAssignableFrom(node.getUserData().getClass())) {
result.add(node);
}
}
return result;
}
public void printApiTableBean(ApiDocWriteEvent<ApiDocNode> event,String name,String...skipProperties) throws SAXException {
printApiTableBean(event, event.getEventObject().getUserData(), name, skipProperties);
}
public void printApiTableBean(ApiDocWriteEvent<ApiDocNode> 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<ApiDocNode> 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();
}
}

View file

@ -59,6 +59,7 @@ public enum ApiDocContentCss {
docSummary,
contentContainer,
packageSummary,
overviewSummary,
colOne,
colFirst,

View file

@ -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<String> keywords) throws SAXException {
public void docHtmlStart(String title,List<String> 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<String> navList = new ArrayList<String>(10);
Map<String,String> navLinks = new HashMap<String,String>(10);
Map<String,String> navNames = new HashMap<String,String>(10);
Map<String,String> navTitles = new HashMap<String,String>(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 addNavItem(String id,String navLink,String navName) {
navList.add(id);
if (navLink!=null) {
navLinks.put(id, navLink);
}
navNames.put(id, navName);
}
}
private void docNavBar(NavBarConfig conf,boolean isTop) throws SAXException {
String pathPrefix = conf.pathPrefix;
String barComment = "TOP";
String barCssDiv = "topNav";
String barId = "navbar_top";
if (isTop==false) {
barComment = "BOTTOM";
barCssDiv = "bottomNav";
barId = "navbar_bottom";
}
comment("========= START OF "+barComment+" NAVBAR =======");
printTagStart(Tag.div,barCssDiv);
printHrefNamed(barId); // Print named link navigation
AttributesImpl atts = new AttributesImpl();
atts.addAttribute ("", "href", "", "", "#skip-"+barId);
atts.addAttribute ("", "title", "", "", "Skip navigation links");
startElement("", "a", "", atts);
endElement("", "a", "");
printHrefNamed(barId+"_firstrow");
atts = new AttributesImpl();// Print nav bar
atts.addAttribute ("", "class", "", "", "navList");
atts.addAttribute ("", "title", "", "", "Navigation");
startElement("", "ul", "", atts);
for (String navKey:conf.navList) {
String navName = conf.navNames.get(navKey);
String navLink = conf.navLinks.get(navKey);
String navTitle = conf.navTitles.get(navKey);
String selectedCss = null;
if (navKey.equals(conf.navSelected)) {
selectedCss = "navBarCell1Rev";
navLink = null; // disables link
}
if (navTitle==null) {
navTitle = navName;
}
if (navLink==null) {
printTagCharacters(Tag.li, navName, selectedCss);
} else {
docNavBarListItemHref(pathPrefix+navLink,navName,navTitle,selectedCss,null,null);
}
}
endElement("", "ul", "");
public void docNavBarAbout(String about) throws SAXException {
printTagStart(Tag.div,ApiDocContentCss.aboutLanguage); // Print about language
printTagStart(Tag.em);
printTagStart(Tag.strong);
for (int i=0;i<conf.aboutLanguage.length();i++) {
char c = conf.aboutLanguage.charAt(i);
if (c=='\n') {
String[] lines = about.split("\n");
for (int i=0;i<lines.length;i++) {
String line = lines[i];
characters(line);
if (i<lines.length-1) {
printTagStartEnd(Tag.br);
} else {
characters(c);// TODO: use buffer so char entities are not escaped.
}
}
printTagEnd(Tag.strong);
printTagEnd(Tag.em);
printTagEnd(Tag.div);
printTagEnd(Tag.div); // end barCssDiv
printTagStart(Tag.div,ApiDocContentCss.subNav);
printTagStart(Tag.ul,ApiDocContentCss.navList);
if (conf.prev==null) {
printTagCharacters(Tag.li, "Prev");
} else {
docNavBarListItemHref(pathPrefix+conf.prev,"Prev","Previous Item",null,"strong",null);
}
if (conf.next==null) {
printTagCharacters(Tag.li, "Next");
} else {
docNavBarListItemHref(pathPrefix+conf.next,"Next","Next Item",null,"strong",null);
}
printTagEnd(Tag.ul);
if (conf.frame!=null) {
printTagStart(Tag.ul,ApiDocContentCss.navList);
printTagStart(Tag.li);
printHrefTarget(pathPrefix+"index.html?"+conf.frame, "Frames", "_top");
printTagEnd(Tag.li);
printTagStart(Tag.li);
printHrefTarget(pathPrefix+conf.frame, "No Frames", "_top");
printTagEnd(Tag.li);
printTagEnd(Tag.ul);
}
if (conf.noFrameAllName!=null && conf.noFrameAllLink!=null) {
printTagStart(Tag.ul,ApiDocContentCss.navList,"allclasses_"+barId);
docNavBarListItemHref(pathPrefix+conf.noFrameAllLink,conf.noFrameAllName,null,null,null,null);
printTagEnd(Tag.ul);
printTagStart(Tag.div);
if (isTop) {
printScriptInline(conf.noFrameAllTopJS);
} else {
printScriptInline(conf.noFrameAllBottomJS);
}
printTagEnd(Tag.div);
}
String tabSpace = "&nbsp;|&nbsp;";
boolean printLink = conf.linkConstructors || conf.linkFields || conf.linkMethods;
if (printLink) {
printTagStart(Tag.div);
printTagStart(Tag.ul,ApiDocContentCss.subNavList);
printTagStart(Tag.li);charactersRaw("Summary:&nbsp;");printTagEnd(Tag.li);
//printTagText(Tag.li,"Nested | "); // TODO: Nested
if (conf.linkFields) {
docNavBarListItemHrefLinkSpace("#field_summary",conf.linkFieldName);
} else {
printTagCharacters(Tag.li,conf.linkFieldName);charactersRaw(tabSpace);
}
if (conf.linkConstructors) {
docNavBarListItemHrefLinkSpace("#constructor_summary",conf.linkConstructorName);
} else {
printTagCharacters(Tag.li,conf.linkConstructorName);charactersRaw(tabSpace);
}
if (conf.linkMethods) {
docNavBarListItemHref("#method_summary",conf.linkMethodName,null);
} else {
printTagCharacters(Tag.li,conf.linkMethodName);
}
printTagEnd(Tag.ul);
if (conf.linkDetails){
printTagStart(Tag.ul,ApiDocContentCss.subNavList);
printTagStart(Tag.li);charactersRaw("Detail:&nbsp;");printTagEnd(Tag.li);
//printTagText(Tag.li,"Nested | ");
if (conf.linkFields) {
docNavBarListItemHrefLinkSpace("#field_detail",conf.linkFieldName);
} else {
printTagCharacters(Tag.li,conf.linkFieldName);charactersRaw(tabSpace);
}
if (conf.linkConstructors) {
docNavBarListItemHrefLinkSpace("#constructor_detail",conf.linkConstructorName);
} else {
printTagCharacters(Tag.li,conf.linkConstructorName);charactersRaw(tabSpace);
}
if (conf.linkMethods) {
docNavBarListItemHref("#method_detail",conf.linkMethodName,null);
} else {
printTagCharacters(Tag.li,conf.linkMethodName);
}
printTagEnd(Tag.ul);
}
printTagEnd(Tag.div);
}
printHrefNamed("skip-"+barId);
printTagEnd(Tag.div);
comment("========= END OF "+barComment+" NAVBAR =======");
}
private void docNavBarListItemHrefLinkSpace(String href,String title) throws SAXException {
String tabSpace = "&nbsp;|&nbsp;";
docNavBarListItemHref(href, title, title, null, null, tabSpace);
}
private void docNavBarListItemHref(String href,String title, String cssClass) throws SAXException {
docNavBarListItemHref(href, title, title, cssClass, null, null);
}
private void docNavBarListItemHref(String href,String title,String text,String cssClass,String spanCss,String linkSpace) throws SAXException {
printTagStart(Tag.li,cssClass);
printHref(href,title,text,spanCss);
charactersRaw(linkSpace);
printTagEnd(Tag.li);
}
public void docPagePackageTitle(String title,String summary) throws SAXException {
@ -314,7 +114,7 @@ public class ApiDocContentWriter extends ContentWriterHtml {
printTagCharacters(Tag.div, summary,ApiDocContentCss.block.name());
printTagEnd(Tag.div);
printTagStart(Tag.p);
charactersRaw("See:&nbsp;");
characters("See:&nbsp;");
printHref("#package_description", "Description");
printTagEnd(Tag.p);
printTagEnd(Tag.div);
@ -327,7 +127,7 @@ public class ApiDocContentWriter extends ContentWriterHtml {
characters(description);
}
public void docPageClassStart(String title,String subTitle) throws SAXException {
public void docPageClassStart(String title,String subTitle,Tag titleTag) throws SAXException {
comment("======== START OF CLASS DATA ========");
printTagStart(Tag.div,ApiDocContentCss.header);
if (subTitle!=null) {
@ -335,7 +135,7 @@ public class ApiDocContentWriter extends ContentWriterHtml {
characters(subTitle);
printTagEnd(Tag.div);
}
printTagCharacters(Tag.h2, title, "title");
printTagCharacters(titleTag, title, "title");
printTagEnd(Tag.div);
}
@ -375,9 +175,11 @@ public class ApiDocContentWriter extends ContentWriterHtml {
printTagStart(Tag.li,ApiDocContentCss.blockList);
}
public void docTableStart(String tableTitle,String tableDescription) throws SAXException {
public void docTableStart(String tableTitle,String tableDescription,ApiDocContentCss tableCss) throws SAXException {
AttributesImpl atts = new AttributesImpl();
atts.addAttribute ("", "class", "", "", "packageSummary");
if (tableCss!=null) {
atts.addAttribute ("", "class", "", "", tableCss.name());
}
atts.addAttribute ("", "border", "", "", "0");
atts.addAttribute ("", "cellpadding", "", "", "3");
atts.addAttribute ("", "cellspacing", "", "", "0");
@ -388,7 +190,7 @@ public class ApiDocContentWriter extends ContentWriterHtml {
printTagStart(Tag.caption);
printTagStart(Tag.span);characters(tableTitle);printTagEnd(Tag.span);
printTagStart(Tag.span,ApiDocContentCss.tabEnd);charactersRaw("&nbsp;");printTagEnd(Tag.span);
printTagStart(Tag.span,ApiDocContentCss.tabEnd);characters("&nbsp;");printTagEnd(Tag.span);
printTagEnd(Tag.caption);
}
@ -401,9 +203,9 @@ public class ApiDocContentWriter extends ContentWriterHtml {
printTagStart(Tag.tr);
AttributesImpl atts = new AttributesImpl();
if (titleLast==null) {
atts.addAttribute ("", "class", "", "", "colOne");
atts.addAttribute ("", "class", "", "", ApiDocContentCss.colOne.name());
} else {
atts.addAttribute ("", "class", "", "", "colFirst");
atts.addAttribute ("", "class", "", "", ApiDocContentCss.colFirst.name());
}
atts.addAttribute ("", "scope", "", "", "col");
startElement("", "th", "", atts);
@ -414,7 +216,7 @@ public class ApiDocContentWriter extends ContentWriterHtml {
return;
}
atts = new AttributesImpl();
atts.addAttribute ("", "class", "", "", "colLast");
atts.addAttribute ("", "class", "", "", ApiDocContentCss.colLast.name());
atts.addAttribute ("", "scope", "", "", "col");
startElement("", "th", "", atts);
characters(titleLast);
@ -422,15 +224,28 @@ public class ApiDocContentWriter extends ContentWriterHtml {
printTagEnd(Tag.tr);
}
public void docTableRowLink(String dataFirstHref,String dataFirst,String dataLast) throws SAXException {
docTableRowHref(dataFirstHref,dataFirst,dataLast,null,false,false,false);
}
public void docTableRow(String dataFirst,String dataLast) throws SAXException {
docTableRow(dataFirst,dataLast,null);
}
public void docTableRow(String dataFirst,String dataLast,String dataBlock) throws SAXException {
docTableRowHref(null,dataFirst,dataLast,dataBlock);
docTableRowHref(null,dataFirst,dataLast,dataBlock,false,false,false);
}
public void docTableRowHref(String dataFirstHref,String dataFirst,String dataLast,String dataBlock) throws SAXException {
public void docTableRowLastStart(String dataFirst,String dataFirstHref) throws SAXException {
docTableRowHref(dataFirstHref,dataFirst,null,null,false,false,true);
}
public void docTableRowLastEnd() throws SAXException {
printTagEnd(Tag.td);
printTagEnd(Tag.tr);
}
private void docTableRowHref(String dataFirstHref,String dataFirst,String dataLast,String dataBlock,boolean dataFirstCode,boolean dataLastCode,boolean skipLast) throws SAXException {
if (isAltRow) {
printTagStart(Tag.tr,ApiDocContentCss.altColor);
} else {
@ -442,22 +257,35 @@ public class ApiDocContentWriter extends ContentWriterHtml {
} else {
printTagStart(Tag.td,ApiDocContentCss.colFirst);
}
if (dataFirstCode) {
printTagStart(Tag.code);
}
if (dataFirstHref==null) {
characters(dataFirst);
} else {
printHref(dataFirstHref, dataFirst, dataFirst);
}
if (dataFirstCode) {
printTagEnd(Tag.code);
}
printTagEnd(Tag.td);
if (skipLast) {
printTagStart(Tag.td,ApiDocContentCss.colLast);
return;
}
if (dataLast==null) {
printTagEnd(Tag.tr);
return;
}
printTagStart(Tag.td,ApiDocContentCss.colLast);
if (dataLastCode) {
printTagStart(Tag.code);characters(dataLast);printTagEnd(Tag.code);
} else {
printTagStart(Tag.div,ApiDocContentCss.block);characters(dataLast);printTagEnd(Tag.div);
}
if (dataBlock!=null) {
printTagStart(Tag.div,ApiDocContentCss.block);characters(dataBlock);printTagEnd(Tag.div);
}

View file

@ -0,0 +1,128 @@
/*
* 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.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.ApiDocNode;
import org.x4o.xml.eld.doc.api.dom.ApiDocNodeData;
import org.x4o.xml.eld.doc.api.dom.ApiDocNodeDataConfigurator;
/**
* ApiDocNodeDataConfiguratorBean wraps the ApiDocNodeDataConfigurator to a single method of a bean.
*
* @author Willem Cazander
* @version 1.0 May 1, 2013
*/
public class ApiDocNodeDataConfiguratorBean implements ApiDocNodeDataConfigurator {
private Object bean = null;
private String method = null;
private List<Class<?>> targetClasses = null;
public ApiDocNodeDataConfiguratorBean() {
targetClasses = new ArrayList<Class<?>>(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<Class<?>> 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;
}
}

View file

@ -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();
}

View file

@ -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<String> path = new ArrayList<String>(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<ApiDocNode> bodyEvent = new ApiDocWriteEvent<ApiDocNode>(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();
if (!isNodePageMode) {
writeNodeTreePath(bodyEvent);
writeNodeDescription(bodyEvent);
writeNodeSummary(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<ApiDocNode> event) throws SAXException {
List<ApiDocNodeWriter> bodyWriterTreePath = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.TREE_PATH);
List<ApiDocNodeWriter> 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<bodyWriterTreePath.size();i++) {
ApiDocNodeWriter nodeWriter = bodyWriterTreePath.get(i);
@ -164,15 +209,16 @@ public class ApiDocWriter {
}
private void defaultWriteNodeDescription(ApiDocWriteEvent<ApiDocNode> event) throws SAXException {
event.getWriter().characters(event.getEvent().getDescription());
event.getWriter().characters(event.getEventObject().getDescription());
}
private void writeNodeDescription(ApiDocWriteEvent<ApiDocNode> event) throws SAXException {
private void writeNodeDescription(ApiDocWriteEvent<ApiDocNode> event,boolean isPageMode) throws SAXException {
ApiDocContentWriter writer = event.getWriter();
List<ApiDocNodeWriter> bodyWriterDescriptionLinks = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.DESCRIPTION_LINKS);
List<ApiDocNodeWriter> bodyWriterDescriptionNode = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.DESCRIPTION_NODE);
List<ApiDocNodeWriter> bodyWriterDescriptionLinks = findNodeBodyWriters(event.getEventObject(),ApiDocNodeBody.DESCRIPTION_LINKS);
List<ApiDocNodeWriter> bodyWriterDescriptionNode = findNodeBodyWriters(event.getEventObject(),ApiDocNodeBody.DESCRIPTION_NODE);
writer.printTagStart(Tag.div, ApiDocContentCss.description);
writer.docPageBlockStart();
if (isPageMode==false) {
if (bodyWriterDescriptionLinks.isEmpty()) {
//defaultWriteTreePath(node,writer);
}
@ -182,6 +228,7 @@ public class ApiDocWriter {
}
writer.printTagStartEnd(Tag.hr);
writer.printTagStartEnd(Tag.br); // mmm
}
if (bodyWriterDescriptionNode.isEmpty()) {
defaultWriteNodeDescription(event);
}
@ -193,30 +240,52 @@ public class ApiDocWriter {
writer.printTagEnd(Tag.div); // description
}
private void writeNodeSummary(ApiDocWriteEvent<ApiDocNode> event) throws SAXException {
private void writeNodeSummary(ApiDocWriteEvent<ApiDocNode> event,boolean isPage) throws SAXException {
ApiDocContentWriter writer = event.getWriter();
List<ApiDocNodeWriter> bodyWriterSummary = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.SUMMARY);
List<ApiDocNodeWriter> bodyWriterSummary = null;
List<ApiDocNodeWriter> bodyWriterSummaryPage = findNodeBodyWriters(event.getEventObject(),ApiDocNodeBody.SUMMARY_PAGE);
List<ApiDocNodeWriter> 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<bodyWriterSummary.size();i++) {
writer.docPageBlockStart();
writer.printTagCharacters(Tag.h3, "Summary");
ApiDocNodeWriter nodeWriter = bodyWriterSummary.get(i);
if (!isPage) { writer.docPageBlockStart(); }
writeSubNavNamedHref(event,nodeWriter);
if (!isPage) { writer.printTagCharacters(Tag.h3, "Summary"); }
nodeWriter.writeNodeContent(event);
writer.docPageBlockEnd();
if (!isPage) { writer.docPageBlockEnd(); }
if (isPage) { writer.printTagStartEnd(Tag.br); } // mm .. mm
}
if (!isPage) {
writer.docPageBlockEnd();
writer.printTagEnd(Tag.div); // Summary
}
}
private void writeSubNavNamedHref(ApiDocWriteEvent<ApiDocNode> 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<ApiDocNode> event) throws SAXException {
ApiDocContentWriter writer = event.getWriter();
List<ApiDocNodeWriter> bodyWriterDetail = findNodeBodyWriters(event.getEvent(),ApiDocNodeBody.DETAIL);
List<ApiDocNodeWriter> 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<bodyWriterDetail.size();i++) {
writer.docPageBlockStart();
writer.printTagCharacters(Tag.h3, "Detail");
ApiDocNodeWriter nodeWriter = bodyWriterDetail.get(i);
writer.docPageBlockStart();
writeSubNavNamedHref(event,nodeWriter);
writer.printTagCharacters(Tag.h3, "Detail");
nodeWriter.writeNodeContent(event);
writer.docPageBlockEnd();
}
@ -239,18 +309,42 @@ public class ApiDocWriter {
}
private void configActiveNavConceptLinks(NavBarConfig conf,ApiDocNode node,ApiDocConcept concept,String prefix) {
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);
// Reset hrefs
for (ApiDocNavLink link:doc.getNodeData().getNavLinks()) {
if (link.isResetHref()) {
link.setHref(null);
}
}
}
private void configActiveNavConceptLinks(ApiDocNode node,ApiDocConcept concept,String prefix) {
List<String> pathClean = new ArrayList<String>(10);
buildParentPath(node,pathClean);
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+"/..");
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(NavBarConfig conf,ApiDocNode node) {
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)<pnSize) {
@ -270,23 +364,45 @@ public class ApiDocWriter {
ApiDocNode nextNode = pn.get(nodeIdx+1);
if (node.getUserData().getClass().equals(nextNode.getUserData().getClass())) {
buildParentPath(nextNode,pathClean);
conf.next = ApiDocContentWriter.toSafeUri(pathClean)+"/index.html";
doc.getNodeData().setNextLink(ApiDocContentWriter.toSafeUri(pathClean)+"/index.html");
}
}
}
private void configData(ApiDocNode node) {
ApiDocNodeData confData = doc.getNodeData();
for (ApiDocNodeDataConfigurator conf:findDataConfigurators(node)) {
conf.configNodeData(doc, node,confData);
}
}
private void configSubNavLinks(ApiDocNode node) {
ApiDocNodeData conf = doc.getNodeData();
for (ApiDocNodeWriter writer:findNodeBodyWriters(node, null)) {
String group = writer.getContentGroup();
String groupTypeKey = writer.getContentGroupType();
if (group==null | groupTypeKey==null) {
continue;
}
if (conf.getGroupTypeKeys().contains(groupTypeKey)==false) {
conf.addGroupTypeKey(groupTypeKey);
}
String groupTypeName = doc.getGroupTypeName(groupTypeKey);
String groupName = group.substring(0,1).toUpperCase()+group.substring(1);
ApiDocNavLink link = new ApiDocNavLink();
link.setId(group);
link.setHref("#"+groupTypeKey+"_"+group);
link.setText(groupName);
link.setTitle(groupTypeName+" "+groupName);
conf.addGroupTypeLink(groupTypeKey, link);
}
}
public void defaultWriteSummary(ApiDocNode node,ApiDocContentWriter writer) throws SAXException {
ApiDocConcept concept = findConceptByClass(node.getUserData().getClass());
writer.docTableStart(concept.getName()+" Summary", "All childeren in "+concept.getName());
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();
ApiDocConcept concept = doc.findConceptByClass(node.getUserData().getClass());
printApiTable(node, node.getNodes(), writer, concept.getName()+" Summary");
}
public void defaultWriteTreePath(ApiDocNode node,ApiDocContentWriter writer) throws SAXException {
@ -317,7 +433,7 @@ public class ApiDocWriter {
}
String linkHref = buf+"index.html";
if (doc.getRootNode().equals(node)) {
ApiDocConcept concept = findConceptByClass(node.getUserData().getClass());
ApiDocConcept concept = doc.findConceptByClass(node.getUserData().getClass());
linkHref = buf+"../overview-"+concept.getId()+".html";
}
writer.printHref(linkHref, node.getDescription(), nodeTitle);
@ -333,6 +449,8 @@ public class ApiDocWriter {
private void defaultWriteTreePathBuildPath(ApiDocNode node,List<ApiDocNode> 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<ApiDocNodeWriter> findNodeBodyWriters(ApiDocNode node,ApiDocNodeBody nodeBody) {
List<ApiDocNodeWriter> result = new ArrayList<ApiDocNodeWriter>();
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()) {
@ -442,20 +527,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<ApiDocNodeDataConfigurator> findDataConfigurators(ApiDocNode node) {
List<ApiDocNodeDataConfigurator> result = new ArrayList<ApiDocNodeDataConfigurator>();
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<String> path) {
if (node.getParent()==null) {
path.add(node.getId());
@ -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<ApiDocNode> nodes = new ArrayList<ApiDocNode>(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<ApiDocNode> nodes = new ArrayList<ApiDocNode>(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<ApiDocPage> e = new ApiDocWriteEvent<ApiDocPage>(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 = "&nbsp;|&nbsp;";
List<String> 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<groupKeys.size();i++) {
String groupKey = groupKeys.get(i);
String groupName = doc.getGroupTypeName(groupKey);
List<ApiDocNavLink> links = conf.getGroupTypeLinks(groupKey);
if (links.isEmpty()==false) {
writer.printTagStart(Tag.li);writer.characters(groupName+":&nbsp;");writer.printTagEnd(Tag.li);
for (int l=0;l<links.size();l++) {
ApiDocNavLink link = links.get(l);
writer.printTagStart(Tag.li);
String tab = null;
if (l<links.size()-1) {
tab = tabSpace;
}
if (link.getHref()!=null) {
docNavBarListItemHref(writer,link.getHref(), link.getTitle(), link.getText(), null, null, tab);
} else {
writer.characters(link.getText());
if (tab!=null) {
writer.characters(tab);
}
}
writer.printTagEnd(Tag.li);
}
}
}
writer.printTagEnd(Tag.ul);
writer.printTagEnd(Tag.div);
}
writer.printHrefNamed("skip-"+barId);
writer.printTagEnd(Tag.div);
writer.comment("========= END OF "+barComment+" NAVBAR =======");
}
private void docNavBarListItemHref(ApiDocContentWriter writer,String href,String title,String text,String cssClass,String spanCss,String linkSpace) throws SAXException {
writer.printTagStart(Tag.li,cssClass);
writer.printHref(href,title,text,spanCss);
writer.characters(linkSpace);
writer.printTagEnd(Tag.li);
}
}

View file

@ -59,14 +59,14 @@ public class DefaultPageWriterHelp implements ApiDocPageWriter {
for (ApiDocConcept concept:doc.getConcepts()) {
writer.printTagCharacters(Tag.h2, concept.getName());
writer.printTagStart(Tag.p);
writer.charactersRaw(concept.getDescriptionHelp());
writer.characters(concept.getDescriptionHelp());
writer.printTagEnd(Tag.p);
writer.docPageBlockNext();
}
for (ApiDocPage docPage:doc.getDocPages()) {
writer.printTagCharacters(Tag.h2, docPage.getName());
writer.printTagStart(Tag.p);
writer.charactersRaw(docPage.getDescription());
writer.characters(docPage.getDescription());
writer.printTagEnd(Tag.p);
writer.docPageBlockNext();
}

View file

@ -47,7 +47,7 @@ public class DefaultPageWriterIndexAll implements ApiDocPageWriter {
writer.docPageContentStart();
for (char i='A';i<='Z';i++) {
writer.printHref("#_"+i+"_", ""+i);
writer.charactersRaw("&nbsp;");
writer.characters("&nbsp;");
}
for (char i='A';i<='Z';i++) {
writer.printHrefNamed("_"+i+"_");

View file

@ -52,7 +52,7 @@ public class DefaultPageWriterTree implements ApiDocPageWriter {
public void writePageContent(ApiDocWriteEvent<ApiDocPage> 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('/');
}
}

View file

@ -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<Class<?>> treeNodeClassExcludes = null;
private List<Class<?>> treeNodePageModeClass = null;
private List<ApiDocNodeDataConfigurator> dataConfigurators = null;
private List<Class<?>> 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<ApiDocRemoteClass> remoteClasses = null;
private boolean skipRootTreePathNode = true;
private boolean printConceptTitle = true;
private boolean printConceptPrevNext = true;
private Map<String,String> groupTypeNames = null;
private String docPageSubTitle = null;
public ApiDoc() {
nodeBodyWriters = new ArrayList<ApiDocNodeWriter>(20);
@ -58,6 +80,11 @@ public class ApiDoc {
docKeywords = new ArrayList<String>(5);
docPages = new ArrayList<ApiDocPage>(5);
treeNodeClassExcludes = new ArrayList<Class<?>>(5);
treeNodePageModeClass = new ArrayList<Class<?>>(5);
dataConfigurators = new ArrayList<ApiDocNodeDataConfigurator>(5);
annotatedClasses = new ArrayList<Class<?>>(5);
remoteClasses = new ArrayList<ApiDocRemoteClass>(5);
groupTypeNames = new HashMap<String,String>(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<ApiDocRemoteClass> getRemoteClasses() {
return remoteClasses;
}
public void addRemoteClass(ApiDocRemoteClass remoteClass) {
remoteClasses.add(remoteClass);
}
public void removeRemoteClass(ApiDocRemoteClass remoteClass) {
remoteClasses.add(remoteClass);
}
public List<Class<?>> getAnnotatedClasses() {
return annotatedClasses;
}
public void removeAnnotatedClasses(Class<?> annotatedClass) {
annotatedClasses.remove(annotatedClass);
}
public void addAnnotatedClasses(Class<?> annotatedClass) {
annotatedClasses.add(annotatedClass);
}
public List<ApiDocNodeDataConfigurator> 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<Class<?>> 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;
}
}

View file

@ -39,10 +39,10 @@ public class ApiDocConcept {
private String descriptionHelp = null;
private ApiDocConcept parent = null;
private Class<?> conceptClass = null;
private List<Class<?>> conceptChildClasses = null;
private List<ApiDocConcept> childConcepts = null;
public ApiDocConcept() {
conceptChildClasses = new ArrayList<Class<?>>(5);
childConcepts = new ArrayList<ApiDocConcept>(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<Class<?>> getConceptChildClasses() {
return conceptChildClasses;
public List<ApiDocConcept> getChildConcepts() {
return childConcepts;
}
/**

View file

@ -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;
}
}

View file

@ -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
}

View file

@ -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<String> groupTypeKeys = null;
private Map<String,List<ApiDocNavLink>> groupTypeLinks = null;
private String prevLink = null;
private String nextLink = null;
private String framePath = null;;
private List<ApiDocNavLink> navLinks = null;
public ApiDocNodeData() {
navLinks = new ArrayList<ApiDocNavLink>(12);
groupTypeKeys = new ArrayList<String>(navLinks.size()/3);
groupTypeLinks = new HashMap<String,List<ApiDocNavLink>>(groupTypeKeys.size());
}
public void addGroupTypeKey(String groupTypeKey) {
groupTypeKeys.add(groupTypeKey);
}
public List<String> getGroupTypeKeys() {
return groupTypeKeys;
}
public void addGroupTypeLink(String groupTypeKey,ApiDocNavLink link) {
List<ApiDocNavLink> result = groupTypeLinks.get(groupTypeKey);
if (result==null) {
result = new ArrayList<ApiDocNavLink>(10);
groupTypeLinks.put(groupTypeKey, result);
}
result.add(link);
}
public List<ApiDocNavLink> getGroupTypeLinks(String groupTypeKey) {
List<ApiDocNavLink> result = groupTypeLinks.get(groupTypeKey);
if (result==null) {
result = new ArrayList<ApiDocNavLink>(0);
}
return result;
}
public ApiDocNavLink getGroupTypeLink(String groupTypeKey,String group) {
List<ApiDocNavLink> links = getGroupTypeLinks(groupTypeKey);
for (ApiDocNavLink link:links) {
if (link.getId().equals(group)) {
return link;
}
}
return null;
}
public void clearGroupTypeLinks() {
groupTypeLinks.clear();
}
public List<ApiDocNavLink> 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;
}
}

View file

@ -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<Class<?>> getTargetClasses();
void configNodeData(ApiDoc doc,ApiDocNode node,ApiDocNodeData data);
}

View file

@ -37,6 +37,8 @@ public interface ApiDocNodeWriter {
ApiDocNodeBody getNodeBody();
List<Class<?>> getTargetClasses();
List<Integer> getNodeBodyOrders();
String getContentGroup();
String getContentGroupType();
void writeNodeContent(ApiDocWriteEvent<ApiDocNode> e) throws SAXException;
}

View file

@ -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<String> packageList = null;
private ApiDocRemoteClass() {
packageList = new ArrayList<String>(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<String> getPackageList() {
return packageList;
}
}

View file

@ -33,7 +33,7 @@ import org.x4o.xml.eld.doc.api.ApiDocContentWriter;
public class ApiDocWriteEvent<T> {
private ApiDoc doc = null;
private T event = null;
private T eventObject = null;
private ApiDocContentWriter writer = null;
/**
@ -42,10 +42,10 @@ public class ApiDocWriteEvent<T> {
* @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<T> {
/**
* @return the event
*/
public T getEvent() {
return event;
public T getEventObject() {
return eventObject;
}
/**