| /* |
| * 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.ext.GeneratorContext; |
| import com.google.gwt.core.ext.TreeLogger; |
| import com.google.gwt.core.ext.typeinfo.JClassType; |
| 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.Validator; |
| import javax.validation.metadata.BeanDescriptor; |
| |
| /** |
| * A simple struct for the various values associated with a Bean that can be |
| * validated. |
| */ |
| final class BeanHelper { |
| |
| private static final Validator serverSideValidor = Validation.buildDefaultValidatorFactory().getValidator(); |
| |
| // stash the map in a ThreadLocal, since each GWT module lives in its own |
| // thread in DevMode |
| private static final ThreadLocal<Map<JClassType, BeanHelper>> threadLocalHelperMap = |
| new ThreadLocal<Map<JClassType, BeanHelper>>() { |
| @Override |
| protected synchronized Map<JClassType, BeanHelper> initialValue() { |
| return new HashMap<JClassType, BeanHelper>(); |
| } |
| }; |
| |
| protected static BeanHelper createBeanHelper(Class<?> clazz, |
| TreeLogger logger, GeneratorContext context) { |
| JClassType beanType = context.getTypeOracle().findType( |
| clazz.getCanonicalName()); |
| BeanHelper helper = getBeanHelper(beanType); |
| if (helper == null) { |
| helper = new BeanHelper(beanType, clazz, |
| serverSideValidor.getConstraintsForClass(clazz)); |
| addBeanHelper(helper); |
| writeInterface(context, logger, helper); |
| } |
| return helper; |
| } |
| |
| protected static boolean isClassConstrained(Class<?> clazz) { |
| return serverSideValidor.getConstraintsForClass(clazz).isBeanConstrained(); |
| } |
| |
| static BeanHelper getBeanHelper(JClassType beanType) { |
| return getBeanHelpers().get(beanType); |
| } |
| |
| /** |
| * 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.makeInterface(); |
| SourceWriter sw = factory.createSourceWriter(context, pw); |
| sw.commit(interfaceLogger); |
| pw.close(); |
| } |
| } |
| |
| private static synchronized void addBeanHelper(BeanHelper helper) { |
| threadLocalHelperMap.get().put(helper.getJClass(), helper); |
| } |
| |
| private static Map<JClassType, BeanHelper> getBeanHelpers() { |
| return Collections.unmodifiableMap(threadLocalHelperMap.get()); |
| } |
| |
| 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 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 makeJavaSafe(jClass.getName().toLowerCase() + "Validator"); |
| } |
| |
| public String getValidatorName() { |
| return makeJavaSafe("_" + jClass.getName() + "Validator"); |
| } |
| |
| @Override |
| public String toString() { |
| return getTypeCanonicalName(); |
| } |
| |
| private String makeJavaSafe(String in) { |
| return in.replaceAll("\\.", "_"); |
| } |
| |
| } |