001/** 002 * Copyright 2005-2018 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.document; 017 018import org.apache.commons.lang.StringUtils; 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.KewApiConstants; 024import org.w3c.dom.Element; 025 026import javax.xml.bind.annotation.XmlAccessType; 027import javax.xml.bind.annotation.XmlAccessorType; 028import javax.xml.bind.annotation.XmlAnyElement; 029import javax.xml.bind.annotation.XmlElement; 030import javax.xml.bind.annotation.XmlElementWrapper; 031import javax.xml.bind.annotation.XmlRootElement; 032import javax.xml.bind.annotation.XmlType; 033import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 034import java.io.Serializable; 035import java.util.ArrayList; 036import java.util.Collection; 037import java.util.Collections; 038import java.util.HashMap; 039import java.util.List; 040import java.util.Map; 041 042/** 043 * Defines an update to document meta-data on a particular workflow document, 044 * including title, application document id, application document status, 045 * and routing branch variables. This structure is used to convey changes to 046 * the document meta-data on document actions, and to retrieve their state 047 * afterwards. 048 * Document titles will be truncated to to {@link KewApiConstants#TITLE_MAX_LENGTH} length. 049 * 050 * @author Kuali Rice Team (rice.collab@kuali.org) 051 * @see org.kuali.rice.kew.api.WorkflowDocumentFactory 052 * @see WorkflowDocumentImpl 053 * @see WorkflowDocumentImpl.ModifiableDocument 054 * @see WorkflowDocumentActionsServiceImpl 055 */ 056@XmlRootElement(name = DocumentUpdate.Constants.ROOT_ELEMENT_NAME) 057@XmlAccessorType(XmlAccessType.NONE) 058@XmlType(name = DocumentUpdate.Constants.TYPE_NAME, propOrder = { 059 DocumentUpdate.Elements.TITLE, 060 DocumentUpdate.Elements.APPLICATION_DOCUMENT_ID, 061 DocumentUpdate.Elements.APPLICATION_DOCUMENT_STATUS, 062 DocumentUpdate.Elements.VARIABLES, 063 DocumentUpdate.Elements.DIRTY_FIELDS, 064 CoreConstants.CommonElements.FUTURE_ELEMENTS 065}) 066public final class DocumentUpdate extends AbstractDataTransferObject { 067 068 private static final long serialVersionUID = 608839901744771499L; 069 070 @XmlElement(name = Elements.TITLE, required = false) 071 private final String title; 072 073 @XmlElement(name = Elements.APPLICATION_DOCUMENT_ID, required = false) 074 private final String applicationDocumentId; 075 076 @XmlElement(name = Elements.APPLICATION_DOCUMENT_STATUS, required = false) 077 private final String applicationDocumentStatus; 078 079 @XmlElement(name = Elements.VARIABLES, required = false) 080 @XmlJavaTypeAdapter(MapStringStringAdapter.class) 081 private final Map<String, String> variables; 082 083 @XmlElementWrapper(name = Elements.DIRTY_FIELDS, required = false) 084 @XmlElement(name = "field", required = false) 085 private final List<String> dirtyFields; 086 087 @SuppressWarnings("unused") 088 @XmlAnyElement 089 private final Collection<Element> _futureElements = null; 090 091 private DocumentUpdate() { 092 this.title = null; 093 this.applicationDocumentId = null; 094 this.applicationDocumentStatus = null; 095 this.variables = null; 096 this.dirtyFields = new ArrayList<String>(); 097 } 098 099 private DocumentUpdate(Builder builder) { 100 this.title = builder.getTitle(); 101 this.applicationDocumentId = builder.getApplicationDocumentId(); 102 this.applicationDocumentStatus = builder.getApplicationDocumentStatus(); 103 this.variables = builder.getVariables(); 104 this.dirtyFields = builder.getDirtyFields(); 105 } 106 107 public String getTitle() { 108 return title; 109 } 110 111 public String getApplicationDocumentId() { 112 return applicationDocumentId; 113 } 114 115 public String getApplicationDocumentStatus() { 116 return applicationDocumentStatus; 117 } 118 119 public Map<String, String> getVariables() { 120 if (variables == null) { 121 return Collections.emptyMap(); 122 } 123 return Collections.unmodifiableMap(variables); 124 } 125 public List<String> getDirtyFields() { 126 return dirtyFields; 127 } 128 /** 129 * A builder which can be used to construct {@link DocumentUpdate} instances. 130 */ 131 public final static class Builder implements Serializable, ModelBuilder { 132 133 private static final long serialVersionUID = 2220000561051177421L; 134 135 private String title; 136 private String applicationDocumentId; 137 private String applicationDocumentStatus; 138 private Map<String, String> variables; 139 private List<String> dirtyFields; 140 141 private Builder() { 142 this.title = ""; 143 this.variables = new HashMap<String, String>(); 144 } 145 146 public static Builder create() { 147 return new Builder(); 148 } 149 150 public static Builder create(Document document) { 151 if (document == null) { 152 throw new IllegalArgumentException("document was null"); 153 } 154 Builder builder = create(); 155 builder.setTitle(document.getTitle()); 156 builder.setApplicationDocumentId(document.getApplicationDocumentId()); 157 builder.setApplicationDocumentStatus(document.getApplicationDocumentStatus()); 158 builder.setVariables(document.getVariables()); 159 return builder; 160 } 161 162 public DocumentUpdate build() { 163 return new DocumentUpdate(this); 164 } 165 166 public String getTitle() { 167 return title; 168 } 169 170 /** 171 * Sets the document title - will be truncated to {@link KewApiConstants#TITLE_MAX_LENGTH} length. 172 */ 173 public void setTitle(String title) { 174 if (title == null) { 175 title = ""; 176 } 177 if (title.length() > KewApiConstants.TITLE_MAX_LENGTH) { 178 title = title.substring(0, KewApiConstants.TITLE_MAX_LENGTH); 179 } 180 this.title = title; 181 } 182 183 public String getApplicationDocumentId() { 184 return applicationDocumentId; 185 } 186 187 public void setApplicationDocumentId(String applicationDocumentId) { 188 this.applicationDocumentId = applicationDocumentId; 189 } 190 191 public String getApplicationDocumentStatus() { 192 return applicationDocumentStatus; 193 } 194 195 public void setApplicationDocumentStatus(String applicationDocumentStatus) { 196 this.applicationDocumentStatus = applicationDocumentStatus; 197 } 198 199 public void setVariables(Map<String, String> variables) { 200 if (variables == null) { 201 this.variables = new HashMap<String, String>(); 202 } else { 203 this.variables = new HashMap<String, String>(variables); 204 } 205 } 206 207 public Map<String, String> getVariables() { 208 return variables; 209 } 210 211 public String getVariableValue(String name) { 212 return variables.get(name); 213 } 214 215 public void setVariable(String name, String value) { 216 if (StringUtils.isBlank(name)) { 217 throw new IllegalArgumentException("name was null or blank"); 218 } 219 variables.put(name, value); 220 } 221 222 public List<String> getDirtyFields() { 223 return dirtyFields; 224 } 225 226 public void setDirtyFields(List<String> dirtyFields) { 227 this.dirtyFields = dirtyFields; 228 } 229 230 public void addDirtyField(String field) { 231 if(this.getDirtyFields() == null) { 232 this.setDirtyFields(new ArrayList<String>()); 233 } 234 this.getDirtyFields().add(field); 235 } 236 237 } 238 239 /** 240 * Defines some internal constants used on this class. 241 */ 242 static class Constants { 243 final static String ROOT_ELEMENT_NAME = "documentUpdate"; 244 final static String TYPE_NAME = "DocumentUpdateType"; 245 } 246 247 /** 248 * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML. 249 */ 250 static class Elements { 251 final static String TITLE = "title"; 252 final static String APPLICATION_DOCUMENT_ID = "applicationDocumentId"; 253 final static String APPLICATION_DOCUMENT_STATUS = "applicationDocumentStatus"; 254 final static String VARIABLES = "variables"; 255 final static String DIRTY_FIELDS = "dirtyFields"; 256 } 257}