diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/application/internal')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIServices.java (renamed from src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIProperties.java) | 96 | ||||
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java | 2 | ||||
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java | 13 | ||||
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java | 176 | ||||
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/application/internal/package-info.java | 2 |
5 files changed, 205 insertions, 84 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIProperties.java b/src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIServices.java index fa260564..21ed047b 100644 --- a/src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIProperties.java +++ b/src/de/lmu/ifi/dbs/elki/application/internal/CheckELKIServices.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.internal; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2011 + Copyright (C) 2012 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -23,36 +23,44 @@ package de.lmu.ifi.dbs.elki.application.internal; along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URISyntaxException; +import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import de.lmu.ifi.dbs.elki.logging.Logging; -import de.lmu.ifi.dbs.elki.properties.Properties; +import de.lmu.ifi.dbs.elki.utilities.ELKIServiceLoader; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; import de.lmu.ifi.dbs.elki.utilities.InspectionUtil; +import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException; /** - * Helper application to test the ELKI properties file for "missing" implementations. + * Helper application to test the ELKI properties file for "missing" + * implementations. * * @author Erich Schubert * - * @apiviz.uses Properties + * @apiviz.uses ELKIServiceLoader */ -public class CheckELKIProperties { +public class CheckELKIServices { /** * The logger for this class. */ - private static final Logging logger = Logging.getLogger(CheckELKIProperties.class); - + private static final Logging logger = Logging.getLogger(CheckELKIServices.class); + /** * Pattern to strip comments, while keeping commented class names. */ - private Pattern strip = Pattern.compile("^[\\s#]*(.*?)[\\s,]*$"); + private Pattern strip = Pattern.compile("^[\\s#]*(.*?)[\\s]*$"); /** * Package to skip matches in - unreleased code. @@ -65,25 +73,36 @@ public class CheckELKIProperties { * @param argv Command line arguments */ public static void main(String[] argv) { - new CheckELKIProperties().checkProperties(); + new CheckELKIServices().checkServices(); } - + /** * Retrieve all properties and check them. */ - public void checkProperties() { - Set<String> props = Properties.ELKI_PROPERTIES.getPropertyNames(); - for(String prop : props) { - checkProperty(prop); + public void checkServices() { + URL u = getClass().getClassLoader().getResource(ELKIServiceLoader.PREFIX); + try { + for(String prop : new File(u.toURI()).list()) { + if (".svn".equals(prop)) { + continue; + } + if (logger.isVerbose()) { + logger.verbose("Checking property: "+prop); + } + checkService(prop); + } + } + catch(URISyntaxException e) { + throw new AbortException("Cannot check all properties, as some are not in a file: URL."); } } /** - * Check a single property + * Check a single service class * - * @param prop Property = Class name. + * @param prop Class name. */ - private void checkProperty(String prop) { + private void checkService(String prop) { Class<?> cls; try { cls = Class.forName(prop); @@ -108,23 +127,34 @@ public class CheckELKIProperties { names.add(c2.getName()); } - String[] known = Properties.ELKI_PROPERTIES.getProperty(cls.getName()); - for(String k : known) { - Matcher m = strip.matcher(k); - if(m.matches()) { - String stripped = m.group(1); - if(stripped.length() > 0) { - if(names.contains(stripped)) { - names.remove(stripped); - } - else { - logger.warning("Name " + stripped + " found for property " + prop + " but no class discovered (or referenced twice?)."); + try { + InputStream is = getClass().getClassLoader().getResource(ELKIServiceLoader.PREFIX + cls.getName()).openStream(); + BufferedReader r = new BufferedReader(new InputStreamReader(is, "utf-8")); + for(String line;;) { + line = r.readLine(); + // End of stream: + if(line == null) { + break; + } + Matcher m = strip.matcher(line); + if(m.matches()) { + String stripped = m.group(1); + if(stripped.length() > 0) { + if(names.contains(stripped)) { + names.remove(stripped); + } + else { + logger.warning("Name " + stripped + " found for property " + prop + " but no class discovered (or referenced twice?)."); + } } } + else { + logger.warning("Line: " + line + " didn't match regexp."); + } } - else { - logger.warning("Line: " + k + " didn't match regexp."); - } + } + catch(IOException e) { + logger.exception(e); } if(names.size() > 0) { StringBuffer message = new StringBuffer(); @@ -134,7 +164,7 @@ public class CheckELKIProperties { // TODO: sort by package, then classname Collections.sort(sorted); for(String remaining : sorted) { - message.append("# " + remaining + ",\\" + FormatUtil.NEWLINE); + message.append("# " + remaining + FormatUtil.NEWLINE); } logger.warning(message.toString()); } diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java b/src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java index 017f2d12..b94ee47a 100644 --- a/src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java +++ b/src/de/lmu/ifi/dbs/elki/application/internal/CheckParameterizables.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.internal; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2011 + Copyright (C) 2012 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java index 05af4b4d..c77e9dbb 100644 --- a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java +++ b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentParameters.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.internal; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2011 + Copyright (C) 2012 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -33,6 +33,7 @@ import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -50,11 +51,10 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import de.lmu.ifi.dbs.elki.logging.Logging; -import de.lmu.ifi.dbs.elki.properties.Properties; import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil; +import de.lmu.ifi.dbs.elki.utilities.ELKIServiceLoader; import de.lmu.ifi.dbs.elki.utilities.InspectionUtil; import de.lmu.ifi.dbs.elki.utilities.datastructures.HashMapList; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizer; @@ -635,8 +635,8 @@ public class DocumentParameters { private static void appendKnownImplementationsIfNonempty(Document htmldoc, ClassParameter<?> opt, Element elemdd) { if(opt.getRestrictionClass() != Object.class) { - IterableIterator<Class<?>> iter = opt.getKnownImplementations(); - if(iter.hasNext()) { + List<Class<?>> iter = opt.getKnownImplementations(); + if(!iter.isEmpty()) { Element p = htmldoc.createElement(HTMLUtil.HTML_P_TAG); p.appendChild(htmldoc.createTextNode(HEADER_KNOWN_IMPLEMENTATIONS)); elemdd.appendChild(p); @@ -652,7 +652,8 @@ public class DocumentParameters { elemdd.appendChild(ul); } // Report when not in properties file. - if(Properties.ELKI_PROPERTIES.getProperty(opt.getRestrictionClass().getName()).length == 0) { + Iterator<Class<?>> clss = new ELKIServiceLoader(opt.getRestrictionClass()); + if (!clss.hasNext()) { logger.warning(opt.getRestrictionClass().getName() + " not in properties. No autocompletion available in release GUI."); } } diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java index 949a7874..2e002243 100644 --- a/src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java +++ b/src/de/lmu/ifi/dbs/elki/application/internal/DocumentReferences.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.application.internal; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2011 + Copyright (C) 2012 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -25,12 +25,12 @@ package de.lmu.ifi.dbs.elki.application.internal; import java.io.BufferedOutputStream; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.PrintStream; +import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -44,9 +44,9 @@ import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.Element; +import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; import de.lmu.ifi.dbs.elki.utilities.InspectionUtil; -import de.lmu.ifi.dbs.elki.utilities.documentation.DocumentationUtil; import de.lmu.ifi.dbs.elki.utilities.documentation.Reference; import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; import de.lmu.ifi.dbs.elki.utilities.xml.HTMLUtil; @@ -64,46 +64,56 @@ public class DocumentReferences { private static final String MODIFICATION_WARNING = "WARNING: THIS DOCUMENT IS AUTOMATICALLY GENERATED. MODIFICATIONS MAY GET LOST."; /** + * Logger + */ + private static final Logging logger = Logging.getLogger(DocumentReferences.class); + + /** * @param args Command line arguments */ public static void main(String[] args) { - if(args.length != 1) { - LoggingUtil.warning("I need exactly one file name to operate!"); + if(args.length < 1 || args.length > 2) { + LoggingUtil.warning("I need exactly one or two file names to operate!"); System.exit(1); } - if(!args[0].endsWith(".html")) { - LoggingUtil.warning("File name doesn't end with .html!"); + if(!args[0].endsWith(".html") || (args.length > 1 && !args[1].endsWith(".wiki"))) { + LoggingUtil.warning("File name doesn't end in expected extension!"); System.exit(1); } - File references = new File(args[0]); - { - FileOutputStream reffo; - try { - reffo = new FileOutputStream(references); - } - catch(FileNotFoundException e) { - LoggingUtil.exception("Can't create output stream!", e); - throw new RuntimeException(e); - } + List<Pair<Reference, List<Class<?>>>> refs = sortedReferences(); + try { + File references = new File(args[0]); + FileOutputStream reffo = new FileOutputStream(references); + Document refdoc = documentReferences(refs); OutputStream refstream = new BufferedOutputStream(reffo); - Document refdoc = documentParameters(); + HTMLUtil.writeXHTML(refdoc, refstream); + refstream.flush(); + refstream.close(); + reffo.close(); + } + catch(IOException e) { + LoggingUtil.exception("IO Exception writing HTML output.", e); + throw new RuntimeException(e); + } + if(args.length > 1) { try { - HTMLUtil.writeXHTML(refdoc, refstream); - refstream.flush(); - refstream.close(); - reffo.close(); + File refwiki = new File(args[1]); + FileOutputStream reffow = new FileOutputStream(refwiki); + PrintStream refstreamW = new PrintStream(reffow); + documentReferencesWiki(refs, refstreamW); + refstreamW.flush(); + refstreamW.close(); + reffow.close(); } catch(IOException e) { - LoggingUtil.exception("IO Exception writing output.", e); + LoggingUtil.exception("IO Exception writing Wiki output.", e); throw new RuntimeException(e); } } } - private static Document documentParameters() { - List<Pair<Reference, List<Class<?>>>> refs = sortedReferences(); - + private static Document documentReferences(List<Pair<Reference, List<Class<?>>>> refs) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder; try { @@ -165,7 +175,7 @@ public class DocumentReferences { { boolean first = true; for(Class<?> cls : pair.second) { - if (!first) { + if(!first) { classdt.appendChild(htmldoc.createTextNode(", ")); } Element classan = htmldoc.createElement(HTMLUtil.HTML_A_TAG); @@ -177,7 +187,7 @@ public class DocumentReferences { classa.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, linkForClassName(cls.getName())); classa.setTextContent(cls.getName()); classdt.appendChild(classa); - + first = false; } } @@ -222,25 +232,98 @@ public class DocumentReferences { return htmldoc; } - private static List<Pair<Reference, List<Class<?>>>> sortedReferences() { - ArrayList<Class<?>> classes = findAllClassesWithReferences(); - Collections.sort(classes, new InspectionUtil.ClassSorter()); + private static void documentReferencesWiki(List<Pair<Reference, List<Class<?>>>> refs, PrintStream refstreamW) { + for(Pair<Reference, List<Class<?>>> pair : refs) { + // JavaDoc links for relevant classes. + { + boolean first = true; + for(Class<?> cls : pair.second) { + if(!first) { + refstreamW.println(",[[br]]"); + } + refstreamW.print("[[javadoc("); + refstreamW.print(cls.getName()); + refstreamW.print(","); + refstreamW.print(cls.getName()); + refstreamW.print(")]]"); + + first = false; + } + } + refstreamW.println(""); - List<Pair<Reference, List<Class<?>>>> refs = new ArrayList<Pair<Reference, List<Class<?>>>>(classes.size()); - Map<Reference, List<Class<?>>> map = new HashMap<Reference, List<Class<?>>>(classes.size()); - for(Class<?> cls : classes) { - Reference ref = DocumentationUtil.getReference(cls); - List<Class<?>> list = map.get(ref); - if(list == null) { - list = new ArrayList<Class<?>>(5); - map.put(ref, list); - refs.add(new Pair<Reference, List<Class<?>>>(ref, list)); + String indent = " "; + { + Reference ref = pair.first; + // Prefix + if(ref.prefix().length() > 0) { + refstreamW.println(indent + ref.prefix() + " [[br]]"); + } + // Authors + refstreamW.println(indent + "By: " + ref.authors() + " [[br]]"); + // Title + refstreamW.println(indent + "'''" + ref.title() + "'''" + " [[br]]"); + // Booktitle + refstreamW.println(indent + "In: " + ref.booktitle() + " [[br]]"); + // URL + if(ref.url().length() > 0) { + refstreamW.println(indent + "Online: [" + ref.url() + "][[br]]"); + } } - list.add(cls); + refstreamW.println(""); + refstreamW.println(""); + } + } + + private static List<Pair<Reference, List<Class<?>>>> sortedReferences() { + List<Pair<Reference, List<Class<?>>>> refs = new ArrayList<Pair<Reference, List<Class<?>>>>(); + Map<Reference, List<Class<?>>> map = new HashMap<Reference, List<Class<?>>>(); + + for(final Class<?> cls : InspectionUtil.findAllImplementations(Object.class, true)) { + inspectClass(cls, refs, map); } return refs; } + private static void inspectClass(final Class<?> cls, List<Pair<Reference, List<Class<?>>>> refs, Map<Reference, List<Class<?>>> map) { + try { + if(cls.isAnnotationPresent(Reference.class)) { + Reference ref = cls.getAnnotation(Reference.class); + List<Class<?>> list = map.get(ref); + if(list == null) { + list = new ArrayList<Class<?>>(5); + map.put(ref, list); + refs.add(new Pair<Reference, List<Class<?>>>(ref, list)); + } + list.add(cls); + } + // Inner classes + for(Class<?> c2 : cls.getDeclaredClasses()) { + inspectClass(c2, refs, map); + } + for(Method m : cls.getDeclaredMethods()) { + if(m.isAnnotationPresent(Reference.class)) { + Reference ref = m.getAnnotation(Reference.class); + List<Class<?>> list = map.get(ref); + if(list == null) { + list = new ArrayList<Class<?>>(5); + map.put(ref, list); + refs.add(new Pair<Reference, List<Class<?>>>(ref, list)); + } + list.add(cls); + } + } + } + catch(NoClassDefFoundError e) { + if(!cls.getCanonicalName().startsWith("experimentalcode.")) { + logger.warning("Exception in finding references for class " + cls.getCanonicalName() + " - missing referenced class?"); + } + } + catch(Error e) { + logger.warning("Exception in finding references for class " + cls.getCanonicalName() + ": " + e, e); + } + } + private static String linkForClassName(String name) { String link = name.replace(".", "/") + ".html"; return link; @@ -253,10 +336,17 @@ public class DocumentReferences { */ public static ArrayList<Class<?>> findAllClassesWithReferences() { ArrayList<Class<?>> references = new ArrayList<Class<?>>(); - for(final Class<?> cls : InspectionUtil.findAllImplementations(Object.class, false)) { + for(final Class<?> cls : InspectionUtil.findAllImplementations(Object.class, true)) { if(cls.isAnnotationPresent(Reference.class)) { references.add(cls); } + else { + for(Method m : cls.getDeclaredMethods()) { + if(m.isAnnotationPresent(Reference.class)) { + references.add(cls); + } + } + } } return references; } diff --git a/src/de/lmu/ifi/dbs/elki/application/internal/package-info.java b/src/de/lmu/ifi/dbs/elki/application/internal/package-info.java index dd7746e8..56326655 100644 --- a/src/de/lmu/ifi/dbs/elki/application/internal/package-info.java +++ b/src/de/lmu/ifi/dbs/elki/application/internal/package-info.java @@ -5,7 +5,7 @@ This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures -Copyright (C) 2011 +Copyright (C) 2012 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team |