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