Java tutorial
/* * Copyright 2010 Google Inc. Copyright 2016 Manfred Tremmel * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package de.knightsoftnet.validators.rebind; import de.knightsoftnet.validators.client.GwtValidation; import de.knightsoftnet.validators.client.impl.AbstractGwtValidator; import de.knightsoftnet.validators.client.impl.GwtBeanDescriptor; import de.knightsoftnet.validators.client.impl.GwtSpecificValidator; import de.knightsoftnet.validators.client.impl.GwtValidationContext; import de.knightsoftnet.validators.client.impl.metadata.ValidationGroupsMetadata; import com.google.gwt.core.client.GWT; import com.google.gwt.core.ext.GeneratorContext; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.core.ext.typeinfo.JClassType; import com.google.gwt.thirdparty.guava.common.collect.ImmutableList; import com.google.gwt.thirdparty.guava.common.collect.Lists; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; import com.google.gwt.user.rebind.SourceWriter; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.GroupSequence; import javax.validation.groups.Default; import javax.validation.metadata.BeanDescriptor; /** * Creates the validator for the given input class. */ public final class ValidatorCreator extends AbstractCreator { /** * The beans to validate in source declaration order. */ private final ImmutableList<BeanHelper> beansToValidate; private final GwtValidation gwtValidation; /** * constructor. */ public ValidatorCreator(final JClassType validatorType, // final GwtValidation gwtValidation, // final TreeLogger logger, // final GeneratorContext context, final BeanHelperCache cache) throws UnableToCompleteException { super(context, logger, validatorType, cache); this.gwtValidation = gwtValidation; final List<BeanHelper> temp = Lists.newArrayList(); for (final Class<?> clazz : gwtValidation.value()) { final BeanHelper helper = this.createBeanHelper(clazz); temp.add(helper); } this.beansToValidate = Util.sortMostSpecificFirst(temp, BeanHelper.TO_CLAZZ); } @Override protected void compose(final ClassSourceFileComposerFactory composerFactory) { this.addImports(composerFactory, GWT.class, GwtBeanDescriptor.class, GwtSpecificValidator.class, GwtValidationContext.class, ValidationGroupsMetadata.class, Set.class, HashSet.class, Map.class, HashMap.class, Default.class, ConstraintViolation.class, BeanDescriptor.class); composerFactory.setSuperclass(AbstractGwtValidator.class.getCanonicalName()); composerFactory.addImplementedInterface(this.validatorType.getQualifiedSourceName()); } @Override protected void writeClassBody(final SourceWriter sourceWriter) { this.writeConstructor(sourceWriter); sourceWriter.println(); this.writeCreateValidationGroupsMetadata(sourceWriter); sourceWriter.println(); this.writeValidate(sourceWriter); sourceWriter.println(); this.writeValidateProperty(sourceWriter); sourceWriter.println(); this.writeValidateValue(sourceWriter); sourceWriter.println(); this.writeGetConstraintsForClass(sourceWriter); sourceWriter.println(); this.writeGwtValidate(sourceWriter); } private void writeConstructor(final SourceWriter sw) { // public MyValidator() { sw.println("public " + this.getSimpleName() + "() {"); sw.indent(); // super(createValidationGroupsMetadata()); sw.println("super(createValidationGroupsMetadata());"); sw.outdent(); sw.println("}"); } private void writeContext(final SourceWriter sw, final BeanHelper bean, final String objectName) { // GwtValidationContext<MyBean> context = new GwtValidationContext<MyBean>( sw.print(GwtValidationContext.class.getSimpleName()); sw.print("<T> context = new "); sw.print(GwtValidationContext.class.getSimpleName()); sw.println("<T>("); sw.indent(); sw.indent(); // (Class<T>) MyBean.class, sw.print("(Class<T>) "); sw.println(bean.getTypeCanonicalName() + ".class, "); // object, sw.println(objectName + ", "); // MyBeanValidator.INSTANCE.getConstraints(getValidationGroupsMetadata()), sw.print(bean.getFullyQualifiedValidatorName()); sw.println(".INSTANCE.getConstraints(getValidationGroupsMetadata()), "); // getMessageInterpolator(), sw.println("getMessageInterpolator(), "); // getTraversableResolver(), sw.println("getTraversableResolver(), "); // this); sw.println("this);"); sw.outdent(); sw.outdent(); } private void writeCreateValidationGroupsMetadata(final SourceWriter sw) { // private static ValidationGroupsMetadata createValidationGroupsMetadata() { sw.println("private static ValidationGroupsMetadata createValidationGroupsMetadata() {"); sw.indent(); // return ValidationGroupsMetadata.builder() sw.println("return ValidationGroupsMetadata.builder()"); sw.indent(); sw.indent(); for (final Class<?> group : this.gwtValidation.groups()) { final GroupSequence sequenceAnnotation = group.getAnnotation(GroupSequence.class); Class<?>[] groups; if (sequenceAnnotation == null) { // .addGroup(<<group>> sw.print(".addGroup("); sw.print(group.getCanonicalName() + ".class"); groups = group.getInterfaces(); } else { // .addSequence(<<sequence>> sw.print(".addSequence("); sw.print(group.getCanonicalName() + ".class"); groups = sequenceAnnotation.value(); } for (final Class<?> clazz : groups) { // , <<group class>> sw.print(", "); sw.print(clazz.getCanonicalName() + ".class"); } // ) sw.println(")"); } // .build(); sw.println(".build();"); sw.outdent(); sw.outdent(); // } sw.outdent(); sw.println("}"); } private void writeGetConstraintsForClass(final SourceWriter sw) { // public BeanDescriptor getConstraintsForClass(Class<?> clazz { sw.println("public BeanDescriptor getConstraintsForClass(Class<?> clazz) {"); sw.indent(); // checkNotNull(clazz, "clazz"); sw.println("checkNotNull(clazz, \"clazz\");"); for (final BeanHelper bean : this.beansToValidate) { this.writeGetConstraintsForClass(sw, bean); } this.writeThrowIllegalArgumnet(sw, "clazz.getName()"); // } sw.outdent(); sw.println("}"); } private void writeGetConstraintsForClass(final SourceWriter sw, final BeanHelper bean) { // if (clazz.eqals(MyBean.class)) { sw.println("if (clazz.equals(" + bean.getTypeCanonicalName() + ".class)) {"); sw.indent(); // return MyBeanValidator.INSTANCE.getConstraints(getValidationGroupsMetadata()); sw.print("return "); sw.print(bean.getFullyQualifiedValidatorName()); sw.println(".INSTANCE.getConstraints(getValidationGroupsMetadata());"); // } sw.outdent(); sw.println("}"); } private void writeGwtValidate(final SourceWriter sw) { // public <T> Set<ConstraintViolation<T>> validate(GwtValidationContext<T> // context, sw.print("public <T> Set<ConstraintViolation<T>> "); sw.println("validate(GwtValidationContext<T> context,"); sw.indent(); sw.indent(); // Object object, Class<?>... groups) { sw.println("Object object, Class<?>... groups) {"); sw.outdent(); sw.println("checkNotNull(context, \"context\");"); sw.println("checkNotNull(object, \"object\");"); sw.println("checkNotNull(groups, \"groups\");"); sw.println("checkGroups(groups);"); for (final BeanHelper bean : this.cache.getAllBeans()) { this.writeGwtValidate(sw, bean); } // TODO(nchalko) log warning instead. this.writeThrowIllegalArgumnet(sw, "object.getClass().getName()"); sw.outdent(); sw.println("}"); } private void writeGwtValidate(final SourceWriter sw, final BeanHelper bean) { this.writeIfInstanceofBeanType(sw, bean); sw.indent(); // return PersonValidator.INSTANCE sw.print("return "); sw.println(bean.getFullyQualifiedValidatorName() + ".INSTANCE"); sw.indent(); sw.indent(); // .validate(context, (<<MyBean>>) object, groups); sw.print(".validate(context, "); sw.print("(" + bean.getTypeCanonicalName() + ") object, "); sw.println("groups);"); sw.outdent(); sw.outdent(); // } sw.outdent(); sw.println("}"); } private void writeIfInstanceofBeanType(final SourceWriter sourceWriter, final BeanHelper bean) { // if (object instanceof MyBean) { sourceWriter.print("if (object instanceof "); sourceWriter.print(bean.getTypeCanonicalName()); sourceWriter.println(") {"); } private void writeThrowIllegalArgumnet(final SourceWriter sourceWriter, final String getClassName) { // throw new IllegalArgumentException("MyValidator can not validate ", sourceWriter.print("throw new IllegalArgumentException(\""); sourceWriter.print(this.validatorType.getName() + " can not validate \""); sourceWriter.indent(); sourceWriter.indent(); // + object.getClass().getName() +". " sourceWriter.print("+ "); sourceWriter.print(getClassName); sourceWriter.println("+ \". \""); // + "Valid values are {Foo.clas, Bar.class} sourceWriter.print("+ \"Valid types are "); sourceWriter.print(this.beansToValidate.toString()); sourceWriter.println("\");"); sourceWriter.outdent(); sourceWriter.outdent(); } private void writeValidate(final SourceWriter sw) { // public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... // groups) { sw.println("public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {"); sw.indent(); sw.println("checkNotNull(object, \"object\");"); sw.println("checkNotNull(groups, \"groups\");"); sw.println("checkGroups(groups);"); for (final BeanHelper bean : this.beansToValidate) { this.writeValidate(sw, bean); } this.writeThrowIllegalArgumnet(sw, "object.getClass().getName()"); sw.outdent(); sw.println("}"); } private void writeValidate(final SourceWriter sw, final BeanHelper bean) { this.writeIfInstanceofBeanType(sw, bean); sw.indent(); this.writeContext(sw, bean, "object"); // return PersonValidator.INSTANCE sw.print("return "); sw.println(bean.getFullyQualifiedValidatorName() + ".INSTANCE"); sw.indent(); sw.indent(); // .validate(context, (<<MyBean>>) object, groups); sw.print(".validate(context, "); sw.print("(" + bean.getTypeCanonicalName() + ") object, "); sw.println("groups);"); sw.outdent(); sw.outdent(); // } sw.outdent(); sw.println("}"); } private void writeValidateProperty(final SourceWriter sw) { sw.println("public <T> Set<ConstraintViolation<T>> validateProperty(" + "T object,String propertyName, Class<?>... groups) {"); sw.indent(); sw.println("checkNotNull(object, \"object\");"); sw.println("checkNotNull(propertyName, \"propertyName\");"); sw.println("checkNotNull(groups, \"groups\");"); sw.println("checkGroups(groups);"); for (final BeanHelper bean : this.beansToValidate) { this.writeValidateProperty(sw, bean); } this.writeThrowIllegalArgumnet(sw, "object.getClass().getName()"); sw.outdent(); sw.println("}"); } private void writeValidateProperty(final SourceWriter sw, final BeanHelper bean) { this.writeIfInstanceofBeanType(sw, bean); sw.indent(); this.writeContext(sw, bean, "object"); // return PersonValidator.INSTANCE sw.print("return "); sw.println(bean.getFullyQualifiedValidatorName() + ".INSTANCE"); sw.indent(); sw.indent(); // .validateProperty(context, (MyBean) object, propertyName, groups); sw.print(".validateProperty(context, ("); sw.print(bean.getTypeCanonicalName()); sw.print(") object, propertyName, "); sw.println("groups);"); sw.outdent(); sw.outdent(); // } sw.outdent(); sw.println("}"); } private void writeValidateValue(final SourceWriter sw) { sw.println("public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, " + "String propertyName, Object value, Class<?>... groups) {"); sw.indent(); sw.println("checkNotNull(beanType, \"beanType\");"); sw.println("checkNotNull(propertyName, \"propertyName\");"); sw.println("checkNotNull(groups, \"groups\");"); sw.println("checkGroups(groups);"); for (final BeanHelper bean : this.beansToValidate) { this.writeValidateValue(sw, bean); } this.writeThrowIllegalArgumnet(sw, "beanType.getName()"); sw.outdent(); sw.println("}"); } private void writeValidateValue(final SourceWriter sw, final BeanHelper bean) { sw.println("if (beanType.equals(" + bean.getTypeCanonicalName() + ".class)) {"); sw.indent(); this.writeContext(sw, bean, "null"); // return PersonValidator.INSTANCE sw.print("return "); sw.println(bean.getFullyQualifiedValidatorName() + ".INSTANCE"); sw.indent(); sw.indent(); // .validateValue(context, (Class<MyBean> beanType, propertyName, value, // groups); sw.print(".validateValue(context, (Class<"); sw.print(bean.getTypeCanonicalName()); sw.println(">)beanType, propertyName, value, groups);"); sw.outdent(); sw.outdent(); // } sw.outdent(); sw.println("}"); } }