incubator-bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mat...@apache.org
Subject svn commit: r924153 [11/13] - in /incubator/bval/trunk: ./ agimatec-jsr303/ agimatec-jsr303/src/ agimatec-jsr303/src/main/ agimatec-jsr303/src/main/java/ agimatec-jsr303/src/main/java/com/ agimatec-jsr303/src/main/java/com/agimatec/ agimatec-jsr303/src...
Date Wed, 17 Mar 2010 04:39:14 GMT
Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanCache.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanCache.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanCache.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanCache.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,83 @@
+/**
+ *  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 com.agimatec.validation;
+
+import com.agimatec.validation.model.MetaBean;
+import org.apache.commons.collections.FastHashMap;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * Description: a cache to hold metabeans by id and by class.<br/>
+ * User: roman.stumm <br/>
+ * Date: 18.02.2008 <br/>
+ * Time: 11:38:53 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class MetaBeanCache implements MetaBeanFinder, Serializable {
+    protected final FastHashMap cacheById;
+    protected final FastHashMap cacheByClass;
+
+    public MetaBeanCache() {
+        this.cacheById = new FastHashMap();
+        cacheByClass = new FastHashMap();
+        cacheByClass.setFast(true);
+        cacheById.setFast(true);
+    }
+
+    public MetaBeanCache(Map<String, MetaBean> beans) {
+        this();
+        for (MetaBean bean : beans.values()) {
+            cache(bean);
+        }
+    }
+
+    public void clear() {
+        cacheById.clear();
+        cacheByClass.clear();
+    }
+
+    public MetaBean findForId(String beanInfoId) {
+        return (MetaBean) cacheById.get(beanInfoId);
+    }
+
+    public MetaBean findForClass(Class clazz) {
+        return (MetaBean) cacheByClass.get(clazz);
+    }
+
+    public Map<String, MetaBean> findAll() {
+        return cacheById;
+    }
+
+    public void cache(MetaBean beanInfo) {
+        cacheById.put(beanInfo.getId(), beanInfo);
+        if (beanInfo.getBeanClass() != null &&
+                beanInfo.getId().equals(beanInfo.getBeanClass().getName())) {
+            cacheByClass.put(beanInfo.getBeanClass(), beanInfo);
+        }
+    }
+
+    public void removeFromCache(MetaBean beanInfo) {
+        cacheById.remove(beanInfo.getId());
+        if (beanInfo.getBeanClass() != null &&
+                beanInfo.getId().equals(beanInfo.getBeanClass().getName())) {
+            cacheByClass.remove(beanInfo.getBeanClass());
+        }
+    }
+
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanEnricher.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanEnricher.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanEnricher.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanEnricher.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,42 @@
+/**
+ *  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 com.agimatec.validation;
+
+import com.agimatec.validation.model.MetaBean;
+import com.agimatec.validation.xml.XMLMetaBeanInfos;
+
+import java.util.Map;
+
+/**
+ * Description: Interface to merge meta beans<br/>
+ * User: roman.stumm <br/>
+ * Date: 14.02.2008 <br/>
+ * Time: 11:00:21 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public interface MetaBeanEnricher {
+
+    /**
+     * @param infos - the patches to apply
+     * @return all MetaBeans for classes that have a xml descriptor and
+     *         additional the MetaBeans loaded by the given loaders.
+     *         The given loaders may also return patches for MetaBeans that have
+     *         also been returned by other loaders. The beans with patches for
+     *         references to patched beans will be copied.
+     */
+    Map<String, MetaBean> enrichCopies(XMLMetaBeanInfos... infos);
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanFactory.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanFactory.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanFactory.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanFactory.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,31 @@
+/**
+ *  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 com.agimatec.validation;
+
+import com.agimatec.validation.model.MetaBean;
+
+/**
+ * Description: interface for abstraction how to initialize a MetaBean
+ * with information from somewhere<br/>
+ * User: roman <br/>
+ * Date: 07.10.2009 <br/>
+ * Time: 11:38:03 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public interface MetaBeanFactory {
+     void buildMetaBean(MetaBean metaBean) throws Exception;
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanFinder.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanFinder.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanFinder.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanFinder.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,49 @@
+/**
+ *  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 com.agimatec.validation;
+
+import com.agimatec.validation.model.MetaBean;
+
+import java.util.Map;
+
+/**
+ * Description: Interface to find BeanInfos <br/>
+ * User: roman.stumm <br/>
+ * Date: 05.07.2007 <br/>
+ * Time: 16:17:20 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public interface MetaBeanFinder {
+    /**
+     * @param beanInfoId - symbolic unique name of Meta Info
+     * @return BeanInfo
+     * @throws IllegalArgumentException - when MetaBean not found
+     */
+    MetaBean findForId(String beanInfoId);
+
+    /**
+     * @param clazz - bean class
+     * @return BeanInfo (never null)
+     */
+    MetaBean findForClass(Class clazz);
+
+    /**
+     * @return all MetaBeans for classes that have a xml descriptor:
+     *         key = bean.id, value = MetaBean
+     */
+    public Map<String, MetaBean> findAll();
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanManager.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanManager.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanManager.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanManager.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,190 @@
+/**
+ *  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 com.agimatec.validation;
+
+import static com.agimatec.validation.model.Features.Property.*;
+import com.agimatec.validation.model.MetaBean;
+import com.agimatec.validation.model.MetaProperty;
+import com.agimatec.validation.util.PrivilegedActions;
+import com.agimatec.validation.xml.XMLMetaBeanInfos;
+import com.agimatec.validation.xml.XMLMetaBeanLoader;
+import com.agimatec.validation.xml.XMLMetaBeanRegistry;
+import com.agimatec.validation.xml.XMLMetaBeanURLLoader;
+
+import java.util.Map;
+
+/**
+ * Description: Default implementation for the interface to find, register and
+ * create MetaBeans. In most situations a single instance of this class is
+ * sufficient and you can get this instance from the {@link MetaBeanManagerFactory}.
+ * <br/>
+ * User: roman.stumm <br/>
+ * Date: 05.07.2007 <br/>
+ * Time: 16:19:43 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class MetaBeanManager implements MetaBeanFinder, XMLMetaBeanRegistry, MetaBeanEnricher {
+
+    protected final MetaBeanCache cache = new MetaBeanCache();
+    protected final MetaBeanBuilder builder;
+    private boolean complete = false;
+
+    public MetaBeanManager() {
+        builder = new MetaBeanBuilder();
+    }
+
+    public MetaBeanManager(MetaBeanBuilder builder) {
+        this.builder = builder;
+    }
+
+    public void addResourceLoader(String resource) {
+        addLoader(new XMLMetaBeanURLLoader(
+              PrivilegedActions.getClassLoader(getClass()).getResource(resource)));
+    }
+
+    public synchronized void addLoader(XMLMetaBeanLoader loader) {
+        builder.addLoader(loader);
+        cache.clear(); // clear because new loaders can affect ALL MetaBeans already created!
+        complete = false;
+    }
+
+    public MetaBeanBuilder getBuilder() {
+        return builder;
+    }
+
+    public MetaBeanCache getCache() {
+        return cache;
+    }
+
+    /**
+     * @return all MetaBeans for classes that have a xml descriptor:
+     *         key = bean.id, value = MetaBean
+     */
+    public Map<String, MetaBean> findAll() {
+        if (!complete) {
+            try {
+                Map<String, MetaBean> allBuilt = builder.buildAll();
+                for (MetaBean meta : allBuilt.values()) {
+                    MetaBean cached = cache.findForId(meta.getId());
+                    if (cached == null) {
+                        cache.cache(meta);
+                    }
+                }
+                Map<String, MetaBean> map = cache.findAll();
+                for (Object oentry : map.values()) {
+                    MetaBean meta = (MetaBean) oentry;
+                    computeRelationships(meta, map);
+                }
+                complete = true;
+                return map;
+            } catch (RuntimeException e) {
+                throw e; // do not wrap runtime exceptions
+            } catch (Exception e) {
+                throw new IllegalArgumentException("error creating beanInfos", e);
+            }
+        } else {
+            return cache.findAll();
+        }
+    }
+
+    /**
+     * @param infos - the patches to apply
+     * @return all MetaBeans for classes that have a xml descriptor and
+     *         additional the MetaBeans loaded by the given loaders.
+     *         The given loaders may also return patches for MetaBeans that have
+     *         also been returned by other loaders. The beans with patches for
+     *         references to patched beans will be copied.
+     */
+    public Map<String, MetaBean> enrichCopies(XMLMetaBeanInfos... infos) {
+        Map<String, MetaBean> cached = findAll();
+        try {
+            Map<String, MetaBean> patched = builder.enrichCopies(cached, infos);
+            for (Object oentry : patched.values()) {
+                MetaBean meta = (MetaBean) oentry;
+                computeRelationships(meta, patched);
+            }
+            return patched;
+        } catch (RuntimeException e) {
+            throw e; // do not wrap runtime exceptions
+        } catch (Exception e) {
+            throw new IllegalArgumentException("error enriching beanInfos", e);
+        }
+    }
+
+    public MetaBean findForId(String beanInfoId) {
+        MetaBean beanInfo = cache.findForId(beanInfoId);
+        if (beanInfo != null) return beanInfo;
+        try {
+            beanInfo = builder.buildForId(beanInfoId);
+            cache.cache(beanInfo);
+            computeRelationships(beanInfo);
+            return beanInfo;
+        } catch (RuntimeException e) {
+            throw e; // do not wrap runtime exceptions
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                  "error creating beanInfo with id: " + beanInfoId, e);
+        }
+    }
+
+    public MetaBean findForClass(Class clazz) {
+        if (clazz == null) return null;
+        MetaBean beanInfo = cache.findForClass(clazz);
+        if (beanInfo != null) return beanInfo;
+        try {
+            beanInfo = builder.buildForClass(clazz);
+            cache.cache(beanInfo);
+            computeRelationships(beanInfo);
+            return beanInfo;
+        } catch (RuntimeException e) {
+            throw e; // do not wrap runtime exceptions
+        } catch (Exception e) {
+            throw new IllegalArgumentException("error creating beanInfo for " + clazz, e);
+        }
+    }
+
+    /**
+     * must be called AFTER cache.cache()
+     * to avoid endless loop
+     */
+    protected void computeRelationships(MetaBean beanInfo) {
+        for (MetaProperty prop : beanInfo.getProperties()) {
+            String beanRef = (String) prop.getFeature(REF_BEAN_ID);
+            if (beanRef != null) {
+                prop.setMetaBean(findForId(beanRef));
+            } else {
+                Class beanType = prop.getFeature(REF_BEAN_TYPE);
+                if (beanType != null) {
+                    prop.setMetaBean(findForClass(beanType));
+                } // dynamic type resolution:
+                else if (prop.getFeature(REF_CASCADE) != null) {
+                    prop.setMetaBean(new DynamicMetaBean(this));
+//                            findForClass(prop.getType()));
+                }
+            }
+        }
+    }
+
+    private void computeRelationships(MetaBean beanInfo, Map<String, MetaBean> cached) {
+        for (MetaProperty prop : beanInfo.getProperties()) {
+            String beanRef = (String) prop.getFeature(REF_BEAN_ID);
+            if (beanRef != null) {
+                prop.setMetaBean(cached.get(beanRef));
+            }
+        }
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanManagerFactory.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanManagerFactory.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanManagerFactory.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/MetaBeanManagerFactory.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,67 @@
+/**
+ *  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 com.agimatec.validation;
+
+import com.agimatec.validation.xml.XMLMetaBeanRegistry;
+
+/**
+ * Description: API class to hold a singleton of a {@link MetaBeanManager}
+ * that implements the finder and registry interfaces for MetaBeans<br/>
+ * User: roman.stumm <br/>
+ * Date: 05.07.2007 <br/>
+ * Time: 16:20:03 <br/>
+ * Copyright: Agimatec GmbH 2008
+ *
+ * @see com.agimatec.validation.model.MetaBean
+ * @see MetaBeanManager
+ */
+public class MetaBeanManagerFactory {
+    private static MetaBeanManager manager = new MetaBeanManager();
+
+    /**
+     * global meta bean finder.
+     * @return
+     */
+    public static MetaBeanFinder getFinder() {
+        return manager;
+    }
+
+    /**
+     * global meta bean registry
+     * @return
+     */
+    public static XMLMetaBeanRegistry getRegistry() {
+        return manager;
+    }
+
+    /**
+     * global meta bean enricher
+     * @return
+     */
+    public static MetaBeanEnricher getEnricher() {
+        return manager;
+    }
+
+    /**
+     * set global meta bean manager, that is responsible
+     * for finding, caching, xml registry and enrichment algorithm.
+     * @param finder
+     */
+    public static void setManager(MetaBeanManager finder) {
+        manager = finder;
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/Validate.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/Validate.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/Validate.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/Validate.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,42 @@
+/**
+ *  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 com.agimatec.validation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Description: Annotate an element (parameter) to be validated.
+ * <br>
+ *
+ * Wichtig:<br>
+ * Die Methode muss ebenfalls mit Validate annotiert werden, damit
+ * die Parameter-Annotations ueberhaupt untersucht und ein BeanValidationContext angelegt wird.
+ * <br/>
+ * User: roman.stumm <br/>
+ * Date: 09.07.2007 <br/>
+ * Time: 13:38:24 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+public @interface Validate {
+    /** (optional) the MetaBean.id to use */
+    String value() default "";
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/ValidationResults.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/ValidationResults.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/ValidationResults.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/ValidationResults.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,175 @@
+/**
+ *  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 com.agimatec.validation;
+
+import com.agimatec.validation.model.ValidationContext;
+import com.agimatec.validation.model.ValidationListener;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * Description: Implements a contains to hold and transport validation results<br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 12:26:55 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class ValidationResults implements ValidationListener, Serializable {
+    private Map<String, List<Error>> errorsByReason;
+    private Map<Object, Map<String, List<Error>>> errorsByOwner;
+
+
+    /**
+     * API to add an error to the validation results.
+     *
+     * @param reason       - Features from {@link com.agimatec.validation.routines.Reasons}
+     *                       or custom reason of validation error
+     * @param context        - context information (bean, propertyName, value, ...)
+     */
+    public void addError(String reason, ValidationContext context) {
+        Error error = createError(reason, context.getBean(), context.getPropertyName());
+        addError(error, context);
+    }
+
+
+     /**
+     * API to add an error to the validation results.
+     *
+     * @param error       - holding the description of reason and object to describe
+      *                     the validation error
+     * @param context     - null or the context to provide additional information
+     */
+    public void addError(Error error, ValidationContext context) {
+        if (errorsByReason == null) {
+            initialize();
+        }
+        addToReasonBucket(error);
+        addToOwnerBucket(error);
+    }
+
+    /**
+     * Old API to add an error to the validation results when no context is available.
+     *
+     * @param reason       - Features from {@link com.agimatec.validation.routines.Reasons} or custom validation reason
+     * @param bean         - (optional) owner bean or null
+     * @param propertyName - (optional) propertyName where valiation error occurred or null
+     */
+    public void addError(String reason, Object bean, String propertyName) {
+        addError(createError(reason, bean, propertyName), null);
+    }
+
+
+    protected Error createError(String reason, Object owner, String propertyName) {
+        return new Error(reason, owner, propertyName);
+    }
+
+    /**
+     * initialize the error-buckets now when needed and
+     * not on instance creation to save memory garbage.
+     */
+    protected void initialize() {
+        errorsByReason = new LinkedHashMap();
+        errorsByOwner = new LinkedHashMap();
+    }
+
+    protected void addToReasonBucket(Error error) {
+        if (error.getReason() == null) return;
+
+        List<Error> errors = errorsByReason.get(error.getReason());
+        if (errors == null) {
+            errors = new ArrayList<Error>();
+            errorsByReason.put(error.getReason(), errors);
+        }
+        errors.add(error);
+    }
+
+    protected void addToOwnerBucket(Error error) {
+        if (error.getOwner() == null) return;
+
+        Map<String, List<Error>> errors = errorsByOwner.get(error.getOwner());
+        if (errors == null) {
+            errors = new HashMap<String, List<Error>>();
+            errorsByOwner.put(error.getOwner(), errors);
+        }
+        List<Error> list = errors.get(error.getPropertyName());
+        if (list == null) {
+            list = new ArrayList<Error>();
+            errors.put(error.getPropertyName(), list);
+        }
+        list.add(error);
+    }
+
+    /** key = reason, value = list of errors for this reason */
+    public Map<String, List<Error>> getErrorsByReason() {
+        if (errorsByReason == null) return Collections.emptyMap();
+        return errorsByReason;
+    }
+
+    /**
+     * key = owner, value = map with:<br>
+     * &nbsp;&nbsp; key = propertyName, value = list of errors for this owner.propertyName
+     */
+    public Map<Object, Map<String, List<Error>>> getErrorsByOwner() {
+        if (errorsByOwner == null) return Collections.emptyMap();
+        return errorsByOwner;
+    }
+
+    /** @return true when there are NO errors in this validation result */
+    public boolean isEmpty() {
+        if (errorsByReason == null ||
+              (errorsByReason.isEmpty() && errorsByOwner.isEmpty())) return true;
+        for (List<Error> list : errorsByReason.values()) {
+            if (!list.isEmpty()) return false;
+        }
+        for (Map<String, List<Error>> map : errorsByOwner.values()) {
+            for (List<Error> list : map.values()) {
+                if (!list.isEmpty()) return false;
+            }
+        }
+        return true;
+    }
+
+    public boolean hasErrorForReason(String reason) {
+        if (errorsByReason == null) return false;
+        List<Error> errors = errorsByReason.get(reason);
+        return errors != null && !errors.isEmpty();
+    }
+
+    /**
+     * @param propertyName - may be null: any property is checked
+     *                     OR the name of the property to check
+     */
+    public boolean hasError(Object bean, String propertyName) {
+        if (errorsByOwner == null) return false;
+        Map<String, List<Error>> errors = errorsByOwner.get(bean);
+        if (errors == null) return false;
+        if (propertyName != null) {
+            List<Error> list = errors.get(propertyName);
+            return list != null && !list.isEmpty();
+        } else {
+            for (List<Error> list : errors.values()) {
+                if (!list.isEmpty()) return true;
+            }
+            return false;
+        }
+    }
+
+    public String toString() {
+        return "ValidationResults{" + errorsByOwner + "}";
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/integration/ThreadBeanValidator.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/integration/ThreadBeanValidator.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/integration/ThreadBeanValidator.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/integration/ThreadBeanValidator.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,50 @@
+/**
+ *  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 com.agimatec.validation.integration;
+
+import com.agimatec.validation.BeanValidator;
+import com.agimatec.validation.MetaBeanFinder;
+import com.agimatec.validation.model.ValidationContext;
+
+/**
+ * Description: Validatator that puts the current validation
+ * context into a {@link ThreadLocal} <br/>
+ * User: roman.stumm <br/>
+ * Date: 09.07.2007 <br/>
+ * Time: 13:49:11 <br/>
+ * Copyright: Agimatec GmbH 2008
+ *
+ * @see ThreadValidationContext
+ */
+public class ThreadBeanValidator extends BeanValidator {
+    public ThreadBeanValidator() {
+    }
+
+    public ThreadBeanValidator(MetaBeanFinder metaBeanFinder) {
+        super(metaBeanFinder);
+    }
+
+    @Override
+    protected ValidationContext createContext() {
+        ThreadValidationContext context = ThreadValidationContext.getCurrent();
+        if (context == null) {
+            context = new ThreadValidationContext(createResults());
+            ThreadValidationContext.setCurrent(context);
+        }
+        return context;
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/integration/ThreadValidationContext.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/integration/ThreadValidationContext.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/integration/ThreadValidationContext.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/integration/ThreadValidationContext.java Wed Mar 17 04:39:07 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 com.agimatec.validation.integration;
+
+import com.agimatec.validation.BeanValidationContext;
+import com.agimatec.validation.model.ValidationListener;
+
+/**
+ * Description: Used to bind the current validation context to the current thread.
+ * Use this class when you need to append validation errors in service layers
+ * without handing a ValidationContext and/or ValidationResults instance
+ * through your method signatures.<br/>
+ * User: roman.stumm <br/>
+ * Date: 09.07.2007 <br/>
+ * Time: 13:41:10 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class ThreadValidationContext extends BeanValidationContext {
+    protected static final ThreadLocal<ThreadValidationContext> current =
+            new ThreadLocal<ThreadValidationContext>();
+
+    public ThreadValidationContext(ValidationListener listener) {
+        super(listener);
+    }
+
+    public static ThreadValidationContext getCurrent() {
+        return current.get();
+    }
+
+    public static void setCurrent(ThreadValidationContext aValidationContext) {
+        if (aValidationContext == null) {
+            current.remove();
+        } else {
+            current.set(aValidationContext);
+        }
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/json/JSONGenerator.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/json/JSONGenerator.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/json/JSONGenerator.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/json/JSONGenerator.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,75 @@
+/**
+ *  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 com.agimatec.validation.json;
+
+import com.agimatec.validation.model.MetaBean;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.*;
+
+/**
+ * Description: Generate a JSON String for a collection of {@link MetaBean}s.
+ * This implementation uses a freemarker template to generate the output.<br/>
+ * User: roman.stumm <br/>
+ * Date: 09.07.2007 <br/>
+ * Time: 17:14:12 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class JSONGenerator {
+    private final Template template;
+
+    public JSONGenerator() throws IOException {
+        this("bean-infos-json.ftl");
+    }
+
+    public JSONGenerator(String templateName) throws IOException {
+        Configuration freemarker = new Configuration();
+        freemarker.setNumberFormat("0.######");  // prevent locale-sensitive number format
+        freemarker.setClassForTemplateLoading(getClass(), "");
+        template = freemarker.getTemplate(templateName);
+    }
+
+    public JSONGenerator(Template template) {
+        this.template = template;
+    }
+
+    public String toJSON(MetaBean metaBean) throws IOException, TemplateException {
+        List<MetaBean> metaBeans = new ArrayList(1);
+        metaBeans.add(metaBean);
+        return toJSON(metaBeans);
+    }
+
+    public String toJSON(Collection<MetaBean> metaBeans)
+            throws IOException, TemplateException {
+        final StringWriter out = new StringWriter();
+        toJSON(metaBeans, out);
+        return out.toString();
+    }
+
+    public void toJSON(Collection<MetaBean> metaBeans, Writer out)
+            throws IOException, TemplateException {
+        Map rootMap = new HashMap();
+        rootMap.put("metaBeans", metaBeans);
+        rootMap.put("generator", this);
+        template.process(rootMap, out);
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/DynaType.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/DynaType.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/DynaType.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/DynaType.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,31 @@
+/**
+ *  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 com.agimatec.validation.model;
+
+import java.lang.reflect.Type;
+
+/**
+ * Description: implementation of a dynamic type. can be used inside a
+ * MetaProperty for instance-based types <br/>
+ * User: roman <br/>
+ * Date: 12.02.2009 <br/>
+ * Time: 16:49:56 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public interface DynaType extends Type {
+    Type getRawType();
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/DynaTypeEnum.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/DynaTypeEnum.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/DynaTypeEnum.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/DynaTypeEnum.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,92 @@
+/**
+ *  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 com.agimatec.validation.model;
+
+/**
+ * Description: ("artificial" enum with custom values)<br/>
+ * User: roman <br/>
+ * Date: 12.02.2009 <br/>
+ * Time: 16:56:31 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public class DynaTypeEnum implements DynaType {
+    private final Class enumClass;
+    private Value[] enumConstants;
+
+    public DynaTypeEnum(Class enumClass) {
+        this.enumClass = enumClass;
+    }
+
+    public DynaTypeEnum(Class enumClass, String... names) {
+        this.enumClass = enumClass;
+        setEnumNames(names);
+    }
+
+    public void setEnumNames(String[] names) {
+        enumConstants = new Value[names.length];
+        int i=0;
+        for(String each : names) {
+            enumConstants[i++] = new Value(each);
+        }
+    }
+
+    public String getName() {
+        return enumClass.getName();
+    }
+
+    public Class getRawType() {
+        return enumClass;
+    }
+
+    /**
+     * used by freemarker-template "bean-infos-json.ftl"
+     */
+    public boolean isEnum() {
+        return enumClass.isEnum();
+    }
+
+    /**
+     * used by freemarker-template "bean-infos-json.ftl"
+     */
+    public Value[] getEnumConstants() {
+        return enumConstants;
+    }
+
+    public boolean isAssignableFrom(Class cls) {
+        return enumClass.isAssignableFrom(cls);
+    }
+
+    /**
+     * represent a single "enum" instance (= the value)
+     */
+    public static final class Value {
+        final String name;
+
+        Value(String name) {
+            this.name = name;
+        }
+
+        /**
+         * used by freemarker-template "bean-infos-json.ftl"
+         * @return
+         */
+        public String name() {
+            return name;
+        }
+
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/Features.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/Features.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/Features.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/Features.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,117 @@
+/**
+ *  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 com.agimatec.validation.model;
+
+/**
+ * Description: Contains key of common feature keys used by standard validators etc.
+ * This DOES NOT MEAN that the list of property- or bean-features is closed. You can
+ * put anything into the metabean as a feature and use it in your custom validators
+ * and other classes that access your metabeans.<br/>
+ * User: roman.stumm <br/>
+ * Date: 05.07.2007 <br/>
+ * Time: 17:03:47 <br/>
+ * Copyright: Agimatec GmbH 2008
+ *
+ * @see FeaturesCapable
+ */
+public interface Features {
+    /** Features of {@link MetaBean} */
+    public interface Bean {
+        /** INFO: String, name of the Property, that is the Primary Key */
+        String MAIN_KEY = "mainKey";
+        /** INFO: category/domain to which the metaBean belongs to */
+        String DOMAIN = "domain";
+
+        //        String DISPLAY_NAME = "displayName";
+        String UNIQUE_KEY = "uniqueKey";
+    }
+
+    /** Features of {@link MetaProperty} */
+    public interface Property {
+        /** INFO: possible Enum values */
+        String ENUM = "enum";
+        /** INFO: Boolean, TRUE if Property is a Unique Key */
+        String UNIQUE_KEY = "uniqueKey";
+        /** VALIDATION: Boolean, mandatory field? */
+        String MANDATORY = "mandatory";
+        /** VALIDATION: Integer, max. number of chars/digits / max. cardinality of a to-many relationship */
+        String MAX_LENGTH = "maxLen";
+        /** VALIDATION: Comparable (e.g. a subclass of Number), max value */
+        String MAX_VALUE = "maxValue";
+        /** VALIDATION: Integer, min. number of chars/digits / min. cardinality of a to-many relationship */
+        String MIN_LENGTH = "minLen";
+        /** VALIDATION: Comparable (e.g. a subclass of Number), min value */
+        String MIN_VALUE = "minValue";
+        /** INFO: String-representation of a default value */
+        String DEFAULT_VALUE = "defValue";
+        /** SECURITY, INFO: Boolean, is value or relationship unmodifiable */
+        String READONLY = "readonly";
+        /**
+         * SECURITY, INFO: Boolean, Feld accessible?
+         * If false, the field must not be displayed, queried, changed.
+         */
+        String DENIED = "denied";
+        /** VALIDATION: String, regular expression to validate the format of input data */
+        String REG_EXP = "regExp";
+        /**
+         * VALIDATION: String, Constraint for time-information of a Date-field:
+         * {@link com.agimatec.validation.xml.XMLMetaValue#TIMELAG_Past}
+         * or
+         * {@link com.agimatec.validation.xml.XMLMetaValue#TIMELAG_Future}
+         */
+        String TIME_LAG = "timeLag";
+
+        /**
+         * INFO: Boolean, Feld visible?
+         *
+         * @see java.beans.PropertyDescriptor#isHidden()
+         */
+        String HIDDEN = "hidden";
+        /**
+         * INFO: Boolean
+         *
+         * @see java.beans.PropertyDescriptor#isPreferred()
+         */
+        String PREFERRED = "preferred";
+
+        /** INFO: relationship's target metaBean.id * */
+        String REF_BEAN_ID = "refBeanId";
+
+        /**
+         * INFO: Class<br>
+         * Relationship's target metaBean.beanClass.
+         * In case of to-many relationships, this feature
+         * hold the Bean-type not the Collection-type.
+         */
+        String REF_BEAN_TYPE = "refBeanType";
+
+        /**
+         * INFO: AccessStrategy[]<br>
+         * an array of accessStrategies
+         * how validation should cascade into relationship target beans<br>
+         * null when validation should NOT cascade into relationship target
+         * beans<br>
+         * <p/>
+         * Default: {PropertyAccess(metaProperty.name)},
+         * when MetaProperty.metaBean is != null
+         */
+        String REF_CASCADE = "refCascade";
+
+        /** INFO: an array with the string names of custom java script validation functions */
+        String JAVASCRIPT_VALIDATION_FUNCTIONS = "jsFunctions";
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/FeaturesCapable.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/FeaturesCapable.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/FeaturesCapable.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/FeaturesCapable.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,106 @@
+/**
+ *  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 com.agimatec.validation.model;
+
+import org.apache.commons.collections.FastHashMap;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * Description: abstract superclass of meta objects that support a map of features.<br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 10:29:57 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public abstract class FeaturesCapable implements Serializable {
+    private FastHashMap features = new FastHashMap();
+    /** key = validation id, value = the validation */
+    private Validation[] validations = new Validation[0];
+
+    public FeaturesCapable() {
+        features.setFast(true);
+    }
+
+    public Map<String, Object> getFeatures() {
+        return features;
+    }
+
+    public void optimizeRead(boolean fast) {
+        features.setFast(fast);
+    }
+
+    public <T> T getFeature(String key) {
+        return (T) features.get(key);
+    }
+
+    public <T> T getFeature(String key, T defaultValue) {
+        final T v = (T) features.get(key);
+        if (v == null) {
+            return (features.containsKey(key)) ? null : defaultValue;
+        } else {
+            return v;
+        }
+    }
+
+    /** convenience method. */
+    public <T> void putFeature(String key, T value) {
+        features.put(key, value);
+    }
+
+    /** create a deep copy! (copy receiver and copy properties) */
+    public <T extends FeaturesCapable> T copy() {
+        try {
+            T self = (T) clone();
+            copyInto(self);
+            return self;
+        } catch (CloneNotSupportedException e) {
+            throw new IllegalStateException("cannot clone() " + this, e);
+        }
+    }
+
+    protected <T extends FeaturesCapable> void copyInto(T target) {
+        target.features = (FastHashMap) features.clone();
+        if (validations != null) {
+            target.validations = validations.clone();
+        }
+    }
+
+    public Validation[] getValidations() {
+        return validations;
+    }
+
+    public void addValidation(Validation validation) {
+        if (validations.length == 0) {
+            validations = new Validation[1];
+        } else {
+            Validation[] newvalidations = new Validation[validations.length + 1];
+            System.arraycopy(validations, 0, newvalidations, 0, validations.length);
+            validations = newvalidations;
+        }
+        validations[validations.length - 1] = validation;
+    }
+
+    public boolean hasValidation(Validation aValidation) {
+        if (validations == null) return false;
+        for (Validation validation : validations) {
+            if (validation.equals(aValidation)) return true;
+        }
+        return false;
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/MetaBean.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/MetaBean.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/MetaBean.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/MetaBean.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,126 @@
+/**
+ *  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 com.agimatec.validation.model;
+
+import org.apache.commons.lang.ArrayUtils;
+
+/**
+ * Description: the meta description of a bean or class.
+ * the class/bean itself can have a map of features and an array of metaproperties.<br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 09:44:31 <br/>
+ * Copyright: Agimatec GmbH 2008
+ *
+ * @see MetaProperty
+ */
+public class MetaBean extends FeaturesCapable implements Cloneable, Features.Bean {
+    private String id;
+    private String name;
+    private Class beanClass;
+    private MetaProperty[] properties = new MetaProperty[0];
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Class getBeanClass() {
+        return beanClass;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setBeanClass(Class beanClass) {
+        this.beanClass = beanClass;
+    }
+
+    public MetaProperty[] getProperties() {
+        return properties;
+    }
+
+    public void setProperties(MetaProperty[] properties) {
+        this.properties = properties;
+    }
+
+    public MetaProperty getProperty(String name) {
+        for (MetaProperty p : properties) {
+            if (name.equals(p.getName())) return p;
+        }
+        return null;
+    }
+
+    /** @return true when at least one of the properties is a relationship */
+    public boolean hasRelationships() {
+        for (MetaProperty p : properties) {
+            if (p.isRelationship()) return true;
+        }
+        return false;
+    }
+
+    public boolean hasProperties() {
+        return properties.length > 0;
+    }
+
+    public void putProperty(String name, MetaProperty property) {
+        final MetaProperty oldProperty = getProperty(name);
+        if (oldProperty == null) { // add
+            if (properties.length == 0) {
+                properties = new MetaProperty[1];
+            } else {
+                MetaProperty[] newproperties = new MetaProperty[properties.length + 1];
+                System.arraycopy(properties, 0, newproperties, 0, properties.length);
+                properties = newproperties;
+            }
+            properties[properties.length - 1] = property;
+        } else { // replace
+            int idx = ArrayUtils.indexOf(properties, oldProperty);
+            properties[idx] = property;
+        }
+    }
+
+    public String toString() {
+        return "MetaBean{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", beanClass=" +
+                beanClass + '}';
+    }
+
+    @Override
+    protected <T extends FeaturesCapable> void copyInto(T target) {
+        super.copyInto(target);
+        final MetaBean copy = (MetaBean) target;
+        if (properties != null) {
+            copy.properties = properties.clone();
+            for (int i = copy.properties.length - 1; i >= 0; i--) {
+                copy.properties[i] = copy.properties[i].copy();
+            }
+        }
+    }
+
+    public MetaBean resolveMetaBean(Object bean) {
+        return bean == null || bean == beanClass || beanClass.isInstance(bean) ? this : null;
+    }
+
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/MetaProperty.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/MetaProperty.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/MetaProperty.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/MetaProperty.java Wed Mar 17 04:39:07 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 com.agimatec.validation.model;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+/**
+ * Description: the meta description of a property of a bean. it supports a map
+ * of features and multiple validations<br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 09:58:57 <br/>
+ * Copyright: Agimatec GmbH 2008
+ *
+ * @see Validation
+ * @see MetaBean
+ */
+public class MetaProperty extends FeaturesCapable
+      implements Cloneable, Features.Property {
+    private String name;
+
+    private Type type;
+    private MetaBean metaBean;
+
+    public MetaProperty() {
+    }
+
+    /** the meta info of the target bean (mainly for relationships) */
+    public MetaBean getMetaBean() {
+        return metaBean;
+    }
+
+    public void setMetaBean(MetaBean metaBean) {
+        this.metaBean = metaBean;
+    }
+
+    public boolean isRelationship() {
+        return metaBean != null;
+    }
+
+    public void setType(Type type) {
+        this.type = type;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public Class<?> getTypeClass() {
+        return getTypeClass(type);
+    }
+
+    private Class<?> getTypeClass(Type rawType) {
+        if (rawType instanceof Class) {
+            return (Class) rawType;
+        } else if (rawType instanceof ParameterizedType) {
+            return getTypeClass(((ParameterizedType) rawType).getRawType()); // recursion!
+        } else if(rawType instanceof DynaType) {
+            return getTypeClass(((DynaType)rawType).getRawType()); // recursion
+        } else {
+            return null; // class cannot be determined!
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean isMandatory() {
+        return getFeature(MANDATORY, Boolean.FALSE).booleanValue();
+    }
+
+    public void setMandatory(boolean mandatory) {
+        putFeature(MANDATORY, Boolean.valueOf(mandatory));
+    }
+
+    public String[] getJavaScriptValidations() {
+        return getFeature(JAVASCRIPT_VALIDATION_FUNCTIONS);
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String toString() {
+        return "MetaProperty{" + "name='" + name + '\'' + ", type=" + type + '}';
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/Validation.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/Validation.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/Validation.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/Validation.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,34 @@
+/**
+ *  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 com.agimatec.validation.model;
+
+/**
+ * Description: Interface for a single validation <br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 10:04:39 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public interface Validation {
+    /**
+     * Perform a single validation routine.
+     * Validate the object or property according to the current ValidationContext.
+     *
+     * @param context - to access the property, value, constraints
+     */
+    void validate(ValidationContext context);
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/ValidationContext.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/ValidationContext.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/ValidationContext.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/ValidationContext.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,72 @@
+/**
+ *  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 com.agimatec.validation.model;
+
+import com.agimatec.validation.util.AccessStrategy;
+
+/**
+ * Description: Interface of the context that holds all state information
+ * during the validation process<br/>
+ * User: roman.stumm <br/>
+ * Date: 28.04.2008 <br/>
+ * Time: 09:36:02 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public interface ValidationContext<T extends ValidationListener> {
+    Object getPropertyValue();
+
+    /** get the value by using the given access strategy and cache it */
+    Object getPropertyValue(AccessStrategy access);
+
+    String getPropertyName();
+
+    T getListener();
+
+    Object getBean();
+
+    MetaBean getMetaBean();
+
+    void setMetaBean(MetaBean metaBean);
+
+    MetaProperty getMetaProperty();
+
+    void setBean(Object bean);
+
+    boolean collectValidated();
+
+    void setBean(Object aBean, MetaBean aMetaBean);
+
+    void setMetaProperty(MetaProperty metaProperty);
+
+    /** step deeper into association at 'prop' */
+    void moveDown(MetaProperty prop, AccessStrategy access);
+
+    /** step out from a validation of associated objects. */
+    void moveUp(Object bean, MetaBean metaBean);
+
+    /**
+     * set the index of the object currently validated into the context.
+     * used to create the propertyPath with [index] information for collections.
+     */
+    void setCurrentIndex(int index);
+
+    /**
+     * set the key of the object in a map currently validated into the context.
+     * used to create the propertyPath with [key] information for maps.
+     */
+    void setCurrentKey(Object key);
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/ValidationListener.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/ValidationListener.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/ValidationListener.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/model/ValidationListener.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,80 @@
+/**
+ *  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 com.agimatec.validation.model;
+
+import com.agimatec.validation.ValidationResults;
+
+import java.io.Serializable;
+
+
+/**
+ * Description: The interface to collect errors found during validation<br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 13:18:24 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public interface ValidationListener {
+    /**
+     * Simple API to add an error reason during validation.
+     * Error notification added from a {@link Validation} with context information
+     * taken from the given {@link ValidationContext}.
+     *
+     * @param reason  a constant describing the reason. This is normally the key of the
+     *                feature that was violated in the object 'owner' for property 'propertyName'
+     * @param context - contains
+     *                bean =         the object that contains the error (owner)
+     *                propertyName = the Name of the attribute that caused the error
+     */
+    void addError(String reason, ValidationContext context);
+
+    /** Alternative method to add a fully initialized {@link ValidationResults.Error} object. */
+    void addError(Error error, ValidationContext context);
+
+    /**
+     * an object holding a single validation constraint violation
+     * found during the validation process.
+     */
+    public class Error implements Serializable {
+        final String reason;
+        final Object owner;
+        final String propertyName;
+
+        public Error(String aReason, Object aOwner, String aPropertyName) {
+            this.reason = aReason;
+            this.owner = aOwner;
+            this.propertyName = aPropertyName;
+        }
+
+        public String getReason() {
+            return reason;
+        }
+
+        public Object getOwner() {
+            return owner;
+        }
+
+        public String getPropertyName() {
+            return propertyName;
+        }
+
+        public String toString() {
+            return "Error{" + "reason='" + reason + '\'' + ", propertyName='" +
+                  propertyName + '\'' + '}';
+        }
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/EMailValidation.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/EMailValidation.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/EMailValidation.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/EMailValidation.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,81 @@
+/**
+ *  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 com.agimatec.validation.routines;
+
+import com.agimatec.validation.model.Validation;
+import com.agimatec.validation.model.ValidationContext;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Description: example validation for email addresses using a regular expression
+ * (taken from hibernate EmailValidator)<br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 16:51:16 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class EMailValidation implements Validation {
+    private static String ATOM =
+            "[^\\x00-\\x1F^\\(^\\)^\\<^\\>^\\@^\\,^\\;^\\:^\\\\^\\\"^\\.^\\[^\\]^\\s]";
+    private static String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)*";
+    private static String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]";
+    private static final java.util.regex.Pattern DEFAULT_PATTERN;
+
+    static {
+        DEFAULT_PATTERN = java.util.regex.Pattern.compile(
+                "^" + ATOM + "+(\\." + ATOM + "+)*@"
+                        + DOMAIN
+                        + "|"
+                        + IP_DOMAIN
+                        + ")$",
+                java.util.regex.Pattern.CASE_INSENSITIVE
+        );
+    }
+
+    private java.util.regex.Pattern pattern = DEFAULT_PATTERN;
+
+    public void validate(ValidationContext context) {
+        if (context.getPropertyValue() == null) return;
+        if (!isValid(context.getPropertyValue(), pattern)) {
+            context.getListener().addError(Reasons.EMAIL_ADDRESS, context);
+        }
+    }
+
+    public Pattern getPattern() {
+        return pattern;
+    }
+
+    public void setPattern(Pattern pattern) {
+        this.pattern = pattern;
+    }
+
+    public static boolean isValid(Object value) {
+        return isValid(value, DEFAULT_PATTERN);
+    }
+
+    private static boolean isValid(Object value, Pattern aPattern) {
+        if (value == null) return true;
+        if (!(value instanceof String)) return false;
+        String string = (String) value;
+        if (string.length() == 0) return true;
+        Matcher m = aPattern.matcher(string);
+        return m.matches();
+    }
+
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/NOPValidation.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/NOPValidation.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/NOPValidation.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/NOPValidation.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,34 @@
+/**
+ *  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 com.agimatec.validation.routines;
+
+import com.agimatec.validation.model.Validation;
+import com.agimatec.validation.model.ValidationContext;
+
+/**
+ * Description: DO NOTHING VALIDATION (can be used to turn off standard validation)<br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 16:51:28 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class NOPValidation implements Validation {
+
+    public void validate(ValidationContext context) {
+        // do nothing
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/Reasons.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/Reasons.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/Reasons.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/Reasons.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,35 @@
+/**
+ *  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 com.agimatec.validation.routines;
+
+import com.agimatec.validation.model.Features;
+
+/**
+ * Description: StandardReasons for validation errors found in
+ * {@link com.agimatec.validation.ValidationResults}<br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 13:20:43 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public interface Reasons extends Features.Property {
+    // The reasons inherited from Features are VALIDATION features only.
+    // INFO features are not meant to be validated.
+
+    // Add more reasons here.
+    String EMAIL_ADDRESS = "emailAddress";
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/StandardValidation.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/StandardValidation.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/StandardValidation.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/routines/StandardValidation.java Wed Mar 17 04:39:07 2010
@@ -0,0 +1,177 @@
+/**
+ *  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 com.agimatec.validation.routines;
+
+import com.agimatec.validation.model.Features;
+import com.agimatec.validation.model.MetaProperty;
+import com.agimatec.validation.model.Validation;
+import com.agimatec.validation.model.ValidationContext;
+import static com.agimatec.validation.routines.Reasons.*;
+import com.agimatec.validation.xml.XMLMetaValue;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Description: This class implements the standard validations for properties!
+ * You can subclass this class and replace the implementation
+ * in the beanInfo-xml by providing it a validation "standard"<br/>
+ * User: roman.stumm <br/>
+ * Date: 06.07.2007 <br/>
+ * Time: 12:41:06 <br/>
+ * Copyright: Agimatec GmbH 2008
+ */
+public class StandardValidation implements Validation {
+    /** key for this validation in the validation list of the beanInfos */
+    public String getValidationId() {
+        return "standard";
+    }
+
+    public void validate(ValidationContext context) {
+        validateMandatory(context);
+        validateMaxLength(context);
+        validateMinLength(context);
+        validateMaxValue(context);
+        validateMinValue(context);
+        validateRegExp(context);
+        validateTimeLag(context);
+    }
+
+    protected void validateTimeLag(ValidationContext context) {
+        String lag = (String) context.getMetaProperty().getFeature(TIME_LAG);
+        if (lag == null) return;
+        if (context.getPropertyValue() == null) return;
+        long date = ((Date) context.getPropertyValue()).getTime();
+        long now = System.currentTimeMillis();
+        if (XMLMetaValue.TIMELAG_Future.equals(lag)) {
+            if (date < now) {
+                context.getListener().addError(TIME_LAG, context);
+            }
+        } else if (XMLMetaValue.TIMELAG_Past.equals(lag)) {
+            if (date > now) {
+                context.getListener().addError(TIME_LAG, context);
+            }
+        } else {
+            throw new IllegalArgumentException("unknown timelag " + lag + " at " + context);
+        }
+    }
+
+    private static final String REG_EXP_PATTERN = "cachedRegExpPattern";
+
+    protected void validateRegExp(ValidationContext context) {
+        final MetaProperty meta = context.getMetaProperty();
+        final String regExp = (String) meta.getFeature(REG_EXP);
+        if (regExp == null) return;
+        if (context.getPropertyValue() == null) return;
+
+        final String value = String.valueOf(context.getPropertyValue());
+        try {
+            Pattern pattern = (Pattern) meta.getFeature(REG_EXP_PATTERN);
+            if (pattern == null) {
+                pattern = Pattern.compile(regExp);
+                meta.putFeature(REG_EXP_PATTERN, pattern);
+            }
+            if (!pattern.matcher(value).matches()) {
+                context.getListener().addError(REG_EXP, context);
+            }
+        } catch (PatternSyntaxException e) {
+            throw new IllegalArgumentException(
+                  "regular expression malformed. regexp " + regExp + " at " + context, e);
+        }
+    }
+
+    protected void validateMinValue(ValidationContext context) {
+        Comparable minValue = (Comparable) context.getMetaProperty().getFeature(MIN_VALUE);
+        if (minValue == null || context.getPropertyValue() == null) return;
+        if (compare(context, minValue, context.getPropertyValue()) > 0) {
+            context.getListener().addError(MIN_VALUE, context);
+        }
+    }
+
+    protected void validateMaxValue(ValidationContext context) {
+        Comparable maxValue = (Comparable) context.getMetaProperty().getFeature(MAX_VALUE);
+        if (maxValue == null || context.getPropertyValue() == null) return;
+        if (compare(context, maxValue, context.getPropertyValue()) < 0) {
+            context.getListener().addError(MAX_VALUE, context);
+        }
+    }
+
+    private int compare(ValidationContext context, Comparable constraintValue,
+                        Object currentValue) {
+        int r;
+        if (constraintValue.getClass().isAssignableFrom(currentValue.getClass())) {
+            r = constraintValue.compareTo(context.getPropertyValue());
+        } else if (currentValue instanceof Number) {
+            double dv = ((Number) currentValue).doubleValue();
+            double mdv = ((Number) constraintValue).doubleValue();
+            r = mdv > dv ? 1 : -1;
+        } else {
+            r = String.valueOf(constraintValue).compareTo(String.valueOf(currentValue));
+        }
+        return r;
+    }
+
+    protected void validateMaxLength(ValidationContext context) {
+        Integer maxLength = (Integer) context.getMetaProperty()
+              .getFeature(Features.Property.MAX_LENGTH);
+        if (maxLength == null) return;
+        if (context.getPropertyValue() == null) return;
+
+        final Object value = context.getPropertyValue();
+        int length = 0;
+        if (value instanceof String) {
+            length = ((String) value).length();
+        } else if (value instanceof Collection) {
+            length = ((Collection) value).size();
+        }
+        if (length > maxLength) {
+            context.getListener().addError(MAX_LENGTH, context);
+        }
+    }
+
+    protected void validateMinLength(ValidationContext context) {
+        Integer maxLength = (Integer) context.getMetaProperty()
+              .getFeature(Features.Property.MIN_LENGTH);
+        if (maxLength == null) return;
+        if (context.getPropertyValue() == null) return;
+
+        final Object value = context.getPropertyValue();
+        int length = 0;
+        if (value instanceof String) {
+            length = ((String) value).length();
+        } else if (value instanceof Collection) {
+            length = ((Collection) value).size();
+        }
+        if (length < maxLength) {
+            context.getListener().addError(MIN_LENGTH, context);
+        }
+    }
+
+    protected void validateMandatory(ValidationContext context) {
+        if (context.getMetaProperty().isMandatory()) {
+            if (context.getPropertyValue() == null) {
+                context.getListener().addError(MANDATORY, context);
+            }
+        }
+    }
+
+    public static StandardValidation getInstance() {
+        return new StandardValidation();
+    }
+}

Added: incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/util/AccessStrategy.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/util/AccessStrategy.java?rev=924153&view=auto
==============================================================================
--- incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/util/AccessStrategy.java (added)
+++ incubator/bval/trunk/agimatec-validation/src/main/java/com/agimatec/validation/util/AccessStrategy.java Wed Mar 17 04:39:07 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 com.agimatec.validation.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.reflect.Type;
+
+/**
+ * Description: abstract class to encapsulate different strategies
+ * to get the value of a Property.<br/>
+ * User: roman <br/>
+ * Date: 29.10.2009 <br/>
+ * Time: 12:12:08 <br/>
+ * Copyright: Agimatec GmbH
+ */
+public abstract class AccessStrategy {
+    /**
+     * get the value from the given instance.
+     * @param instance
+     * @return the value
+     * @throws IllegalArgumentException in case of an error
+     */
+    public abstract Object get(Object instance);
+
+    public abstract ElementType getElementType();
+
+    public abstract Type getJavaType();
+
+    public abstract String getPropertyName();
+}



Mime
View raw message