in json/src/main/java/org/netbeans/html/json/impl/ModelProcessor.java [759:946]
private boolean generateComputedProperties(
String className,
Writer w, Prprt[] fixedProps,
Collection<? extends Element> arr, Collection<GetSet> props,
Map<String,Collection<String[]>> deps
) throws IOException {
boolean ok = true;
NEXT_ANNOTATION: for (Element e : arr) {
if (e.getKind() != ElementKind.METHOD) {
continue;
}
final ComputedProperty cp = e.getAnnotation(ComputedProperty.class);
final Transitive tp = e.getAnnotation(Transitive.class);
if (cp == null) {
continue;
}
if (!e.getModifiers().contains(Modifier.STATIC)) {
error("Method " + e.getSimpleName() + " has to be static when annotated by @ComputedProperty", e);
ok = false;
continue;
}
ExecutableElement ee = (ExecutableElement)e;
ExecutableElement write = null;
boolean instance = e.getEnclosingElement().getAnnotation(Model.class).instance();
if (!cp.write().isEmpty()) {
write = findWrite(ee, (TypeElement)e.getEnclosingElement(), cp.write(), className);
ok = write != null;
}
final TypeMirror rt = ee.getReturnType();
final Types tu = processingEnv.getTypeUtils();
TypeMirror ert = tu.erasure(rt);
String tn = fqn(ert, ee);
boolean array = false;
final TypeMirror toCheck;
if (tn.equals("java.util.List")) {
array = true;
toCheck = ((DeclaredType)rt).getTypeArguments().get(0);
} else {
toCheck = rt;
}
final String sn = ee.getSimpleName().toString();
if (toCheck.getKind().isPrimitive()) {
// OK
} else {
TypeMirror stringType = processingEnv.getElementUtils().getTypeElement("java.lang.String").asType();
TypeMirror enumType = processingEnv.getElementUtils().getTypeElement("java.lang.Enum").asType();
if (tu.isSubtype(toCheck, stringType)) {
// OK
} else if (tu.isSubtype(tu.erasure(toCheck), tu.erasure(enumType))) {
// OK
} else if (isModel(toCheck)) {
// OK
} else {
try {
tu.unboxedType(toCheck);
// boxed types are OK
} catch (IllegalArgumentException ex) {
ok = false;
error(sn + " cannot return " + toCheck, e);
}
}
}
final String propertyName = e.getSimpleName().toString();
for (GetSet prop : props) {
if (propertyName.equals(prop.name)) {
error("Cannot have the property " + propertyName + " defined twice", e);
ok = false;
continue NEXT_ANNOTATION;
}
}
String[] gs = toGetSet(sn, tn, array);
w.write(" public " + tn);
if (array) {
w.write("<" + toCheck + ">");
}
w.write(" " + gs[0] + "() {\n");
int arg = 0;
boolean deep = false;
final List<? extends VariableElement> methodParameters = ee.getParameters();
String unknownSingleProperty = methodParameters.size() != 1 ? null :
verifyPropName(methodParameters.get(0), fixedProps);
if (unknownSingleProperty == null) {
for (VariableElement pe : methodParameters) {
final String dn = pe.getSimpleName().toString();
String unknownPropertyError = verifyPropName(pe, fixedProps);
if (unknownPropertyError != null) {
error(unknownPropertyError, e);
ok = false;
}
final TypeMirror pt = pe.asType();
if (isModel(pt)) {
deep = true;
}
final String dt = fqn(pt, ee);
if (dt.startsWith("java.util.List") && pt instanceof DeclaredType) {
final List<? extends TypeMirror> ptArgs = ((DeclaredType)pt).getTypeArguments();
if (ptArgs.size() == 1 && isModel(ptArgs.get(0))) {
deep = true;
}
}
String[] call = toGetSet(dn, dt, false);
w.write(" " + dt + " arg" + (++arg) + " = ");
w.write(call[0] + "();\n");
Collection<String[]> depends = deps.get(dn);
if (depends == null) {
depends = new LinkedHashSet<String[]>();
deps.put(dn, depends);
}
depends.add(new String[] { sn, gs[0] });
}
} else {
VariableElement firstProp = methodParameters.get(0);
TypeMirror type = firstProp.asType();
CharSequence simpleName;
if (type.getKind() == TypeKind.DECLARED) {
simpleName = ((DeclaredType) type).asElement().getSimpleName();
} else {
simpleName = type.toString();
}
if (simpleName.toString().equals(className)) {
} else {
error("Single parameter needs to be of type " + className + " or " + unknownSingleProperty, e);
ok = false;
continue NEXT_ANNOTATION;
}
w.write(" " + simpleName + " arg" + (++arg) + " = this;\n");
}
w.write(" try {\n");
if (tp != null) {
deep = tp.deep();
}
if (deep) {
w.write(" proto.acquireLock(\"" + sn + "\");\n");
} else {
w.write(" proto.acquireLock();\n");
}
w.write(" return " + fqn(ee.getEnclosingElement().asType(), ee) + '.' + e.getSimpleName() + "(");
String sep = "";
for (int i = 1; i <= arg; i++) {
w.write(sep);
w.write("arg" + i);
sep = ", ";
}
w.write(");\n");
w.write(" } finally {\n");
w.write(" proto.releaseLock();\n");
w.write(" }\n");
w.write(" }\n");
if (write == null) {
props.add(new GetSet(
propertyName,
gs[0],
null,
tn,
true,
false
));
} else {
w.write(" public void " + gs[4] + "(" + write.getParameters().get(1).asType());
w.write(" value) {\n");
w.write(" " + (instance ? "instance" : fqn(ee.getEnclosingElement().asType(), ee)) + '.' + write.getSimpleName() + "(this, value);\n");
w.write(" }\n");
props.add(new GetSet(
propertyName,
gs[0],
gs[4],
tn,
false,
false
));
}
}
return ok;
}