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

com.google.gwt.validation.rebind.BeanHelper Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * Copyright 2010 Google Inc.
 *
 * 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 com.google.gwt.validation.rebind;

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.JArrayType;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JField;
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.JRawType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.thirdparty.guava.common.base.Function;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.google.gwt.validation.client.impl.GwtSpecificValidator;

import java.io.PrintWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.validation.Validation;
import javax.validation.ValidationException;
import javax.validation.Validator;
import javax.validation.metadata.BeanDescriptor;
import javax.validation.metadata.PropertyDescriptor;

/**
 * EXPERIMENTAL and subject to change. Do not use this in
 * production code.
 * 

* A simple struct for the various values associated with a Bean that can be * validated. */ public final class BeanHelper { public static final Function> TO_CLAZZ = new Function>() { public Class apply(BeanHelper helper) { return helper.getClazz(); } }; private static final Validator serverSideValidator = Validation.buildDefaultValidatorFactory().getValidator(); // stash the map in a ThreadLocal, since each GWT module lives in its own // thread in DevMode private static final ThreadLocal> threadLocalHelperMap = new ThreadLocal>() { @Override protected synchronized Map initialValue() { return new HashMap(); } }; /** * Visible for testing. */ public static void clearBeanHelpersForTests() { threadLocalHelperMap.get().clear(); } public static BeanHelper createBeanHelper(Class clazz, TreeLogger logger, GeneratorContext context) throws UnableToCompleteException { JClassType beanType = context.getTypeOracle().findType( clazz.getCanonicalName()); return createBeanHelper(clazz, beanType, logger, context); } public static Map getBeanHelpers() { return Collections.unmodifiableMap(threadLocalHelperMap.get()); } protected static BeanHelper createBeanHelper(JClassType jType, TreeLogger logger, GeneratorContext context) throws UnableToCompleteException { JClassType erasedType = jType.getErasedType(); try { Class clazz = Class.forName(erasedType.getQualifiedBinaryName()); return createBeanHelper(clazz, erasedType, logger, context); } catch (ClassNotFoundException e) { logger.log(TreeLogger.ERROR, "Unable to create BeanHelper for " + erasedType, e); throw new UnableToCompleteException(); } } protected static boolean isClassConstrained(Class clazz) { return serverSideValidator.getConstraintsForClass(clazz).isBeanConstrained(); } static BeanHelper getBeanHelper(JClassType beanType) { return getBeanHelpers().get(beanType.getErasedType()); } /** * Write an Empty Interface implementing {@link GwtSpecificValidator} with * Generic parameter of the bean type. */ static void writeInterface(GeneratorContext context, TreeLogger logger, BeanHelper bean) { PrintWriter pw = context.tryCreate(logger, bean.getPackage(), bean.getValidatorName()); if (pw != null) { TreeLogger interfaceLogger = logger.branch(TreeLogger.TRACE, "Creating the interface for " + bean.getFullyQualifiedValidatorName()); ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory( bean.getPackage(), bean.getValidatorName()); factory.addImplementedInterface(GwtSpecificValidator.class.getCanonicalName() + " <" + bean.getTypeCanonicalName() + ">"); factory.addImport(GWT.class.getCanonicalName()); factory.makeInterface(); SourceWriter sw = factory.createSourceWriter(context, pw); // static MyValidator INSTANCE = GWT.create(MyValidator.class); sw.print("static "); sw.print(bean.getValidatorName()); sw.print(" INSTANCE = GWT.create("); sw.print(bean.getValidatorName()); sw.println(".class);"); sw.commit(interfaceLogger); pw.close(); } } private static synchronized void addBeanHelper(BeanHelper helper) { threadLocalHelperMap.get().put(helper.getJClass(), helper); } private static BeanHelper createBeanHelper(Class clazz, JClassType beanType, TreeLogger logger, GeneratorContext context) throws UnableToCompleteException { BeanHelper helper = getBeanHelper(beanType); if (helper == null) { BeanDescriptor bean; try { bean = serverSideValidator.getConstraintsForClass(clazz); } catch (ValidationException e) { logger.log(TreeLogger.ERROR, "Unable to create a validator for " + clazz.getCanonicalName() + " because " + e.getMessage(), e); throw new UnableToCompleteException(); } helper = new BeanHelper(beanType, clazz, bean); addBeanHelper(helper); writeInterface(context, logger, helper); // now recurse on all Cascaded elements for (PropertyDescriptor p : bean.getConstrainedProperties()) { if (p.isCascaded()) { createBeanHelper(p, helper, logger, context); } } } return helper; } private static void createBeanHelper(PropertyDescriptor p, BeanHelper parent, TreeLogger logger, GeneratorContext context) throws UnableToCompleteException { Class elementClass = p.getElementClass(); if (GwtSpecificValidatorCreator.isIterableOrMap(elementClass)) { if (parent.hasField(p)) { JClassType type = parent.getAssociationType(p, true); createBeanHelper(type.getErasedType(), logger, context); } if (parent.hasGetter(p)) { JClassType type = parent.getAssociationType(p, false); createBeanHelper(type.getErasedType(), logger, context); } } else { if (serverSideValidator.getConstraintsForClass(elementClass).isBeanConstrained()) { createBeanHelper(elementClass, logger, context); } } } private final BeanDescriptor beanDescriptor; private final JClassType jClass; private Class clazz; private BeanHelper(JClassType jClass, Class clazz, BeanDescriptor beanDescriptor) { super(); this.beanDescriptor = beanDescriptor; this.jClass = jClass; this.clazz = clazz; } public JClassType getAssociationType(PropertyDescriptor p, boolean useField) { JType type = this.getElementType(p, useField); JArrayType jArray = type.isArray(); if (jArray != null) { return jArray.getComponentType().isClassOrInterface(); } JParameterizedType pType = type.isParameterized(); JClassType[] typeArgs; if (pType == null) { JRawType rType = type.isRawType(); typeArgs = rType.getGenericType().getTypeParameters(); } else { typeArgs = pType.getTypeArgs(); } // it is either a Iterable or a Map use the last type arg. return typeArgs[typeArgs.length - 1].isClassOrInterface(); } public BeanDescriptor getBeanDescriptor() { return beanDescriptor; } /* * The server side validator needs an actual class. */ public Class getClazz() { return clazz; } public String getDescriptorName() { return jClass.getName() + "Descriptor"; } public String getFullyQualifiedValidatorName() { return getPackage() + "." + getValidatorName(); } public JClassType getJClass() { return jClass; } public String getPackage() { return jClass.getPackage().getName(); } public String getTypeCanonicalName() { return jClass.getQualifiedSourceName(); } public String getValidatorInstanceName() { return getFullyQualifiedValidatorName() + ".INSTANCE"; } public String getValidatorName() { return makeJavaSafe("_" + jClass.getName() + "Validator"); } @Override public String toString() { return getTypeCanonicalName(); } JType getElementType(PropertyDescriptor p, boolean useField) { if (useField) { return jClass.findField(p.getPropertyName()).getType(); } else { return jClass.findMethod(GwtSpecificValidatorCreator.asGetter(p), GwtSpecificValidatorCreator.NO_ARGS).getReturnType(); } } boolean hasField(PropertyDescriptor p) { JField field = jClass.findField(p.getPropertyName()); return field != null; } boolean hasGetter(PropertyDescriptor p) { JType[] paramTypes = new JType[]{}; try { jClass.getMethod(GwtSpecificValidatorCreator.asGetter(p), paramTypes); return true; } catch (NotFoundException e) { return false; } } private String makeJavaSafe(String in) { return in.replaceAll("\\.", "_"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy