001 /*
002 * Copyright 2011 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/ecl1.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.document;
017
018 import java.io.Serializable;
019 import java.util.Collection;
020 import java.util.Collections;
021 import java.util.HashMap;
022 import java.util.Map;
023
024 import javax.xml.bind.annotation.XmlAccessType;
025 import javax.xml.bind.annotation.XmlAccessorType;
026 import javax.xml.bind.annotation.XmlAnyElement;
027 import javax.xml.bind.annotation.XmlElement;
028 import javax.xml.bind.annotation.XmlRootElement;
029 import javax.xml.bind.annotation.XmlType;
030 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
031
032 import org.apache.commons.lang.StringUtils;
033 import org.apache.commons.lang.builder.EqualsBuilder;
034 import org.apache.commons.lang.builder.HashCodeBuilder;
035 import org.apache.commons.lang.builder.ToStringBuilder;
036 import org.kuali.rice.core.api.CoreConstants;
037 import org.kuali.rice.core.api.mo.ModelBuilder;
038 import org.kuali.rice.core.util.jaxb.MapStringStringAdapter;
039 import org.kuali.rice.kew.api.KewApiConstants;
040 import org.w3c.dom.Element;
041
042 /**
043 * Defines an update to document content on a particular workflow document.
044 * Contains general application content as well as a list of attribute
045 * definitions and searchable definitions. When passed to the appropriate
046 * workflow services to perform an update on document content, if any of the
047 * internal content or definitions on this object have not been set then they
048 * will not be updated. This allows for this data structure to be used to only
049 * update the portion of the document content that is desired to be updated.
050 *
051 * @author Kuali Rice Team (rice.collab@kuali.org)
052 *
053 */
054 @XmlRootElement(name = DocumentUpdate.Constants.ROOT_ELEMENT_NAME)
055 @XmlAccessorType(XmlAccessType.NONE)
056 @XmlType(name = DocumentUpdate.Constants.TYPE_NAME, propOrder = {
057 DocumentUpdate.Elements.TITLE,
058 DocumentUpdate.Elements.APPLICATION_DOCUMENT_ID,
059 DocumentUpdate.Elements.APPLICATION_DOCUMENT_STATUS,
060 DocumentUpdate.Elements.VARIABLES,
061 CoreConstants.CommonElements.FUTURE_ELEMENTS
062 })
063 public final class DocumentUpdate implements Serializable {
064
065 private static final long serialVersionUID = 608839901744771499L;
066
067 @XmlElement(name = Elements.TITLE, required = false)
068 private final String title;
069
070 @XmlElement(name = Elements.APPLICATION_DOCUMENT_ID, required = false)
071 private final String applicationDocumentId;
072
073 @XmlElement(name = Elements.APPLICATION_DOCUMENT_STATUS, required = false)
074 private final String applicationDocumentStatus;
075
076 @XmlElement(name = Elements.VARIABLES, required = false)
077 @XmlJavaTypeAdapter(MapStringStringAdapter.class)
078 private final Map<String, String> variables;
079
080 @SuppressWarnings("unused")
081 @XmlAnyElement
082 private final Collection<Element> _futureElements = null;
083
084 private DocumentUpdate() {
085 this.title = null;
086 this.applicationDocumentId = null;
087 this.applicationDocumentStatus = null;
088 this.variables = null;
089 }
090
091 private DocumentUpdate(Builder builder) {
092 this.title = builder.getTitle();
093 this.applicationDocumentId = builder.getApplicationDocumentId();
094 this.applicationDocumentStatus = builder.getApplicationDocumentStatus();
095 this.variables = builder.getVariables();
096 }
097
098 public String getTitle() {
099 return title;
100 }
101
102 public String getApplicationDocumentId() {
103 return applicationDocumentId;
104 }
105
106 public String getApplicationDocumentStatus() {
107 return applicationDocumentStatus;
108 }
109
110 public Map<String, String> getVariables() {
111 if (variables == null) {
112 return Collections.emptyMap();
113 }
114 return Collections.unmodifiableMap(variables);
115 }
116
117 @Override
118 public int hashCode() {
119 return HashCodeBuilder.reflectionHashCode(this, Constants.HASH_CODE_EQUALS_EXCLUDE);
120 }
121
122 @Override
123 public boolean equals(Object object) {
124 return EqualsBuilder.reflectionEquals(object, this, Constants.HASH_CODE_EQUALS_EXCLUDE);
125 }
126
127 @Override
128 public String toString() {
129 return ToStringBuilder.reflectionToString(this);
130 }
131
132 /**
133 * A builder which can be used to construct {@link DocumentUpdate} instances.
134 */
135 public final static class Builder implements Serializable, ModelBuilder {
136
137 private static final long serialVersionUID = 2220000561051177421L;
138
139 private String title;
140 private String applicationDocumentId;
141 private String applicationDocumentStatus;
142 private Map<String, String> variables;
143
144
145 private Builder() {
146 this.title = "";
147 this.variables = new HashMap<String, String>();
148 }
149
150 public static Builder create() {
151 return new Builder();
152 }
153
154 public static Builder create(Document document) {
155 if (document == null) {
156 throw new IllegalArgumentException("document was null");
157 }
158 Builder builder = create();
159 builder.setTitle(document.getTitle());
160 builder.setApplicationDocumentId(document.getApplicationDocumentId());
161 builder.setApplicationDocumentStatus(document.getApplicationDocumentStatus());
162 builder.setVariables(document.getVariables());
163 return builder;
164 }
165
166 public DocumentUpdate build() {
167 return new DocumentUpdate(this);
168 }
169
170 public String getTitle() {
171 return title;
172 }
173
174 /**
175 * TODO: document the fact that this will auto-truncate the title...
176 */
177 public void setTitle(String title) {
178 if (title == null) {
179 title = "";
180 }
181 if (title.length() > KewApiConstants.TITLE_MAX_LENGTH) {
182 title = title.substring(0, KewApiConstants.TITLE_MAX_LENGTH);
183 }
184 this.title = title;
185 }
186
187 public String getApplicationDocumentId() {
188 return applicationDocumentId;
189 }
190
191 public void setApplicationDocumentId(String applicationDocumentId) {
192 this.applicationDocumentId = applicationDocumentId;
193 }
194
195 public String getApplicationDocumentStatus() {
196 return applicationDocumentStatus;
197 }
198
199 public void setApplicationDocumentStatus(String applicationDocumentStatus) {
200 this.applicationDocumentStatus = applicationDocumentStatus;
201 }
202
203 public void setVariables(Map<String, String> variables) {
204 if (variables == null) {
205 this.variables = new HashMap<String, String>();
206 } else {
207 this.variables = new HashMap<String, String>(variables);
208 }
209 }
210
211 public Map<String, String> getVariables() {
212 return variables;
213 }
214
215 public String getVariableValue(String name) {
216 return variables.get(name);
217 }
218
219 public void setVariable(String name, String value) {
220 if (StringUtils.isBlank(name)) {
221 throw new IllegalArgumentException("name was null or blank");
222 }
223 variables.put(name, value);
224 }
225
226 }
227
228 /**
229 * Defines some internal constants used on this class.
230 */
231 static class Constants {
232 final static String ROOT_ELEMENT_NAME = "documentUpdate";
233 final static String TYPE_NAME = "DocumentUpdateType";
234 final static String[] HASH_CODE_EQUALS_EXCLUDE = new String[] { CoreConstants.CommonElements.FUTURE_ELEMENTS };
235 }
236
237 /**
238 * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
239 */
240 static class Elements {
241 final static String TITLE = "title";
242 final static String APPLICATION_DOCUMENT_ID = "applicationDocumentId";
243 final static String APPLICATION_DOCUMENT_STATUS = "applicationDocumentStatus";
244 final static String VARIABLES = "variables";
245 }
246
247 }