1.1 --- a/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Wed Dec 09 23:59:56 2015 +0100
1.2 +++ b/json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java Sun Dec 13 21:33:32 2015 +0100
1.3 @@ -223,11 +223,36 @@
1.4 try {
1.5 w.append("package " + pkg + ";\n");
1.6 w.append("import net.java.html.json.*;\n");
1.7 - final String inPckName = inPckName(e);
1.8 + final String inPckName = inPckName(e, false);
1.9 w.append("/** Generated for {@link ").append(inPckName).append("}*/\n");
1.10 w.append("public final class ").append(className).append(" implements Cloneable {\n");
1.11 w.append(" private static Class<").append(inPckName).append("> modelFor() { return ").append(inPckName).append(".class; }\n");
1.12 w.append(" private static final Html4JavaType TYPE = new Html4JavaType();\n");
1.13 + if (m.instance()) {
1.14 + int cCnt = 0;
1.15 + for (Element c : e.getEnclosedElements()) {
1.16 + if (c.getKind() != ElementKind.CONSTRUCTOR) {
1.17 + continue;
1.18 + }
1.19 + cCnt++;
1.20 + ExecutableElement ec = (ExecutableElement) c;
1.21 + if (ec.getParameters().size() > 0) {
1.22 + continue;
1.23 + }
1.24 + if (ec.getModifiers().contains(Modifier.PRIVATE)) {
1.25 + continue;
1.26 + }
1.27 + cCnt = 0;
1.28 + break;
1.29 + }
1.30 + if (cCnt > 0) {
1.31 + ok = false;
1.32 + error("Needs non-private default constructor when instance=true", e);
1.33 + w.append(" private final ").append(inPckName).append(" instance = null;\n");
1.34 + } else {
1.35 + w.append(" private final ").append(inPckName).append(" instance = new ").append(inPckName).append("();\n");
1.36 + }
1.37 + }
1.38 w.append(" private final org.netbeans.html.json.spi.Proto proto;\n");
1.39 w.append(body.toString());
1.40 w.append(" private ").append(className).append("(net.java.html.BrwsrCtx context) {\n");
1.41 @@ -382,7 +407,13 @@
1.42 if (param instanceof ExecutableElement) {
1.43 ExecutableElement ee = (ExecutableElement)param;
1.44 w.append(" case " + (i / 2) + ":\n");
1.45 - w.append(" ").append(((TypeElement)e).getQualifiedName()).append(".").append(name).append("(");
1.46 + w.append(" ");
1.47 + if (m.instance()) {
1.48 + w.append("model.instance");
1.49 + } else {
1.50 + w.append(((TypeElement)e).getQualifiedName());
1.51 + }
1.52 + w.append(".").append(name).append("(");
1.53 w.append(wrapParams(ee, null, className, "model", "ev", "data"));
1.54 w.append(");\n");
1.55 w.append(" return;\n");
1.56 @@ -940,6 +971,7 @@
1.57 Element clazz, StringWriter body, String className,
1.58 List<? extends Element> enclosedElements, List<Object> functions
1.59 ) {
1.60 + boolean instance = clazz.getAnnotation(Model.class).instance();
1.61 for (Element m : enclosedElements) {
1.62 if (m.getKind() != ElementKind.METHOD) {
1.63 continue;
1.64 @@ -949,7 +981,7 @@
1.65 if (onF == null) {
1.66 continue;
1.67 }
1.68 - if (!e.getModifiers().contains(Modifier.STATIC)) {
1.69 + if (!instance && !e.getModifiers().contains(Modifier.STATIC)) {
1.70 error("@OnFunction method needs to be static", e);
1.71 return false;
1.72 }
1.73 @@ -972,6 +1004,7 @@
1.74 Prprt[] properties, String className,
1.75 Map<String, Collection<String>> functionDeps
1.76 ) {
1.77 + boolean instance = clazz.getAnnotation(Model.class).instance();
1.78 for (Element m : clazz.getEnclosedElements()) {
1.79 if (m.getKind() != ElementKind.METHOD) {
1.80 continue;
1.81 @@ -987,7 +1020,7 @@
1.82 return false;
1.83 }
1.84 }
1.85 - if (!e.getModifiers().contains(Modifier.STATIC)) {
1.86 + if (!instance && !e.getModifiers().contains(Modifier.STATIC)) {
1.87 error("@OnPrprtChange method needs to be static", e);
1.88 return false;
1.89 }
1.90 @@ -1004,7 +1037,7 @@
1.91
1.92 for (String pn : onPC.value()) {
1.93 StringBuilder call = new StringBuilder();
1.94 - call.append(" ").append(inPckName(clazz)).append(".").append(n).append("(");
1.95 + call.append(" ").append(inPckName(clazz, instance)).append(".").append(n).append("(");
1.96 call.append(wrapPropName(e, className, "name", pn));
1.97 call.append(");\n");
1.98
1.99 @@ -1032,6 +1065,7 @@
1.100 List<? extends Element> enclosedElements,
1.101 List<Object> functions
1.102 ) {
1.103 + boolean instance = clazz.getAnnotation(Model.class).instance();
1.104 for (Element m : enclosedElements) {
1.105 if (m.getKind() != ElementKind.METHOD) {
1.106 continue;
1.107 @@ -1041,7 +1075,7 @@
1.108 if (mO == null) {
1.109 continue;
1.110 }
1.111 - if (!e.getModifiers().contains(Modifier.STATIC)) {
1.112 + if (!instance && !e.getModifiers().contains(Modifier.STATIC)) {
1.113 error("@ModelOperation method needs to be static", e);
1.114 return false;
1.115 }
1.116 @@ -1092,7 +1126,7 @@
1.117
1.118 StringBuilder call = new StringBuilder();
1.119 call.append("{ Object[] arr = (Object[])data; ");
1.120 - call.append(inPckName(clazz)).append(".").append(m.getSimpleName()).append("(");
1.121 + call.append(inPckName(clazz, true)).append(".").append(m.getSimpleName()).append("(");
1.122 int i = 0;
1.123 for (VariableElement ve : e.getParameters()) {
1.124 if (i++ == 0) {
1.125 @@ -1133,6 +1167,7 @@
1.126 inType.append(" switch (index) {\n");
1.127 int index = 0;
1.128 boolean ok = true;
1.129 + boolean instance = clazz.getAnnotation(Model.class).instance();
1.130 for (Element m : enclosedElements) {
1.131 if (m.getKind() != ElementKind.METHOD) {
1.132 continue;
1.133 @@ -1142,7 +1177,7 @@
1.134 if (onR == null) {
1.135 continue;
1.136 }
1.137 - if (!e.getModifiers().contains(Modifier.STATIC)) {
1.138 + if (!instance && !e.getModifiers().contains(Modifier.STATIC)) {
1.139 error("@OnReceive method needs to be static", e);
1.140 return false;
1.141 }
1.142 @@ -1392,7 +1427,7 @@
1.143 body.append(
1.144 " case " + index + ": {\n" +
1.145 " if (type == 0) { /* on open */\n" +
1.146 - " ").append(inPckName(clazz)).append(".").append(n).append("(");
1.147 + " ").append(inPckName(clazz, true)).append(".").append(n).append("(");
1.148 {
1.149 String sep = "";
1.150 for (String arg : args) {
1.151 @@ -1419,7 +1454,7 @@
1.152 if (!findOnError(e, ((TypeElement)clazz), onR.onError(), className)) {
1.153 return true;
1.154 }
1.155 - body.append(" ").append(inPckName(clazz)).append(".").append(onR.onError()).append("(");
1.156 + body.append(" ").append(inPckName(clazz, true)).append(".").append(onR.onError()).append("(");
1.157 body.append("model, value);\n");
1.158 }
1.159 body.append(
1.160 @@ -1440,7 +1475,7 @@
1.161 " TYPE.copyJSON(model.proto.getContext(), ev, " + modelClass + ".class, arr);\n"
1.162 );
1.163 {
1.164 - body.append(" ").append(inPckName(clazz)).append(".").append(n).append("(");
1.165 + body.append(" ").append(inPckName(clazz, true)).append(".").append(n).append("(");
1.166 String sep = "";
1.167 for (String arg : args) {
1.168 body.append(sep);
1.169 @@ -1455,7 +1490,7 @@
1.170 );
1.171 if (!onR.onError().isEmpty()) {
1.172 body.append(" else if (type == 3) { /* on close */\n");
1.173 - body.append(" ").append(inPckName(clazz)).append(".").append(onR.onError()).append("(");
1.174 + body.append(" ").append(inPckName(clazz, true)).append(".").append(onR.onError()).append("(");
1.175 body.append("model, null);\n");
1.176 body.append(
1.177 " return;" +
1.178 @@ -1687,7 +1722,10 @@
1.179 w.write(" }\n");
1.180 }
1.181
1.182 - private String inPckName(Element e) {
1.183 + private String inPckName(Element e, boolean preferInstance) {
1.184 + if (preferInstance && e.getAnnotation(Model.class).instance()) {
1.185 + return "model.instance";
1.186 + }
1.187 StringBuilder sb = new StringBuilder();
1.188 while (e.getKind() != ElementKind.PACKAGE) {
1.189 if (sb.length() == 0) {