001/**
002 * Copyright 2005-2015 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 */
016package org.kuali.rice.kew.api.validation;
017
018import org.apache.commons.collections.CollectionUtils;
019import org.kuali.rice.core.api.CoreConstants;
020import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
021import org.kuali.rice.core.api.mo.ModelBuilder;
022import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
023import org.kuali.rice.kew.api.rule.RuleContract;
024import org.kuali.rice.kew.api.rule.RuleDelegationContract;
025import org.kuali.rice.kew.api.rule.RuleResponsibility;
026import org.kuali.rice.kew.api.rule.RuleResponsibilityContract;
027import org.w3c.dom.Element;
028
029import javax.xml.bind.annotation.XmlAccessType;
030import javax.xml.bind.annotation.XmlAccessorType;
031import javax.xml.bind.annotation.XmlAnyElement;
032import javax.xml.bind.annotation.XmlElement;
033import javax.xml.bind.annotation.XmlRootElement;
034import javax.xml.bind.annotation.XmlType;
035import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
036import java.io.Serializable;
037import java.util.ArrayList;
038import java.util.Collection;
039import java.util.Collections;
040import java.util.HashMap;
041import java.util.List;
042import 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})
055public 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}