javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/ElementGenerator.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 02 May 2013 10:19:07 +0200
branchelements
changeset 1074 3ab2f70b300d
parent 866 9b4751828ceb
permissions -rw-r--r--
Hide what can be hidden
     1 /**
     2  * Back 2 Browser Bytecode Translator
     3  * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 2 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. Look for COPYING file in the top folder.
    16  * If not, see http://opensource.org/licenses/GPL-2.0.
    17  */
    18 package org.apidesign.bck2brwsr.htmlpage;
    19 
    20 import java.io.IOException;
    21 import java.io.OutputStreamWriter;
    22 import java.io.Writer;
    23 import java.util.Arrays;
    24 import java.util.Collections;
    25 import java.util.HashMap;
    26 import java.util.Map;
    27 import java.util.Map.Entry;
    28 import java.util.ServiceLoader;
    29 import javax.annotation.processing.ProcessingEnvironment;
    30 import javax.lang.model.element.Element;
    31 import javax.tools.Diagnostic;
    32 import javax.tools.FileObject;
    33 import org.netbeans.modules.html.editor.lib.api.HtmlVersion;
    34 import org.netbeans.modules.html.editor.lib.api.model.HtmlModel;
    35 import org.netbeans.modules.html.editor.lib.api.model.HtmlModelProvider;
    36 import org.netbeans.modules.html.editor.lib.api.model.HtmlTag;
    37 import org.netbeans.modules.html.editor.lib.api.model.HtmlTagAttribute;
    38 
    39 /**
    40  *
    41  * @author Jan Horvath <jhorvath@netbeans.org>
    42  */
    43 final class ElementGenerator {
    44 
    45     static final Map<String, String> NAMING_EXCEPTIONS = new HashMap<String, String>() {
    46         {
    47             put("img", "Image");
    48             put("class", "Clazz");
    49         }
    50     };
    51     
    52     static final String javaKeywords[] = {
    53         "abstract", "assert", "boolean", "break", "byte", "case",
    54         "catch", "char", "class", "const", "continue", "default", 
    55         "do", "double", "else", "extends", "false", "final", "finally", 
    56         "float", "for", "goto", "if", "implements", "import", 
    57         "instanceof", "int", "interface", "long", "native", "new",
    58         "null", "package", "private", "protected", "public",
    59         "return", "short", "static", "strictfp", "super",
    60         "switch", "synchronized", "this", "throw", "throws",
    61         "transient", "true", "try", "void", "volatile", "while"
    62     };
    63     
    64     private static Map<String, String> elements = new HashMap<String, String>();
    65     private final ProcessingEnvironment processingEnv;
    66     private HtmlModel model = null;
    67 
    68     ElementGenerator(ProcessingEnvironment processingEnv) {
    69         this.processingEnv = processingEnv;
    70     }
    71 
    72     String getType(String pkg, String tag, Element e) {
    73         String className = elements.get(tag);
    74         if (className == null) {
    75             className = createClass(pkg, tag, e);
    76             elements.put(tag, className);
    77         }
    78         return className;
    79     }
    80 
    81     private String createClass(String pkg, String tag, Element e) {
    82         String className = className(tag);
    83         Writer w;
    84         try {
    85             FileObject java = processingEnv.getFiler().createSourceFile(pkg + '.' + className, e);
    86             w = new OutputStreamWriter(java.openOutputStream());
    87             try {
    88                 w.append("package " + pkg + ";\n\n");
    89                 w.append("import org.apidesign.bck2brwsr.htmlpage.api.*;\n");
    90                 PredefinedFields.appendImports(w, tag);
    91                 w.append("\n");
    92                 
    93                 w.append("class ").append(className).append(" extends Element {\n\n");
    94                 w.append("    public ").append(className).append("(String id) {\n");
    95                 w.append("        super(id);\n");
    96                 w.append("    }\n\n");
    97                 for (Entry<String, String> entry : getAttributes(tag).entrySet()) {
    98                     String attrName = entry.getKey();
    99                     String attrType = entry.getValue();
   100                     // getter
   101                     w.append("    public ").append(attrType).append(" ")
   102                             .append("get").append(className(attrName)).append("() {\n");
   103                     w.append("        return (").append(attrType).append(")getAttribute(\"")
   104                             .append(attrName).append("\");\n");
   105                     w.append("    }\n\n");
   106                     // setter
   107                     w.append("    public void ")
   108                             .append("set").append(className(attrName)).append("(")
   109                             .append(attrType).append(" ").append(attributeName(attrName)).append(") {\n");
   110                     w.append("        setAttribute(\"").append(attrName).append("\", ").append(attributeName(attrName)).append(");\n");
   111                     w.append("    }\n\n");
   112                 }
   113                 PredefinedFields.appendFields(w, tag);
   114                 w.append("}\n");
   115             } finally {
   116                 w.close();
   117             }
   118         } catch (IOException ex) {
   119             processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Can't create " + className + ".java", e);
   120             return null;
   121         }
   122         return className;
   123     }
   124 
   125     Map<String, String> getAttributes(String tagName) {
   126         Map<String, String> result = new HashMap<String, String>();
   127 
   128         if (model == null) {
   129             // HtmlModelProvider modelProvider = Lookup.getDefault().lookup(HtmlModelProvider.class);
   130             ServiceLoader<HtmlModelProvider> hmpLoader = 
   131                     ServiceLoader.load(HtmlModelProvider.class, this.getClass().getClassLoader());
   132             for (HtmlModelProvider htmlModelProvider : hmpLoader) {
   133                 model = htmlModelProvider.getModel(HtmlVersion.HTML5);
   134                 if (model != null) {
   135                     break;
   136                 }
   137             }
   138         }
   139         
   140         if (model == null) {
   141             processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, 
   142                     "HTML 5 model provider was not found on classpath");
   143             return Collections.emptyMap();
   144         }
   145         HtmlTag tag = model.getTag(tagName);
   146         for (HtmlTagAttribute attr : tag.getAttributes()) {
   147             String name = attr.getName();
   148             String type = Attributes.TYPES.get(name);
   149             if (type != null) {
   150                 result.put(name, type);
   151             }
   152         }
   153         
   154         return result;
   155     }
   156 
   157     private String className(String s) {
   158         if (s.length() == 0) {
   159             return s;
   160         }
   161         String name = NAMING_EXCEPTIONS.get(s.toLowerCase());
   162         if (name == null) {
   163             name = s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
   164         }
   165         return name;
   166     }
   167 
   168     private String attributeName(String s) {
   169         if (Arrays.binarySearch(javaKeywords, s) >= 0) {
   170             return String.format("%sAttr", s);
   171         }
   172         return s;
   173     }
   174     
   175 }