You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by si...@apache.org on 2010/03/28 14:28:32 UTC
svn commit: r928387 [10/15] - in /incubator/bval/trunk: ./ agimatec-jsr303/
agimatec-validation/ bval-core/ bval-core/.externalToolBuilders/
bval-core/.settings/ bval-core/src/ bval-core/src/main/
bval-core/src/main/java/ bval-core/src/main/java/org/ b...
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/CachingTraversableResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/CachingTraversableResolver.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/CachingTraversableResolver.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/DefaultTraversableResolver.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/DefaultTraversableResolver.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/DefaultTraversableResolver.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/DefaultTraversableResolver.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you 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 org.apache.bval.jsr303.resolver;
+
+import org.apache.bval.jsr303.util.SecureActions;
+import org.apache.commons.lang.ClassUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.validation.Path;
+import javax.validation.TraversableResolver;
+import java.lang.annotation.ElementType;
+
+
+/** @see javax.validation.TraversableResolver */
+public class DefaultTraversableResolver implements TraversableResolver, CachingRelevant {
+ private static final Log log = LogFactory.getLog(DefaultTraversableResolver.class);
+
+ /** Class to load to check whether JPA 2 is on the classpath. */
+ private static final String PERSISTENCE_UTIL_CLASSNAME =
+ "javax.persistence.PersistenceUtil";
+
+ /** Class to instantiate in case JPA 2 is on the classpath. */
+ private static final String JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME =
+ "org.apache.bval.jsr303.resolver.JPATraversableResolver";
+
+
+ private TraversableResolver jpaTR;
+
+
+ public DefaultTraversableResolver() {
+ initJpa();
+ }
+
+ public boolean isReachable(Object traversableObject, Path.Node traversableProperty,
+ Class<?> rootBeanType, Path pathToTraversableObject,
+ ElementType elementType) {
+ return jpaTR == null || jpaTR.isReachable(traversableObject, traversableProperty,
+ rootBeanType, pathToTraversableObject, elementType);
+ }
+
+ public boolean isCascadable(Object traversableObject, Path.Node traversableProperty,
+ Class<?> rootBeanType, Path pathToTraversableObject,
+ ElementType elementType) {
+ return jpaTR == null || jpaTR.isCascadable(traversableObject, traversableProperty,
+ rootBeanType, pathToTraversableObject, elementType);
+ }
+
+ /** Tries to load detect and load JPA. */
+ private void initJpa() {
+ try {
+ ClassUtils.getClass(PERSISTENCE_UTIL_CLASSNAME);
+ if (log.isDebugEnabled())
+ log.debug("Found " + PERSISTENCE_UTIL_CLASSNAME + " on classpath.");
+ } catch (Exception e) {
+ if (log.isDebugEnabled())
+ log.debug("Cannot find " + PERSISTENCE_UTIL_CLASSNAME +
+ " on classpath. All properties will per default be traversable.");
+ return;
+ }
+
+ try {
+ Class<? extends TraversableResolver> jpaAwareResolverClass =
+ (Class<? extends TraversableResolver>) ClassUtils
+ .getClass(JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME);
+ jpaTR = SecureActions.newInstance(jpaAwareResolverClass);
+ if (log.isDebugEnabled())
+ log.debug("Instantiated an instance of " +
+ JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME + ".");
+ } catch (Exception e) {
+ log.warn("Unable to load or instanciate JPA aware resolver " +
+ JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME +
+ ". All properties will per default be traversable.", e);
+ }
+ }
+
+ public boolean needsCaching() {
+ return jpaTR != null && CachingTraversableResolver.needsCaching(jpaTR);
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/DefaultTraversableResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/DefaultTraversableResolver.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/DefaultTraversableResolver.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/JPATraversableResolver.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/JPATraversableResolver.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/JPATraversableResolver.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/JPATraversableResolver.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you 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 org.apache.bval.jsr303.resolver;
+
+import javax.persistence.Persistence;
+import javax.validation.Path;
+import javax.validation.TraversableResolver;
+import java.lang.annotation.ElementType;
+
+
+/** @see javax.validation.TraversableResolver */
+public class JPATraversableResolver implements TraversableResolver, CachingRelevant {
+
+ public boolean isReachable(Object traversableObject, Path.Node traversableProperty,
+ Class<?> rootBeanType, Path pathToTraversableObject,
+ ElementType elementType) {
+ return traversableObject == null || Persistence.getPersistenceUtil()
+ .isLoaded(traversableObject, traversableProperty.getName());
+ }
+
+ public boolean isCascadable(Object traversableObject, Path.Node traversableProperty,
+ Class<?> rootBeanType, Path pathToTraversableObject,
+ ElementType elementType) {
+ return true;
+ }
+
+ public boolean needsCaching() {
+ return true; // yes
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/JPATraversableResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/JPATraversableResolver.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/JPATraversableResolver.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/SimpleTraversableResolver.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/SimpleTraversableResolver.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/SimpleTraversableResolver.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/SimpleTraversableResolver.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.resolver;
+
+import javax.validation.Path;
+import javax.validation.TraversableResolver;
+import java.lang.annotation.ElementType;
+
+/**
+ * Description: traversable resolver that does always resolve<br/>
+ * User: roman <br/>
+ * Date: 25.11.2009 <br/>
+ * Time: 13:21:18 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class SimpleTraversableResolver implements TraversableResolver, CachingRelevant {
+ /** @return true */
+ public boolean isReachable(Object traversableObject, Path.Node traversableProperty,
+ Class<?> rootBeanType, Path pathToTraversableObject,
+ java.lang.annotation.ElementType elementType) {
+ return true;
+ }
+
+ /** @return true */
+
+ public boolean isCascadable(Object traversableObject, Path.Node traversableProperty,
+ Class<?> rootBeanType, Path pathToTraversableObject,
+ ElementType elementType) {
+ return true;
+ }
+
+ public boolean needsCaching() {
+ return false; // no
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/SimpleTraversableResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/SimpleTraversableResolver.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/resolver/SimpleTraversableResolver.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConverterUtils.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConverterUtils.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConverterUtils.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConverterUtils.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.util;
+
+import javax.validation.ValidationException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Description: method for value conversion<br/>
+ * User: roman <br/>
+ * Date: 25.11.2009 <br/>
+ * Time: 09:32:44 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public final class ConverterUtils {
+ private static interface Converter {
+ Object fromString(String value) throws Exception;
+ }
+
+ private static final Map<String, Converter> converterMap;
+
+ static {
+ converterMap = new HashMap<String, Converter>();
+ converterMap.put(byte.class.getName(), new Converter() {
+ public Byte fromString(String value) {
+ return Byte.valueOf(value);
+ }
+ });
+ converterMap.put(short.class.getName(), new Converter() {
+ public Short fromString(String value) {
+ return Short.valueOf(value);
+ }
+ });
+ converterMap.put(int.class.getName(), new Converter() {
+ public Integer fromString(String value) {
+ return Integer.valueOf(value);
+ }
+ });
+ converterMap.put(long.class.getName(), new Converter() {
+ public Long fromString(String value) {
+ return Long.valueOf(value);
+ }
+ });
+ converterMap.put(float.class.getName(), new Converter() {
+ public Float fromString(String value) {
+ return Float.valueOf(value);
+ }
+ });
+ converterMap.put(double.class.getName(), new Converter() {
+ public Double fromString(String value) {
+ return Double.valueOf(value);
+ }
+ });
+ converterMap.put(boolean.class.getName(), new Converter() {
+ public Boolean fromString(String value) {
+ return Boolean.valueOf(value);
+ }
+ });
+ converterMap.put(char.class.getName(), new Converter() {
+ public Character fromString(String value) {
+ if (value.length() != 1) {
+ throw new ValidationException("Invalid char value: " + value);
+ }
+ return value.charAt(0);
+ }
+ });
+ converterMap.put(String.class.getName(), new Converter() {
+ public String fromString(String value) {
+ return value;
+ }
+ });
+ converterMap.put(Class.class.getName(), new Converter() {
+ public Class<?> fromString(String value) {
+ return SecureActions.loadClass(value, getClass());
+ }
+ });
+
+ }
+
+
+ /** implementation of spec: 7.1.3. Converting the string representation of a value */
+ public static Object fromStringToType(String value, Class<?> type) {
+ Converter converter = converterMap.get(type.getName());
+ if (converter != null) {
+ try {
+ return converter.fromString(value);
+ } catch (Exception e) {
+ throw new ValidationException(
+ "Invalid " + type.getSimpleName() + " format: " + value, e);
+ }
+ } else if (type.isEnum()) {
+ try {
+ @SuppressWarnings("unchecked")
+ final Class<Enum> enumClass = (Class<Enum>) type;
+ return Enum.valueOf(enumClass, value);
+ } catch (Exception e) { // IllegalArgumentException
+ throw new ValidationException(
+ "Invalid type: " + type + ". There is no enum member: " + value);
+ }
+ } else {
+ // spec: If any of the string representation does not match its type counterpart,
+ // a ValidationException is raised.
+ throw new ValidationException("Cannot convert " + value + " to " + type.getName());
+ }
+
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConverterUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConverterUtils.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ConverterUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderCustomizableContextImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderCustomizableContextImpl.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderCustomizableContextImpl.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderCustomizableContextImpl.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.util;
+
+
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.Path;
+
+import org.apache.bval.jsr303.ConstraintValidatorContextImpl;
+
+/**
+ * Description: <br/>
+ * User: roman <br/>
+ * Date: 28.09.2009 <br/>
+ * Time: 15:30:03 <br/>
+ * Copyright: Agimatec GmbH
+ */
+final class NodeBuilderCustomizableContextImpl
+ implements ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext {
+ private final ConstraintValidatorContextImpl parent;
+ private final String messageTemplate;
+ private final PathImpl propertyPath;
+
+ NodeBuilderCustomizableContextImpl(ConstraintValidatorContextImpl contextImpl, String template,
+ PathImpl path) {
+ parent = contextImpl;
+ messageTemplate = template;
+ propertyPath = path;
+ }
+
+ public ConstraintValidatorContext.ConstraintViolationBuilder.NodeContextBuilder inIterable() {
+ return new NodeContextBuilderImpl(parent, messageTemplate, propertyPath);
+ }
+
+ public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(
+ String name) {
+ Path.Node node = new NodeImpl(name);
+ propertyPath.addNode(node);
+ return this;
+ }
+
+ public ConstraintValidatorContext addConstraintViolation() {
+ parent.addError(messageTemplate, propertyPath);
+ return parent;
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderCustomizableContextImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderCustomizableContextImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderCustomizableContextImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderDefinedContextImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderDefinedContextImpl.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderDefinedContextImpl.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderDefinedContextImpl.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.util;
+
+
+import javax.validation.ConstraintValidatorContext;
+
+import org.apache.bval.jsr303.ConstraintValidatorContextImpl;
+
+/**
+ * Description: <br/>
+ * User: roman <br/>
+ * Date: 28.09.2009 <br/>
+ * Time: 15:29:03 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public final class NodeBuilderDefinedContextImpl
+ implements ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderDefinedContext {
+ private final ConstraintValidatorContextImpl parent;
+ private final String messageTemplate;
+ private final PathImpl propertyPath;
+
+ public NodeBuilderDefinedContextImpl(ConstraintValidatorContextImpl contextImpl, String template,
+ PathImpl path) {
+ parent = contextImpl;
+ messageTemplate = template;
+ propertyPath = path;
+ }
+
+ public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(
+ String name) {
+ NodeImpl node = new NodeImpl(name);
+ propertyPath.addNode(node);
+ return new NodeBuilderCustomizableContextImpl(parent, messageTemplate, propertyPath);
+ }
+
+ public ConstraintValidatorContext addConstraintViolation() {
+ parent.addError(messageTemplate, propertyPath);
+ return parent;
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderDefinedContextImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderDefinedContextImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeBuilderDefinedContextImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeContextBuilderImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeContextBuilderImpl.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeContextBuilderImpl.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeContextBuilderImpl.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.util;
+
+
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.Path;
+
+import org.apache.bval.jsr303.ConstraintValidatorContextImpl;
+
+/**
+ * Description: <br/>
+ * User: roman <br/>
+ * Date: 28.09.2009 <br/>
+ * Time: 15:30:38 <br/>
+ * Copyright: Agimatec GmbH
+ */
+final class NodeContextBuilderImpl
+ implements ConstraintValidatorContext.ConstraintViolationBuilder.NodeContextBuilder {
+ private final ConstraintValidatorContextImpl parent;
+ private final String messageTemplate;
+ private final PathImpl propertyPath;
+
+ NodeContextBuilderImpl(ConstraintValidatorContextImpl contextImpl,
+ String template, PathImpl path) {
+ parent = contextImpl;
+ messageTemplate = template;
+ propertyPath = path;
+ propertyPath.getLeafNode().setInIterable(true);
+ }
+
+ public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderDefinedContext atKey(
+ Object key) {
+ propertyPath.getLeafNode().setKey(key);
+ return new NodeBuilderDefinedContextImpl(parent, messageTemplate, propertyPath);
+ }
+
+ public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderDefinedContext atIndex(
+ Integer index) {
+ propertyPath.getLeafNode().setIndex(index);
+ return new NodeBuilderDefinedContextImpl(parent, messageTemplate, propertyPath);
+ }
+
+ public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(
+ String name) {
+ Path.Node node = new NodeImpl(name);
+ propertyPath.addNode(node);
+ return new NodeBuilderCustomizableContextImpl(parent, messageTemplate, propertyPath);
+ }
+
+ public ConstraintValidatorContext addConstraintViolation() {
+ parent.addError(messageTemplate, propertyPath);
+ return parent;
+ }
+}
\ No newline at end of file
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeContextBuilderImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeContextBuilderImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeContextBuilderImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeImpl.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeImpl.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeImpl.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.util;
+
+import javax.validation.Path;
+import java.io.Serializable;
+
+/**
+ * Description: a node (property) as part of a Path.
+ * (Implementation based on reference implementation) <br/>
+ * User: roman <br/>
+ * Date: 28.09.2009 <br/>
+ * Time: 11:56:35 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public final class NodeImpl implements Path.Node, Serializable {
+
+ private static final String INDEX_OPEN = "[";
+ private static final String INDEX_CLOSE = "]";
+
+ private final String name;
+ private boolean isInIterable;
+ private Integer index;
+ private Object key;
+
+ public NodeImpl(String name) {
+ this.name = name;
+ }
+
+ NodeImpl(Path.Node node) {
+ this.name = node.getName();
+ this.isInIterable = node.isInIterable();
+ this.index = node.getIndex();
+ this.key = node.getKey();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isInIterable() {
+ return isInIterable;
+ }
+
+ public void setInIterable(boolean inIterable) {
+ isInIterable = inIterable;
+ }
+
+ public Integer getIndex() {
+ return index;
+ }
+
+ public void setIndex(Integer index) {
+ isInIterable = true;
+ this.index = index;
+ }
+
+ public Object getKey() {
+ return key;
+ }
+
+ public void setKey(Object key) {
+ isInIterable = true;
+ this.key = key;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder(name == null ? "" : name);
+ if (isInIterable) {
+ builder.append(INDEX_OPEN);
+ if (getIndex() != null) {
+ builder.append(getIndex());
+ } else if (getKey() != null) {
+ builder.append(getKey());
+ }
+ builder.append(INDEX_CLOSE);
+ }
+ return builder.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ NodeImpl node = (NodeImpl) o;
+
+ if (isInIterable != node.isInIterable) {
+ return false;
+ }
+ if (index != null ? !index.equals(node.index) : node.index != null) {
+ return false;
+ }
+ if (key != null ? !key.equals(node.key) : node.key != null) {
+ return false;
+ }
+ if (name != null ? !name.equals(node.name) : node.name != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (isInIterable ? 1 : 0);
+ result = 31 * result + (index != null ? index.hashCode() : 0);
+ result = 31 * result + (key != null ? key.hashCode() : 0);
+ return result;
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/NodeImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/PathImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/PathImpl.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/PathImpl.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/PathImpl.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.util;
+
+import javax.validation.Path;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Description: object holding the property path as a list of nodes.
+ * (Implementation based on reference implementation)
+ * <br/>
+ * User: roman <br/>
+ * Date: 28.09.2009 <br/>
+ * Time: 11:21:33 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class PathImpl implements Path, Serializable {
+
+ /**
+ * Regular expression used to split a string path into its elements.
+ *
+ * @see <a href="http://www.regexplanet.com/simple/index.jsp">Regular expression tester</a>
+ */
+ private static final Pattern pathPattern =
+ Pattern.compile("(\\w+)(\\[(\\w*)\\])?(\\.(.*))*");
+
+ private static final String PROPERTY_PATH_SEPERATOR = ".";
+
+ private final List<Node> nodeList;
+
+ /**
+ * Returns a {@code Path} instance representing the path described by the given string. To create a root node the empty string should be passed.
+ * Note: This signature is to maintain pluggability with the RI impl.
+ *
+ * @param propertyPath the path as string representation.
+ * @return a {@code Path} instance representing the path described by the given string.
+ */
+ public static PathImpl createPathFromString(String propertyPath) {
+ if (propertyPath == null || propertyPath.length() == 0) {
+ return create(null);
+ }
+
+ return parseProperty(propertyPath);
+ }
+
+ public static PathImpl create(String name) {
+ PathImpl path = new PathImpl();
+ NodeImpl node = new NodeImpl(name);
+ path.addNode(node);
+ return path;
+ }
+
+ public static PathImpl copy(Path path) {
+ return path == null ? null : new PathImpl(path);
+ }
+
+ private PathImpl(Path path) {
+ this.nodeList = new ArrayList<Node>();
+ for (Object aPath : path) {
+ nodeList.add(new NodeImpl((Node) aPath));
+ }
+ }
+
+ private PathImpl() {
+ nodeList = new ArrayList<Node>();
+ }
+
+ private PathImpl(List<Node> nodeList) {
+ this.nodeList = new ArrayList<Node>();
+ for (Node node : nodeList) {
+ this.nodeList.add(new NodeImpl(node));
+ }
+ }
+
+ public boolean isRootPath() {
+ return nodeList.size() == 1 && nodeList.get(0).getName() == null;
+ }
+
+ public PathImpl getPathWithoutLeafNode() {
+ List<Node> nodes = new ArrayList<Node>(nodeList);
+ PathImpl path = null;
+ if (nodes.size() > 1) {
+ nodes.remove(nodes.size() - 1);
+ path = new PathImpl(nodes);
+ }
+ return path;
+ }
+
+ public void addNode(Node node) {
+ nodeList.add(node);
+ }
+
+ public Node removeLeafNode() {
+ if (nodeList.size() == 0) {
+ throw new IllegalStateException("No nodes in path!");
+ }
+ return nodeList.remove(nodeList.size() - 1);
+ }
+
+ public NodeImpl getLeafNode() {
+ if (nodeList.size() == 0) {
+ return null;
+ }
+ return (NodeImpl) nodeList.get(nodeList.size() - 1);
+ }
+
+
+ public Iterator<Path.Node> iterator() {
+ return nodeList.iterator();
+ }
+
+ public boolean isSubPathOf(Path path) {
+ Iterator<Node> pathIter = path.iterator();
+ Iterator<Node> thisIter = iterator();
+ while (pathIter.hasNext()) {
+ Node pathNode = pathIter.next();
+ if (!thisIter.hasNext()) {
+ return false;
+ }
+ Node thisNode = thisIter.next();
+ if (!thisNode.equals(pathNode)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ Iterator<Path.Node> iter = iterator();
+ while (iter.hasNext()) {
+ Node node = iter.next();
+ builder.append(node.toString());
+ if (iter.hasNext() && builder.length() > 0) {
+ builder.append(PROPERTY_PATH_SEPERATOR);
+ }
+ }
+ return builder.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ PathImpl path = (PathImpl) o;
+ return !(nodeList != null && !nodeList.equals(path.nodeList)) &&
+ !(nodeList == null && path.nodeList != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return nodeList != null ? nodeList.hashCode() : 0;
+ }
+
+ private static PathImpl parseProperty(String property) {
+ PathImpl path = new PathImpl();
+ String tmp = property;
+ do {
+ Matcher matcher = pathPattern.matcher(tmp);
+ if (matcher.matches()) {
+ String value = matcher.group(1);
+ String indexed = matcher.group(2);
+ String index = matcher.group(3);
+ NodeImpl node = new NodeImpl(value);
+ if (indexed != null) {
+ node.setInIterable(true);
+ }
+ if (index != null && index.length() > 0) {
+ try {
+ Integer i = Integer.valueOf(index);
+ node.setIndex(i);
+ } catch (NumberFormatException e) {
+ node.setKey(index);
+ }
+ }
+ path.addNode(node);
+ tmp = matcher.group(5);
+ } else {
+ throw new IllegalArgumentException(
+ "Unable to parse property path " + property);
+ }
+ } while (tmp != null);
+ return path;
+ }
+
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/PathImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/PathImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/PathImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/SecureActions.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/SecureActions.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/SecureActions.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/SecureActions.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.util;
+
+import org.apache.bval.util.PrivilegedActions;
+import org.apache.commons.lang.StringUtils;
+
+import javax.validation.ValidationException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.PrivilegedAction;
+
+/**
+ * Description: utility methods to perform actions with AccessController or without.<br/>
+ * User: roman <br/>
+ * Date: 01.10.2009 <br/>
+ * Time: 16:44:09 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class SecureActions extends PrivilegedActions {
+
+ /**
+ * create a new instance of the class using the default no-arg constructor.
+ * perform newInstance() call with AccessController.doPrivileged() if possible.
+ *
+ * @param cls - the class (no interface, non-abstract, has accessible default no-arg-constructor)
+ * @return a new instance
+ */
+ public static <T> T newInstance(final Class<T> cls) {
+ return newInstance(cls, ValidationException.class);
+ }
+
+ public static <T> T newInstance(final Class<T> cls, final Class[] paramTypes,
+ final Object[] values) {
+ return newInstance(cls, ValidationException.class, paramTypes, values);
+ }
+
+ public static Class<?> loadClass(final String className, final Class<?> caller) {
+ return run(new PrivilegedAction<Class<?>>() {
+ public Class<?> run() {
+ try {
+ ClassLoader contextClassLoader =
+ Thread.currentThread().getContextClassLoader();
+ if (contextClassLoader != null) {
+ return contextClassLoader.loadClass(className);
+ }
+ } catch (Throwable e) {
+ // ignore
+ }
+ try {
+ return Class.forName(className, true, caller.getClassLoader());
+ } catch (ClassNotFoundException e) {
+ throw new ValidationException("Unable to load class: " + className, e);
+ }
+ }
+ });
+ }
+
+ public static Field getDeclaredField(final Class clazz, final String fieldName) {
+ return run(new PrivilegedAction<Field>() {
+ public Field run() {
+ try {
+ Field f = clazz.getDeclaredField(fieldName);
+ setAccessibility(f);
+ return f;
+ } catch (NoSuchFieldException e) {
+ return null;
+ }
+ }
+ });
+ }
+
+ private static void setAccessibility(Field field) {
+ if (!Modifier.isPublic(field.getModifiers()) || (
+ Modifier.isPublic(field.getModifiers()) &&
+ Modifier.isAbstract(field.getModifiers()))) {
+ field.setAccessible(true);
+ }
+ }
+
+ /**
+ * Returns the <b>public method</b> with the specified name or null if it does not exist.
+ *
+ * @return Returns the method or null if not found.
+ */
+ public static Method getGetter(final Class<?> clazz, final String methodName) {
+ return run(new PrivilegedAction<Method>() {
+ public Method run() {
+ try {
+ String methodName0 = StringUtils.capitalize(methodName);
+ try {
+ return clazz.getMethod("get" + methodName0);
+ } catch (NoSuchMethodException e) {
+ return clazz.getMethod("is" + methodName0);
+ }
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+ });
+
+ }
+
+ public static Method getMethod(final Class<?> clazz, final String methodName) {
+ return run(new PrivilegedAction<Method>() {
+ public Method run() {
+ try {
+ return clazz.getMethod(methodName);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+ });
+ }
+
+ public static Method[] getDeclaredMethods(final Class<?> clazz) {
+ return run(new PrivilegedAction<Method[]>() {
+ public Method[] run() {
+ return clazz.getDeclaredMethods();
+ }
+ });
+ }
+
+ public static <T> Constructor<T> getConstructor(final Class<T> clazz,
+ final Class<?>... params) {
+ return run(new PrivilegedAction<Constructor<T>>() {
+ public Constructor<T> run() {
+ try {
+ return clazz.getConstructor(params);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+ });
+ }
+
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/SecureActions.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/SecureActions.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/SecureActions.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/TypeUtils.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/TypeUtils.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/TypeUtils.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/TypeUtils.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,494 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.util;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ValidationException;
+import java.io.Serializable;
+import java.lang.reflect.*;
+import java.util.*;
+
+
+/**
+ * Description: Helper methods to determine the type for a {@link ConstraintValidator} class.
+ * Alternative: could also do this by using <pre>
+ * <groupId>com.googlecode.jtype</groupId>
+ * <artifactId>jtype</artifactId>
+ * <version>0.1.1</version>
+ * </pre> but tried to reduce dependencies, so here is some code, that
+ * handles java5 generic types to find suitable implementations for
+ * ConstraintValidators.
+ * <br/>
+ * User: roman <br/>
+ * Date: 17.11.2009 <br/>
+ * Time: 16:36:02 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class TypeUtils {
+ private static final Map<Class<?>, Set<Class<?>>> SUBTYPES_BY_PRIMITIVE;
+ private static final int VALIDATOR_TYPE_INDEX = 1;
+
+ static {
+ Map<Class<?>, Set<Class<?>>> subtypesByPrimitive =
+ new HashMap<Class<?>, Set<Class<?>>>();
+
+ putPrimitiveSubtypes(subtypesByPrimitive, Void.TYPE);
+ putPrimitiveSubtypes(subtypesByPrimitive, Boolean.TYPE);
+ putPrimitiveSubtypes(subtypesByPrimitive, Byte.TYPE);
+ putPrimitiveSubtypes(subtypesByPrimitive, Character.TYPE);
+ putPrimitiveSubtypes(subtypesByPrimitive, Short.TYPE, Byte.TYPE);
+ putPrimitiveSubtypes(subtypesByPrimitive, Integer.TYPE, Character.TYPE, Short.TYPE);
+ putPrimitiveSubtypes(subtypesByPrimitive, Long.TYPE, Integer.TYPE);
+ putPrimitiveSubtypes(subtypesByPrimitive, Float.TYPE, Long.TYPE);
+ putPrimitiveSubtypes(subtypesByPrimitive, Double.TYPE, Float.TYPE);
+
+ SUBTYPES_BY_PRIMITIVE = subtypesByPrimitive;
+ }
+
+ private static void putPrimitiveSubtypes(Map<Class<?>, Set<Class<?>>> subtypesByPrimitive,
+ Class<?> primitiveType,
+ Class<?>... directSubtypes) {
+ Set<Class<?>> subtypes = new HashSet<Class<?>>();
+
+ for (Class<?> directSubtype : directSubtypes) {
+ subtypes.add(directSubtype);
+ subtypes.addAll(subtypesByPrimitive.get(directSubtype));
+ }
+
+ subtypesByPrimitive.put(primitiveType, subtypes);
+ }
+
+ private static Type getArrayType(final Type componentType) {
+ if (componentType instanceof Class<?>) {
+ return getClassArrayType((Class<?>) componentType);
+ } else {
+ return getGenericArrayType(componentType);
+ }
+ }
+
+ private static Type getGenericArrayType(final Type componentType) {
+ return new GenericArrayType() {
+ public Type getGenericComponentType() {
+ return componentType;
+ }
+
+ public int hashCode() {
+ return componentType.hashCode();
+ }
+
+ public boolean equals(Object object) {
+ return object instanceof GenericArrayType && componentType
+ .equals(((GenericArrayType) object).getGenericComponentType());
+ }
+ };
+ }
+
+ private static Class<?> getClassArrayType(Class<?> componentType) {
+ return Array.newInstance(componentType, 0).getClass();
+ }
+
+ private static Type getComponentType(Type type) {
+ if (type instanceof Class<?>) {
+ Class<?> clazz = (Class<?>) type;
+ return clazz.isArray() ? clazz.getComponentType() : null;
+ } else if (type instanceof GenericArrayType) {
+ return ((GenericArrayType) type).getGenericComponentType();
+ } else {
+ return null;
+ }
+ }
+
+ public static Map<Type, Class<? extends ConstraintValidator<?, ?>>> getValidatorsTypes(
+ Class<? extends ConstraintValidator<?, ?>>[] validators) {
+ Map<Type, Class<? extends ConstraintValidator<?, ?>>> validatorsTypes =
+ new HashMap<Type, Class<? extends ConstraintValidator<?, ?>>>();
+ for (Class<? extends ConstraintValidator<?, ?>> validator : validators) {
+ validatorsTypes.put(getValidatorType(validator), validator);
+ }
+ return validatorsTypes;
+ }
+
+ // ((ParameterizedType)validator.getGenericInterfaces()[0]).getActualTypeArguments()[1]
+ private static Type getValidatorType(
+ Class<? extends ConstraintValidator<?, ?>> validator) {
+ Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
+ Type constraintValidatorType = resolveTypes(resolvedTypes, validator);
+ Type validatorType = ((ParameterizedType) constraintValidatorType)
+ .getActualTypeArguments()[VALIDATOR_TYPE_INDEX];
+ if (validatorType == null) {
+ throw new ValidationException("null is an invalid type for a ConstraintValidator");
+ } else if (validatorType instanceof GenericArrayType) {
+ validatorType = getArrayType(getComponentType(validatorType));
+ }
+ while (resolvedTypes.containsKey(validatorType)) {
+ validatorType = resolvedTypes.get(validatorType);
+ }
+ return validatorType;
+ }
+
+ private static Type resolveTypes(Map<Type, Type> resolvedTypes, Type type) {
+ if (type == null) {
+ return null;
+ } else if (type instanceof Class) {
+ Class clazz = (Class) type;
+ final Type returnedType = resolveTypeForHierarchy(resolvedTypes, clazz);
+ if (returnedType != null) {
+ return returnedType;
+ }
+ } else if (type instanceof ParameterizedType) {
+ ParameterizedType paramType = (ParameterizedType) type;
+ if (!(paramType.getRawType() instanceof Class)) {
+ return null;
+ }
+ Class<?> rawType = (Class<?>) paramType.getRawType();
+
+ TypeVariable<?>[] originalTypes = rawType.getTypeParameters();
+ Type[] partiallyResolvedTypes = paramType.getActualTypeArguments();
+ int nbrOfParams = originalTypes.length;
+ for (int i = 0; i < nbrOfParams; i++) {
+ resolvedTypes.put(originalTypes[i], partiallyResolvedTypes[i]);
+ }
+
+ if (rawType.equals(ConstraintValidator.class)) {
+ return type; // we found what we were looking for
+ } else {
+ Type returnedType = resolveTypeForHierarchy(resolvedTypes, rawType);
+ if (returnedType != null) {
+ return returnedType;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static Type resolveTypeForHierarchy(Map<Type, Type> resolvedTypes,
+ Class<?> clazz) {
+ Type returnedType = resolveTypes(resolvedTypes, clazz.getGenericSuperclass());
+ if (returnedType != null) {
+ return returnedType;
+ }
+ for (Type genericInterface : clazz.getGenericInterfaces()) {
+ returnedType = resolveTypes(resolvedTypes, genericInterface);
+ if (returnedType != null) {
+ return returnedType;
+ }
+ }
+ return null;
+ }
+
+ public static boolean isAssignable(Type supertype, Type type) {
+ if (supertype.equals(type)) {
+ return true;
+ }
+
+ if (supertype instanceof Class<?>) {
+ if (type instanceof Class<?>) {
+ return isClassAssignable((Class<?>) supertype, (Class<?>) type);
+ }
+
+ if (type instanceof ParameterizedType) {
+ return isAssignable(supertype, ((ParameterizedType) type).getRawType());
+ }
+
+ if (type instanceof TypeVariable<?>) {
+ return isTypeVariableAssignable(supertype, (TypeVariable<?>) type);
+ }
+
+ if (type instanceof GenericArrayType) {
+ if (((Class<?>) supertype).isArray()) {
+ return isAssignable(getComponentType(supertype), getComponentType(type));
+ }
+
+ return isArraySupertype((Class<?>) supertype);
+ }
+
+ return false;
+ }
+
+ if (supertype instanceof ParameterizedType) {
+ if (type instanceof Class<?>) {
+ return isSuperAssignable(supertype, type);
+ }
+
+ return type instanceof ParameterizedType && isParameterizedTypeAssignable(
+ (ParameterizedType) supertype, (ParameterizedType) type);
+
+ }
+
+ if (type instanceof TypeVariable<?>) {
+ return isTypeVariableAssignable(supertype, (TypeVariable<?>) type);
+ }
+
+ if (supertype instanceof GenericArrayType) {
+ return isArray(type) &&
+ isAssignable(getComponentType(supertype), getComponentType(type));
+
+ }
+
+ return supertype instanceof WildcardType &&
+ isWildcardTypeAssignable((WildcardType) supertype, type);
+
+ }
+
+ private static boolean isClassAssignable(Class<?> supertype, Class<?> type) {
+ if (supertype.isPrimitive() && type.isPrimitive()) {
+ return SUBTYPES_BY_PRIMITIVE.get(supertype).contains(type);
+ }
+
+ return supertype.isAssignableFrom(type);
+ }
+
+ private static boolean isParameterizedTypeAssignable(ParameterizedType supertype,
+ ParameterizedType type) {
+ Type rawSupertype = supertype.getRawType();
+ Type rawType = type.getRawType();
+
+
+ if (!rawSupertype.equals(rawType)) {
+ return !(rawSupertype instanceof Class<?> && rawType instanceof Class<?> &&
+ !(((Class<?>) rawSupertype).isAssignableFrom((Class<?>) rawType))) &&
+ isSuperAssignable(supertype, type);
+ }
+
+ Type[] supertypeArgs = supertype.getActualTypeArguments();
+ Type[] typeArgs = type.getActualTypeArguments();
+
+ if (supertypeArgs.length != typeArgs.length) {
+ return false;
+ }
+
+ for (int i = 0; i < supertypeArgs.length; i++) {
+ Type supertypeArg = supertypeArgs[i];
+ Type typeArg = typeArgs[i];
+
+ if (supertypeArg instanceof WildcardType) {
+ if (!isWildcardTypeAssignable((WildcardType) supertypeArg, typeArg)) {
+ return false;
+ }
+ } else if (!supertypeArg.equals(typeArg)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean isTypeVariableAssignable(Type supertype, TypeVariable<?> type) {
+ for (Type bound : type.getBounds()) {
+ if (isAssignable(supertype, bound)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean isWildcardTypeAssignable(WildcardType supertype, Type type) {
+ for (Type upperBound : supertype.getUpperBounds()) {
+ if (!isAssignable(upperBound, type)) {
+ return false;
+ }
+ }
+
+ for (Type lowerBound : supertype.getLowerBounds()) {
+ if (!isAssignable(type, lowerBound)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean isSuperAssignable(Type supertype, Type type) {
+ Type superclass = getResolvedSuperclass(type);
+
+ if (superclass != null && isAssignable(supertype, superclass)) {
+ return true;
+ }
+
+ for (Type interphace : getResolvedInterfaces(type)) {
+ if (isAssignable(supertype, interphace)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean isArraySupertype(Class<?> type) {
+ return Object.class.equals(type) || Cloneable.class.equals(type) ||
+ Serializable.class.equals(type);
+ }
+
+ private static Type getResolvedSuperclass(Type type) {
+ Class<?> rawType = getErasedReferenceType(type);
+ Type supertype = rawType.getGenericSuperclass();
+
+ if (supertype == null) {
+ return null;
+ }
+
+ return resolveTypeVariables(supertype, type);
+ }
+
+ private static Class<?> getErasedReferenceType(Type type) {
+ return (Class<?>) getErasedType(type);
+ }
+
+
+ private static Type getErasedType(Type type) {
+ if (type instanceof ParameterizedType) {
+ Type rawType = ((ParameterizedType) type).getRawType();
+
+ return getErasedType(rawType);
+ }
+
+ if (isArray(type)) {
+ Type componentType = getComponentType(type);
+ Type erasedComponentType = getErasedType(componentType);
+
+ return getArrayType(erasedComponentType);
+ }
+
+ if (type instanceof TypeVariable<?>) {
+ Type[] bounds = ((TypeVariable<?>) type).getBounds();
+
+ return getErasedType(bounds[0]);
+ }
+
+ return type;
+ }
+
+ private static boolean isArray(Type type) {
+ return (type instanceof Class<?> && ((Class<?>) type).isArray()) ||
+ (type instanceof GenericArrayType);
+ }
+
+ private static Type[] getResolvedInterfaces(Type type) {
+
+ Class<?> rawType = getErasedReferenceType(type);
+ Type[] interfaces = rawType.getGenericInterfaces();
+ Type[] resolvedInterfaces = new Type[interfaces.length];
+
+ for (int i = 0; i < interfaces.length; i++) {
+ resolvedInterfaces[i] = resolveTypeVariables(interfaces[i], type);
+ }
+
+ return resolvedInterfaces;
+ }
+
+ private static Type resolveTypeVariables(Type type, Type subtype) {
+ if (!(type instanceof ParameterizedType)) {
+ return type;
+ }
+
+ Map<Type, Type> actualTypeArgumentsByParameter =
+ getActualTypeArgumentsByParameter(type, subtype);
+ Class<?> rawType = getErasedReferenceType(type);
+
+ return parameterizeClass(rawType, actualTypeArgumentsByParameter);
+ }
+
+ private static Map<Type, Type> getActualTypeArgumentsByParameter(Type... types) {
+ Map<Type, Type> actualTypeArgumentsByParameter = new LinkedHashMap<Type, Type>();
+
+ for (Type type : types) {
+ actualTypeArgumentsByParameter
+ .putAll(getActualTypeArgumentsByParameterInternal(type));
+ }
+
+ return normalize(actualTypeArgumentsByParameter);
+ }
+
+ private static <K> Map<K, K> normalize(Map<K, K> map) {
+ for (Map.Entry<K, K> entry : map.entrySet()) {
+ K key = entry.getKey();
+ K value = entry.getValue();
+
+ while (map.containsKey(value)) {
+ value = map.get(value);
+ }
+ map.put(key, value);
+ }
+ return map;
+ }
+
+ private static Map<Type, Type> getActualTypeArgumentsByParameterInternal(Type type) {
+ if (!(type instanceof ParameterizedType)) {
+ return Collections.emptyMap();
+ }
+
+ TypeVariable<?>[] typeParameters = getErasedReferenceType(type).getTypeParameters();
+ Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments();
+
+ if (typeParameters.length != typeArguments.length) {
+ throw new MalformedParameterizedTypeException();
+ }
+
+ Map<Type, Type> actualTypeArgumentsByParameter = new LinkedHashMap<Type, Type>();
+
+ for (int i = 0; i < typeParameters.length; i++) {
+ actualTypeArgumentsByParameter.put(typeParameters[i], typeArguments[i]);
+ }
+
+ return actualTypeArgumentsByParameter;
+ }
+
+ private static ParameterizedType parameterizeClass(Class<?> type,
+ Map<Type, Type> actualTypeArgumentsByParameter) {
+ return parameterizeClassCapture(type, actualTypeArgumentsByParameter);
+ }
+
+ private static <T> ParameterizedType parameterizeClassCapture(Class<T> type,
+ Map<Type, Type> actualTypeArgumentsByParameter) {
+ TypeVariable<Class<T>>[] typeParameters = type.getTypeParameters();
+ Type[] actualTypeArguments = new Type[typeParameters.length];
+
+ for (int i = 0; i < typeParameters.length; i++) {
+ TypeVariable<Class<T>> typeParameter = typeParameters[i];
+ Type actualTypeArgument = actualTypeArgumentsByParameter.get(typeParameter);
+
+ if (actualTypeArgument == null) {
+ throw new IllegalArgumentException(
+ "Missing actual type argument for type parameter: " + typeParameter);
+ }
+
+ actualTypeArguments[i] = actualTypeArgument;
+ }
+
+ return parameterizedType(getErasedReferenceType(type), actualTypeArguments);
+ }
+
+ private static ParameterizedType parameterizedType(final Class<?> rawType,
+ final Type... actualTypeArguments) {
+ return new ParameterizedType() {
+ public Type getOwnerType() {
+ return null;
+ }
+
+ public Type getRawType() {
+ return rawType;
+ }
+
+ public Type[] getActualTypeArguments() {
+ return actualTypeArguments.clone();
+ }
+ };
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/TypeUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/TypeUtils.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/TypeUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationIgnores.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationIgnores.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationIgnores.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationIgnores.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.bval.jsr303.xml;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Description: This class instantiated during the parsing of the XML configuration
+ * data and keeps track of the annotations which should be ignored.<br/>
+ * User: roman <br/>
+ * Date: 26.11.2009 <br/>
+ * Time: 13:09:21 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public final class AnnotationIgnores {
+
+ private static final Log log = LogFactory.getLog(AnnotationIgnores.class);
+
+ /**
+ * Keeps track whether the 'ignore-annotations' flag is set on bean level in the
+ * xml configuration.
+ * If 'ignore-annotations' is not specified: default = true
+ */
+ private final Map<Class<?>, Boolean> ignoreAnnotationDefaults =
+ new HashMap<Class<?>, Boolean>();
+
+ /**
+ * Keeps track of explicitly excluded members (fields and properties) for a given class.
+ * If a member appears in
+ * the list mapped to a given class 'ignore-annotations' was explicitly set to
+ * <code>true</code> in the configuration
+ * for this class.
+ */
+ private final Map<Class<?>, List<Member>> ignoreAnnotationOnMember =
+ new HashMap<Class<?>, List<Member>>();
+
+ private final Map<Class<?>, Boolean> ignoreAnnotationOnClass =
+ new HashMap<Class<?>, Boolean>();
+
+ public void setDefaultIgnoreAnnotation(Class<?> clazz, Boolean b) {
+ if (b == null) {
+ ignoreAnnotationDefaults.put(clazz, Boolean.TRUE);
+ } else {
+ ignoreAnnotationDefaults.put(clazz, b);
+ }
+ }
+
+ public boolean getDefaultIgnoreAnnotation(Class<?> clazz) {
+ return ignoreAnnotationDefaults.containsKey(clazz) &&
+ ignoreAnnotationDefaults.get(clazz);
+ }
+
+ public void setIgnoreAnnotationsOnMember(Member member) {
+ Class<?> beanClass = member.getDeclaringClass();
+ if (ignoreAnnotationOnMember.get(beanClass) == null) {
+ List<Member> tmpList = new ArrayList<Member>();
+ tmpList.add(member);
+ ignoreAnnotationOnMember.put(beanClass, tmpList);
+ } else {
+ ignoreAnnotationOnMember.get(beanClass).add(member);
+ }
+ }
+
+ public boolean isIgnoreAnnotations(Member member) {
+ boolean ignoreAnnotation;
+ Class<?> clazz = member.getDeclaringClass();
+ List<Member> ignoreAnnotationForMembers = ignoreAnnotationOnMember.get(clazz);
+ if (ignoreAnnotationForMembers == null ||
+ !ignoreAnnotationForMembers.contains(member)) {
+ ignoreAnnotation = getDefaultIgnoreAnnotation(clazz);
+ } else {
+ ignoreAnnotation = ignoreAnnotationForMembers.contains(member);
+ }
+ if (ignoreAnnotation) {
+ logMessage(member, clazz);
+ }
+ return ignoreAnnotation;
+ }
+
+ private void logMessage(Member member, Class<?> clazz) {
+ String type;
+ if (member instanceof Field) {
+ type = "Field";
+ } else {
+ type = "Property";
+ }
+ log.debug(type + " level annotations are getting ignored for " + clazz.getName() +
+ "." + member.getName());
+ }
+
+ public void setIgnoreAnnotationsOnClass(Class<?> clazz, boolean b) {
+ ignoreAnnotationOnClass.put(clazz, b);
+ }
+
+ public boolean isIgnoreAnnotations(Class<?> clazz) {
+ boolean ignoreAnnotation;
+ if (ignoreAnnotationOnClass.containsKey(clazz)) {
+ ignoreAnnotation = ignoreAnnotationOnClass.get(clazz);
+ } else {
+ ignoreAnnotation = getDefaultIgnoreAnnotation(clazz);
+ }
+ if (log.isDebugEnabled() && ignoreAnnotation) {
+ log.debug("Class level annotation are getting ignored for " + clazz.getName());
+ }
+ return ignoreAnnotation;
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationIgnores.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationIgnores.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationIgnores.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxy.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxy.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxy.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxy.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.bval.jsr303.xml;
+
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.bval.jsr303.util.SecureActions;
+
+
+/**
+ * Description: <br/>
+ * InvocationHandler implementation of <code>Annotation</code> that pretends it is a
+ * "real" source code annotation.
+ * <p/>
+ * <p/>
+ * User: roman <br/>
+ * Date: 27.11.2009 <br/>
+ * Time: 14:31:26 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class AnnotationProxy implements Annotation, InvocationHandler {
+
+ private final Class<? extends Annotation> annotationType;
+ private final Map<String, Object> values;
+
+ public AnnotationProxy(AnnotationProxyBuilder descriptor) {
+ this.annotationType = descriptor.getType();
+ values = getAnnotationValues(descriptor);
+ }
+
+ private Map<String, Object> getAnnotationValues(AnnotationProxyBuilder descriptor) {
+ Map<String, Object> result = new HashMap();
+ int processedValuesFromDescriptor = 0;
+ final Method[] declaredMethods = SecureActions.getDeclaredMethods(annotationType);
+ for (Method m : declaredMethods) {
+ if (descriptor.contains(m.getName())) {
+ result.put(m.getName(), descriptor.getValue(m.getName()));
+ processedValuesFromDescriptor++;
+ } else if (m.getDefaultValue() != null) {
+ result.put(m.getName(), m.getDefaultValue());
+ } else {
+ throw new IllegalArgumentException("No value provided for " + m.getName());
+ }
+ }
+ if (processedValuesFromDescriptor != descriptor.size()) {
+ throw new RuntimeException(
+ "Trying to instanciate " + annotationType + " with unknown paramters.");
+ }
+ return result;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (values.containsKey(method.getName())) {
+ return values.get(method.getName());
+ }
+ return method.invoke(this, args);
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return annotationType;
+ }
+
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append('@').append(annotationType().getName()).append('(');
+ boolean comma = false;
+ for (String m : getMethodsSorted()) {
+ if (comma) result.append(", ");
+ result.append(m).append('=').append(values.get(m));
+ comma = true;
+ }
+ result.append(")");
+ return result.toString();
+ }
+
+ private SortedSet<String> getMethodsSorted() {
+ SortedSet<String> result = new TreeSet();
+ result.addAll(values.keySet());
+ return result;
+ }
+}
+
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxy.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxy.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxyBuilder.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxyBuilder.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxyBuilder.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxyBuilder.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,105 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.bval.jsr303.xml;
+
+
+import javax.validation.Payload;
+import javax.validation.ValidationException;
+
+import org.apache.bval.jsr303.util.SecureActions;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Description: Holds the information and creates an annotation proxy
+ * during xml parsing of validation mapping constraints. <br/>
+ * User: roman <br/>
+ * Date: 27.11.2009 <br/>
+ * Time: 14:13:12 <br/>
+ * Copyright: Agimatec GmbH
+ */
+final class AnnotationProxyBuilder<A extends Annotation> {
+ private static final String ANNOTATION_PAYLOAD = "payload";
+ private static final String ANNOTATION_GROUPS = "groups";
+ private static final String ANNOTATION_MESSAGE = "message";
+
+ private final Class<A> type;
+
+ private final Map<String, Object> elements = new HashMap<String, Object>();
+
+ public AnnotationProxyBuilder(Class<A> annotationType) {
+ this.type = annotationType;
+ }
+
+ public AnnotationProxyBuilder(Class<A> annotationType, Map<String, Object> elements) {
+ this.type = annotationType;
+ for (Map.Entry<String, Object> entry : elements.entrySet()) {
+ this.elements.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ public void putValue(String elementName, Object value) {
+ elements.put(elementName, value);
+ }
+
+ public Object getValue(String elementName) {
+ return elements.get(elementName);
+ }
+
+ public boolean contains(String elementName) {
+ return elements.containsKey(elementName);
+ }
+
+ public int size() {
+ return elements.size();
+ }
+
+ public Class<A> getType() {
+ return type;
+ }
+
+ public void setMessage(String message) {
+ putValue(ANNOTATION_MESSAGE, message);
+ }
+
+ public void setGroups(Class<?>[] groups) {
+ putValue(ANNOTATION_GROUPS, groups);
+ }
+
+ public void setPayload(Class<? extends Payload>[] payload) {
+ putValue(ANNOTATION_PAYLOAD, payload);
+ }
+
+ public A createAnnotation() {
+ ClassLoader classLoader = SecureActions.getClassLoader(getClass());
+ Class<A> proxyClass = (Class<A>) Proxy.getProxyClass(classLoader, getType());
+ InvocationHandler handler = new AnnotationProxy(this);
+ try {
+ return SecureActions.getConstructor(proxyClass, InvocationHandler.class)
+ .newInstance(handler);
+ } catch (ValidationException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ValidationException(
+ "Unable to create annotation for configured constraint", e);
+ }
+ }
+}
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxyBuilder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxyBuilder.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/AnnotationProxyBuilder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/MetaConstraint.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/MetaConstraint.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/MetaConstraint.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/xml/MetaConstraint.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.bval.jsr303.xml;
+
+
+import javax.validation.ValidationException;
+
+import org.apache.bval.util.AccessStrategy;
+import org.apache.bval.util.FieldAccess;
+import org.apache.bval.util.MethodAccess;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+/**
+ * Description: hold parsed information from xml to complete MetaBean later<br/>
+ * User: roman <br/>
+ * Date: 27.11.2009 <br/>
+ * Time: 13:53:40 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class MetaConstraint<T, A extends Annotation> {
+
+ /** The member the constraint was defined on. */
+ private final Member member;
+
+ /** The class of the bean hosting this constraint. */
+ private final Class<T> beanClass;
+
+ /** constraint annotation (proxy) */
+ private final A annotation;
+
+ private final AccessStrategy accessStrategy;
+
+ /**
+ * @param beanClass The class in which the constraint is defined on
+ * @param member The member on which the constraint is defined on, {@code null} if it is a class constraint}
+ */
+ public MetaConstraint(Class<T> beanClass, Member member, A annotation) {
+ this.member = member;
+ this.beanClass = beanClass;
+ this.annotation = annotation;
+ if (member != null) {
+ accessStrategy = createAccessStrategy(member);
+ if (accessStrategy == null || accessStrategy.getPropertyName() ==
+ null) { // can happen if method does not follow the bean convention
+ throw new ValidationException(
+ "Annotated method does not follow the JavaBeans naming convention: " +
+ member);
+ }
+ } else {
+ this.accessStrategy = null;
+ }
+ }
+
+ private static AccessStrategy createAccessStrategy(Member member) {
+ if (member instanceof Method) {
+ return new MethodAccess((Method) member);
+ } else if (member instanceof Field) {
+ return new FieldAccess((Field) member);
+ } else {
+ return null; // class level
+ }
+ }
+
+ public Class<T> getBeanClass() {
+ return beanClass;
+ }
+
+ public Member getMember() {
+ return member;
+ }
+
+ public A getAnnotation() {
+ return annotation;
+ }
+
+ public AccessStrategy getAccessStrategy() {
+ return accessStrategy;
+ }
+}