blob: 2a55ed1d8f865f833149208917680bd9faeabf91 [file] [log] [blame]
/*
* 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,
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 BeanHelper(JClassType jClass, BeanDescriptor beanDescriptor) {
super();
this.beanDescriptor = beanDescriptor;
this.jClass = jClass;
}
public BeanDescriptor getBeanDescriptor() {
return beanDescriptor;
}
/*
* The server side validator needs an actual class.
*/
public Class<?> getClazz() throws ClassNotFoundException {
return Class.forName(jClass.getQualifiedSourceName());
}
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("\\.", "_");
}
}