Coverage Report - no.sesat.mojo.modes.Builder
 
Classes in this File Line Coverage Branch Coverage Complexity
Builder
0%
0/108
0%
0/34
0
Builder$1
0%
0/2
N/A
0
Builder$2
0%
0/2
N/A
0
Builder$3
0%
0/2
N/A
0
 
 1  
 package no.sesat.mojo.modes;
 2  
 
 3  
 import static com.sun.tools.javac.code.Flags.PROTECTED;
 4  
 import static com.sun.tools.javac.code.Flags.PUBLIC;
 5  
 
 6  
 import java.io.ByteArrayOutputStream;
 7  
 import java.io.File;
 8  
 import java.io.IOException;
 9  
 import java.io.PrintStream;
 10  
 import java.util.Vector;
 11  
 
 12  
 import com.sun.javadoc.ClassDoc;
 13  
 import com.sun.javadoc.RootDoc;
 14  
 import com.sun.tools.javac.util.Context;
 15  
 import com.sun.tools.javac.util.ListBuffer;
 16  
 import com.sun.tools.javac.util.Options;
 17  
 import com.sun.tools.javadoc.JavadocTool;
 18  
 import com.sun.tools.javadoc.Messager;
 19  
 import com.sun.tools.javadoc.ModifierFilter;
 20  
 import com.sun.tools.javadoc.RootDocImpl;
 21  
 
 22  
 /**
 23  
  * Builder to build a structure that mirrors the structure that should be used
 24  
  * in the modes.xml files. *
 25  
  */
 26  
 public final class Builder {
 27  
 
 28  0
     private static String outputDir = "";
 29  0
     private static String id = "";
 30  
 
 31  0
     private Builder() {
 32  0
     }
 33  
 
 34  
     /**
 35  
      * Build and generate schema for modes.xml files.
 36  
      *
 37  
      * @param classpath
 38  
      *            Where to find the classes
 39  
      * @param dir
 40  
      *            Where the results should be put
 41  
      * @param idString
 42  
      *            Id
 43  
      */
 44  
     public static void build(final String classpath, final String dir, final String idString) {
 45  0
         outputDir = new File(dir).getAbsolutePath() + File.separator;
 46  0
         id = idString;
 47  0
         RootDocImpl root = null;
 48  
         
 49  
         // hack to suppress javadoc's warnings.
 50  0
         final PrintStream out = System.out;
 51  0
         final PrintStream err = System.err;
 52  
         try {
 53  0
             System.setOut(new PrintStream(new ByteArrayOutputStream()));
 54  0
             System.setErr(new PrintStream(new ByteArrayOutputStream()));
 55  
 
 56  0
             final Context context = new Context();
 57  0
             Messager.preRegister(context, "Builder");
 58  0
             final JavadocTool comp = JavadocTool.make0(context);
 59  
 
 60  0
             final ListBuffer<String> subPackages = new ListBuffer<String>();
 61  0
             subPackages.append("no");
 62  0
             final ListBuffer<String> xcludePackages = new ListBuffer<String>();
 63  0
             final ListBuffer<String> javaNames = new ListBuffer<String>();
 64  0
             final ListBuffer<String[]> options = new ListBuffer<String[]>();
 65  
 
 66  0
             final Options compOpts = Options.instance(context);
 67  0
             compOpts.put("-classpath", classpath);
 68  
             
 69  
             try {
 70  0
                 root = comp.getRootDocImpl("", "", new ModifierFilter(PUBLIC | PROTECTED), javaNames.toList(), options
 71  
                         .toList(), false, subPackages.toList(), xcludePackages.toList(), false, false, false);
 72  0
             } catch (IOException e) {
 73  0
                 e.printStackTrace(err);
 74  
                 return;
 75  0
             }
 76  0
         } catch (Throwable e) {
 77  
             // e.printStackTrace(out);
 78  0
             out.print("Generating schema files failed due to error: " + e.getMessage());
 79  
         } finally {
 80  0
             System.setOut(out);
 81  0
             System.setErr(err);
 82  0
         }
 83  0
         if (root != null) {
 84  0
             start(root);
 85  
         }
 86  0
     }
 87  
 
 88  
     /**
 89  
      * This is the entry point for a doclet.
 90  
      *
 91  
      * @param root
 92  
      *            Root document
 93  
      * @return true when everything is ok
 94  
      */
 95  
     public static boolean start(final RootDoc root) {
 96  0
         final ConfigElement defaultConvert = new ConfigElement("default-convert");
 97  0
         defaultConvert.attributes.add(new ConfigAttribute("name"));
 98  0
         defaultConvert.attributes.add(new ConfigAttribute("prefix"));
 99  0
         defaultConvert.attributes.add(new ConfigAttribute("postfix"));
 100  
 
 101  0
         final Vector<ConfigElement> commands = new Vector<ConfigElement>();
 102  0
         final Vector<ConfigElement> resultHandlers = new Vector<ConfigElement>();
 103  0
         final Vector<ConfigElement> queryTransformers = new Vector<ConfigElement>();
 104  
         {
 105  0
             final ClassDoc[] classes = root.classes();
 106  0
             for (int i = 0; i < classes.length; i++) {
 107  0
                 final String name = classes[i].name();
 108  0
                 if (name.endsWith("Config") && !classes[i].isAbstract()) {
 109  0
                     final ConfigElement element = new ConfigElement(classes[i]);
 110  
 
 111  0
                     if (name.endsWith("CommandConfig")) {
 112  0
                         element.applyNameFilter(new NameFilter() {
 113  
                             public String filter(final String name) {
 114  0
                                 return toXmlName(name.substring(0, name.lastIndexOf("Config")));
 115  
                             }
 116  
                         });
 117  0
                         commands.add(element);
 118  0
                     } else if (name.endsWith("ResultHandlerConfig")) {
 119  0
                         element.applyNameFilter(new NameFilter() {
 120  
                             public String filter(final String name) {
 121  0
                                 return toXmlName(name.substring(0, name.lastIndexOf("ResultHandlerConfig")));
 122  
                             }
 123  
                         });
 124  0
                         if (!element.name.isEmpty()) {
 125  0
                             resultHandlers.add(element);
 126  
                         }
 127  0
                     } else if (name.endsWith("QueryTransformer") || (name.endsWith("QueryTransformerConfig"))) {
 128  0
                         element.applyNameFilter(new NameFilter() {
 129  
                             public String filter(final String name) {
 130  0
                                 return toXmlName(name.substring(0, name.lastIndexOf("QueryTransformer")));
 131  
                             }
 132  
                         });
 133  
 
 134  0
                         if (name.equals("NewsCaseQueryTransformerConfig")) {
 135  0
                             element.addChild(defaultConvert);
 136  
                         }
 137  
 
 138  0
                         queryTransformers.add(element);
 139  
                     } else {
 140  0
                         System.out.println("Lost: " + element.name);
 141  
                     }
 142  
                 }
 143  
             }
 144  
         }
 145  
 
 146  0
         final ConfigElement modes = new ConfigElement("modes");
 147  0
         modes.attributes.add(new ConfigAttribute("template-prefix"));
 148  
 
 149  0
         final ConfigElement mode = new ConfigElement("mode");
 150  0
         mode.attributes.add(new ConfigAttribute("id"));
 151  0
         mode.attributes.add(new ConfigAttribute("inherit"));
 152  0
         mode.attributes.add(new ConfigAttribute("analysis"));
 153  0
         mode.attributes.add(new ConfigAttribute("executor"));
 154  
 
 155  0
         mode.addChildren(commands);
 156  0
         modes.addChild(mode);
 157  
 
 158  0
         final ConfigElement resultHandler = new ConfigElement("result-handlers");
 159  0
         resultHandler.addChildren(resultHandlers);
 160  
 
 161  0
         final ConfigElement queryTransform = new ConfigElement("query-transformers");
 162  0
         queryTransform.addChildren(queryTransformers);
 163  
 
 164  0
         final ConfigElement navigators = new ConfigElement("navigators");
 165  0
         final ConfigElement navigator = new ConfigElement("navigator");
 166  0
         navigator.attributes.add(new ConfigAttribute("id", null, true));
 167  0
         navigator.attributes.add(new ConfigAttribute("name", null, true));
 168  0
         navigator.attributes.add(new ConfigAttribute("field", null, true));
 169  0
         navigator.attributes.add(new ConfigAttribute("display-name", null, true));
 170  0
         navigator.attributes.add(new ConfigAttribute("sort", null, false));
 171  0
         navigator.attributes.add(new ConfigAttribute("boundary-match"));
 172  
 
 173  
         // allow recursive nesting of navigator.
 174  0
         navigator.addChild(navigator);
 175  
 
 176  
         // only for fast commands
 177  0
         navigators.addChild(navigator);
 178  
 
 179  0
         for (ConfigElement command : commands) {
 180  0
             command.addChild(resultHandler);
 181  0
             command.addChild(queryTransform);
 182  0
             command.addChild(navigators);
 183  
         }
 184  
 
 185  0
         final Runnable[] jobs = {new GenerateRelaxNG(modes, outputDir + "modes.rnc", id),
 186  
                 new GenerateXSD(modes, outputDir + "modes.xsd", id),
 187  
                 new GenerateDTD(modes, outputDir + "modes.dtd", id)};
 188  0
         final int jobCount = 5;
 189  0
         for (int i = 0; i < (jobs.length + jobCount - 1); i++) {
 190  
 
 191  0
             if (i < jobs.length) {
 192  
                 // System.out.println("start job: " + i);
 193  0
                 final Thread thread = new Thread(jobs[i]);
 194  0
                 thread.start();
 195  0
                 jobs[i] = thread;
 196  
             }
 197  0
             if (i >= (jobCount - 1)) {
 198  
                 try {
 199  0
                     ((Thread) jobs[i - jobCount + 1]).join();
 200  
                     // System.out.println("job done: " + (i - jobCount + 1));
 201  0
                 } catch (InterruptedException e) {
 202  0
                     e.printStackTrace();
 203  0
                 }
 204  
             }
 205  
         }
 206  
 
 207  0
         System.out.println("commands : " + commands.size());
 208  0
         System.out.println("result handlers : " + resultHandlers.size());
 209  0
         System.out.println("query transformers : " + queryTransformers.size());
 210  
 
 211  0
         return true;
 212  
     }
 213  
 
 214  
     /**
 215  
      * Helper function to convert a java name to the equivalent XML name.
 216  
      *
 217  
      * @param name
 218  
      *            Name that should be converted
 219  
      * @return The name converted like this MySuperClass --> my-super-class
 220  
      */
 221  
     public static String toXmlName(final String name) {
 222  0
         final StringBuilder xmlName = new StringBuilder(name);
 223  0
         for (int i = 0; i < xmlName.length(); ++i) {
 224  0
             final char c = xmlName.charAt(i);
 225  0
             if (Character.isUpperCase(c)) {
 226  0
                 xmlName.replace(i, i + 1, (i == 0 ? "" : "-") + Character.toLowerCase(c));
 227  0
                 ++i;
 228  
             }
 229  
         }
 230  0
         return xmlName.toString();
 231  
     }
 232  
 }