incubator-bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From simonetrip...@apache.org
Subject svn commit: r928387 [7/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/ bv...
Date Sun, 28 Mar 2010 12:28:32 GMT
Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AgimatecValidatorFactory.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AgimatecValidatorFactory.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AgimatecValidatorFactory.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AgimatecValidatorFactory.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,236 @@
+/*
+ * 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;
+
+
+import org.apache.bval.jsr303.util.SecureActions;
+import org.apache.bval.jsr303.xml.AnnotationIgnores;
+import org.apache.bval.jsr303.xml.MetaConstraint;
+import org.apache.bval.jsr303.xml.ValidationMappingParser;
+import org.apache.bval.util.AccessStrategy;
+import org.apache.commons.lang.ClassUtils;
+
+import javax.validation.*;
+import javax.validation.bootstrap.ProviderSpecificBootstrap;
+import javax.validation.spi.ConfigurationState;
+import java.lang.annotation.Annotation;
+import java.util.*;
+
+/**
+ * Description: a factory is a complete configurated object that can create validators<br/>
+ * this instance is not thread-safe<br/>
+ * User: roman.stumm <br/>
+ * Date: 29.10.2008 <br/>
+ * Time: 17:06:20 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class AgimatecValidatorFactory implements ValidatorFactory, Cloneable {
+    private static AgimatecValidatorFactory DEFAULT_FACTORY;
+    private static final ConstraintDefaults defaultConstraints = new ConstraintDefaults();
+
+    private MessageInterpolator messageResolver;
+    private TraversableResolver traversableResolver;
+    private ConstraintValidatorFactory constraintValidatorFactory;
+    private final Map<String, String> properties;
+
+    /** information from xml parsing */
+    private final AnnotationIgnores annotationIgnores = new AnnotationIgnores();
+    private final ConstraintCached constraintsCache = new ConstraintCached();
+    private final Map<Class<?>, Class<?>[]> defaultSequences;
+    /**
+     * access strategies for properties with cascade validation @Valid support
+     */
+    private final Map<Class<?>, List<AccessStrategy>> validAccesses;
+    private final Map<Class<?>, List<MetaConstraint<?, ? extends Annotation>>> constraintMap;
+
+    /** convenience to retrieve a default global AgimatecValidatorFactory */
+    public static AgimatecValidatorFactory getDefault() {
+        if (DEFAULT_FACTORY == null) {
+            ProviderSpecificBootstrap<AgimatecValidatorConfiguration> provider =
+                  Validation.byProvider(AgimatecValidationProvider.class);
+            AgimatecValidatorConfiguration configuration = provider.configure();
+            DEFAULT_FACTORY = (AgimatecValidatorFactory) configuration
+                  .buildValidatorFactory();
+        }
+        return DEFAULT_FACTORY;
+    }
+
+    public AgimatecValidatorFactory() {
+        properties = new HashMap<String, String>();
+        defaultSequences = new HashMap();
+        validAccesses = new HashMap();
+        constraintMap = new HashMap();
+    }
+
+    public void configure(ConfigurationState configuration) {
+        getProperties().putAll(configuration.getProperties());
+        setMessageInterpolator(configuration.getMessageInterpolator());
+        setTraversableResolver(configuration.getTraversableResolver());
+        setConstraintValidatorFactory(configuration.getConstraintValidatorFactory());
+        ValidationMappingParser parser = new ValidationMappingParser(this);
+        parser.processMappingConfig(configuration.getMappingStreams());
+    }
+
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    protected MessageInterpolator getDefaultMessageInterpolator() {
+        return messageResolver;
+    }
+
+    /**
+     * shortcut method to create a new Validator instance with factory's settings
+     *
+     * @return the new validator instance
+     */
+    public Validator getValidator() {
+        return usingContext().getValidator();
+    }
+
+    /** @return the validator factory's context */
+    public AgimatecFactoryContext usingContext() {
+        return new AgimatecFactoryContext(this);
+    }
+
+    @SuppressWarnings({"CloneDoesntDeclareCloneNotSupportedException"})
+    @Override
+    public synchronized AgimatecValidatorFactory clone() {
+        try {
+            return (AgimatecValidatorFactory) super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new InternalError(); // VM bug.
+        }
+    }
+
+    public final void setMessageInterpolator(MessageInterpolator messageResolver) {
+        this.messageResolver = messageResolver;
+    }
+
+    public MessageInterpolator getMessageInterpolator() {
+        return ((messageResolver != null) ? messageResolver : getDefaultMessageInterpolator());
+    }
+
+    public final void setTraversableResolver(TraversableResolver traversableResolver) {
+        this.traversableResolver = traversableResolver;
+    }
+
+    public TraversableResolver getTraversableResolver() {
+        return traversableResolver;
+    }
+
+    public ConstraintValidatorFactory getConstraintValidatorFactory() {
+        return constraintValidatorFactory;
+    }
+
+    public final void setConstraintValidatorFactory(
+          ConstraintValidatorFactory constraintValidatorFactory) {
+        this.constraintValidatorFactory = constraintValidatorFactory;
+    }
+
+    /**
+     * Return an object of the specified type to allow access to the
+     * provider-specific API.  If the Bean Validation provider
+     * implementation does not support the specified class, the
+     * ValidationException is thrown.
+     *
+     * @param type the class of the object to be returned.
+     * @return an instance of the specified class
+     * @throws ValidationException if the provider does not
+     *                             support the call.
+     */
+    public <T> T unwrap(Class<T> type) {
+        if (type.isAssignableFrom(getClass())) {
+            return (T) this;
+        } else if (!type.isInterface()) {
+            return SecureActions.newInstance(type);
+        } else {
+            try {
+                Class<T> cls = ClassUtils.getClass(type.getName() + "Impl");
+                return SecureActions.newInstance(cls);
+            } catch (ClassNotFoundException e) {
+                throw new ValidationException("Type " + type + " not supported");
+            }
+        }
+    }
+
+    public ConstraintDefaults getDefaultConstraints() {
+        return defaultConstraints;
+    }
+
+    public AnnotationIgnores getAnnotationIgnores() {
+        return annotationIgnores;
+    }
+
+    public ConstraintCached getConstraintsCache() {
+        return constraintsCache;
+    }
+
+    public void addMetaConstraint(Class<?> beanClass, MetaConstraint<?, ?> metaConstraint) {
+        List<MetaConstraint<?,? extends Annotation>> slot = constraintMap.get(beanClass);
+        if (slot != null) {
+            slot.add(metaConstraint);
+        } else {
+            List<MetaConstraint<?, ? extends Annotation>> constraintList =
+                  new ArrayList<MetaConstraint<?, ? extends Annotation>>();
+            constraintList.add(metaConstraint);
+            constraintMap.put(beanClass, constraintList);
+        }
+    }
+
+    public void addValid(Class<?> beanClass, AccessStrategy accessStategy) {
+        List<AccessStrategy> slot = validAccesses.get(beanClass);
+        if (slot != null) {
+            slot.add(accessStategy);
+        } else {
+            List<AccessStrategy> tmpList = new ArrayList();
+            tmpList.add(accessStategy);
+            validAccesses.put(beanClass, tmpList);
+        }
+    }
+
+    public void addDefaultSequence(Class<?> beanClass, Class<?>[] groupSequence) {
+        defaultSequences.put(beanClass, groupSequence);
+    }
+
+    public <T> List<MetaConstraint<T, ? extends Annotation>> getMetaConstraints(
+          Class<T> beanClass) {
+        List<MetaConstraint<?,? extends Annotation>> slot = constraintMap.get(beanClass);
+        if (slot != null) {
+            //noinspection RedundantCast
+            return (List)slot;
+        } else {
+            return Collections.EMPTY_LIST;
+        }
+    }
+
+    public List<AccessStrategy> getValidAccesses(Class<?> beanClass) {
+        List<AccessStrategy> slot = validAccesses.get(beanClass);
+        if (slot != null) {
+            return slot;
+        } else {
+            return Collections.EMPTY_LIST;
+        }
+    }
+
+    public Class<?>[] getDefaultSequence(Class<?> beanClass) {
+        return defaultSequences.get(beanClass);
+    }
+
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AgimatecValidatorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AgimatecValidatorFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AgimatecValidatorFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,256 @@
+/*
+ * 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;
+
+
+import org.apache.bval.jsr303.groups.GroupsComputer;
+import org.apache.bval.jsr303.util.SecureActions;
+import org.apache.bval.util.AccessStrategy;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.validation.*;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.PrivilegedAction;
+import java.util.*;
+
+/**
+ * Description: helper class that builds a {@link ConstraintValidation} or its
+ * composite constraint validations by parsing the jsr303-annotations
+ * and providing information (e.g. for @OverridesAttributes) <br/>
+ * User: roman <br/>
+ * Date: 28.10.2009 <br/>
+ * Time: 13:53:13 <br/>
+ * Copyright: Agimatec GmbH
+ */
+final class AnnotationConstraintBuilder {
+    private static final Log log = LogFactory.getLog(AnnotationConstraintBuilder.class);
+    private static final String ANNOTATION_PAYLOAD = "payload";
+    private static final String ANNOTATION_GROUPS = "groups";
+
+    private final ConstraintValidation<?> constraintValidation;
+    private List<ConstraintOverrides> overrides;
+
+    public AnnotationConstraintBuilder(
+          Class<? extends ConstraintValidator<?, ?>>[] validatorClasses,
+          ConstraintValidator constraintValidator, Annotation annotation, Class owner,
+          AccessStrategy access) {
+        boolean reportFromComposite = annotation != null && annotation.annotationType()
+              .isAnnotationPresent(ReportAsSingleViolation.class);
+        constraintValidation = new ConstraintValidation(validatorClasses,
+              constraintValidator, annotation, owner, access, reportFromComposite);
+        buildFromAnnotation();
+    }
+
+    /** build attributes, payload, groups from 'annotation' */
+    private void buildFromAnnotation() {
+        if (constraintValidation.getAnnotation() != null) {
+            SecureActions.run(new PrivilegedAction<Object>() {
+                public Object run() {
+                    for (Method method : constraintValidation.getAnnotation()
+                          .annotationType()
+                          .getDeclaredMethods()) {
+                        // enhancement: clarify: should groups + payload also appear in attributes?
+                        if (method.getParameterTypes().length == 0) {
+                            try {
+                                if (ANNOTATION_PAYLOAD.equals(method.getName())) {
+                                    buildPayload(method);
+                                } else if (ANNOTATION_GROUPS.equals(method.getName())) {
+                                    buildGroups(method);
+                                } else {
+                                    constraintValidation.getAttributes()
+                                          .put(method.getName(), method.invoke(
+                                                constraintValidation.getAnnotation()));
+                                }
+                            } catch (Exception e) { // do nothing
+                                log.warn("error processing annotation: " +
+                                      constraintValidation.getAnnotation(), e);
+                            }
+                        }
+                    }
+                    return null;
+                }
+            });
+        }
+        try {
+            /*
+           spec: Invalid constraint definitions causes are multiple but include missing or illegal message
+           or groups elements
+            */
+            if (constraintValidation.getGroups() == null) {
+                throw new ConstraintDefinitionException(
+                      constraintValidation.getAnnotation().annotationType()
+                            .getName() + " does not contain a groups parameter.");
+            }
+            if (constraintValidation.getMessageTemplate() == null) {
+                throw new ConstraintDefinitionException(
+                      constraintValidation.getAnnotation().annotationType()
+                            .getName() + " does not contain a message parameter.");
+            }
+            if (constraintValidation.getPayload() == null) {
+                throw new ConstraintDefinitionException(
+                      constraintValidation.getAnnotation().annotationType()
+                            .getName() + " does not contain a payload parameter.");
+            }
+        } catch (ConstraintDefinitionException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new IllegalArgumentException(e); // execution never reaches this point
+        }
+    }
+
+    private void buildGroups(Method method)
+          throws IllegalAccessException, InvocationTargetException {
+        Object raw = method.invoke(constraintValidation.getAnnotation());
+        Class<?>[] garr;
+        if (raw instanceof Class) {
+            garr = new Class<?>[]{(Class) raw};
+        } else if (raw instanceof Class<?>[]) {
+            garr = (Class<?>[]) raw;
+        } else {
+            garr = null;
+        }
+        garr = (garr == null || garr.length == 0) ? GroupsComputer.DEFAULT_GROUP_ARRAY :
+              garr;
+        constraintValidation.setGroups(new HashSet(Arrays.asList(garr)));
+    }
+
+    private void buildPayload(Method method)
+          throws IllegalAccessException, InvocationTargetException {
+        Class<Payload>[] payload_raw =
+              (Class<Payload>[]) method.invoke(constraintValidation.getAnnotation());
+        if (payload_raw == null) {
+            constraintValidation
+                  .setPayload(Collections.<Class<? extends Payload>>emptySet());
+        } else {
+            Set pl = new HashSet(payload_raw.length);
+            pl.addAll(Arrays.asList(payload_raw));
+            constraintValidation.setPayload(pl);
+        }
+    }
+
+    public ConstraintValidation getConstraintValidation() {
+        return constraintValidation;
+    }
+
+    /**
+     * initialize a child composite 'validation' with @OverridesAttribute
+     * from 'constraintValidation' and add to composites.
+     */
+    public void addComposed(ConstraintValidation composite) {
+        applyOverridesAttributes(composite);
+        constraintValidation.addComposed(composite); // add AFTER apply()
+    }
+
+    private void applyOverridesAttributes(ConstraintValidation composite) {
+        if (null == overrides) buildOverridesAttributes();
+        if (!overrides.isEmpty()) {
+            int index = computeIndex(composite); // assume composite not yet added! (+1)
+            if (index < 0) {
+                ConstraintOverrides override = // search for constraintIndex = -1
+                      findOverride(composite.getAnnotation().annotationType(), -1);
+                if (override != null) override.applyOn(composite);
+                else override = // search for constraintIndex == 0
+                      findOverride(composite.getAnnotation().annotationType(), 0);
+                if (override != null) override.applyOn(composite);
+            } else { // search for constraintIndex > 0
+                ConstraintOverrides override =
+                      findOverride(composite.getAnnotation().annotationType(), index + 1);
+                if (override != null) override.applyOn(composite);
+            }
+        }
+    }
+
+    private int computeIndex(ConstraintValidation composite) {
+        int idx = -1;
+        for (ConstraintValidation<?> each : constraintValidation.getComposingValidations()) {
+            if (each.getAnnotation().annotationType() ==
+                  composite.getAnnotation().annotationType()) {
+                idx++;
+            }
+        }
+        return idx;
+    }
+
+    /** read overridesAttributes from constraintValidation.annotation */
+    private void buildOverridesAttributes() {
+        overrides = new LinkedList();
+        for (Method method : constraintValidation.getAnnotation()
+              .annotationType()
+              .getDeclaredMethods()) {
+            OverridesAttribute.List annoOAL =
+                  method.getAnnotation(OverridesAttribute.List.class);
+            if (annoOAL != null) {
+                for (OverridesAttribute annoOA : annoOAL.value()) {
+                    parseConstraintOverride(method.getName(), annoOA);
+                }
+            }
+            OverridesAttribute annoOA = method.getAnnotation(OverridesAttribute.class);
+            if (annoOA != null) {
+                parseConstraintOverride(method.getName(), annoOA);
+            }
+        }
+    }
+
+    private void parseConstraintOverride(String methodName, OverridesAttribute oa) {
+        ConstraintOverrides target = findOverride(oa.constraint(), oa.constraintIndex());
+        if (target == null) {
+            target = new ConstraintOverrides(oa.constraint(), oa.constraintIndex());
+            overrides.add(target);
+        }
+        target.values
+              .put(oa.name(), constraintValidation.getAttributes().get(methodName));
+    }
+
+    private ConstraintOverrides findOverride(Class<? extends Annotation> constraint,
+                                             int constraintIndex) {
+        for (ConstraintOverrides each : overrides) {
+            if (each.constraintType == constraint &&
+                  each.constraintIndex == constraintIndex) {
+                return each;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Holds the values to override in a composed constraint
+     * during creation of a composed ConstraintValidation
+     */
+    private static final class ConstraintOverrides {
+        final Class<? extends Annotation> constraintType;
+        final int constraintIndex;
+
+        /** key = attributeName, value = overridden value */
+        final Map<String, Object> values;
+
+        private ConstraintOverrides(Class<? extends Annotation> constraintType,
+                                    int constraintIndex) {
+            this.constraintType = constraintType;
+            this.constraintIndex = constraintIndex;
+            values = new HashMap();
+        }
+
+        public void applyOn(ConstraintValidation composite) {
+            composite.getAttributes().putAll(values);
+        }
+    }
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidation.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidation.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidation.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidation.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,28 @@
+/**
+ *  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;
+
+/**
+ * Description: <br/>
+ * User: roman <br/>
+ * Date: 01.02.2010 <br/>
+ * Time: 12:27:22 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public interface AppendValidation {
+     void append(ConstraintValidation validation);
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidation.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidation.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToBuilder.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToBuilder.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToBuilder.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToBuilder.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,36 @@
+/**
+ *  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;
+
+/**
+ * Description: <br/>
+ * User: roman <br/>
+ * Date: 01.02.2010 <br/>
+ * Time: 12:28:56 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class AppendValidationToBuilder implements AppendValidation {
+    private final AnnotationConstraintBuilder builder;
+
+    public AppendValidationToBuilder(AnnotationConstraintBuilder builder) {
+        this.builder = builder;
+    }
+
+    public void append(ConstraintValidation validation) {
+        builder.addComposed(validation);
+    }
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToMeta.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToMeta.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToMeta.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToMeta.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,38 @@
+/**
+ *  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;
+
+import org.apache.bval.model.FeaturesCapable;
+
+/**
+ * Description: <br/>
+ * User: roman <br/>
+ * Date: 01.02.2010 <br/>
+ * Time: 12:29:52 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class AppendValidationToMeta implements AppendValidation {
+    private final FeaturesCapable feature;
+
+    public AppendValidationToMeta(FeaturesCapable meta) {
+        this.feature = meta;
+    }
+
+    public void append(ConstraintValidation validation) {
+        feature.addValidation(validation);
+    }
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToMeta.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToMeta.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/AppendValidationToMeta.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,127 @@
+/*
+ * 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;
+
+
+import javax.validation.metadata.BeanDescriptor;
+import javax.validation.metadata.PropertyDescriptor;
+
+import org.apache.bval.model.Features;
+import org.apache.bval.model.MetaBean;
+import org.apache.bval.model.MetaProperty;
+import org.apache.bval.model.Validation;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Description: <br/>
+ * User: roman <br/>
+ * Date: 25.02.2009 <br/>
+ * Time: 16:54:16 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class BeanDescriptorImpl extends ElementDescriptorImpl implements BeanDescriptor {
+    protected final AgimatecFactoryContext factoryContext;
+
+    protected BeanDescriptorImpl(AgimatecFactoryContext factoryContext, MetaBean metaBean,
+                                 Validation[] validations) {
+        super(metaBean, validations);
+        this.factoryContext = factoryContext;
+    }
+
+    /**
+     * Returns true if the bean involves validation:
+     * - a constraint is hosted on the bean itself
+     * - a constraint is hosted on one of the bean properties
+     * - or a bean property is marked for cascade (@Valid)
+     *
+     * @return true if the bean nvolves validation
+     */
+    public boolean isBeanConstrained() {
+        if (hasAnyConstraints()) return true;
+        for (MetaProperty mprop : metaBean.getProperties()) {
+            if (mprop.getMetaBean() != null ||
+                  mprop.getFeature(Features.Property.REF_CASCADE) != null) return true;
+        }
+        return false;
+    }
+
+    private boolean hasAnyConstraints() {
+        if (hasConstraints()) return true;
+        if (metaBean.getValidations().length > 0) return true;
+        for (MetaProperty mprop : metaBean.getProperties()) {
+            if (mprop.getValidations().length > 0) return true;
+        }
+        return false;
+    }
+
+    /**
+     * Return the property level constraints for a given propertyName
+     * or null if either the property does not exist or has no constraint
+     * The returned object (and associated objects including ConstraintDescriptors)
+     * are immutable.
+     *
+     * @param propertyName property evaludated
+     */
+    public PropertyDescriptor getConstraintsForProperty(String propertyName) {
+        MetaProperty prop = metaBean.getProperty(propertyName);
+        if (prop == null) return null;
+        return getPropertyDescriptor(prop);
+    }
+
+    private PropertyDescriptor getPropertyDescriptor(MetaProperty prop) {
+        PropertyDescriptorImpl edesc =
+              prop.getFeature(Jsr303Features.Property.PropertyDescriptor);
+        if (edesc == null) {
+            Class<?> targetClass =
+                  prop.getFeature(Features.Property.REF_BEAN_TYPE, prop.getTypeClass());
+            if (targetClass.isPrimitive()) {
+                // optimization: do not create MetaBean for primitives
+                // enhancement: do not create MetaBean for classes without any metadata?
+                edesc = new PropertyDescriptorImpl(targetClass, prop.getValidations());
+            } else {
+                edesc = new PropertyDescriptorImpl(
+                      factoryContext.getMetaBeanFinder().findForClass(targetClass),
+                      prop.getValidations());
+            }
+            edesc.setCascaded((prop.getMetaBean() != null ||
+                  prop.getFeature(Features.Property.REF_CASCADE) != null));
+            edesc.setPropertyPath(prop.getName());
+            prop.putFeature(Jsr303Features.Property.PropertyDescriptor, edesc);
+        }
+        return edesc;
+    }
+
+    /** return the property descriptors having at least a constraint defined */
+    public Set<PropertyDescriptor> getConstrainedProperties() {
+        Set<PropertyDescriptor> validatedProperties = new HashSet();
+        for (MetaProperty prop : metaBean.getProperties()) {
+            if (prop.getValidations().length > 0 || (prop.getMetaBean() != null ||
+                  prop.getFeature(Features.Property.REF_CASCADE) != null)) {
+                validatedProperties.add(getPropertyDescriptor(prop));
+            }
+        }
+        return validatedProperties;
+    }
+
+    public String toString() {
+        return "BeanDescriptorImpl{" + "returnType=" + elementClass + '}';
+    }
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,339 @@
+/*
+ * 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;
+
+
+import org.apache.bval.BeanValidator;
+import org.apache.bval.jsr303.groups.Group;
+import org.apache.bval.jsr303.groups.Groups;
+import org.apache.bval.jsr303.groups.GroupsComputer;
+import org.apache.bval.jsr303.util.SecureActions;
+import org.apache.bval.model.MetaBean;
+import org.apache.bval.model.ValidationContext;
+import org.apache.commons.lang.ClassUtils;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import javax.validation.metadata.BeanDescriptor;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * API class -
+ * Description:
+ * instance is able to validate bean instances (and the associated object graphs).
+ * concurrent, multithreaded access implementation is safe.
+ * It is recommended to cache the instance.
+ * <br/>
+ * User: roman.stumm <br/>
+ * Date: 01.04.2008 <br/>
+ * Time: 13:36:33 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class ClassValidator extends BeanValidator implements Validator {
+    protected final AgimatecFactoryContext factoryContext;
+    protected final GroupsComputer groupsComputer = new GroupsComputer();
+
+    public ClassValidator(AgimatecFactoryContext factoryContext) {
+        super(factoryContext.getMetaBeanFinder());
+        this.factoryContext = factoryContext;
+    }
+
+    /** @deprecated provided for backward compatibility */
+    public ClassValidator(AgimatecValidatorFactory factory) {
+        this(factory.usingContext());
+    }
+
+    /**
+     * validate all constraints on object
+     *
+     * @throws javax.validation.ValidationException
+     *          if a non recoverable error happens during the validation process
+     */
+    public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groupArray) {
+        if (object == null) throw new IllegalArgumentException("cannot validate null");
+        try {
+            final GroupValidationContext<ConstraintValidationListener<T>> context =
+                  createContext(factoryContext.getMetaBeanFinder()
+                        .findForClass(object.getClass()), object, groupArray);
+            final ConstraintValidationListener result = context.getListener();
+            final Groups groups = context.getGroups();
+            // 1. process groups
+            for (Group current : groups.getGroups()) {
+                context.setCurrentGroup(current);
+                validateContext(context);
+            }
+            // 2. process sequences
+            for (List<Group> eachSeq : groups.getSequences()) {
+                for (Group current : eachSeq) {
+                    context.setCurrentGroup(current);
+                    validateContext(context);
+                    /**
+                     * if one of the group process in the sequence leads to one or more validation failure,
+                     * the groups following in the sequence must not be processed
+                     */
+                    if (!result.isEmpty()) break;
+                }
+//                if (!result.isEmpty()) break; // ?? TODO RSt - clarify!
+            }
+            return result.getConstaintViolations();
+        } catch (RuntimeException ex) {
+            throw unrecoverableValidationError(ex, object);
+        }
+    }
+
+    @Override
+    public void validateBeanNet(ValidationContext vcontext) {
+        GroupValidationContext context = (GroupValidationContext) vcontext;
+        List<Group> defaultGroups = expandDefaultGroup(context);
+        if (defaultGroups != null) {
+            Group currentGroup = context.getCurrentGroup();
+            for (Group each : defaultGroups) {
+                context.setCurrentGroup(each);
+                super.validateBeanNet(context);
+                // continue validation, even if errors already found: if (!result.isEmpty())
+            }
+            context.setCurrentGroup(currentGroup); // restore  (finally{} not required)
+        } else {
+            super.validateBeanNet(context);
+        }
+    }
+
+    /**
+     * in case of a default group return the list of groups
+     * for a redefined default GroupSequence
+     *
+     * @return null when no in default group or default group sequence not redefined
+     */
+    private List<Group> expandDefaultGroup(GroupValidationContext context) {
+        if (context.getCurrentGroup().isDefault()) {
+            // mention if metaBean redefines the default group
+            List<Group> groupSeq =
+                  context.getMetaBean().getFeature(Jsr303Features.Bean.GROUP_SEQUENCE);
+            if (groupSeq != null) {
+                context.getGroups().assertDefaultGroupSequenceIsExpandable(groupSeq);
+            }
+            return groupSeq;
+        } else {
+            return null;
+        }
+    }
+
+    protected ValidationException unrecoverableValidationError(RuntimeException ex,
+                                                               Object object) {
+        if (ex instanceof ValidationException) {
+            throw ex; // do not wrap specific ValidationExceptions (or instances from subclasses)
+        } else {
+            throw new ValidationException("error during validation of " + object, ex);
+        }
+    }
+
+    /**
+     * validate all constraints on <code>propertyName</code> property of object
+     *
+     * @param propertyName - the attribute name, or nested property name (e.g. prop[2].subpropA.subpropB)
+     * @throws javax.validation.ValidationException
+     *          if a non recoverable error happens
+     *          during the validation process
+     */
+    public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName,
+                                                            Class<?>... groups) {
+        if (object == null) throw new IllegalArgumentException("cannot validate null");
+        try {
+            MetaBean metaBean =
+                  factoryContext.getMetaBeanFinder().findForClass(object.getClass());
+            GroupValidationContext<ConstraintValidationListener<T>> context =
+                  createContext(metaBean, object, groups);
+            ConstraintValidationListener result = context.getListener();
+            NestedMetaProperty nestedProp = getNestedProperty(metaBean, object, propertyName);
+            context.setMetaProperty(nestedProp.getMetaProperty());
+            if (nestedProp.isNested()) {
+                context.setFixedValue(nestedProp.getValue());
+            } else {
+                context.setMetaProperty(nestedProp.getMetaProperty());
+            }
+            if (context.getMetaProperty() == null) throw new IllegalArgumentException(
+                  "Unknown property " + object.getClass().getName() + "." + propertyName);
+            Groups sequence = context.getGroups();
+            // 1. process groups
+            for (Group current : sequence.getGroups()) {
+                context.setCurrentGroup(current);
+                validatePropertyInGroup(context);
+            }
+            // 2. process sequences
+            for (List<Group> eachSeq : sequence.getSequences()) {
+                for (Group current : eachSeq) {
+                    context.setCurrentGroup(current);
+                    validatePropertyInGroup(context);
+                    /**
+                     * if one of the group process in the sequence leads to one or more validation failure,
+                     * the groups following in the sequence must not be processed
+                     */
+                    if (!result.isEmpty()) break;
+                }
+//                if (!result.isEmpty()) break; // ?? TODO RSt - clarify!
+            }
+            return result.getConstaintViolations();
+        } catch (RuntimeException ex) {
+            throw unrecoverableValidationError(ex, object);
+        }
+    }
+
+    private void validatePropertyInGroup(GroupValidationContext context) {
+        Group currentGroup = context.getCurrentGroup();
+        List<Group> defaultGroups = expandDefaultGroup(context);
+        if (defaultGroups != null) {
+            for (Group each : defaultGroups) {
+                context.setCurrentGroup(each);
+                validateProperty(context);
+                // continue validation, even if errors already found: if (!result.isEmpty())
+            }
+            context.setCurrentGroup(currentGroup); // restore
+        } else {
+            validateProperty(context);
+        }
+    }
+
+    /**
+     * find the MetaProperty for the given propertyName,
+     * which could contain a path, following the path on a given object to resolve
+     * types at runtime from the instance
+     */
+    private NestedMetaProperty getNestedProperty(MetaBean metaBean, Object t,
+                                                 String propertyName) {
+        NestedMetaProperty nested = new NestedMetaProperty(propertyName, t);
+        nested.setMetaBean(metaBean);
+        nested.parse();
+        return nested;
+    }
+
+    /**
+     * validate all constraints on <code>propertyName</code> property
+     * if the property value is <code>value</code>
+     *
+     * @throws javax.validation.ValidationException
+     *          if a non recoverable error happens
+     *          during the validation process
+     */
+    public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType,
+                                                         String propertyName, Object value,
+                                                         Class<?>... groups) {
+        try {
+            MetaBean metaBean = factoryContext.getMetaBeanFinder().findForClass(beanType);
+            GroupValidationContext<ConstraintValidationListener<T>> context =
+                  createContext(metaBean, null, groups);
+            ConstraintValidationListener result = context.getListener();
+            context.setMetaProperty(
+                  getNestedProperty(metaBean, null, propertyName).getMetaProperty());
+            context.setFixedValue(value);
+            Groups sequence = context.getGroups();
+            // 1. process groups
+            for (Group current : sequence.getGroups()) {
+                context.setCurrentGroup(current);
+                validatePropertyInGroup(context);
+            }
+            // 2. process sequences
+            for (List<Group> eachSeq : sequence.getSequences()) {
+                for (Group current : eachSeq) {
+                    context.setCurrentGroup(current);
+                    validatePropertyInGroup(context);
+                    /**
+                     * if one of the group process in the sequence leads to one or more validation failure,
+                     * the groups following in the sequence must not be processed
+                     */
+                    if (!result.isEmpty()) break;
+                }
+//                if (!result.isEmpty()) break; // ?? TODO RSt - clarify!
+            }
+            return result.getConstaintViolations();
+        } catch (RuntimeException ex) {
+            throw unrecoverableValidationError(ex, value);
+        }
+    }
+
+    protected <T> GroupValidationContext<ConstraintValidationListener<T>> createContext(
+          MetaBean metaBean, T object, Class<?>[] groups) {
+        ConstraintValidationListener<T> listener = new ConstraintValidationListener<T>(object);
+        GroupValidationContextImpl<ConstraintValidationListener<T>> context =
+              new GroupValidationContextImpl(listener,
+                    this.factoryContext.getMessageInterpolator(),
+                    this.factoryContext.getTraversableResolver(), metaBean);
+        context.setBean(object, metaBean);
+        context.setGroups(groupsComputer.computeGroups(groups));
+        return context;
+    }
+
+    /**
+     * Return the descriptor object describing bean constraints
+     * The returned object (and associated objects including ConstraintDescriptors)
+     * are immutable.
+     *
+     * @throws ValidationException if a non recoverable error happens
+     *                             during the metadata discovery or if some
+     *                             constraints are invalid.
+     */
+    public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
+        try {
+            MetaBean metaBean = factoryContext.getMetaBeanFinder().findForClass(clazz);
+            BeanDescriptorImpl edesc =
+                  metaBean.getFeature(Jsr303Features.Bean.BEAN_DESCRIPTOR);
+            if (edesc == null) {
+                edesc = createBeanDescriptor(metaBean);
+                metaBean.putFeature(Jsr303Features.Bean.BEAN_DESCRIPTOR, edesc);
+            }
+            return edesc;
+        } catch (RuntimeException ex) {
+            throw new ValidationException("error retrieving constraints for " + clazz, ex);
+        }
+    }
+
+    protected BeanDescriptorImpl createBeanDescriptor(MetaBean metaBean) {
+        return new BeanDescriptorImpl(factoryContext, metaBean, metaBean.getValidations());
+    }
+
+    /**
+     * Return an object of the specified type to allow access to the
+     * provider-specific API.  If the Bean Validation provider
+     * implementation does not support the specified class, the
+     * ValidationException is thrown.
+     *
+     * @param type the class of the object to be returned.
+     * @return an instance of the specified class
+     * @throws ValidationException if the provider does not
+     *                             support the call.
+     */
+    public <T> T unwrap(Class<T> type) {
+        if (type.isAssignableFrom(getClass())) {
+            return (T) this;
+        } else if (!type.isInterface()) {
+            return SecureActions.newInstance(type, new Class[]{AgimatecFactoryContext.class},
+                  new Object[]{factoryContext});
+        } else {
+            try {
+                Class<T> cls = ClassUtils.getClass(type.getName() + "Impl");
+                return SecureActions.newInstance(cls,
+                      new Class[]{AgimatecFactoryContext.class}, new Object[]{factoryContext});
+            } catch (ClassNotFoundException e) {
+                throw new ValidationException("Type " + type + " not supported");
+            }
+        }
+    }
+
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConfigurationImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConfigurationImpl.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConfigurationImpl.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConfigurationImpl.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,259 @@
+/*
+ * 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;
+
+
+import org.apache.bval.jsr303.resolver.DefaultTraversableResolver;
+import org.apache.bval.jsr303.xml.ValidationParser;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.validation.*;
+import javax.validation.spi.BootstrapState;
+import javax.validation.spi.ConfigurationState;
+import javax.validation.spi.ValidationProvider;
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * Description: used to configure agimatec-validation for jsr303.
+ * Implementation of Configuration that also implements ConfigurationState,
+ * hence this can be passed to buildValidatorFactory(ConfigurationState).
+ * <br/>
+ * User: roman.stumm <br/>
+ * Date: 29.10.2008 <br/>
+ * Time: 14:47:44 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class ConfigurationImpl implements AgimatecValidatorConfiguration, ConfigurationState {
+    private static final Log log = LogFactory.getLog(ConfigurationImpl.class);
+    
+    protected final ValidationProvider provider;
+    protected final ValidationProviderResolver providerResolver;
+    protected Class<? extends ValidationProvider<?>> providerClass;
+    protected MessageInterpolator messageInterpolator;
+    protected ConstraintValidatorFactory constraintValidatorFactory;
+    private TraversableResolver traversableResolver;
+
+    // BEGIN DEFAULTS
+    /**
+     * false = dirty flag (to prevent from multiple parsing validation.xml)
+     */
+    private boolean prepared = false;
+    private final TraversableResolver defaultTraversableResolver =
+          new DefaultTraversableResolver();
+    protected final MessageInterpolator defaultMessageInterpolator =
+          new DefaultMessageInterpolator();
+    private final ConstraintValidatorFactory defaultConstraintValidatorFactory =
+          new DefaultConstraintValidatorFactory();
+    // END DEFAULTS
+
+    private Set<InputStream> mappingStreams = new HashSet<InputStream>();
+    private Map<String, String> properties = new HashMap<String, String>();
+    private boolean ignoreXmlConfiguration = false;
+
+    public ConfigurationImpl(BootstrapState aState, ValidationProvider aProvider) {
+        if (aProvider != null) {
+            this.provider = aProvider;
+            this.providerResolver = null;
+        } else if (aState != null) {
+            this.provider = null;
+            if (aState.getValidationProviderResolver() == null) {
+                providerResolver = aState.getDefaultValidationProviderResolver();
+            } else {
+                providerResolver = aState.getValidationProviderResolver();
+            }
+        } else {
+            throw new ValidationException("either provider or state are required");
+        }
+    }
+
+    public AgimatecValidatorConfiguration traversableResolver(TraversableResolver resolver) {
+        traversableResolver = resolver;
+        this.prepared = false;
+        return this;
+    }
+
+    /**
+     * Ignore data from the <i>META-INF/validation.xml</i> file if this
+     * method is called.
+     *
+     * @return this
+     */
+    public AgimatecValidatorConfiguration ignoreXmlConfiguration() {
+        ignoreXmlConfiguration = true;
+//        this.prepared = false;
+        return this;
+    }
+
+    public ConfigurationImpl messageInterpolator(MessageInterpolator resolver) {
+        this.messageInterpolator = resolver;
+        this.prepared = false;
+        return this;
+    }
+
+    public ConfigurationImpl constraintValidatorFactory(
+          ConstraintValidatorFactory constraintFactory) {
+        this.constraintValidatorFactory = constraintFactory;
+        this.prepared = false;
+        return this;
+    }
+
+    /**
+     * Add a stream describing constraint mapping in the Bean Validation
+     * XML format.
+     *
+     * @return this
+     */
+    public AgimatecValidatorConfiguration addMapping(InputStream stream) {
+        mappingStreams.add(stream);
+        return this;
+    }
+
+    /**
+     * Add a provider specific property. This property is equivalent to
+     * XML configuration properties.
+     * If we do not know how to handle the property, we silently ignore it.
+     *
+     * @return this
+     */
+    public AgimatecValidatorConfiguration addProperty(String name, String value) {
+        properties.put(name, value);
+        return this;
+    }
+
+    /**
+     * Return a map of non type-safe custom properties.
+     *
+     * @return null
+     */
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    /**
+     * Returns true if Configuration.ignoreXMLConfiguration() has been called.
+     * In this case, we ignore META-INF/validation.xml
+     *
+     * @return true
+     */
+    public boolean isIgnoreXmlConfiguration() {
+        return ignoreXmlConfiguration;
+    }
+
+    public Set<InputStream> getMappingStreams() {
+        return mappingStreams;
+    }
+
+    public MessageInterpolator getMessageInterpolator() {
+        return messageInterpolator;
+    }
+
+    public MessageInterpolator getDefaultMessageInterpolator() {
+        return defaultMessageInterpolator;
+    }
+
+    public TraversableResolver getDefaultTraversableResolver() {
+        return defaultTraversableResolver;
+    }
+
+    public ConstraintValidatorFactory getDefaultConstraintValidatorFactory() {
+        return defaultConstraintValidatorFactory;
+    }
+
+    /**
+     * main factory method to build a ValidatorFactory
+     *
+     * @throw ValidationException if the ValidatorFactory cannot be built
+     */
+    public ValidatorFactory buildValidatorFactory() {
+        prepare();
+        if (provider != null) {
+            return provider.buildValidatorFactory(this);
+        } else {
+            return findProvider().buildValidatorFactory(this);
+        }
+    }
+
+    private void prepare() {
+        if (prepared) return;
+        parseValidationXml();
+        applyDefaults();
+        prepared = true;
+    }
+
+    /** Check whether a validation.xml file exists and parses it with JAXB */
+    private void parseValidationXml() {
+        if (isIgnoreXmlConfiguration()) {
+            log.info("ignoreXmlConfiguration == true");
+        } else {
+            new ValidationParser(getProperties().get(Properties.VALIDATION_XML_PATH))
+                  .processValidationConfig(this);
+        }
+    }
+
+    private void applyDefaults() {
+        // make sure we use the defaults in case they haven't been provided yet
+        if (traversableResolver == null) {
+            traversableResolver = getDefaultTraversableResolver();
+        }
+        if (messageInterpolator == null) {
+            messageInterpolator = getDefaultMessageInterpolator();
+        }
+        if (constraintValidatorFactory == null) {
+            constraintValidatorFactory = getDefaultConstraintValidatorFactory();
+        }
+    }
+
+    /**
+     * @return the constraint validator factory of this configuration.
+     */
+    public ConstraintValidatorFactory getConstraintValidatorFactory() {
+        return constraintValidatorFactory;
+    }
+
+    public TraversableResolver getTraversableResolver() {
+        return traversableResolver;
+    }
+
+    public ValidationProvider getProvider() {
+        return provider;
+    }
+
+    private ValidationProvider findProvider() {
+        if (providerClass != null) {
+            for (ValidationProvider provider : providerResolver
+                  .getValidationProviders()) {
+                if (providerClass.isAssignableFrom(provider.getClass())) {
+                    return provider;
+                }
+            }
+            throw new ValidationException(
+                  "Unable to find suitable provider: " + providerClass);
+        } else {
+            List<ValidationProvider<?>> providers = providerResolver.getValidationProviders();
+            return providers.get(0);
+        }
+    }
+
+    public void setProviderClass(Class<? extends ValidationProvider<?>> providerClass) {
+        this.providerClass = providerClass;
+    }
+
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConfigurationImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConfigurationImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConfigurationImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintCached.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintCached.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintCached.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintCached.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import javax.validation.ConstraintValidator;
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Description: hold the relationship annotation->validatedBy[] ConstraintValidator classes
+ * that are already parsed in a cache.<br/>
+ * User: roman <br/>
+ * Date: 27.11.2009 <br/>
+ * Time: 11:48:26 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class ConstraintCached {
+    private final Map<Class<? extends Annotation>, Class<? extends ConstraintValidator<?, ?>>[]> classes =
+          new HashMap();
+
+    public <A extends Annotation> void putConstraintValidator(Class<A> annotationClass,
+                                                              Class<? extends ConstraintValidator<?, ?>>[] definitionClasses) {
+        classes.put(annotationClass, definitionClasses);
+    }
+
+    public boolean containsConstraintValidator(Class<? extends Annotation> annotationClass) {
+        return classes.containsKey(annotationClass);
+    }
+
+    public <A extends Annotation> Class<? extends ConstraintValidator<?, ?>>[] getConstraintValidators(
+          Class<A> annotationClass) {
+        return classes.get(annotationClass);
+    }
+
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintCached.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintCached.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintCached.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintDefaults.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintDefaults.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintDefaults.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintDefaults.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,107 @@
+/*
+ * 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;
+
+import org.apache.bval.jsr303.util.SecureActions;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.validation.ConstraintValidator;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.PrivilegedAction;
+import java.util.*;
+
+/**
+ * Description: hold default constraints that are build in the framework.
+ * The default constraints are configured in DefaultConstraints.properties.<br/>
+ * User: roman <br/>
+ * Date: 26.11.2009 <br/>
+ * Time: 15:12:23 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class ConstraintDefaults {
+    private static final Log log = LogFactory.getLog(ConstraintDefaults.class);
+    private static final String DEFAULT_CONSTAINTS =
+          "com/agimatec/validation/jsr303/DefaultConstraints.properties";
+    protected Map<String, Class[]> defaultConstraints;
+
+    public ConstraintDefaults() {
+        defaultConstraints = loadDefaultConstraints(DEFAULT_CONSTAINTS);
+    }
+
+    public Map<String, Class[]> getDefaultConstraints() {
+        return defaultConstraints;
+    }
+
+    public Class<? extends ConstraintValidator<?, ?>>[] getValidatorClasses(
+          Class<? extends java.lang.annotation.Annotation> annotationType) {
+        return getDefaultConstraints().get(annotationType.getName());
+    }
+    
+    private Map<String, Class[]> loadDefaultConstraints(String resource) {
+        Properties constraintProperties = new Properties();
+        final ClassLoader classloader = getClassLoader();
+        InputStream stream = classloader.getResourceAsStream(resource);
+        if (stream != null) {
+            try {
+                constraintProperties.load(stream);
+            } catch (IOException e) {
+                log.error("cannot load " + resource, e);
+            }
+        } else {
+            log.warn("cannot find " + resource);
+        }
+        Map<String, Class[]> loadedConstraints = new HashMap();
+        for (Map.Entry entry : constraintProperties.entrySet()) {
+
+            StringTokenizer tokens = new StringTokenizer((String) entry.getValue(), ", ");
+            LinkedList classes = new LinkedList();
+            while (tokens.hasMoreTokens()) {
+                final String eachClassName = tokens.nextToken();
+
+                Class constraintValidatorClass =
+                      SecureActions.run(new PrivilegedAction<Class>() {
+                          public Class run() {
+                              try {
+                                  return Class.forName(eachClassName, true, classloader);
+                              } catch (ClassNotFoundException e) {
+                                  log.error("Cannot find class " + eachClassName, e);
+                                  return null;
+                              }
+                          }
+                      });
+
+                if (constraintValidatorClass != null) classes.add(constraintValidatorClass);
+
+            }
+            loadedConstraints
+                  .put((String) entry.getKey(),
+                        (Class[]) classes.toArray(new Class[classes.size()]));
+
+        }
+        return loadedConstraints;
+    }
+
+    private ClassLoader getClassLoader() {
+        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
+        if (classloader == null) classloader = getClass().getClassLoader();
+        return classloader;
+    }
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintDefaults.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintDefaults.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintDefaults.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintFinderImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintFinderImpl.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintFinderImpl.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintFinderImpl.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,128 @@
+/*
+ * 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;
+
+
+import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.ElementDescriptor;
+import javax.validation.metadata.Scope;
+
+import org.apache.bval.jsr303.groups.Group;
+import org.apache.bval.jsr303.groups.Groups;
+import org.apache.bval.jsr303.groups.GroupsComputer;
+import org.apache.bval.model.MetaBean;
+
+import java.lang.annotation.ElementType;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Description: Implementation to find constraints.<br/>
+ * User: roman <br/>
+ * Date: 13.10.2009 <br/>
+ * Time: 10:44:46 <br/>
+ * Copyright: Agimatec GmbH
+ */
+final class ConstraintFinderImpl implements ElementDescriptor.ConstraintFinder {
+    private final MetaBean metaBean;
+    private final Set<Scope> findInScopes;
+    private Set<ConstraintValidation> constraintDescriptors;
+
+    ConstraintFinderImpl(MetaBean metaBean, Set constraintDescriptors) {
+        this.metaBean = metaBean;
+        this.constraintDescriptors = constraintDescriptors;
+        this.findInScopes = new HashSet<Scope>(Arrays.asList(Scope.values()));
+    }
+
+    public ElementDescriptor.ConstraintFinder unorderedAndMatchingGroups(Class<?>... groups) {
+        Set<ConstraintValidation> matchingDescriptors =
+              new HashSet<ConstraintValidation>(constraintDescriptors.size());
+        Groups groupChain = new GroupsComputer().computeGroups(groups);
+        for (Group group : groupChain.getGroups()) {
+            for (ConstraintValidation descriptor : constraintDescriptors) {
+                if (isInScope(descriptor) && isInGroup(descriptor, group)) {
+                    matchingDescriptors.add(descriptor);
+                }
+            }
+        }
+        return thisWith(matchingDescriptors);
+    }
+
+    public ElementDescriptor.ConstraintFinder lookingAt(Scope scope) {
+        if (scope.equals(Scope.LOCAL_ELEMENT)) {
+            findInScopes.remove(Scope.HIERARCHY);
+        }
+        return this;
+    }
+
+    public ElementDescriptor.ConstraintFinder declaredOn(ElementType... elementTypes) {
+        Set<ConstraintValidation> matchingDescriptors =
+              new HashSet<ConstraintValidation>(constraintDescriptors.size());
+        for (ElementType each : elementTypes) {
+            for (ConstraintValidation descriptor : constraintDescriptors) {
+                if (isInScope(descriptor) && isAtElement(descriptor, each)) {
+                    matchingDescriptors.add(descriptor);
+                }
+            }
+        }
+        return thisWith(matchingDescriptors);
+    }
+
+    private boolean isAtElement(ConstraintValidation descriptor, ElementType each) {
+        return descriptor.getAccess().getElementType() == each;
+    }
+
+    private boolean isInScope(ConstraintValidation descriptor) {
+        if (findInScopes.size() == Scope.values().length) return true; // all scopes
+        if (metaBean != null) {
+            Class owner = descriptor.getOwner();
+            for (Scope scope : findInScopes) {
+                switch (scope) {
+                    case LOCAL_ELEMENT:
+                        if (owner.equals(metaBean.getBeanClass())) return true;
+                        break;
+                    case HIERARCHY:
+                        if (!owner.equals(metaBean.getBeanClass())) return true;
+                        break;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean isInGroup(ConstraintValidation descriptor, Group group) {
+        return descriptor.getGroups().contains(group.getGroup());
+    }
+
+    private ElementDescriptor.ConstraintFinder thisWith(
+          Set<ConstraintValidation> matchingDescriptors) {
+        constraintDescriptors = matchingDescriptors;
+        return this;
+    }
+
+    public Set<ConstraintDescriptor<?>> getConstraintDescriptors() {
+        //noinspection RedundantCast
+        return (Set) constraintDescriptors;
+    }
+
+    public boolean hasConstraints() {
+        return !constraintDescriptors.isEmpty();
+    }
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintFinderImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintFinderImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintFinderImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintValidation.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintValidation.java?rev=928387&view=auto
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintValidation.java (added)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintValidation.java Sun Mar 28 12:28:25 2010
@@ -0,0 +1,259 @@
+/*
+ * 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;
+
+
+import javax.validation.ConstraintValidator;
+import javax.validation.Payload;
+import javax.validation.ValidationException;
+import javax.validation.metadata.ConstraintDescriptor;
+
+import org.apache.bval.BeanValidationContext;
+import org.apache.bval.ValidationResults;
+import org.apache.bval.jsr303.util.NodeImpl;
+import org.apache.bval.jsr303.util.PathImpl;
+import org.apache.bval.model.Validation;
+import org.apache.bval.model.ValidationContext;
+import org.apache.bval.util.AccessStrategy;
+
+import java.lang.annotation.Annotation;
+import java.util.*;
+
+/**
+ * Description: Adapter between Constraint (JSR303) and Validation (Agimatec)<br/>
+ * this instance is immutable!<br/>
+ * User: roman.stumm <br/>
+ * Date: 01.04.2008 <br/>
+ * Time: 17:31:36 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class ConstraintValidation<T extends Annotation>
+      implements Validation, ConstraintDescriptor<T> {
+    private static final String ANNOTATION_MESSAGE = "message";
+    private final ConstraintValidator validator;
+    private final T annotation; // for metadata request API
+    private final AccessStrategy access;
+    private final boolean reportFromComposite;
+    private final Map<String, Object> attributes;
+
+    private Set<ConstraintValidation<?>> composedConstraints;
+
+    /**
+     * the owner is the type where the validation comes from.
+     * it is used to support implicit grouping.
+     */
+    private final Class owner;
+    private Set<Class<?>> groups;
+    private Set<Class<? extends Payload>> payload;
+    private Class<? extends ConstraintValidator<T, ?>>[] validatorClasses;
+
+    /**
+     * @param validator  - the constraint validator
+     * @param annotation - the annotation of the constraint
+     * @param owner      - the type where the annotated element is placed
+     *                   (class, interface, annotation type)
+     * @param access     - how to access the value
+     */
+    public ConstraintValidation(
+          Class<? extends ConstraintValidator<T, ?>>[] validatorClasses,
+          ConstraintValidator validator, T annotation, Class owner,
+          AccessStrategy access, boolean reportFromComposite) {
+        this.attributes = new HashMap();
+        this.validatorClasses = validatorClasses;
+        this.validator = validator;
+        this.annotation = annotation;
+        this.owner = owner;
+        this.access = access;
+        this.reportFromComposite = reportFromComposite;
+    }
+
+    void setGroups(Set<Class<?>> groups) {
+        this.groups = groups;
+    }
+
+    void setPayload(Set<Class<? extends Payload>> payload) {
+        this.payload = payload;
+    }
+
+    public boolean isReportAsSingleViolation() {
+        return reportFromComposite;
+    }
+
+    public void addComposed(ConstraintValidation aConstraintValidation) {
+        if (composedConstraints == null) {
+            composedConstraints = new HashSet();
+        }
+        composedConstraints.add(aConstraintValidation);
+    }
+
+    public void validate(ValidationContext context) {
+        validate((GroupValidationContext) context);
+    }
+
+    public void validate(GroupValidationContext context) {
+        context.setConstraintDescriptor(this);
+        /**
+         * execute unless the given validation constraint has already been processed
+         * during this validation routine (as part of a previous group match)
+         */
+        if (!isMemberOf(context.getCurrentGroup().getGroup())) {
+            return; // do not validate in the current group
+        }
+        if (validator != null && !context.collectValidated(context.getBean(), validator))
+            return; // already done
+
+        if (context.getMetaProperty() != null && !isCascadeEnabled(context)) {
+            return;
+        }
+
+        // process composed constraints
+        if (isReportAsSingleViolation()) {
+            BeanValidationContext gctx = (BeanValidationContext) context;
+            ConstraintValidationListener oldListener =
+                  ((ConstraintValidationListener) gctx.getListener());
+            ConstraintValidationListener listener =
+                  new ConstraintValidationListener(oldListener.getRootBean());
+            gctx.setListener(listener);
+            try {
+                for (ConstraintValidation composed : getComposingValidations()) {
+                    composed.validate(context);
+                }
+            } finally {
+                gctx.setListener(oldListener);
+            }
+            // stop validating when already failed and ReportAsSingleInvalidConstraint = true ?
+            if (!listener.getConstaintViolations().isEmpty()) {
+                // TODO RSt - how should the composed constraint error report look like?
+                ConstraintValidatorContextImpl jsrContext =
+                      new ConstraintValidatorContextImpl(context, this);
+                addErrors(context, jsrContext); // add defaultErrorMessage only*/
+                return;
+            }
+        } else {
+            for (ConstraintValidation composed : getComposingValidations()) {
+                composed.validate(context);
+            }
+        }
+
+        if (validator != null) {
+            ConstraintValidatorContextImpl jsrContext =
+                  new ConstraintValidatorContextImpl(context, this);
+            if (!validator.isValid(context.getValidatedValue(), jsrContext)) {
+                addErrors(context, jsrContext);
+            }
+        }
+    }
+
+    private boolean isCascadeEnabled(GroupValidationContext context) {
+        PathImpl path = context.getPropertyPath();
+        NodeImpl node = path.getLeafNode();
+        PathImpl beanPath = path.getPathWithoutLeafNode();
+        if (beanPath == null) {
+            beanPath = PathImpl.create(null);
+        }
+        try {
+            if (!context.getTraversableResolver()
+                  .isReachable(context.getBean(), node,
+                        context.getRootMetaBean().getBeanClass(), beanPath,
+                        access.getElementType())) return false;
+        } catch (RuntimeException e) {
+            throw new ValidationException(
+                  "Error in TraversableResolver.isReachable() for " + context.getBean(), e);
+        }
+
+        try {
+            if (!context.getTraversableResolver()
+                  .isCascadable(context.getBean(), node,
+                        context.getRootMetaBean().getBeanClass(), beanPath,
+                        access.getElementType())) return false;
+        } catch (RuntimeException e) {
+            throw new ValidationException(
+                  "Error TraversableResolver.isCascadable() for " + context.getBean(), e);
+        }
+
+        return true;
+    }
+
+    private void addErrors(GroupValidationContext context,
+                           ConstraintValidatorContextImpl jsrContext) {
+        for (ValidationResults.Error each : jsrContext.getErrorMessages()) {
+            context.getListener().addError(each, context);
+        }
+    }
+
+    public String toString() {
+        return "ConstraintValidation{" + validator + '}';
+    }
+
+    public String getMessageTemplate() {
+        return (String) attributes.get(ANNOTATION_MESSAGE);
+    }
+
+    public ConstraintValidator getValidator() {
+        return validator;
+    }
+
+    protected boolean isMemberOf(Class<?> reqGroup) {
+        /**
+         * owner: implicit grouping support:
+         * owner is reqGroup or a superclass/superinterface of reqGroup
+         */
+        return owner.isAssignableFrom(reqGroup) || groups.contains(reqGroup);
+    }
+
+    public Class getOwner() {
+        return owner;
+    }
+
+    public T getAnnotation() {
+        return annotation;
+    }
+
+    public AccessStrategy getAccess() {
+        return access;
+    }
+
+    /////////////////////////// ConstraintDescriptor implementation
+
+
+    public Map<String, Object> getAttributes() {
+        return attributes;
+    }
+
+    public Set<ConstraintDescriptor<?>> getComposingConstraints() {
+        return composedConstraints == null ? Collections.EMPTY_SET : composedConstraints;
+    }
+
+    Set<ConstraintValidation<?>> getComposingValidations() {
+        return composedConstraints == null ? Collections.EMPTY_SET : composedConstraints;
+    }
+
+    public Set<Class<?>> getGroups() {
+        return groups;
+    }
+
+    public Set<Class<? extends Payload>> getPayload() {
+        return payload;
+    }
+
+    public List<Class<? extends ConstraintValidator<T, ?>>> getConstraintValidatorClasses() {
+        return Arrays.asList(validatorClasses);
+    }
+
+}

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintValidation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintValidation.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ConstraintValidation.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message