From: <jen...@us...> - 2011-08-17 14:31:20
|
Revision: 3061 http://dl-learner.svn.sourceforge.net/dl-learner/?rev=3061&view=rev Author: jenslehmann Date: 2011-08-17 14:31:09 +0000 (Wed, 17 Aug 2011) Log Message: ----------- - first version of HTML help page generator for annotation based components completed * see interfaces/doc/configOptions.html * display general information about components as well as information about their options * component visibility can be toggled by type - config option annotation refined: * the "required" method allows to distinguish between required and optional options * the "defaultValue" method allows to specify a default value (see also its Javadoc) - added some convenience methods in AnnComponentManager Modified Paths: -------------- trunk/components-core/src/main/java/org/dllearner/algorithms/DisjointClassesLearner.java trunk/components-core/src/main/java/org/dllearner/algorithms/SimpleSubclassLearner.java trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java trunk/components-core/src/main/java/org/dllearner/core/AnnComponentManager.java trunk/components-core/src/main/java/org/dllearner/core/ComponentAnn.java trunk/components-core/src/main/java/org/dllearner/core/config/ConfigHelper.java trunk/components-core/src/main/java/org/dllearner/core/config/ConfigOption.java trunk/scripts/src/main/java/org/dllearner/scripts/DocumentationHTMLGenerator.java Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/DisjointClassesLearner.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/DisjointClassesLearner.java 2011-08-17 13:30:12 UTC (rev 3060) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/DisjointClassesLearner.java 2011-08-17 14:31:09 UTC (rev 3061) @@ -22,6 +22,7 @@ import java.util.List; import org.dllearner.core.ClassExpressionLearningAlgorithm; +import org.dllearner.core.ComponentAnn; import org.dllearner.core.ComponentInitException; import org.dllearner.core.EvaluatedDescription; import org.dllearner.core.owl.Description; @@ -33,6 +34,7 @@ * @author Jens Lehmann * */ +@ComponentAnn(name = "disjoint classes learner", shortName = "cldisjoint", version = 0.1) public class DisjointClassesLearner implements ClassExpressionLearningAlgorithm { @Override Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/SimpleSubclassLearner.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/SimpleSubclassLearner.java 2011-08-17 13:30:12 UTC (rev 3060) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/SimpleSubclassLearner.java 2011-08-17 14:31:09 UTC (rev 3061) @@ -31,6 +31,7 @@ import org.dllearner.algorithms.properties.ObjectPropertyDomainAxiomLearner; import org.dllearner.core.ClassExpressionLearningAlgorithm; +import org.dllearner.core.ComponentAnn; import org.dllearner.core.ComponentInitException; import org.dllearner.core.EvaluatedAxiom; import org.dllearner.core.EvaluatedDescription; @@ -65,13 +66,14 @@ * @author Jens Lehmann * */ +@ComponentAnn(name = "simple subclass learner", shortName = "clsub", version = 0.1) public class SimpleSubclassLearner implements ClassExpressionLearningAlgorithm { private static final Logger logger = LoggerFactory.getLogger(SimpleSubclassLearner.class); - @ConfigOption(name="classToDescribe", description="", propertyEditorClass=NamedClassEditor.class) + @ConfigOption(name="classToDescribe", required=true, description="", propertyEditorClass=NamedClassEditor.class) private NamedClass classToDescribe; - @ConfigOption(name="maxExecutionTimeInSeconds", description="", propertyEditorClass=IntegerEditor.class) + @ConfigOption(name="maxExecutionTimeInSeconds", defaultValue="10", description="", propertyEditorClass=IntegerEditor.class) private int maxExecutionTimeInSeconds = 10; @ConfigOption(name="maxFetchedRows", description="The maximum number of rows fetched from the endpoint to approximate the result.", propertyEditorClass=IntegerEditor.class) private int maxFetchedRows = 0; Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java 2011-08-17 13:30:12 UTC (rev 3060) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java 2011-08-17 14:31:09 UTC (rev 3061) @@ -77,7 +77,7 @@ * @author Jens Lehmann * */ -@ComponentAnn(name="CELOE", shortName="celoe", version=1.0) +@ComponentAnn(name="CELOE", shortName="celoe", version=1.0, description="CELOE is an adapted and extended version of the OCEL algorithm applied for the ontology engineering use case. See http://jens-lehmann.org/files/2011/celoe.pdf for reference.") public class CELOE extends AbstractCELA { private static Logger logger = Logger.getLogger(CELOE.class); Modified: trunk/components-core/src/main/java/org/dllearner/core/AnnComponentManager.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/core/AnnComponentManager.java 2011-08-17 13:30:12 UTC (rev 3060) +++ trunk/components-core/src/main/java/org/dllearner/core/AnnComponentManager.java 2011-08-17 14:31:09 UTC (rev 3061) @@ -19,10 +19,13 @@ */ package org.dllearner.core; +import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -64,8 +67,8 @@ "org.dllearner.algorithms.properties.DataPropertyDomainAxiomLearner", "org.dllearner.algorithms.properties.DataPropertyRangeAxiomLearner", "org.dllearner.algorithms.properties.SubDataPropertyOfAxiomLearner", - "org.dllearner.algorithms.algorithms.DisjointClassesLearner", - "org.dllearner.algorithms.algorithms.SimpleSubclassLearner", + "org.dllearner.algorithms.DisjointClassesLearner", + "org.dllearner.algorithms.SimpleSubclassLearner", } )); private static Collection<Class<? extends Component>> components; private static Map<Class<? extends Component>, String> componentNames; @@ -74,6 +77,8 @@ private AnnComponentManager() { // conversion of class strings to objects + components = new HashSet<Class<? extends Component>>(); + componentNames = new HashMap<Class<? extends Component>, String>(); for (String componentClassName : componentClassNames) { try { Class<? extends Component> component = Class.forName(componentClassName).asSubclass(Component.class); @@ -198,6 +203,28 @@ } return true; } + + // method lists all core interfaces implemented by a component (directly or indirectly) + // TODO: incomplete + public static List<Class<? extends Component>> getCoreComponentTypes(Class<? extends Component> component) { + List<Class<? extends Component>> types = new LinkedList<Class<? extends Component>>(); + if(KnowledgeSource.class.isAssignableFrom(component)) { + types.add(KnowledgeSource.class); + } + if(LearningAlgorithm.class.isAssignableFrom(component)) { + types.add(LearningAlgorithm.class); + } + if(LearningProblem.class.isAssignableFrom(component)) { + types.add(LearningProblem.class); + } + if(ReasonerComponent.class.isAssignableFrom(component)) { + types.add(ReasonerComponent.class); + } + if(AxiomLearningAlgorithm.class.isAssignableFrom(component)) { + types.add(AxiomLearningAlgorithm.class); + } + return types; + } /** * Returns the name of a DL-Learner component. @@ -206,6 +233,9 @@ */ public static String getName(Class<? extends Component> component){ ComponentAnn ann = component.getAnnotation(ComponentAnn.class); + if(ann == null) { + throw new Error("Component " + component + " does not use component annotation."); + } return ann.name(); } @@ -215,7 +245,66 @@ * @return Name of the component. */ public static String getName(Component component){ - ComponentAnn ann = component.getClass().getAnnotation(ComponentAnn.class); - return ann.name(); + return getName(component.getClass()); } + + /** + * Returns the name of a DL-Learner component. + * @param component + * @return Name of the component. + */ + public static String getShortName(Class<? extends Component> component){ + ComponentAnn ann = component.getAnnotation(ComponentAnn.class); + if(ann == null) { + throw new Error("Component " + component + " does not use component annotation."); + } + return ann.shortName(); + } + + /** + * Returns the short name of a DL-Learner component. + * @param component + * @return Short name of the component. + */ + public static String getShortName(Component component){ + return getShortName(component.getClass()); + } + + /** + * Returns the name of a DL-Learner component. + * @param component + * @return Name of the component. + */ + public static String getDescription(Class<? extends Component> component){ + ComponentAnn ann = component.getAnnotation(ComponentAnn.class); + return ann.description(); + } + + /** + * Returns the description of a DL-Learner component. + * @param component + * @return Description of the component. + */ + public static String getDescription(Component component){ + return getDescription(component.getClass()); + } + + /** + * Returns the version of a DL-Learner component. + * @param component + * @return Version of the component. + */ + public static double getVersion(Class<? extends Component> component){ + ComponentAnn ann = component.getAnnotation(ComponentAnn.class); + return ann.version(); + } + + /** + * Returns the version of a DL-Learner component. + * @param component + * @return Version of the component. + */ + public static double getVersion(Component component){ + return getVersion(component.getClass()); + } } Modified: trunk/components-core/src/main/java/org/dllearner/core/ComponentAnn.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/core/ComponentAnn.java 2011-08-17 13:30:12 UTC (rev 3060) +++ trunk/components-core/src/main/java/org/dllearner/core/ComponentAnn.java 2011-08-17 14:31:09 UTC (rev 3061) @@ -53,4 +53,11 @@ * @return A version number of this component. */ double version(); + + /** + * An optional description of the component. This can be shown in tool tips, + * help etc. + * @return The description of the component. + */ + String description() default ""; } Modified: trunk/components-core/src/main/java/org/dllearner/core/config/ConfigHelper.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/core/config/ConfigHelper.java 2011-08-17 13:30:12 UTC (rev 3060) +++ trunk/components-core/src/main/java/org/dllearner/core/config/ConfigHelper.java 2011-08-17 14:31:09 UTC (rev 3061) @@ -9,6 +9,7 @@ import java.util.List; import java.util.Map; +import org.dllearner.algorithms.SimpleSubclassLearner; import org.dllearner.algorithms.properties.ObjectPropertyDomainAxiomLearner; import org.dllearner.core.Component; @@ -69,9 +70,18 @@ * @return */ public static List<ConfigOption> getConfigOptions(Component component){ + return getConfigOptions(component.getClass()); + } + + /** + * Returns all config options for the given component. + * @param component + * @return + */ + public static List<ConfigOption> getConfigOptions(Class<? extends Component> component){ List<ConfigOption> options = new ArrayList<ConfigOption>(); - Field[] fields = component.getClass().getDeclaredFields(); + Field[] fields = component.getDeclaredFields(); for(Field f : fields){ ConfigOption option = f.getAnnotation(ConfigOption.class); if(option != null){ @@ -80,7 +90,7 @@ } return options; - } + } private static Class<?> getClassForObject(Object obj){ if(map.containsKey(obj.getClass())){ Modified: trunk/components-core/src/main/java/org/dllearner/core/config/ConfigOption.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/core/config/ConfigOption.java 2011-08-17 13:30:12 UTC (rev 3060) +++ trunk/components-core/src/main/java/org/dllearner/core/config/ConfigOption.java 2011-08-17 14:31:09 UTC (rev 3061) @@ -50,4 +50,21 @@ * @return */ Class<?> propertyEditorClass(); + + /** + * Returns whether this option is required for initializing the component. + * @return True if the option is required and false otherwise. + */ + boolean required() default false; + + /** + * Returns the default value of this config option. Default values should be set for all + * optional values. + * It is an overhead to describe the default value both in the source code and in the + * annotation. There are two reasons for this: a) the value of the field cannot easily be accessed + * without creating an instance of the component and b) for more complex structures the default + * may only be created in the constructor or init method. + * @return The default value of this option. + */ + String defaultValue() default ""; } Modified: trunk/scripts/src/main/java/org/dllearner/scripts/DocumentationHTMLGenerator.java =================================================================== --- trunk/scripts/src/main/java/org/dllearner/scripts/DocumentationHTMLGenerator.java 2011-08-17 13:30:12 UTC (rev 3060) +++ trunk/scripts/src/main/java/org/dllearner/scripts/DocumentationHTMLGenerator.java 2011-08-17 14:31:09 UTC (rev 3061) @@ -20,12 +20,17 @@ package org.dllearner.scripts; import java.io.File; +import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.Map.Entry; +import org.dllearner.algorithms.SimpleSubclassLearner; import org.dllearner.core.AnnComponentManager; import org.dllearner.core.Component; +import org.dllearner.core.config.ConfigHelper; +import org.dllearner.core.config.ConfigOption; +import org.dllearner.utilities.Files; /** * Script for generating documentation for all components, in particular @@ -58,31 +63,106 @@ // heading sb.append("<h1>DL-Learner Components</h1>\n"); + // filter interface + sb.append("<p>Filter components by implemented interfaces:</p>\n<ul>"); + sb.append("<a href=\"#\" onClick=\"showAllCat()\">show all</a>"); + sb.append("<li><a href=\"#\" onClick=\"showOnlyCat('KnowledgeSource')\">KnowledgeSource</a></li>"); + sb.append("<li><a href=\"#\" onClick=\"showOnlyCat('ReasonerComponent')\">ReasonerComponent</a></li>"); + sb.append("<li><a href=\"#\" onClick=\"showOnlyCat('LearningProblem')\">LearningProblem</a></li>"); + sb.append("<li><a href=\"#\" onClick=\"showOnlyCat('LearningAlgorithm')\">LearningAlgorithm</a>"); + sb.append("<ul><li><a href=\"#\" onClick=\"showOnlyCat('AxiomLearningAlgorithm')\">AxiomLearningAlgorithm</a></li></ul></li>"); + sb.append("</ul>"); + + // general explanations + sb.append("<p>Click on a component to get an overview on its configuration options.</p>"); + // generate component overview sb.append("<ul>\n"); for(Entry<String, Class<? extends Component>> compEntry : componentNamesInv.entrySet()) { - sb.append("<li><a href=\"#" + compEntry.getValue() + "\">"+compEntry.getKey()+"</a></li>\n"); + sb.append("<div class=\"" + getCoreTypes(compEntry.getValue()) + "\"><li><a href=\"#" + compEntry.getValue().getName() + "\">"+compEntry.getKey()+"</a></li></div>\n"); } sb.append("</ul>\n"); // generate actual documentation per component for(Entry<String, Class<? extends Component>> compEntry : componentNamesInv.entrySet()) { - sb.append("<a name=\"#" + compEntry.getValue() + "\" /><h2>"+compEntry.getKey()+"</h2>\n"); + Class<? extends Component> comp = compEntry.getValue(); + sb.append("<div class=\"" + getCoreTypes(comp) + "\">"); + // heading + anchor + sb.append("<a name=\"" + comp.getName() + "\"><h2>"+compEntry.getKey()+"</h2></a>\n"); + // some information about the component + sb.append("<p>short name: " + AnnComponentManager.getShortName(comp) + "<br />"); + sb.append("version: " + AnnComponentManager.getVersion(comp) + "<br />"); + sb.append("implements: " + getCoreTypes(comp).replace(" ", ", ") + "<br />"); + String description = AnnComponentManager.getDescription(comp); + if(description.length() > 0) { + sb.append("description: " + AnnComponentManager.getDescription(comp) + "<br />"); + } + sb.append("</p>"); + + // generate table for configuration options + List<ConfigOption> options = ConfigHelper.getConfigOptions(comp); + if(options.isEmpty()) { + sb.append("This component does not have configuration options."); + } else { + sb.append("<table id=\"hor-minimalist-a\"><thead><tr><th>option name</th><th>description</th><th>type</th><th>default value</th><th>required?</th></tr></thead><tbody>\n"); + for(ConfigOption option : options) { + sb.append("<tr><td>" + option.name() + "</td><td>" + option.description() + "</td><td> " + getOptionType(option) + "</td><td>" + option.defaultValue() + "</td><td> " + option.required() + "</td></tr>\n"); + } + sb.append("</tbody></table>\n"); + } + sb.append("</div>\n"); } sb.append(getFooter()); + + Files.createFile(file, sb.toString()); } private String getHeader() { - return "<html><head><title>DL-Learner components and configuration options</title></head><body>"; + StringBuffer sb = new StringBuffer(); + sb.append("<html><head><title>DL-Learner components and configuration options</title>\n"); + sb.append("<style type=\"text/css\">\n"); + sb.append("body { line-height: 1.6em; font-size: 15px; font-family: \"Lucida Sans Unicode\", \"Lucida Grande\", Sans-Serif; }\n"); + sb.append("#hor-minimalist-a { font-size: 13px; background: #fff; margin: 30px; width: 90%;border-collapse: collapse; text-align: left; } \n"); + sb.append("#hor-minimalist-a th { font-size: 15px; font-weight: normal; color: #039; padding: 10px 8px; border-bottom: 2px solid #6678b1; }\n"); + sb.append("#hor-minimalist-a td { color: #669;padding: 9px 8px 0px 8px; }\n"); + sb.append("#hor-minimalist-a tbody tr:hover td { color: #009; }\n"); + sb.append("</style>\n"); + sb.append("<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js\"></script>"); + sb.append("<script type=\"text/javascript\" language=\"javascript\">\n"); + sb.append("//<![CDATA[\n"); + sb.append("function showOnlyCat(className){\n"); + sb.append(" $('div').show(); $('div').not('.'+className).hide(); }\n"); + sb.append("function showAllCat(){\n"); + sb.append(" $('div').show() };\n"); + sb.append("//]]>\n"); + sb.append("</script>\n"); + sb.append("</head><body>\n"); + return sb.toString(); } private String getFooter() { return "</body></html>"; } + // this is a hack, because we just assume that every PropertyEditor is named + // as TypeEditor (e.g. ObjectPropertyEditor); however that hack does not too much harm here + private static String getOptionType(ConfigOption option) { + String name = option.propertyEditorClass().getSimpleName(); + return name.substring(0, name.length()-6); + } + + private static String getCoreTypes(Class<? extends Component> comp) { + List<Class<? extends Component>> types = AnnComponentManager.getCoreComponentTypes(comp); + String str = ""; + for(Class<?extends Component> type : types) { + str += " " + type.getSimpleName(); + } + return str.substring(1); + } + public static void main(String[] args) { - File file = new File("doc/configOptions.html"); + File file = new File("../interfaces/doc/configOptions.html"); DocumentationHTMLGenerator dg = new DocumentationHTMLGenerator(); dg.writeConfigDocumentation(file); System.out.println("Done"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |