public static void main(String[] args) { Configuration configuration = Validation.byProvider(HibernateValidator.class).configure(); ValidatorFactory factory = configuration.buildValidatorFactory(); Validator validator = factory.getValidator(); validator.validate(Object.class); // programmation constraint mappings ConstraintMapping mapping = new ConstraintMapping(); }
@Provides protected ValidatorFactory getValidationFactory( Provider<MessageInterpolator> interpolatorProvider) { HibernateValidatorConfiguration configure = Validation.byProvider(HibernateValidator.class).configure(); configure.messageInterpolator(interpolatorProvider.get()); return configure.buildValidatorFactory(); }
static { HibernateValidatorConfiguration configuration = Validation.byProvider(HibernateValidator.class).configure().failFast(true); FACTORY = configuration .messageInterpolator( new ContextualMessageInterpolator(configuration.getDefaultMessageInterpolator())) .buildValidatorFactory(); }
@Override @SuppressWarnings("unchecked") public void afterPropertiesSet() { @SuppressWarnings("rawtypes") Configuration configuration = (this.providerClass != null ? Validation.byProvider(this.providerClass).configure() : Validation.byDefaultProvider().configure()); MessageInterpolator targetInterpolator = this.messageInterpolator; if (targetInterpolator == null) { targetInterpolator = configuration.getDefaultMessageInterpolator(); } configuration.messageInterpolator(new LocaleContextMessageInterpolator(targetInterpolator)); if (this.traversableResolver != null) { configuration.traversableResolver(this.traversableResolver); } ConstraintValidatorFactory targetConstraintValidatorFactory = this.constraintValidatorFactory; if (targetConstraintValidatorFactory == null && this.applicationContext != null) { targetConstraintValidatorFactory = new SpringConstraintValidatorFactory( this.applicationContext.getAutowireCapableBeanFactory()); } if (targetConstraintValidatorFactory != null) { configuration.constraintValidatorFactory(targetConstraintValidatorFactory); } configureParameterNameProviderIfPossible(configuration); if (this.mappingLocations != null) { for (Resource location : this.mappingLocations) { try { configuration.addMapping(location.getInputStream()); } catch (IOException ex) { throw new IllegalStateException("Cannot read mapping resource: " + location); } } } for (Map.Entry<String, String> entry : this.validationPropertyMap.entrySet()) { configuration.addProperty(entry.getKey(), entry.getValue()); } // Allow for custom post-processing before we actually build the ValidatorFactory. postProcessConfiguration(configuration); this.validatorFactory = configuration.buildValidatorFactory(); setTargetValidator(this.validatorFactory.getValidator()); }
@Test public void failFast() { Validator validator = Validation.byProvider(HibernateValidator.class) .configure() .failFast(true) .buildValidatorFactory() .getValidator(); Car car = new Car(null, false); Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car); assertEquals(1, constraintViolations.size()); }
@Test public void withConfiguration() { HibernateValidatorConfiguration configuration = Validation.byProvider(HibernateValidator.class) .providerResolver( new ValidationProviderResolver() { @Override public List<ValidationProvider<?>> getValidationProviders() { ValidationProvider<HibernateValidatorConfiguration> prov = new HibernateValidator(); List<ValidationProvider<?>> provs = new ArrayList<>(); provs.add(prov); return provs; } }) .configure(); configuration.externalClassLoader(Thread.currentThread().getContextClassLoader()); Validator validator = configuration.buildValidatorFactory().getValidator(); Thread.currentThread().setContextClassLoader(null); Set<ConstraintViolation<ValidateMe>> violations = validator.validate(new ValidateMe(0)); Assert.assertEquals(1, violations.size()); }
@SuppressWarnings("unchecked") private static Configuration<?> getConfig(final ValidationInfo info) { Configuration<?> target = null; final Thread thread = Thread.currentThread(); final ClassLoader classLoader = thread.getContextClassLoader(); String providerClassName = info.providerClassName; if (providerClassName == null) { providerClassName = SystemInstance.get().getOptions().get(VALIDATION_PROVIDER_KEY, (String) null); } if (providerClassName != null) { try { @SuppressWarnings({"unchecked", "rawtypes"}) final Class clazz = classLoader.loadClass(providerClassName); target = Validation.byProvider(clazz).configure(); logger.info("Using " + providerClassName + " as validation provider."); } catch (final ClassNotFoundException e) { logger.warning("Unable to load provider class " + providerClassName, e); } catch (final ValidationException ve) { logger.warning( "Unable create validator factory with provider " + providerClassName + " (" + ve.getMessage() + ")." + " Default one will be used."); } } if (target == null) { // force to use container provider to ignore any conflicting configuration thread.setContextClassLoader(ValidatorBuilder.class.getClassLoader()); target = Validation.byDefaultProvider().configure(); thread.setContextClassLoader(classLoader); } final Set<ExecutableType> types = new HashSet<>(); for (final String type : info.validatedTypes) { types.add(ExecutableType.valueOf(type)); } final Map<String, String> props = new HashMap<>(); for (final Map.Entry<Object, Object> entry : info.propertyTypes.entrySet()) { final PropertyType property = new PropertyType(); property.setName((String) entry.getKey()); property.setValue((String) entry.getValue()); props.put(property.getName(), property.getValue()); if (logger.isDebugEnabled()) { logger.debug( "Found property '" + property.getName() + "' with value '" + property.getValue()); } target.addProperty(property.getName(), property.getValue()); } final OpenEjbBootstrapConfig bootstrapConfig = new OpenEjbBootstrapConfig( providerClassName, info.constraintFactoryClass, info.messageInterpolatorClass, info.traversableResolverClass, info.parameterNameProviderClass, new HashSet<>(info.constraintMappings), info.executableValidationEnabled, types, props); final OpenEjbConfig config = new OpenEjbConfig(bootstrapConfig, target); target.ignoreXmlConfiguration(); final String messageInterpolatorClass = info.messageInterpolatorClass; if (messageInterpolatorClass != null) { try { @SuppressWarnings("unchecked") final Class<MessageInterpolator> clazz = (Class<MessageInterpolator>) classLoader.loadClass(messageInterpolatorClass); target.messageInterpolator(newInstance(config, clazz)); } catch (final Exception e) { logger.warning( "Unable to set " + messageInterpolatorClass + " as message interpolator.", e); } logger.info("Using " + messageInterpolatorClass + " as message interpolator."); } final String traversableResolverClass = info.traversableResolverClass; if (traversableResolverClass != null) { try { @SuppressWarnings("unchecked") final Class<TraversableResolver> clazz = (Class<TraversableResolver>) classLoader.loadClass(traversableResolverClass); target.traversableResolver(newInstance(config, clazz)); } catch (final Exception e) { logger.warning( "Unable to set " + traversableResolverClass + " as traversable resolver.", e); } logger.info("Using " + traversableResolverClass + " as traversable resolver."); } final String constraintFactoryClass = info.constraintFactoryClass; if (constraintFactoryClass != null) { try { @SuppressWarnings("unchecked") final Class<ConstraintValidatorFactory> clazz = (Class<ConstraintValidatorFactory>) classLoader.loadClass(constraintFactoryClass); target.constraintValidatorFactory(newInstance(config, clazz)); } catch (final Exception e) { logger.warning("Unable to set " + constraintFactoryClass + " as constraint factory.", e); } logger.info("Using " + constraintFactoryClass + " as constraint factory."); } for (final String mappingFileName : info.constraintMappings) { if (logger.isDebugEnabled()) { logger.debug("Opening input stream for " + mappingFileName); } final InputStream in = classLoader.getResourceAsStream(mappingFileName); if (in == null) { logger.warning( "Unable to open input stream for mapping file " + mappingFileName + ". It will be ignored"); } else { target.addMapping(in); } } if (info.parameterNameProviderClass != null) { try { final Class<ParameterNameProvider> clazz = (Class<ParameterNameProvider>) classLoader.loadClass(info.parameterNameProviderClass); target.parameterNameProvider(newInstance(config, clazz)); } catch (final Exception e) { logger.warning( "Unable to set " + info.parameterNameProviderClass + " as parameter name provider.", e); } logger.info("Using " + info.parameterNameProviderClass + " as parameter name provider."); } return config; }
public class QueryParser { private static final Logger logger = LoggerFactory.getLogger(QueryParser.class); private static final Validator VALIDATOR = Validation.byProvider(ApacheValidationProvider.class) .configure() .buildValidatorFactory() .getValidator(); private AggregatorFactory m_aggregatorFactory; private QueryPluginFactory m_pluginFactory; private GroupByFactory m_groupByFactory; private Map<Class, Map<String, PropertyDescriptor>> m_descriptorMap; private final Object m_descriptorMapLock = new Object(); private Gson m_gson; @Inject public QueryParser( AggregatorFactory aggregatorFactory, GroupByFactory groupByFactory, QueryPluginFactory pluginFactory) { m_aggregatorFactory = aggregatorFactory; m_groupByFactory = groupByFactory; m_pluginFactory = pluginFactory; m_descriptorMap = new HashMap<Class, Map<String, PropertyDescriptor>>(); GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapterFactory(new LowercaseEnumTypeAdapterFactory()); builder.registerTypeAdapter(TimeUnit.class, new TimeUnitDeserializer()); builder.registerTypeAdapter(DateTimeZone.class, new DateTimeZoneDeserializer()); builder.registerTypeAdapter(Metric.class, new MetricDeserializer()); builder.registerTypeAdapter(SetMultimap.class, new SetMultimapDeserializer()); builder.registerTypeAdapter(RelativeTime.class, new RelativeTimeSerializer()); builder.registerTypeAdapter(SetMultimap.class, new SetMultimapSerializer()); builder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); m_gson = builder.create(); } public Gson getGson() { return m_gson; } private PropertyDescriptor getPropertyDescriptor(Class objClass, String property) throws IntrospectionException { synchronized (m_descriptorMapLock) { Map<String, PropertyDescriptor> propMap = m_descriptorMap.get(objClass); if (propMap == null) { propMap = new HashMap<String, PropertyDescriptor>(); m_descriptorMap.put(objClass, propMap); BeanInfo beanInfo = Introspector.getBeanInfo(objClass); PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor descriptor : descriptors) { propMap.put(getUnderscorePropertyName(descriptor.getName()), descriptor); } } return (propMap.get(property)); } } public static String getUnderscorePropertyName(String camelCaseName) { StringBuilder sb = new StringBuilder(); for (char c : camelCaseName.toCharArray()) { if (Character.isUpperCase(c)) sb.append('_').append(Character.toLowerCase(c)); else sb.append(c); } return (sb.toString()); } private void validateObject(Object object) throws BeanValidationException { validateObject(object, null); } private void validateObject(Object object, String context) throws BeanValidationException { // validate object using the bean validation framework Set<ConstraintViolation<Object>> violations = VALIDATOR.validate(object); if (!violations.isEmpty()) { throw new BeanValidationException(violations, context); } } public List<QueryMetric> parseQueryMetric(String json) throws QueryException, BeanValidationException { JsonParser parser = new JsonParser(); JsonObject obj = parser.parse(json).getAsJsonObject(); return parseQueryMetric(obj); } private List<QueryMetric> parseQueryMetric(JsonObject obj) throws QueryException, BeanValidationException { return parseQueryMetric(obj, ""); } private List<QueryMetric> parseQueryMetric(JsonObject obj, String contextPrefix) throws QueryException, BeanValidationException { List<QueryMetric> ret = new ArrayList<QueryMetric>(); Query query; try { query = m_gson.fromJson(obj, Query.class); validateObject(query); } catch (ContextualJsonSyntaxException e) { throw new BeanValidationException( new SimpleConstraintViolation(e.getContext(), e.getMessage()), "query"); } JsonArray metricsArray = obj.getAsJsonArray("metrics"); if (metricsArray == null) { throw new BeanValidationException( new SimpleConstraintViolation("metric[]", "must have a size of at least 1"), contextPrefix + "query"); } for (int I = 0; I < metricsArray.size(); I++) { String context = (!contextPrefix.isEmpty() ? contextPrefix + "." : contextPrefix) + "query.metric[" + I + "]"; try { Metric metric = m_gson.fromJson(metricsArray.get(I), Metric.class); validateObject(metric, context); long startTime = getStartTime(query, context); QueryMetric queryMetric = new QueryMetric(startTime, query.getCacheTime(), metric.getName()); queryMetric.setExcludeTags(metric.isExcludeTags()); queryMetric.setLimit(metric.getLimit()); long endTime = getEndTime(query); if (endTime > -1) queryMetric.setEndTime(endTime); if (queryMetric.getEndTime() < startTime) throw new BeanValidationException( new SimpleConstraintViolation("end_time", "must be greater than the start time"), context); queryMetric.setCacheString(query.getCacheString() + metric.getCacheString()); JsonObject jsMetric = metricsArray.get(I).getAsJsonObject(); JsonElement group_by = jsMetric.get("group_by"); if (group_by != null) { JsonArray groupBys = group_by.getAsJsonArray(); parseGroupBy(context, queryMetric, groupBys); } JsonElement aggregators = jsMetric.get("aggregators"); if (aggregators != null) { JsonArray asJsonArray = aggregators.getAsJsonArray(); if (asJsonArray.size() > 0) parseAggregators(context, queryMetric, asJsonArray, query.getTimeZone()); } JsonElement plugins = jsMetric.get("plugins"); if (plugins != null) { JsonArray pluginArray = plugins.getAsJsonArray(); if (pluginArray.size() > 0) parsePlugins(context, queryMetric, pluginArray); } JsonElement order = jsMetric.get("order"); if (order != null) queryMetric.setOrder(Order.fromString(order.getAsString(), context)); queryMetric.setTags(metric.getTags()); ret.add(queryMetric); } catch (ContextualJsonSyntaxException e) { throw new BeanValidationException( new SimpleConstraintViolation(e.getContext(), e.getMessage()), context); } } return (ret); } public List<RollupTask> parseRollupTasks(String json) throws BeanValidationException, QueryException { List<RollupTask> tasks = new ArrayList<RollupTask>(); JsonParser parser = new JsonParser(); JsonArray rollupTasks = parser.parse(json).getAsJsonArray(); for (int i = 0; i < rollupTasks.size(); i++) { JsonObject taskObject = rollupTasks.get(i).getAsJsonObject(); RollupTask task = parseRollupTask(taskObject, "tasks[" + i + "]"); task.addJson(taskObject.toString().replaceAll("\\n", "")); tasks.add(task); } return tasks; } public RollupTask parseRollupTask(String json) throws BeanValidationException, QueryException { JsonParser parser = new JsonParser(); JsonObject taskObject = parser.parse(json).getAsJsonObject(); RollupTask task = parseRollupTask(taskObject, ""); task.addJson(taskObject.toString().replaceAll("\\n", "")); return task; } public RollupTask parseRollupTask(JsonObject rollupTask, String context) throws BeanValidationException, QueryException { RollupTask task = m_gson.fromJson(rollupTask.getAsJsonObject(), RollupTask.class); validateObject(task); JsonArray rollups = rollupTask.getAsJsonObject().getAsJsonArray("rollups"); if (rollups != null) { for (int j = 0; j < rollups.size(); j++) { JsonObject rollupObject = rollups.get(j).getAsJsonObject(); Rollup rollup = m_gson.fromJson(rollupObject, Rollup.class); context = context + "rollup[" + j + "]"; validateObject(rollup, context); JsonObject queryObject = rollupObject.getAsJsonObject("query"); List<QueryMetric> queries = parseQueryMetric(queryObject, context); for (int k = 0; k < queries.size(); k++) { QueryMetric query = queries.get(k); context += ".query[" + k + "]"; validateHasRangeAggregator(query, context); // Add aggregators needed for rollups SaveAsAggregator saveAsAggregator = (SaveAsAggregator) m_aggregatorFactory.createAggregator("save_as"); saveAsAggregator.setMetricName(rollup.getSaveAs()); TrimAggregator trimAggregator = (TrimAggregator) m_aggregatorFactory.createAggregator("trim"); trimAggregator.setTrim(TrimAggregator.Trim.LAST); query.addAggregator(saveAsAggregator); query.addAggregator(trimAggregator); } rollup.addQueries(queries); task.addRollup(rollup); } } return task; } private void validateHasRangeAggregator(QueryMetric query, String context) throws BeanValidationException { boolean hasRangeAggregator = false; for (Aggregator aggregator : query.getAggregators()) { if (aggregator instanceof RangeAggregator) { hasRangeAggregator = true; break; } } if (!hasRangeAggregator) { throw new BeanValidationException( new SimpleConstraintViolation( "aggregator", "At least one aggregator must be a range aggregator"), context); } } private void parsePlugins(String context, QueryMetric queryMetric, JsonArray plugins) throws BeanValidationException, QueryException { for (int I = 0; I < plugins.size(); I++) { JsonObject pluginJson = plugins.get(I).getAsJsonObject(); JsonElement name = pluginJson.get("name"); if (name == null || name.getAsString().isEmpty()) throw new BeanValidationException( new SimpleConstraintViolation("plugins[" + I + "]", "must have a name"), context); String pluginContext = context + ".plugins[" + I + "]"; String pluginName = name.getAsString(); QueryPlugin plugin = m_pluginFactory.createQueryPlugin(pluginName); if (plugin == null) throw new BeanValidationException( new SimpleConstraintViolation(pluginName, "invalid query plugin name"), pluginContext); deserializeProperties(pluginContext, pluginJson, pluginName, plugin); validateObject(plugin, pluginContext); queryMetric.addPlugin(plugin); } } private void parseAggregators( String context, QueryMetric queryMetric, JsonArray aggregators, DateTimeZone timeZone) throws QueryException, BeanValidationException { for (int J = 0; J < aggregators.size(); J++) { JsonObject jsAggregator = aggregators.get(J).getAsJsonObject(); JsonElement name = jsAggregator.get("name"); if (name == null || name.getAsString().isEmpty()) throw new BeanValidationException( new SimpleConstraintViolation("aggregators[" + J + "]", "must have a name"), context); String aggContext = context + ".aggregators[" + J + "]"; String aggName = name.getAsString(); Aggregator aggregator = m_aggregatorFactory.createAggregator(aggName); if (aggregator == null) throw new BeanValidationException( new SimpleConstraintViolation(aggName, "invalid aggregator name"), aggContext); // If it is a range aggregator we will default the start time to // the start of the query. if (aggregator instanceof RangeAggregator) { RangeAggregator ra = (RangeAggregator) aggregator; ra.setStartTime(queryMetric.getStartTime()); } if (aggregator instanceof TimezoneAware) { TimezoneAware ta = (TimezoneAware) aggregator; ta.setTimeZone(timeZone); } if (aggregator instanceof GroupByAware) { GroupByAware groupByAware = (GroupByAware) aggregator; groupByAware.setGroupBys(queryMetric.getGroupBys()); } deserializeProperties(aggContext, jsAggregator, aggName, aggregator); validateObject(aggregator, aggContext); queryMetric.addAggregator(aggregator); } } private void parseGroupBy(String context, QueryMetric queryMetric, JsonArray groupBys) throws QueryException, BeanValidationException { for (int J = 0; J < groupBys.size(); J++) { String groupContext = "group_by[" + J + "]"; JsonObject jsGroupBy = groupBys.get(J).getAsJsonObject(); JsonElement nameElement = jsGroupBy.get("name"); if (nameElement == null || nameElement.getAsString().isEmpty()) throw new BeanValidationException( new SimpleConstraintViolation(groupContext, "must have a name"), context); String name = nameElement.getAsString(); GroupBy groupBy = m_groupByFactory.createGroupBy(name); if (groupBy == null) throw new BeanValidationException( new SimpleConstraintViolation(groupContext + "." + name, "invalid group_by name"), context); deserializeProperties(context + "." + groupContext, jsGroupBy, name, groupBy); validateObject(groupBy, context + "." + groupContext); groupBy.setStartDate(queryMetric.getStartTime()); queryMetric.addGroupBy(groupBy); } } private void deserializeProperties( String context, JsonObject jsonObject, String name, Object object) throws QueryException, BeanValidationException { Set<Map.Entry<String, JsonElement>> props = jsonObject.entrySet(); for (Map.Entry<String, JsonElement> prop : props) { String property = prop.getKey(); if (property.equals("name")) continue; PropertyDescriptor pd = null; try { pd = getPropertyDescriptor(object.getClass(), property); } catch (IntrospectionException e) { logger.error("Introspection error on " + object.getClass(), e); } if (pd == null) { String msg = "Property '" + property + "' was specified for object '" + name + "' but no matching setter was found on '" + object.getClass() + "'"; throw new QueryException(msg); } Class propClass = pd.getPropertyType(); Object propValue; try { propValue = m_gson.fromJson(prop.getValue(), propClass); validateObject(propValue, context + "." + property); } catch (ContextualJsonSyntaxException e) { throw new BeanValidationException( new SimpleConstraintViolation(e.getContext(), e.getMessage()), context); } catch (NumberFormatException e) { throw new BeanValidationException( new SimpleConstraintViolation(property, e.getMessage()), context); } Method method = pd.getWriteMethod(); if (method == null) { String msg = "Property '" + property + "' was specified for object '" + name + "' but no matching setter was found on '" + object.getClass().getName() + "'"; throw new QueryException(msg); } try { method.invoke(object, propValue); } catch (Exception e) { logger.error("Invocation error: ", e); String msg = "Call to " + object.getClass().getName() + ":" + method.getName() + " failed with message: " + e.getMessage(); throw new QueryException(msg); } } } private long getStartTime(Query request, String context) throws BeanValidationException { if (request.getStartAbsolute() != null) { return request.getStartAbsolute(); } else if (request.getStartRelative() != null) { return request.getStartRelative().getTimeRelativeTo(System.currentTimeMillis()); } else { throw new BeanValidationException( new SimpleConstraintViolation("start_time", "relative or absolute time must be set"), context); } } private long getEndTime(Query request) { if (request.getEndAbsolute() != null) return request.getEndAbsolute(); else if (request.getEndRelative() != null) return request.getEndRelative().getTimeRelativeTo(System.currentTimeMillis()); return -1; } // =========================================================================== private static class Metric { @NotNull @NotEmpty() @SerializedName("name") private String name; @SerializedName("tags") private SetMultimap<String, String> tags; @SerializedName("exclude_tags") private boolean exclude_tags; @SerializedName("limit") private int limit; public Metric(String name, boolean exclude_tags, TreeMultimap<String, String> tags) { this.name = name; this.tags = tags; this.exclude_tags = exclude_tags; this.limit = 0; } public String getName() { return name; } public int getLimit() { return limit; } public void setLimit(int limit) { this.limit = limit; } private boolean isExcludeTags() { return exclude_tags; } public String getCacheString() { StringBuilder sb = new StringBuilder(); sb.append(name).append(":"); for (Map.Entry<String, String> tagEntry : tags.entries()) { sb.append(tagEntry.getKey()).append("="); sb.append(tagEntry.getValue()).append(":"); } return (sb.toString()); } public SetMultimap<String, String> getTags() { if (tags != null) { return tags; } else { return HashMultimap.create(); } } } // =========================================================================== private static class Query { @SerializedName("start_absolute") private Long m_startAbsolute; @SerializedName("end_absolute") private Long m_endAbsolute; @Min(0) @SerializedName("cache_time") private int cache_time; @Valid @SerializedName("start_relative") private RelativeTime start_relative; @Valid @SerializedName("end_relative") private RelativeTime end_relative; @Valid @SerializedName("time_zone") private DateTimeZone m_timeZone; // = DateTimeZone.UTC;; public Long getStartAbsolute() { return m_startAbsolute; } public Long getEndAbsolute() { return m_endAbsolute; } public int getCacheTime() { return cache_time; } public RelativeTime getStartRelative() { return start_relative; } public RelativeTime getEndRelative() { return end_relative; } public DateTimeZone getTimeZone() { return m_timeZone; } public String getCacheString() { StringBuilder sb = new StringBuilder(); if (m_startAbsolute != null) sb.append(m_startAbsolute).append(":"); if (start_relative != null) sb.append(start_relative.toString()).append(":"); if (m_endAbsolute != null) sb.append(m_endAbsolute).append(":"); if (end_relative != null) sb.append(end_relative.toString()).append(":"); return (sb.toString()); } @Override public String toString() { return "Query{" + "startAbsolute='" + m_startAbsolute + '\'' + ", endAbsolute='" + m_endAbsolute + '\'' + ", cache_time=" + cache_time + ", startRelative=" + start_relative + ", endRelative=" + end_relative + '}'; } } // =========================================================================== private static class LowercaseEnumTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { @SuppressWarnings("unchecked") Class<T> rawType = (Class<T>) type.getRawType(); if (!rawType.isEnum()) { return null; } final Map<String, T> lowercaseToConstant = new HashMap<String, T>(); for (T constant : rawType.getEnumConstants()) { lowercaseToConstant.put(toLowercase(constant), constant); } return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { if (value == null) { out.nullValue(); } else { out.value(toLowercase(value)); } } public T read(JsonReader reader) throws IOException { if (reader.peek() == JsonToken.NULL) { reader.nextNull(); return null; } else { return lowercaseToConstant.get(reader.nextString()); } } }; } private String toLowercase(Object o) { return o.toString().toLowerCase(Locale.US); } } // =========================================================================== private class TimeUnitDeserializer implements JsonDeserializer<TimeUnit> { public TimeUnit deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String unit = json.getAsString(); TimeUnit tu; try { tu = TimeUnit.from(unit); } catch (IllegalArgumentException e) { throw new ContextualJsonSyntaxException( unit, "is not a valid time unit, must be one of " + TimeUnit.toValueNames()); } return tu; } } // =========================================================================== private class DateTimeZoneDeserializer implements JsonDeserializer<DateTimeZone> { public DateTimeZone deserialize( JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if (json.isJsonNull()) return null; String tz = json.getAsString(); if (tz.isEmpty()) // defaults to UTC return DateTimeZone.UTC; DateTimeZone timeZone; try { // check if time zone is valid timeZone = DateTimeZone.forID(tz); } catch (IllegalArgumentException e) { throw new ContextualJsonSyntaxException( tz, "is not a valid time zone, must be one of " + DateTimeZone.getAvailableIDs()); } return timeZone; } } // =========================================================================== private class MetricDeserializer implements JsonDeserializer<Metric> { @Override public Metric deserialize( JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { JsonObject jsonObject = jsonElement.getAsJsonObject(); String name = null; if (jsonObject.get("name") != null) name = jsonObject.get("name").getAsString(); boolean exclude_tags = false; if (jsonObject.get("exclude_tags") != null) exclude_tags = jsonObject.get("exclude_tags").getAsBoolean(); TreeMultimap<String, String> tags = TreeMultimap.create(); JsonElement jeTags = jsonObject.get("tags"); if (jeTags != null) { JsonObject joTags = jeTags.getAsJsonObject(); int count = 0; for (Map.Entry<String, JsonElement> tagEntry : joTags.entrySet()) { String context = "tags[" + count + "]"; if (tagEntry.getKey().isEmpty()) throw new ContextualJsonSyntaxException(context, "name must not be empty"); if (tagEntry.getValue().isJsonArray()) { for (JsonElement element : tagEntry.getValue().getAsJsonArray()) { if (element.isJsonNull() || element.getAsString().isEmpty()) throw new ContextualJsonSyntaxException( context + "." + tagEntry.getKey(), "value must not be null or empty"); tags.put(tagEntry.getKey(), element.getAsString()); } } else { if (tagEntry.getValue().isJsonNull() || tagEntry.getValue().getAsString().isEmpty()) throw new ContextualJsonSyntaxException( context + "." + tagEntry.getKey(), "value must not be null or empty"); tags.put(tagEntry.getKey(), tagEntry.getValue().getAsString()); } count++; } } Metric ret = new Metric(name, exclude_tags, tags); JsonElement limit = jsonObject.get("limit"); if (limit != null) ret.setLimit(limit.getAsInt()); return (ret); } } // =========================================================================== private static class ContextualJsonSyntaxException extends RuntimeException { private String context; private ContextualJsonSyntaxException(String context, String msg) { super(msg); this.context = context; } private String getContext() { return context; } } // =========================================================================== public static class SimpleConstraintViolation implements ConstraintViolation<Object> { private String message; private String context; public SimpleConstraintViolation(String context, String message) { this.message = message; this.context = context; } @Override public String getMessage() { return message; } @Override public String getMessageTemplate() { return null; } @Override public Object getRootBean() { return null; } @Override public Class<Object> getRootBeanClass() { return null; } @Override public Object getLeafBean() { return null; } @Override public Path getPropertyPath() { return new SimplePath(context); } @Override public Object getInvalidValue() { return null; } @Override public ConstraintDescriptor<?> getConstraintDescriptor() { return null; } } private static class SimplePath implements Path { private String context; private SimplePath(String context) { this.context = context; } @Override public Iterator<Node> iterator() { return null; } @Override public String toString() { return context; } } }
@Test public void testBootstrapAsServiceWithBuilder() { HibernateValidatorConfiguration configuration = Validation.byProvider(HibernateValidationProvider.class).configure(); assertDefaultBuilderAndFactory(configuration); }
public static <T extends Configuration<T>, U extends ValidationProvider<T>> ProviderSpecificBootstrap<T> byProvider(Class<U> providerType) { ProviderSpecificBootstrap<T> bootstrap = Validation.byProvider(providerType); return new ProviderSpecificBootstrapWrapper<T>(bootstrap); }