org.nuiton.jaxx.compiler.finalizers.ValidatorFinalizer Maven / Gradle / Ivy
/*
* #%L
* JAXX :: Compiler
* %%
* Copyright (C) 2008 - 2018 Code Lutin, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.jaxx.compiler.finalizers;
import com.google.auto.service.AutoService;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.nuiton.jaxx.compiler.CompiledObject;
import org.nuiton.jaxx.compiler.CompiledObject.ChildRef;
import org.nuiton.jaxx.compiler.CompilerException;
import org.nuiton.jaxx.compiler.JAXXCompiler;
import org.nuiton.jaxx.compiler.java.JavaElement;
import org.nuiton.jaxx.compiler.java.JavaElementFactory;
import org.nuiton.jaxx.compiler.java.JavaField;
import org.nuiton.jaxx.compiler.java.JavaFile;
import org.nuiton.jaxx.compiler.reflect.ClassDescriptor;
import org.nuiton.jaxx.compiler.reflect.FieldDescriptor;
import org.nuiton.jaxx.compiler.tags.swing.TabWithValidatorHandler;
import org.nuiton.jaxx.compiler.tags.validator.BeanValidatorHandler;
import org.nuiton.jaxx.compiler.tags.validator.BeanValidatorHandler.CompiledBeanValidator;
import org.nuiton.jaxx.compiler.types.TypeManager;
import org.nuiton.jaxx.runtime.swing.SwingUtil;
import org.nuiton.jaxx.validator.JAXXValidator;
import org.nuiton.jaxx.validator.swing.SwingValidatorUtil;
import org.nuiton.jaxx.validator.swing.meta.Validator;
import org.nuiton.jaxx.validator.swing.meta.ValidatorField;
import org.nuiton.jaxx.validator.swing.tab.TabInfoWithValidator;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.List;
/**
* To finalize validators fields.
*
* @author Tony Chemit - [email protected]
* @plexus.component role-hint="validators" role="org.nuiton.jaxx.compiler.finalizers.JAXXCompilerFinalizer"
*/
@AutoService(JAXXCompilerFinalizer.class)
public class ValidatorFinalizer extends AbstractFinalizer {
/** Logger. */
static final Logger log = LogManager.getLogger(ValidatorFinalizer.class);
protected static final JavaField VALIDATOR_IDS_FIELD =
JavaElementFactory.newField(
Modifier.PROTECTED,
List.class.getName() + "",
"validatorIds",
true
);
@Override
public boolean accept(JAXXCompiler compiler) {
//use this finalizer if compiler is validation aware
return BeanValidatorHandler.hasValidator(compiler);
}
@Override
public void finalizeCompiler(CompiledObject root,
JAXXCompiler compiler,
JavaFile javaFile,
String packageName,
String className) {
for (CompiledObject object : compiler.getObjects().values()) {
List childs = object.getChilds();
if (childs == null || childs.isEmpty()) {
continue;
}
for (ChildRef child : childs) {
String javaCode = child.getChildJavaCode();
// some validators are defined on this object
boolean found = BeanValidatorHandler.isComponentUsedByValidator(compiler, child.getChild().getId());
if (found) {
// compiler.setNeedSwingUtil(true);
String type = compiler.getImportedType(SwingUtil.class);
// box the child component in a JxLayer
child.setChildJavaCode(type + ".boxComponentWithJxLayer(" + javaCode + ")");
}
}
}
String eol = JAXXCompiler.getLineSeparator();
StringBuilder builder = new StringBuilder();
// register validators
List validators =
BeanValidatorHandler.getValidators(compiler);
// javaFile.addImport(Validator.class);
// javaFile.addImport(ValidatorField.class);
// javaFile.addImport(SwingValidatorUtil.class);
String validatorUtilPrefix = compiler.getImportedType(SwingValidatorUtil.class) + ".";
compiler.getJavaFile().addMethod(JavaElementFactory.newMethod(
Modifier.PUBLIC,
TYPE_VOID,
"registerValidatorFields",
validatorUtilPrefix + "detectValidatorFields(this);",
true)
);
builder.append("// register ");
builder.append(validators.size());
builder.append(" validator(s)");
builder.append(eol);
builder.append("validatorIds = ");
builder.append(validatorUtilPrefix).append("detectValidators(this);").append(eol);
builder.append(validatorUtilPrefix).append("installUI(this);").append(eol);
List tabs= TabWithValidatorHandler.getTabs(compiler);
if (!tabs.isEmpty()) {
for (TabInfoWithValidator tab : tabs) {
CompiledObject compiledObject = compiler.getCompiledObject(tab.getId());
// compiledObject.
builder.append(validatorUtilPrefix).append("installTabUI(this, ").append(tab.getId()).append(");").append(eol);
}
}
compiler.appendLateInitializer(builder.toString());
for (CompiledBeanValidator validator : validators) {
registerValidator(validator, compiler, javaFile);
}
}
@Override
public void prepareJavaFile(CompiledObject root,
JAXXCompiler compiler,
JavaFile javaFile,
String packageName,
String className) {
ClassDescriptor validatorClass = compiler.getEngine().getValidatorFactoryClass();
Class> validatorInterface = JAXXValidator.class;
boolean parentIsValidator =
compiler.isSuperClassAware(validatorInterface);
if (parentIsValidator) {
// nothing to generate (use the parent directly)
return;
}
// add JAXXValidator interface
javaFile.addInterface(JAXXCompiler.getCanonicalName(validatorInterface));
// implements JAXXValidator
addField(javaFile, VALIDATOR_IDS_FIELD);
String type = compiler.getImportedType(validatorClass.getName());
String initializer = "return (" + type +
">) (validatorIds.contains(validatorId) ? " +
"getObjectById(validatorId) : null);";
javaFile.addMethod(JavaElementFactory.newMethod(
Modifier.PUBLIC,
type + ">",
"getValidator",
initializer,
true,
JavaElementFactory.newArgument(TYPE_STRING, "validatorId"))
);
}
public void registerValidator(CompiledBeanValidator validator,
JAXXCompiler compiler,
JavaFile javaFile) {
JavaField validatorField = javaFile.getField(validator.getId());
String validatorId = TypeManager.getJavaCode(validator.getId());
String type = compiler.getImportedType(Validator.class);
String fieldType = compiler.getImportedType(ValidatorField.class);
String validatorAnnotation = type +
"( validatorId = " + validatorId + ")";
validatorField.addAnnotation(validatorAnnotation);
// Map fields = validator.getFields();
for (String component : validator.getFieldEditors()) {
Collection propertyNames = validator.getFieldPropertyNames(component);
List keyCodes =
Lists.newArrayListWithCapacity(propertyNames.size());
for (String propertyName : propertyNames) {
if (!validator.checkBeanProperty(compiler, propertyName)) {
// property not find on bean
continue;
}
String keyCode = TypeManager.getJavaCode(propertyName);
keyCodes.add(keyCode);
}
if (keyCodes.isEmpty()) {
// no property
continue;
}
String keyCode = Joiner.on(", ").join(keyCodes);
if (keyCodes.size() > 1) {
keyCode = "{ " + keyCode + " }";
}
// String keyCode = TypeManager.getJavaCode(propertyName);
String editorCode = TypeManager.getJavaCode(component);
String annotation = fieldType +
"( validatorId = " + validatorId + "," +
" propertyName = " + keyCode + "," +
" editorName = " + editorCode + "" + ")";
JavaElement editor = javaFile.getField(component);
if (editor == null) {
if (log.isDebugEnabled()) {
String message = "Could not find editor [" + component +
"] for property(ies) [" + propertyNames +
"] for file " + javaFile.getName();
log.debug(message);
}
// // find in the compiler the object
CompiledObject compiledObject = compiler.getCompiledObject(component);
String fqn;
if (compiledObject == null) {
FieldDescriptor fieldDescriptor = null;
try {
fieldDescriptor = compiler.getRootObject().getObjectClass().getDeclaredFieldDescriptor(component);
} catch (NoSuchFieldException e) {
// can't happen
}
if (fieldDescriptor == null) {
// this is an error, editor is unknown (this case should
// never happen)
String errorMessage =
"Could not find editor [" + component +
"] for property(ies) [" + propertyNames +
"] for file " + javaFile.getName();
throw new CompilerException(errorMessage);
}
try {
Class> parentClass = compiler.getClassLoader().loadClass(compiler.getRootObject().getObjectClass().getName());
Method method = parentClass.getMethod("get" + StringUtils.capitalize(component));
if (method != null) {
String genericReturnType = method.getGenericReturnType().getTypeName();
genericReturnType = javaFile.getImportManager().getType(genericReturnType);
editor = javaFile.addOverrideGetterMethod(component, Modifier.PUBLIC, genericReturnType, true);
editor.addAnnotation(annotation);
continue;
}
} catch (NoSuchMethodException | ClassNotFoundException e) {
// ignore
}
fqn = JAXXCompiler.getCanonicalName(fieldDescriptor.getType());
} else {
fqn = JAXXCompiler.getCanonicalName(compiledObject);
}
// now must add a getter in the javaFile
editor = javaFile.addGetterMethod(component, Modifier.PUBLIC, fqn, true, true);
editor.addAnnotation(annotation);
} else {
editor.addAnnotation(annotation);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy