001    /**
002     * Copyright 2005-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kew.api.validation;
017    
018    import org.apache.commons.collections.CollectionUtils;
019    import org.kuali.rice.core.api.CoreConstants;
020    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
021    import org.kuali.rice.core.api.mo.ModelBuilder;
022    import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
023    import org.kuali.rice.kew.api.rule.RuleContract;
024    import org.kuali.rice.kew.api.rule.RuleDelegationContract;
025    import org.kuali.rice.kew.api.rule.RuleResponsibility;
026    import org.kuali.rice.kew.api.rule.RuleResponsibilityContract;
027    import org.w3c.dom.Element;
028    
029    import javax.xml.bind.annotation.XmlAccessType;
030    import javax.xml.bind.annotation.XmlAccessorType;
031    import javax.xml.bind.annotation.XmlAnyElement;
032    import javax.xml.bind.annotation.XmlElement;
033    import javax.xml.bind.annotation.XmlRootElement;
034    import javax.xml.bind.annotation.XmlType;
035    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
036    import java.io.Serializable;
037    import java.util.ArrayList;
038    import java.util.Collection;
039    import java.util.Collections;
040    import java.util.HashMap;
041    import java.util.List;
042    import java.util.Map;
043    
044    /**
045     * A set of results from validation of a field of data.
046     *
047     * @author Kuali Rice Team (rice.collab@kuali.org)
048     */
049    @XmlRootElement(name = ValidationResults.Constants.ROOT_ELEMENT_NAME)
050    @XmlAccessorType(XmlAccessType.NONE)
051    @XmlType(name = ValidationResults.Constants.TYPE_NAME, propOrder = {
052        ValidationResults.Elements.ERRORS,
053        CoreConstants.CommonElements.FUTURE_ELEMENTS
054    })
055    public class ValidationResults
056        extends AbstractDataTransferObject
057        implements ValidationResultsContract {
058    
059            public static final String GLOBAL = "org.kuali.rice.kew.api.validation.ValidationResults.GLOBAL";
060    
061        @XmlElement(name = Elements.ERRORS, required = false)
062        @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
063        private final Map<String, String> errors;
064    
065        @SuppressWarnings("unused")
066        @XmlAnyElement
067        private final Collection<Element> _futureElements = null;
068    
069        /**
070         * Private constructor used only by JAXB.
071         */
072        private ValidationResults() {
073            this.errors = Collections.emptyMap();
074        }
075    
076        private ValidationResults(Builder builder) {
077           this.errors = Collections.unmodifiableMap(builder.getErrors());
078        }
079    
080        @Override
081            public Map<String, String> getErrors() {
082                    return errors;
083            }
084    
085        /**
086         * A builder which can be used to construct {@link ValidationResults} instances.  Enforces the constraints of the {@link ValidationResultsContract}.
087         *
088         */
089        public final static class Builder
090            implements Serializable, ModelBuilder, ValidationResultsContract
091        {
092    
093            private Map<String, String> errors = new HashMap<String, String>();
094    
095            private Builder() {
096            }
097    
098            public static Builder create() {
099                return new Builder();
100            }
101    
102            public static Builder create(ValidationResultsContract contract) {
103                if (contract == null) {
104                    throw new IllegalArgumentException("contract was null");
105                }
106                Builder builder = create();
107                if (contract.getErrors() != null) {
108                    builder.setErrors(contract.getErrors());
109                }
110                return builder;
111            }
112    
113            public ValidationResults build() {
114                return new ValidationResults(this);
115            }
116    
117            @Override
118            public Map<String, String> getErrors() {
119                return Collections.unmodifiableMap(this.errors);
120            }
121    
122            public void setErrors(Map<String, String> errors) {
123                this.errors = new HashMap<String, String>(errors);
124            }
125    
126            /**
127             * Convenience method for adding an error message
128             * @param errorMessage
129             */
130            public void addError(String errorMessage) {
131                addError(GLOBAL, errorMessage);
132            }
133    
134            /**
135             * Convenience method for adding an error message for a given field
136             * @param errorMessage
137             */
138            public void addError(String fieldName, String errorMessage) {
139                errors.put(fieldName, errorMessage);
140            }
141        }
142    
143        /**
144         * Defines some internal constants used on this class.
145         */
146        static class Constants {
147            final static String ROOT_ELEMENT_NAME = "validationResults";
148            final static String TYPE_NAME = "ValidationResultsType";
149        }
150        /**
151         * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
152         */
153        static class Elements {
154            final static String ERRORS = "errors";
155        }
156    }