Package de.lmu.ifi.dbs.elki.application.internal

Source Code of de.lmu.ifi.dbs.elki.application.internal.DocumentReferences

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) 2012
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import java.io.BufferedOutputStream;
import java.io.File;
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.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Comment;
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.Reference;
import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;
import de.lmu.ifi.dbs.elki.utilities.xml.HTMLUtil;

/**
* Build a reference documentation for all available parameters.
*
* @author Erich Schubert
*
* @apiviz.uses Reference
*/
public class DocumentReferences {
  private static final String CSSFILE = "stylesheet.css";

  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 || args.length > 2) {
      LoggingUtil.warning("I need exactly one or two file names to operate!");
      System.exit(1);
    }
    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);
    }

    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);
      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 {
        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 Wiki output.", e);
        throw new RuntimeException(e);
      }
    }
  }

  private static Document documentReferences(List<Pair<Reference, List<Class<?>>>> refs) {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder;
    try {
      builder = factory.newDocumentBuilder();
    }
    catch(ParserConfigurationException e1) {
      throw new RuntimeException(e1);
    }
    DOMImplementation impl = builder.getDOMImplementation();
    Document htmldoc = impl.createDocument(HTMLUtil.HTML_NAMESPACE, HTMLUtil.HTML_HTML_TAG, null);
    // head
    Element head = htmldoc.createElement(HTMLUtil.HTML_HEAD_TAG);
    htmldoc.getDocumentElement().appendChild(head);
    // body
    Element body = htmldoc.createElement(HTMLUtil.HTML_BODY_TAG);
    htmldoc.getDocumentElement().appendChild(body);
    // modification warnings
    {
      Comment warn = htmldoc.createComment(MODIFICATION_WARNING);
      head.appendChild(warn);
      Comment warn2 = htmldoc.createComment(MODIFICATION_WARNING);
      body.appendChild(warn2);
    }
    // meta with charset information
    {
      Element meta = htmldoc.createElement(HTMLUtil.HTML_META_TAG);
      meta.setAttribute(HTMLUtil.HTML_HTTP_EQUIV_ATTRIBUTE, HTMLUtil.HTML_HTTP_EQUIV_CONTENT_TYPE);
      meta.setAttribute(HTMLUtil.HTML_CONTENT_ATTRIBUTE, HTMLUtil.CONTENT_TYPE_HTML_UTF8);
      head.appendChild(meta);
    }
    // stylesheet
    {
      Element css = htmldoc.createElement(HTMLUtil.HTML_LINK_TAG);
      css.setAttribute(HTMLUtil.HTML_REL_ATTRIBUTE, HTMLUtil.HTML_REL_STYLESHEET);
      css.setAttribute(HTMLUtil.HTML_TYPE_ATTRIBUTE, HTMLUtil.CONTENT_TYPE_CSS);
      css.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, CSSFILE);
      head.appendChild(css);
    }
    // title
    {
      Element title = htmldoc.createElement(HTMLUtil.HTML_TITLE_TAG);
      title.setTextContent("ELKI references overview.");
      head.appendChild(title);
    }
    // Heading
    {
      Element h1 = htmldoc.createElement(HTMLUtil.HTML_H1_TAG);
      h1.setTextContent("ELKI references overview:");
      body.appendChild(h1);
    }

    // Main definition list
    Element maindl = htmldoc.createElement(HTMLUtil.HTML_DL_TAG);
    body.appendChild(maindl);
    for(Pair<Reference, List<Class<?>>> pair : refs) {
      // DT = definition term
      Element classdt = htmldoc.createElement(HTMLUtil.HTML_DT_TAG);
      // Anchor for references
      {
        boolean first = true;
        for(Class<?> cls : pair.second) {
          if(!first) {
            classdt.appendChild(htmldoc.createTextNode(", "));
          }
          Element classan = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
          classan.setAttribute(HTMLUtil.HTML_NAME_ATTRIBUTE, cls.getName());
          classdt.appendChild(classan);

          // Link back to original class
          Element classa = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
          classa.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, linkForClassName(cls.getName()));
          classa.setTextContent(cls.getName());
          classdt.appendChild(classa);

          first = false;
        }
      }
      maindl.appendChild(classdt);
      // DD = definition description
      Element classdd = htmldoc.createElement(HTMLUtil.HTML_DD_TAG);
      maindl.appendChild(classdd);

      {
        Reference ref = pair.first;
        // Prefix
        if(ref.prefix().length() > 0) {
          Element prediv = htmldoc.createElement(HTMLUtil.HTML_DIV_TAG);
          prediv.setTextContent(ref.prefix());
          classdd.appendChild(prediv);
        }
        // Authors
        Element authorsdiv = htmldoc.createElement(HTMLUtil.HTML_DIV_TAG);
        authorsdiv.setTextContent(ref.authors());
        classdd.appendChild(authorsdiv);
        // Title
        Element titlediv = htmldoc.createElement(HTMLUtil.HTML_DIV_TAG);
        Element titleb = htmldoc.createElement(HTMLUtil.HTML_B_TAG);
        titleb.setTextContent(ref.title());
        titlediv.appendChild(titleb);
        classdd.appendChild(titlediv);
        // Booktitle
        Element booktitlediv = htmldoc.createElement(HTMLUtil.HTML_DIV_TAG);
        booktitlediv.setTextContent("In: " + ref.booktitle());
        classdd.appendChild(booktitlediv);
        // URL
        if(ref.url().length() > 0) {
          Element urldiv = htmldoc.createElement(HTMLUtil.HTML_DIV_TAG);
          Element urla = htmldoc.createElement(HTMLUtil.HTML_A_TAG);
          urla.setAttribute(HTMLUtil.HTML_HREF_ATTRIBUTE, ref.url());
          urla.setTextContent(ref.url());
          urldiv.appendChild(urla);
          classdd.appendChild(urldiv);
        }
      }
    }
    return htmldoc;
  }

  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("");

      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]]");
        }
      }
      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;
  }

  /**
   * Fin all classes that have the reference annotation
   *
   * @return All classes with the reference annotation.
   */
  public static ArrayList<Class<?>> findAllClassesWithReferences() {
    ArrayList<Class<?>> references = new ArrayList<Class<?>>();
    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;
  }
}
TOP

Related Classes of de.lmu.ifi.dbs.elki.application.internal.DocumentReferences

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.