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>
+ *  &lt;groupId&gt;com.googlecode.jtype&lt;/groupId&gt;
+ *  &lt;artifactId&gt;jtype&lt;/artifactId&gt;
+ *  &lt;version&gt;0.1.1&lt;/version&gt;
+ * </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;
+    }
+}