All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jaxx.compiler.finalizers.ValidatorFinalizer Maven / Gradle / Ivy

There is a newer version: 3.0-alpha-6
Show newest version
/*
 * #%L
 * JAXX :: Compiler
 * 
 * $Id: ValidatorFinalizer.java 2243 2011-03-18 11:19:23Z tchemit $
 * $HeadURL: http://svn.nuiton.org/svn/jaxx/tags/jaxx-2.5.27/jaxx-compiler/src/main/java/jaxx/compiler/finalizers/ValidatorFinalizer.java $
 * %%
 * Copyright (C) 2008 - 2010 CodeLutin
 * %%
 * 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 jaxx.compiler.finalizers;

import jaxx.compiler.CompiledObject;
import jaxx.compiler.CompiledObject.ChildRef;
import jaxx.compiler.CompilerException;
import jaxx.compiler.JAXXCompiler;
import jaxx.compiler.java.JavaElement;
import jaxx.compiler.java.JavaElementFactory;
import jaxx.compiler.java.JavaField;
import jaxx.compiler.java.JavaFile;
import jaxx.compiler.tags.validator.BeanValidatorHandler;
import jaxx.compiler.tags.validator.BeanValidatorHandler.CompiledBeanValidator;
import jaxx.compiler.types.TypeManager;
import jaxx.runtime.JAXXValidator;
import jaxx.runtime.SwingUtil;
import jaxx.runtime.validator.swing.SwingValidator;
import jaxx.runtime.validator.swing.SwingValidatorUtil;
import jaxx.runtime.validator.swing.meta.Validator;
import jaxx.runtime.validator.swing.meta.ValidatorField;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * To finalize validators fields.
 *
 * @author tchemit 
 * @plexus.component role-hint="validators" role="jaxx.compiler.finalizers.JAXXCompilerFinalizer"
 */
public class ValidatorFinalizer extends AbstractFinalizer {

    /** Logger. */
    static Log log = LogFactory.getLog(ValidatorFinalizer.class);

    protected static final JavaField VALIDATOR_IDS_FIELD =
            JavaElementFactory.newField(
                    Modifier.PROTECTED,
                    List.class.getName() + "",
                    "validatorIds",
                    true,
                    "new %s()",
                    ArrayList.class.getName()
            );

    @Override
    public boolean accept(JAXXCompiler compiler) {

        //use this finalizer if compiler is validation aware
        boolean accept = BeanValidatorHandler.hasValidator(compiler);
        return accept;
    }

    @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);");
        builder.append(eol);

        builder.append(validatorUtilPrefix).append("installUI(this);");
        builder.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) throws ClassNotFoundException {
        Class validatorClass = SwingValidator.class;

        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);

        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 (Map.Entry entry : fields.entrySet()) {
            String propertyName = entry.getKey();
            String component = entry.getValue();

            if (!validator.checkBeanProperty(compiler, propertyName)) {
                // property not find on bean
                continue;
            }

            String keyCode = TypeManager.getJavaCode(propertyName);
            String editorCode = TypeManager.getJavaCode(component);
            JavaElement editor = javaFile.getField(component);
            if (editor == null) {
                if (log.isDebugEnabled()) {
                    String message = "Could not find editor [" + component +
                                     "] for property [" + propertyName +
                                     "] for file " + javaFile.getName();
                    log.debug(message);
                }

                // find in the compiler the object
                CompiledObject compiledObject =
                        compiler.getCompiledObject(component);

                if (compiledObject == null) {

                    // this is an error, editor is unknown (this case should
                    // never happen)

                    String errorMessage =
                            "Could not find editor [" + component +
                            "] for property [" + propertyName +
                            "] for file " + javaFile.getName();

                    throw new CompilerException(errorMessage);
                }

                // now must add a getter in the javaFile
                String fqn = JAXXCompiler.getCanonicalName(compiledObject);

                editor = javaFile.addGetterMethod(component,
                                                  Modifier.PUBLIC,
                                                  fqn,
                                                  true,
                                                  true
                );
            }

            String annotation = fieldType +
                                "( validatorId = " + validatorId + "," +
                                "  propertyName = " + keyCode + "," +
                                "  editorName = " + editorCode + "" + ")";
            editor.addAnnotation(annotation);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy