1.1 --- a/json/src/main/java/net/java/html/json/Model.java Fri Jan 24 05:24:42 2014 +0100
1.2 +++ b/json/src/main/java/net/java/html/json/Model.java Fri Jan 24 13:15:30 2014 +0100
1.3 @@ -129,7 +129,7 @@
1.4 * @author Jaroslav Tulach <jtulach@netbeans.org>
1.5 */
1.6 @Retention(RetentionPolicy.SOURCE)
1.7 -@Target(ElementType.TYPE)
1.8 +@Target({ ElementType.TYPE, ElementType.FIELD })
1.9 public @interface Model {
1.10 /** Name of the model class */
1.11 String className();
2.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Fri Jan 24 05:24:42 2014 +0100
2.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Fri Jan 24 13:15:30 2014 +0100
2.3 @@ -123,13 +123,27 @@
2.4 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
2.5 boolean ok = true;
2.6 for (Element e : roundEnv.getElementsAnnotatedWith(Model.class)) {
2.7 - if (!processModel(e)) {
2.8 + if (e.getKind().isField()) {
2.9 + if (e.getKind() != ElementKind.ENUM_CONSTANT) {
2.10 + error("Only enum constants fields can be annotated by @Model annotations", e);
2.11 + ok = false;
2.12 + continue;
2.13 + }
2.14 + if (e.getEnclosingElement().getAnnotation(Model.class) == null) {
2.15 + error("Enclosing enum has to be annotated by @Model annotation", e);
2.16 + ok = false;
2.17 + continue;
2.18 + }
2.19 + } else if (!processModelOrEnum(e)) {
2.20 ok = false;
2.21 }
2.22 }
2.23 if (roundEnv.processingOver()) {
2.24 models.clear();
2.25 for (Map.Entry<Element, Prprt[]> entry : verify.entrySet()) {
2.26 + if (!(entry.getKey() instanceof TypeElement)) {
2.27 + continue;
2.28 + }
2.29 TypeElement te = (TypeElement)entry.getKey();
2.30 String fqn = processingEnv.getElementUtils().getBinaryName(te).toString();
2.31 Element finalElem = processingEnv.getElementUtils().getTypeElement(fqn);
2.32 @@ -171,6 +185,13 @@
2.33 processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg, e);
2.34 }
2.35
2.36 + private boolean processModelOrEnum(Element e) {
2.37 + if (e.getKind() == ElementKind.ENUM) {
2.38 + return processEnum(e);
2.39 + } else {
2.40 + return processModel(e);
2.41 + }
2.42 + }
2.43 private boolean processModel(Element e) {
2.44 boolean ok = true;
2.45 Model m = e.getAnnotation(Model.class);
2.46 @@ -213,6 +234,342 @@
2.47 try {
2.48 w.append("package " + pkg + ";\n");
2.49 w.append("import net.java.html.json.*;\n");
2.50 + w.append("public final ");
2.51 + generateClassBody(w, className, body, e, props, functionDeps, propsDeps, propsGetSet, functions, onReceiveType);
2.52 + } finally {
2.53 + w.close();
2.54 + }
2.55 + } catch (IOException ex) {
2.56 + error("Can't create " + className + ".java", e);
2.57 + return false;
2.58 + }
2.59 + return ok;
2.60 + }
2.61 +
2.62 + private void generateClassBody(Writer w, String className, StringWriter body, Element e, Prprt[] props, Map<String, Collection<String>> functionDeps, Map<String, Collection<String>> propsDeps, List<String> propsGetSet, List<String> functions, StringBuilder onReceiveType) throws IOException {
2.63 + w.append("class ").append(className).append(" implements Cloneable {\n");
2.64 + w.append(" private static final Html4JavaType TYPE = new Html4JavaType();\n");
2.65 + w.append(" private final org.apidesign.html.json.spi.Proto proto;\n");
2.66 + w.append(body.toString());
2.67 + w.append(" private static Class<" + inPckName(e) + "> modelFor() { return null; }\n");
2.68 + w.append(" private ").append(className).append("(net.java.html.BrwsrCtx context) {\n");
2.69 + w.append(" this.proto = TYPE.createProto(this, context);\n");
2.70 + for (Prprt p : props) {
2.71 + if (p.array()) {
2.72 + final String tn = typeName(e, p);
2.73 + String[] gs = toGetSet(p.name(), tn, p.array());
2.74 + w.write(" this.prop_" + p.name() + " = proto.createList(\""
2.75 + + p.name() + "\"");
2.76 + if (functionDeps.containsKey(p.name())) {
2.77 + int index = Arrays.asList(functionDeps.keySet().toArray()).indexOf(p.name());
2.78 + w.write(", " + index);
2.79 + } else {
2.80 + w.write(", -1");
2.81 + }
2.82 + Collection<String> dependants = propsDeps.get(p.name());
2.83 + if (dependants != null) {
2.84 + for (String depProp : dependants) {
2.85 + w.write(", ");
2.86 + w.write('\"');
2.87 + w.write(depProp);
2.88 + w.write('\"');
2.89 + }
2.90 + }
2.91 + w.write(")");
2.92 + w.write(";\n");
2.93 + }
2.94 + }
2.95 + w.append(" };\n");
2.96 + w.append(" public ").append(className).append("() {\n");
2.97 + w.append(" this(net.java.html.BrwsrCtx.findDefault(").append(className).append(".class));\n");
2.98 + for (Prprt p : props) {
2.99 + if (!p.array()) {
2.100 + boolean[] isModel = {false};
2.101 + boolean[] isEnum = {false};
2.102 + boolean isPrimitive[] = {false};
2.103 + String tn = checkType(p, isModel, isEnum, isPrimitive);
2.104 + if (isModel[0]) {
2.105 + w.write(" prop_" + p.name() + " = new " + tn + "();\n");
2.106 + }
2.107 + }
2.108 + }
2.109 + w.append(" };\n");
2.110 + if (props.length > 0) {
2.111 + w.append(" public ").append(className).append("(");
2.112 + Prprt firstArray = null;
2.113 + String sep = "";
2.114 + for (Prprt p : props) {
2.115 + if (p.array()) {
2.116 + if (firstArray == null) {
2.117 + firstArray = p;
2.118 + }
2.119 + continue;
2.120 + }
2.121 + String tn = typeName(e, p);
2.122 + w.write(sep);
2.123 + w.write(tn);
2.124 + w.write(" " + p.name());
2.125 + sep = ", ";
2.126 + }
2.127 + if (firstArray != null) {
2.128 + String tn;
2.129 + boolean[] isModel = {false};
2.130 + boolean[] isEnum = {false};
2.131 + boolean isPrimitive[] = {false};
2.132 + tn = checkType(firstArray, isModel, isEnum, isPrimitive);
2.133 + w.write(sep);
2.134 + w.write(tn);
2.135 + w.write("... " + firstArray.name());
2.136 + }
2.137 + w.append(") {\n");
2.138 + w.append(" this(net.java.html.BrwsrCtx.findDefault(").append(className).append(".class));\n");
2.139 + for (Prprt p : props) {
2.140 + if (p.array()) {
2.141 + continue;
2.142 + }
2.143 + w.write(" this.prop_" + p.name() + " = " + p.name() + ";\n");
2.144 + }
2.145 + if (firstArray != null) {
2.146 + w.write(" proto.initTo(this.prop_" + firstArray.name() + ", " + firstArray.name() + ");\n");
2.147 + }
2.148 + w.append(" };\n");
2.149 + }
2.150 + w.append(" private static class Html4JavaType extends org.apidesign.html.json.spi.Proto.Type<").append(className).append("> {\n");
2.151 + w.append(" private Html4JavaType() {\n super(").append(className).append(".class, ").
2.152 + append(inPckName(e)).append(".class, " + (propsGetSet.size() / 5) + ", "
2.153 + + (functions.size() / 2) + ");\n");
2.154 + {
2.155 + for (int i = 0; i < propsGetSet.size(); i += 5) {
2.156 + w.append(" registerProperty(\"").append(propsGetSet.get(i)).append("\", ");
2.157 + w.append((i / 5) + ", " + (propsGetSet.get(i + 2) == null) + ");\n");
2.158 + }
2.159 + }
2.160 + {
2.161 + for (int i = 0; i < functions.size(); i += 2) {
2.162 + w.append(" registerFunction(\"").append(functions.get(i)).append("\", ");
2.163 + w.append((i / 2) + ");\n");
2.164 + }
2.165 + }
2.166 + w.append(" }\n");
2.167 + w.append(" @Override public void setValue(" + className + " data, int type, Object value) {\n");
2.168 + w.append(" switch (type) {\n");
2.169 + for (int i = 0; i < propsGetSet.size(); i += 5) {
2.170 + final String set = propsGetSet.get(i + 2);
2.171 + String tn = propsGetSet.get(i + 4);
2.172 + String btn = findBoxedType(tn);
2.173 + if (btn != null) {
2.174 + tn = btn;
2.175 + }
2.176 + if (set != null) {
2.177 + w.append(" case " + (i / 5) + ": data." + strip(set) + "(TYPE.extractValue(" + tn + ".class, value)); return;\n");
2.178 + }
2.179 + }
2.180 + w.append(" }\n");
2.181 + w.append(" }\n");
2.182 + w.append(" @Override public Object getValue(" + className + " data, int type) {\n");
2.183 + w.append(" switch (type) {\n");
2.184 + for (int i = 0; i < propsGetSet.size(); i += 5) {
2.185 + final String get = propsGetSet.get(i + 1);
2.186 + if (get != null) {
2.187 + w.append(" case " + (i / 5) + ": return data." + strip(get) + "();\n");
2.188 + }
2.189 + }
2.190 + w.append(" }\n");
2.191 + w.append(" throw new UnsupportedOperationException();\n");
2.192 + w.append(" }\n");
2.193 + w.append(" @Override public void call(" + className + " model, int type, Object data, Object ev) {\n");
2.194 + w.append(" switch (type) {\n");
2.195 + for (int i = 0; i < functions.size(); i += 2) {
2.196 + final String name = functions.get(i);
2.197 + w.append(" case " + (i / 2) + ": model." + name + "(data, ev); return;\n");
2.198 + }
2.199 + w.append(" }\n");
2.200 + w.append(" throw new UnsupportedOperationException();\n");
2.201 + w.append(" }\n");
2.202 + w.append(" @Override public org.apidesign.html.json.spi.Proto protoFor(Object obj) {\n");
2.203 + w.append(" return ((" + className + ")obj).proto;");
2.204 + w.append(" }\n");
2.205 + w.append(" @Override public void onChange(" + className + " model, int type) {\n");
2.206 + w.append(" switch (type) {\n");
2.207 + {
2.208 + String[] arr = functionDeps.keySet().toArray(new String[0]);
2.209 + for (int i = 0; i < arr.length; i++) {
2.210 + Collection<String> onChange = functionDeps.get(arr[i]);
2.211 + if (onChange != null) {
2.212 + w.append(" case " + i + ":\n");
2.213 + for (String call : onChange) {
2.214 + w.append(" ").append(call).append("\n");
2.215 + }
2.216 + w.write(" return;\n");
2.217 + }
2.218 + }
2.219 + }
2.220 + w.append(" }\n");
2.221 + w.append(" throw new UnsupportedOperationException();\n");
2.222 + w.append(" }\n");
2.223 + w.append(onReceiveType);
2.224 + w.append(" @Override public " + className + " read(net.java.html.BrwsrCtx c, Object json) { return new " + className + "(c, json); }\n");
2.225 + w.append(" @Override public " + className + " cloneTo(" + className + " o, net.java.html.BrwsrCtx c) { return o.clone(c); }\n");
2.226 + w.append(" }\n");
2.227 + w.append(" private ").append(className).append("(net.java.html.BrwsrCtx c, Object json) {\n");
2.228 + w.append(" this(c);\n");
2.229 + int values = 0;
2.230 + for (int i = 0; i < propsGetSet.size(); i += 5) {
2.231 + Prprt p = findPrprt(props, propsGetSet.get(i));
2.232 + if (p == null) {
2.233 + continue;
2.234 + }
2.235 + values++;
2.236 + }
2.237 + w.append(" Object[] ret = new Object[" + values + "];\n");
2.238 + w.append(" proto.extract(json, new String[] {\n");
2.239 + for (int i = 0; i < propsGetSet.size(); i += 5) {
2.240 + Prprt p = findPrprt(props, propsGetSet.get(i));
2.241 + if (p == null) {
2.242 + continue;
2.243 + }
2.244 + w.append(" \"").append(propsGetSet.get(i)).append("\",\n");
2.245 + }
2.246 + w.append(" }, ret);\n");
2.247 + for (int i = 0, cnt = 0, prop = 0; i < propsGetSet.size(); i += 5) {
2.248 + final String pn = propsGetSet.get(i);
2.249 + Prprt p = findPrprt(props, pn);
2.250 + if (p == null) {
2.251 + continue;
2.252 + }
2.253 + boolean[] isModel = { false };
2.254 + boolean[] isEnum = { false };
2.255 + boolean isPrimitive[] = { false };
2.256 + String type = checkType(props[prop++], isModel, isEnum, isPrimitive);
2.257 + if (p.array()) {
2.258 + w.append(" if (ret[" + cnt + "] instanceof Object[]) {\n");
2.259 + w.append(" for (Object e : ((Object[])ret[" + cnt + "])) {\n");
2.260 + if (isModel[0]) {
2.261 + w.append(" this.prop_").append(pn).append(".add(proto.read");
2.262 + w.append("(" + type + ".class, e));\n");
2.263 + } else if (isEnum[0]) {
2.264 + w.append(" this.prop_").append(pn);
2.265 + w.append(".add(e == null ? null : ");
2.266 + w.append(type).append(".valueOf(TYPE.stringValue(e)));\n");
2.267 + } else {
2.268 + if (isPrimitive(type)) {
2.269 + w.append(" this.prop_").append(pn).append(".add(TYPE.numberValue(e).");
2.270 + w.append(type).append("Value());\n");
2.271 + } else {
2.272 + w.append(" this.prop_").append(pn).append(".add((");
2.273 + w.append(type).append(")e);\n");
2.274 + }
2.275 + }
2.276 + w.append(" }\n");
2.277 + w.append(" }\n");
2.278 + } else {
2.279 + if (isEnum[0]) {
2.280 + w.append(" try {\n");
2.281 + w.append(" this.prop_").append(pn);
2.282 + w.append(" = ret[" + cnt + "] == null ? null : ");
2.283 + w.append(type).append(".valueOf(TYPE.stringValue(ret[" + cnt + "]));\n");
2.284 + w.append(" } catch (IllegalArgumentException ex) {\n");
2.285 + w.append(" ex.printStackTrace();\n");
2.286 + w.append(" }\n");
2.287 + } else if (isPrimitive(type)) {
2.288 + w.append(" this.prop_").append(pn);
2.289 + w.append(" = ret[" + cnt + "] == null ? ");
2.290 + if ("char".equals(type)) {
2.291 + w.append("0 : (TYPE.charValue(");
2.292 + } else if ("boolean".equals(type)) {
2.293 + w.append("false : (TYPE.boolValue(");
2.294 + } else {
2.295 + w.append("0 : (TYPE.numberValue(");
2.296 + }
2.297 + w.append("ret[" + cnt + "])).");
2.298 + w.append(type).append("Value();\n");
2.299 + } else if (isModel[0]) {
2.300 + w.append(" this.prop_").append(pn).append(" = proto.read");
2.301 + w.append("(" + type + ".class, ");
2.302 + w.append("ret[" + cnt + "]);\n");
2.303 + }else {
2.304 + w.append(" this.prop_").append(pn);
2.305 + w.append(" = (").append(type).append(')');
2.306 + w.append("ret[" + cnt + "];\n");
2.307 + }
2.308 + }
2.309 + cnt++;
2.310 + }
2.311 + w.append(" }\n");
2.312 + writeToString(props, w);
2.313 + writeClone(className, props, w);
2.314 + w.write(" /** Activates this model instance in the current {@link \n"
2.315 + + "net.java.html.json.Models#bind(java.lang.Object, net.java.html.BrwsrCtx) browser context}. \n"
2.316 + + "In case of using Knockout technology, this means to \n"
2.317 + + "bind JSON like data in this model instance with Knockout tags in \n"
2.318 + + "the surrounding HTML page.\n"
2.319 + + "*/\n"
2.320 + );
2.321 + w.write(" public " + className + " applyBindings() {\n");
2.322 + w.write(" proto.applyBindings();\n");
2.323 + w.write(" return this;\n");
2.324 + w.write(" }\n");
2.325 + w.write(" public boolean equals(Object o) {\n");
2.326 + w.write(" if (o == this) return true;\n");
2.327 + w.write(" if (!(o instanceof " + className + ")) return false;\n");
2.328 + w.write(" " + className + " p = (" + className + ")o;\n");
2.329 + for (Prprt p : props) {
2.330 + w.write(" if (!TYPE.isSame(prop_" + p.name() + ", p.prop_" + p.name() + ")) return false;\n");
2.331 + }
2.332 + w.write(" return true;\n");
2.333 + w.write(" }\n");
2.334 + w.write(" public int hashCode() {\n");
2.335 + w.write(" int h = " + className + ".class.getName().hashCode();\n");
2.336 + for (Prprt p : props) {
2.337 + w.write(" h = TYPE.hashPlus(prop_" + p.name() + ", h);\n");
2.338 + }
2.339 + w.write(" return h;\n");
2.340 + w.write(" }\n");
2.341 + w.write("}\n");
2.342 + }
2.343 +
2.344 + private boolean processEnum(Element e) {
2.345 + boolean ok = true;
2.346 + Model m = e.getAnnotation(Model.class);
2.347 + if (m == null) {
2.348 + return true;
2.349 + }
2.350 + String pkg = findPkgName(e);
2.351 + Writer w;
2.352 + String className = m.className();
2.353 + models.put(e, className);
2.354 + try {
2.355 + StringWriter body = new StringWriter();
2.356 + StringBuilder onReceiveType = new StringBuilder();
2.357 + List<String> propsGetSet = new ArrayList<String>();
2.358 + List<String> functions = new ArrayList<String>();
2.359 + Map<String, Collection<String>> propsDeps = new HashMap<String, Collection<String>>();
2.360 + Map<String, Collection<String>> functionDeps = new HashMap<String, Collection<String>>();
2.361 + Prprt[] props = createProps(e, m.properties());
2.362 +
2.363 + if (!generateComputedProperties(body, props, e.getEnclosedElements(), propsGetSet, propsDeps)) {
2.364 + ok = false;
2.365 + }
2.366 + if (!generateOnChange(e, propsDeps, props, className, functionDeps)) {
2.367 + ok = false;
2.368 + }
2.369 + if (!generateProperties(e, body, className, props, propsGetSet, propsDeps, functionDeps)) {
2.370 + ok = false;
2.371 + }
2.372 + if (!generateFunctions(e, body, className, e.getEnclosedElements(), functions)) {
2.373 + ok = false;
2.374 + }
2.375 + if (!generateReceive(e, body, className, e.getEnclosedElements(), onReceiveType)) {
2.376 + ok = false;
2.377 + }
2.378 + if (!generateOperation(e, body, className, e.getEnclosedElements())) {
2.379 + ok = false;
2.380 + }
2.381 + FileObject java = processingEnv.getFiler().createSourceFile(pkg + '.' + className, e);
2.382 + w = new OutputStreamWriter(java.openOutputStream());
2.383 + try {
2.384 + w.append("package " + pkg + ";\n");
2.385 + w.append("import net.java.html.json.*;\n");
2.386 w.append("public final class ").append(className).append(" implements Cloneable {\n");
2.387 w.append(" private static final Html4JavaType TYPE = new Html4JavaType();\n");
2.388 w.append(" private final org.apidesign.html.json.spi.Proto proto;\n");
2.389 @@ -260,8 +617,12 @@
2.390 }
2.391 }
2.392 w.append(" };\n");
2.393 - if (props.length > 0) {
2.394 - w.append(" public ").append(className).append("(");
2.395 + // enum
2.396 + StringBuilder factoryHeader = new StringBuilder();
2.397 + if (true) {
2.398 + w.write(" private Object union;\n");
2.399 +
2.400 + w.append(" private ").append(className).append("(");
2.401 Prprt firstArray = null;
2.402 String sep = "";
2.403 for (Prprt p : props) {
2.404 @@ -272,9 +633,9 @@
2.405 continue;
2.406 }
2.407 String tn = typeName(e, p);
2.408 - w.write(sep);
2.409 - w.write(tn);
2.410 - w.write(" " + p.name());
2.411 + w.write(sep); factoryHeader.append(sep);
2.412 + w.write(tn); factoryHeader.append(tn);
2.413 + w.write(" " + p.name()); factoryHeader.append(" " + p.name());
2.414 sep = ", ";
2.415 }
2.416 if (firstArray != null) {
2.417 @@ -283,10 +644,11 @@
2.418 boolean[] isEnum = {false};
2.419 boolean isPrimitive[] = {false};
2.420 tn = checkType(firstArray, isModel, isEnum, isPrimitive);
2.421 - w.write(sep);
2.422 - w.write(tn);
2.423 - w.write("... " + firstArray.name());
2.424 + w.write(sep); factoryHeader.append(sep);
2.425 + w.write(tn); factoryHeader.append(tn);
2.426 + w.write("... " + firstArray.name()); factoryHeader.append("... " + firstArray.name());
2.427 }
2.428 + // end of enum
2.429 w.append(") {\n");
2.430 w.append(" this(net.java.html.BrwsrCtx.findDefault(").append(className).append(".class));\n");
2.431 for (Prprt p : props) {
2.432 @@ -491,6 +853,19 @@
2.433 }
2.434 w.write(" return h;\n");
2.435 w.write(" }\n");
2.436 + // enum
2.437 + w.write(" public " + inPckName(e) + " get" + e.getSimpleName() + "() { return null; }\n");
2.438 + for (Element ec : e.getEnclosedElements()) {
2.439 + if (ec.getKind() != ElementKind.ENUM_CONSTANT) {
2.440 + continue;
2.441 + }
2.442 + w.write(" public " + ec.getSimpleName() + " get" + ec.getSimpleName() + "() { return null; }\n");
2.443 + w.write(" public static " + className + " create" + ec.getSimpleName() + " (" + ec.getSimpleName() + " union, ");
2.444 + w.write(factoryHeader.toString());
2.445 + w.write(") { return null; }\n");
2.446 + generateEnumConstantModel(w, ec);
2.447 + }
2.448 + // end of enum
2.449 w.write("}\n");
2.450 } finally {
2.451 w.close();
2.452 @@ -502,6 +877,50 @@
2.453 return ok;
2.454 }
2.455
2.456 + private boolean generateEnumConstantModel(Writer w, Element ec) throws IOException {
2.457 + Model m = ec.getAnnotation(Model.class);
2.458 + if (m == null) {
2.459 + error("Each field in an enum needs to be annotated by @Model", ec);
2.460 + return false;
2.461 + }
2.462 + boolean ok = true;
2.463 +
2.464 + String className = m.className();
2.465 +
2.466 + StringWriter body = new StringWriter();
2.467 + StringBuilder onReceiveType = new StringBuilder();
2.468 + List<String> propsGetSet = new ArrayList<String>();
2.469 + List<String> functions = new ArrayList<String>();
2.470 + Map<String, Collection<String>> propsDeps = new HashMap<String, Collection<String>>();
2.471 + Map<String, Collection<String>> functionDeps = new HashMap<String, Collection<String>>();
2.472 + Prprt[] props = createProps(ec, m.properties());
2.473 +
2.474 +// if (!generateComputedProperties(body, props, e.getEnclosedElements(), propsGetSet, propsDeps)) {
2.475 +// ok = false;
2.476 +// }
2.477 +// if (!generateOnChange(e, propsDeps, props, className, functionDeps)) {
2.478 +// ok = false;
2.479 +// }
2.480 + if (!generateProperties(ec, body, className, props, propsGetSet, propsDeps, functionDeps)) {
2.481 + ok = false;
2.482 + }
2.483 +// if (!generateFunctions(e, body, className, e.getEnclosedElements(), functions)) {
2.484 +// ok = false;
2.485 +// }
2.486 +// if (!generateReceive(e, body, className, e.getEnclosedElements(), onReceiveType)) {
2.487 +// ok = false;
2.488 +// }
2.489 + onReceiveType.append(" @Override public void onMessage(").append(className).append(" model, int index, int type, Object data) {\n");
2.490 + onReceiveType.append(" }\n");
2.491 +
2.492 +// if (!generateOperation(e, body, className, e.getEnclosedElements())) {
2.493 +// ok = false;
2.494 +// }
2.495 + w.write(" public static final ");
2.496 + generateClassBody(w, className, body, ec, props, functionDeps, propsDeps, propsGetSet, functions, onReceiveType);
2.497 + return ok;
2.498 + }
2.499 +
2.500 private boolean generateProperties(
2.501 Element where,
2.502 Writer w, String className, Prprt[] properties,
2.503 @@ -1398,6 +1817,10 @@
2.504 }
2.505
2.506 private String inPckName(Element e) {
2.507 + while (!(e instanceof TypeElement)) {
2.508 + e = e.getEnclosingElement();
2.509 + }
2.510 +
2.511 StringBuilder sb = new StringBuilder();
2.512 while (e.getKind() != ElementKind.PACKAGE) {
2.513 if (sb.length() == 0) {
2.514 @@ -1671,12 +2094,8 @@
2.515 return new Prprt[0];
2.516 }
2.517
2.518 - if (e.getKind() != ElementKind.CLASS) {
2.519 - throw new IllegalStateException("" + e.getKind());
2.520 - }
2.521 - TypeElement te = (TypeElement)e;
2.522 List<? extends AnnotationValue> val = null;
2.523 - for (AnnotationMirror an : te.getAnnotationMirrors()) {
2.524 + for (AnnotationMirror an : e.getAnnotationMirrors()) {
2.525 for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : an.getElementValues().entrySet()) {
2.526 if (entry.getKey().getSimpleName().contentEquals("properties")) {
2.527 val = (List)entry.getValue().getValue();
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/json/src/test/java/org/netbeans/html/json/impl/PlainEnumTest.java Fri Jan 24 13:15:30 2014 +0100
3.3 @@ -0,0 +1,93 @@
3.4 +/**
3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3.6 + *
3.7 + * Copyright 2013-2013 Oracle and/or its affiliates. All rights reserved.
3.8 + *
3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
3.10 + * Other names may be trademarks of their respective owners.
3.11 + *
3.12 + * The contents of this file are subject to the terms of either the GNU
3.13 + * General Public License Version 2 only ("GPL") or the Common
3.14 + * Development and Distribution License("CDDL") (collectively, the
3.15 + * "License"). You may not use this file except in compliance with the
3.16 + * License. You can obtain a copy of the License at
3.17 + * http://www.netbeans.org/cddl-gplv2.html
3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
3.19 + * specific language governing permissions and limitations under the
3.20 + * License. When distributing the software, include this License Header
3.21 + * Notice in each file and include the License file at
3.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
3.23 + * particular file as subject to the "Classpath" exception as provided
3.24 + * by Oracle in the GPL Version 2 section of the License file that
3.25 + * accompanied this code. If applicable, add the following below the
3.26 + * License Header, with the fields enclosed by brackets [] replaced by
3.27 + * your own identifying information:
3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
3.29 + *
3.30 + * Contributor(s):
3.31 + *
3.32 + * The Original Software is NetBeans. The Initial Developer of the Original
3.33 + * Software is Oracle. Portions Copyright 2013-2013 Oracle. All Rights Reserved.
3.34 + *
3.35 + * If you wish your version of this file to be governed by only the CDDL
3.36 + * or only the GPL Version 2, indicate your decision by adding
3.37 + * "[Contributor] elects to include this software in this distribution
3.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
3.39 + * single choice of license, a recipient has the option to distribute
3.40 + * your version of this file under either the CDDL, the GPL Version 2 or
3.41 + * to extend the choice of license to its licensees as provided above.
3.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
3.43 + * Version 2 license, then the option applies only if the new code is
3.44 + * made subject to such option by the copyright holder.
3.45 + */
3.46 +package org.netbeans.html.json.impl;
3.47 +
3.48 +import net.java.html.json.Model;
3.49 +import net.java.html.json.Property;
3.50 +import static org.testng.Assert.*;
3.51 +import org.testng.annotations.Test;
3.52 +
3.53 +/**
3.54 + *
3.55 + * @author Jaroslav Tulach <jtulach@netbeans.org>
3.56 + */
3.57 +public class PlainEnumTest {
3.58 + @Test public void unionA() {
3.59 + Union on = Union.createA(new Union.A(9), 11, 1.1);
3.60 + assertEquals(on.getX(), 11);
3.61 + assertEquals(on.getY(), 1.1);
3.62 +
3.63 + assertEquals(on.getAbc(), Abc.A);
3.64 + assertNotNull(on.getA());
3.65 + assertEquals(on.getA().getUa(), 9);
3.66 + assertNull(on.getB());
3.67 + }
3.68 +
3.69 + @Test public void unionB() {
3.70 + Union on = Union.createB(new Union.B("9.9"), 11, 1.1);
3.71 + assertEquals(on.getX(), 11);
3.72 + assertEquals(on.getY(), 1.1);
3.73 +
3.74 + assertEquals(on.getAbc(), Abc.A);
3.75 + assertNull(on.getA());
3.76 + assertNotNull(on.getB());
3.77 + assertEquals(on.getB().getUb(), "9.9");
3.78 + }
3.79 +
3.80 +
3.81 +
3.82 + @Model(className = "Union", properties = {
3.83 + @Property(name = "x", type = int.class),
3.84 + @Property(name = "y", type = double.class)
3.85 + })
3.86 + enum Abc {
3.87 + @Model(className = "A", properties = {
3.88 + @Property(name = "ua", type = int.class)
3.89 + })
3.90 + A,
3.91 + @Model(className = "B", properties = {
3.92 + @Property(name = "ub", type = String.class)
3.93 + })
3.94 + B
3.95 + }
3.96 +}