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