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.joda.time.DateTime; 020import org.kuali.rice.core.api.CoreConstants; 021import org.kuali.rice.core.api.mo.AbstractDataTransferObject; 022import org.kuali.rice.core.api.mo.ModelBuilder; 023import org.kuali.rice.core.api.util.jaxb.DateTimeAdapter; 024import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter; 025import org.kuali.rice.kew.api.util.UserTextFilterForXml; 026import org.w3c.dom.Element; 027 028import javax.xml.bind.annotation.XmlAccessType; 029import javax.xml.bind.annotation.XmlAccessorType; 030import javax.xml.bind.annotation.XmlAnyElement; 031import javax.xml.bind.annotation.XmlElement; 032import javax.xml.bind.annotation.XmlRootElement; 033import javax.xml.bind.annotation.XmlType; 034import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 035import java.io.Serializable; 036import java.util.Collection; 037import java.util.Collections; 038import java.util.HashMap; 039import java.util.Map; 040 041@XmlRootElement(name = Document.Constants.ROOT_ELEMENT_NAME) 042@XmlAccessorType(XmlAccessType.NONE) 043@XmlType(name = Document.Constants.TYPE_NAME, propOrder = { 044 Document.Elements.DOCUMENT_ID, 045 Document.Elements.STATUS, 046 Document.Elements.DATE_CREATED, 047 Document.Elements.DATE_LAST_MODIFIED, 048 Document.Elements.DATE_APPROVED, 049 Document.Elements.DATE_FINALIZED, 050 Document.Elements.TITLE, 051 Document.Elements.APPLICATION_DOCUMENT_ID, 052 Document.Elements.INITIATOR_PRINCIPAL_ID, 053 Document.Elements.ROUTED_BY_PRINCIPAL_ID, 054 Document.Elements.DOCUMENT_TYPE_NAME, 055 Document.Elements.DOCUMENT_TYPE_ID, 056 Document.Elements.DOCUMENT_HANDLER_URL, 057 Document.Elements.APPLICATION_DOCUMENT_STATUS, 058 Document.Elements.APPLICATION_DOCUMENT_STATUS_DATE, 059 Document.Elements.VARIABLES, 060 CoreConstants.CommonElements.FUTURE_ELEMENTS 061}) 062public final class Document extends AbstractDataTransferObject implements DocumentContract { 063 064 private static final long serialVersionUID = -6954090887747605047L; 065 066 @XmlElement(name = Elements.DOCUMENT_ID, required = true) 067 private final String documentId; 068 069 @XmlElement(name = Elements.STATUS, required = true) 070 private final String status; 071 072 @XmlElement(name = Elements.DATE_CREATED, required = true) 073 @XmlJavaTypeAdapter(DateTimeAdapter.class) 074 private final DateTime dateCreated; 075 076 @XmlElement(name = Elements.DATE_LAST_MODIFIED, required = true) 077 @XmlJavaTypeAdapter(DateTimeAdapter.class) 078 private final DateTime dateLastModified; 079 080 @XmlElement(name = Elements.DATE_APPROVED, required = false) 081 @XmlJavaTypeAdapter(DateTimeAdapter.class) 082 private final DateTime dateApproved; 083 084 @XmlElement(name = Elements.DATE_FINALIZED, required = false) 085 @XmlJavaTypeAdapter(DateTimeAdapter.class) 086 private final DateTime dateFinalized; 087 088 @XmlElement(name = Elements.TITLE, required = false) 089 private final String title; 090 091 @XmlElement(name = Elements.APPLICATION_DOCUMENT_ID, required = false) 092 private final String applicationDocumentId; 093 094 @XmlElement(name = Elements.INITIATOR_PRINCIPAL_ID, required = true) 095 private final String initiatorPrincipalId; 096 097 @XmlElement(name = Elements.ROUTED_BY_PRINCIPAL_ID, required = false) 098 private final String routedByPrincipalId; 099 100 @XmlElement(name = Elements.DOCUMENT_TYPE_NAME, required = true) 101 private final String documentTypeName; 102 103 @XmlElement(name = Elements.DOCUMENT_TYPE_ID, required = true) 104 private final String documentTypeId; 105 106 @XmlElement(name = Elements.DOCUMENT_HANDLER_URL, required = false) 107 private final String documentHandlerUrl; 108 109 @XmlElement(name = Elements.APPLICATION_DOCUMENT_STATUS, required = false) 110 private final String applicationDocumentStatus; 111 112 @XmlElement(name = Elements.APPLICATION_DOCUMENT_STATUS_DATE, required = false) 113 @XmlJavaTypeAdapter(DateTimeAdapter.class) 114 private final DateTime applicationDocumentStatusDate; 115 116 @XmlElement(name = Elements.VARIABLES, required = false) 117 @XmlJavaTypeAdapter(MapStringStringAdapter.class) 118 private final Map<String, String> variables; 119 120 @SuppressWarnings("unused") 121 @XmlAnyElement 122 private final Collection<Element> _futureElements = null; 123 124 /** 125 * Private constructor used only by JAXB. 126 */ 127 private Document() { 128 this.documentId = null; 129 this.status = null; 130 this.dateCreated = null; 131 this.dateLastModified = null; 132 this.dateApproved = null; 133 this.dateFinalized = null; 134 this.title = null; 135 this.applicationDocumentId = null; 136 this.initiatorPrincipalId = null; 137 this.routedByPrincipalId = null; 138 this.documentTypeName = null; 139 this.documentTypeId = null; 140 this.documentHandlerUrl = null; 141 this.applicationDocumentStatus = null; 142 this.applicationDocumentStatusDate = null; 143 this.variables = null; 144 } 145 146 private Document(Builder builder) { 147 this.documentId = builder.getDocumentId(); 148 this.status = builder.getStatus().getCode(); 149 this.dateCreated = builder.getDateCreated(); 150 this.dateLastModified = builder.getDateLastModified(); 151 this.dateApproved = builder.getDateApproved(); 152 this.dateFinalized = builder.getDateFinalized(); 153 this.title = builder.getTitle(); 154 this.applicationDocumentId = builder.getApplicationDocumentId(); 155 this.initiatorPrincipalId = builder.getInitiatorPrincipalId(); 156 this.routedByPrincipalId = builder.getRoutedByPrincipalId(); 157 this.documentTypeName = builder.getDocumentTypeName(); 158 this.documentTypeId = builder.getDocumentTypeId(); 159 this.documentHandlerUrl = builder.getDocumentHandlerUrl(); 160 this.applicationDocumentStatus = builder.getApplicationDocumentStatus(); 161 this.applicationDocumentStatusDate = builder.getApplicationDocumentStatusDate(); 162 this.variables = new HashMap<String, String>(builder.getVariables()); 163 } 164 165 @Override 166 public String getDocumentId() { 167 return this.documentId; 168 } 169 170 @Override 171 public DocumentStatus getStatus() { 172 if (StringUtils.isBlank(this.status)) { 173 throw new IllegalStateException("Status should not be null"); 174 } 175 return DocumentStatus.fromCode(this.status); 176 } 177 178 @Override 179 public DateTime getDateCreated() { 180 return this.dateCreated; 181 } 182 183 @Override 184 public DateTime getDateLastModified() { 185 return this.dateLastModified; 186 } 187 188 @Override 189 public DateTime getDateApproved() { 190 return this.dateApproved; 191 } 192 193 @Override 194 public DateTime getDateFinalized() { 195 return this.dateFinalized; 196 } 197 198 @Override 199 public String getTitle() { 200 return this.title; 201 } 202 203 @Override 204 public String getApplicationDocumentId() { 205 return this.applicationDocumentId; 206 } 207 208 @Override 209 public String getInitiatorPrincipalId() { 210 return this.initiatorPrincipalId; 211 } 212 213 @Override 214 public String getRoutedByPrincipalId() { 215 return this.routedByPrincipalId; 216 } 217 218 @Override 219 public String getDocumentTypeName() { 220 return this.documentTypeName; 221 } 222 223 @Override 224 public String getDocumentTypeId() { 225 return this.documentTypeId; 226 } 227 228 @Override 229 public String getDocumentHandlerUrl() { 230 return this.documentHandlerUrl; 231 } 232 233 @Override 234 public String getApplicationDocumentStatus() { 235 return this.applicationDocumentStatus; 236 } 237 238 @Override 239 public DateTime getApplicationDocumentStatusDate() { 240 return this.applicationDocumentStatusDate; 241 } 242 243 @Override 244 public Map<String, String> getVariables() { 245 return Collections.unmodifiableMap(this.variables); 246 } 247 248 /** 249 * A builder which can be used to construct {@link Document} instances. Enforces the constraints of the {@link DocumentContract}. 250 * 251 */ 252 public final static class Builder 253 implements Serializable, ModelBuilder, DocumentContract 254 { 255 256 private static final long serialVersionUID = -1584497024880308500L; 257 258 private String documentId; 259 private DocumentStatus status; 260 private DateTime dateCreated; 261 private DateTime dateLastModified; 262 private DateTime dateApproved; 263 private DateTime dateFinalized; 264 private String title; 265 private String applicationDocumentId; 266 private String initiatorPrincipalId; 267 private String routedByPrincipalId; 268 private String documentTypeName; 269 private String documentTypeId; 270 private String documentHandlerUrl; 271 private String applicationDocumentStatus; 272 private DateTime applicationDocumentStatusDate; 273 private Map<String, String> variables; 274 275 private Builder(String documentId, DocumentStatus status, DateTime dateCreated, String initiatorPrincipalId, String documentTypeName, String documentTypeId) { 276 setDocumentId(documentId); 277 setStatus(status); 278 setDateCreated(dateCreated); 279 setTitle(""); 280 setInitiatorPrincipalId(initiatorPrincipalId); 281 setDocumentTypeName(documentTypeName); 282 setDocumentTypeId(documentTypeId); 283 setVariables(new HashMap<String, String>()); 284 } 285 286 public static Builder create(String documentId, DocumentStatus status, DateTime dateCreated, String initiatorPrincipalId, String documentTypeName, String documentTypeId) { 287 return new Builder(documentId, status, dateCreated, initiatorPrincipalId, documentTypeName, documentTypeId); 288 } 289 290 public static Builder create(String documentId, String initiatorPrinicpalId, String documentTypeName, String documentTypeId) { 291 return new Builder(documentId, DocumentStatus.INITIATED, new DateTime(), initiatorPrinicpalId, documentTypeName, documentTypeId); 292 } 293 294 public static Builder create(DocumentContract contract) { 295 if (contract == null) { 296 throw new IllegalArgumentException("contract was null"); 297 } 298 Builder builder = create( 299 contract.getDocumentId(), 300 contract.getStatus(), 301 contract.getDateCreated(), 302 contract.getInitiatorPrincipalId(), 303 contract.getDocumentTypeName(), 304 contract.getDocumentTypeId() 305 ); 306 builder.setDateLastModified(contract.getDateLastModified()); 307 builder.setDateApproved(contract.getDateApproved()); 308 builder.setDateFinalized(contract.getDateFinalized()); 309 builder.setTitle(contract.getTitle()); 310 builder.setApplicationDocumentId(contract.getApplicationDocumentId()); 311 builder.setRoutedByPrincipalId(contract.getRoutedByPrincipalId()); 312 builder.setDocumentHandlerUrl(contract.getDocumentHandlerUrl()); 313 builder.setApplicationDocumentStatus(contract.getApplicationDocumentStatus()); 314 builder.setApplicationDocumentStatusDate(contract.getApplicationDocumentStatusDate()); 315 builder.setVariables(new HashMap<String, String>(contract.getVariables())); 316 return builder; 317 } 318 319 public Document build() { 320 return new Document(this); 321 } 322 323 @Override 324 public String getDocumentId() { 325 return this.documentId; 326 } 327 328 @Override 329 public DocumentStatus getStatus() { 330 return this.status; 331 } 332 333 @Override 334 public DateTime getDateCreated() { 335 return this.dateCreated; 336 } 337 338 @Override 339 public DateTime getDateLastModified() { 340 return this.dateLastModified; 341 } 342 343 @Override 344 public DateTime getDateApproved() { 345 return this.dateApproved; 346 } 347 348 @Override 349 public DateTime getDateFinalized() { 350 return this.dateFinalized; 351 } 352 353 @Override 354 public String getTitle() { 355 return this.title; 356 } 357 358 @Override 359 public String getApplicationDocumentId() { 360 return this.applicationDocumentId; 361 } 362 363 @Override 364 public String getInitiatorPrincipalId() { 365 return this.initiatorPrincipalId; 366 } 367 368 @Override 369 public String getRoutedByPrincipalId() { 370 return this.routedByPrincipalId; 371 } 372 373 @Override 374 public String getDocumentTypeName() { 375 return this.documentTypeName; 376 } 377 378 @Override 379 public String getDocumentTypeId() { 380 return this.documentTypeId; 381 } 382 383 @Override 384 public String getDocumentHandlerUrl() { 385 return this.documentHandlerUrl; 386 } 387 388 @Override 389 public String getApplicationDocumentStatus() { 390 return this.applicationDocumentStatus; 391 } 392 393 @Override 394 public DateTime getApplicationDocumentStatusDate() { 395 return this.applicationDocumentStatusDate; 396 } 397 398 @Override 399 public Map<String, String> getVariables() { 400 return this.variables; 401 } 402 403 public void setDocumentId(String documentId) { 404 if (StringUtils.isBlank(documentId)) { 405 throw new IllegalArgumentException("documentId was null or blank"); 406 } 407 this.documentId = documentId; 408 } 409 410 public void setStatus(DocumentStatus status) { 411 if (status == null) { 412 throw new IllegalArgumentException("status was null"); 413 } 414 this.status = status; 415 } 416 417 public void setDateCreated(DateTime dateCreated) { 418 if (dateCreated == null) { 419 throw new IllegalArgumentException("dateCreated was null"); 420 } 421 this.dateCreated = dateCreated; 422 } 423 424 public void setDateLastModified(DateTime dateLastModified) { 425 this.dateLastModified = dateLastModified; 426 } 427 428 public void setDateApproved(DateTime dateApproved) { 429 this.dateApproved = dateApproved; 430 } 431 432 public void setDateFinalized(DateTime dateFinalized) { 433 this.dateFinalized = dateFinalized; 434 } 435 436 public void setTitle(String title) { 437 if (title == null) { 438 title = ""; 439 } 440 this.title = UserTextFilterForXml.cleanInvalidXmlChars(title); 441 } 442 443 public void setApplicationDocumentId(String applicationDocumentId) { 444 this.applicationDocumentId = applicationDocumentId; 445 } 446 447 public void setInitiatorPrincipalId(String initiatorPrincipalId) { 448 if (StringUtils.isBlank(initiatorPrincipalId)) { 449 throw new IllegalArgumentException("initiatorPrincipalId was null or blank"); 450 } 451 this.initiatorPrincipalId = initiatorPrincipalId; 452 } 453 454 public void setRoutedByPrincipalId(String routedByPrincipalId) { 455 this.routedByPrincipalId = routedByPrincipalId; 456 } 457 458 public void setDocumentTypeName(String documentTypeName) { 459 if (StringUtils.isBlank(documentTypeName)) { 460 throw new IllegalArgumentException("documentTypeName was null or blank"); 461 } 462 this.documentTypeName = documentTypeName; 463 } 464 465 public void setDocumentTypeId(String documentTypeId) { 466 if (StringUtils.isBlank(documentTypeId)) { 467 throw new IllegalArgumentException("documentTypeId was null or blank"); 468 } 469 this.documentTypeId = documentTypeId; 470 } 471 472 public void setDocumentHandlerUrl(String documentHandlerUrl) { 473 this.documentHandlerUrl = documentHandlerUrl; 474 } 475 476 public void setApplicationDocumentStatus(String applicationDocumentStatus) { 477 this.applicationDocumentStatus = applicationDocumentStatus; 478 } 479 480 public void setApplicationDocumentStatusDate(DateTime applicationDocumentStatusDate) { 481 this.applicationDocumentStatusDate = applicationDocumentStatusDate; 482 } 483 484 public void setVariables(Map<String, String> variables) { 485 if (variables == null) { 486 variables = new HashMap<String, String>(); 487 } 488 this.variables = variables; 489 } 490 491 } 492 493 /** 494 * Defines some internal constants used on this class. 495 */ 496 static class Constants { 497 final static String ROOT_ELEMENT_NAME = "document"; 498 final static String TYPE_NAME = "DocumentType"; 499 } 500 501 /** 502 * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML. 503 */ 504 static class Elements { 505 final static String DOCUMENT_ID = "documentId"; 506 final static String STATUS = "status"; 507 final static String DATE_CREATED = "dateCreated"; 508 final static String DATE_LAST_MODIFIED = "dateLastModified"; 509 final static String DATE_APPROVED = "dateApproved"; 510 final static String DATE_FINALIZED = "dateFinalized"; 511 final static String TITLE = "title"; 512 final static String APPLICATION_DOCUMENT_ID = "applicationDocumentId"; 513 final static String INITIATOR_PRINCIPAL_ID = "initiatorPrincipalId"; 514 final static String ROUTED_BY_PRINCIPAL_ID = "routedByPrincipalId"; 515 final static String DOCUMENT_TYPE_NAME = "documentTypeName"; 516 final static String DOCUMENT_TYPE_ID = "documentTypeId"; 517 final static String DOCUMENT_HANDLER_URL = "documentHandlerUrl"; 518 final static String APPLICATION_DOCUMENT_STATUS = "applicationDocumentStatus"; 519 final static String APPLICATION_DOCUMENT_STATUS_DATE = "applicationDocumentStatusDate"; 520 final static String VARIABLES = "variables"; 521 } 522 523} 524