001    /**
002     * Copyright 2005-2013 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.extension;
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     * Immutable implementation of the {@link ExtensionDefinitionContract}.  Defines an extension to some component of
041     * Kuali Enterprise Workflow.
042     *
043     * @author Kuali Rice Team (rice.collab@kuali.org)
044     */
045    @XmlRootElement(name = ExtensionDefinition.Constants.ROOT_ELEMENT_NAME)
046    @XmlAccessorType(XmlAccessType.NONE)
047    @XmlType(name = ExtensionDefinition.Constants.TYPE_NAME, propOrder = {
048            ExtensionDefinition.Elements.ID,
049            ExtensionDefinition.Elements.NAME,
050            ExtensionDefinition.Elements.APPLICATION_ID,
051            ExtensionDefinition.Elements.LABEL,
052            ExtensionDefinition.Elements.DESCRIPTION,
053            ExtensionDefinition.Elements.TYPE,
054            ExtensionDefinition.Elements.RESOURCE_DESCRIPTOR,
055            ExtensionDefinition.Elements.CONFIGURATION,
056            CoreConstants.CommonElements.VERSION_NUMBER,
057            CoreConstants.CommonElements.FUTURE_ELEMENTS
058    })
059    public final class ExtensionDefinition extends AbstractDataTransferObject implements ExtensionDefinitionContract {
060    
061        private static final long serialVersionUID = 6234968409006917945L;
062        
063        @XmlElement(name = Elements.ID, required = false)
064        private final String id;
065    
066        @XmlElement(name = Elements.NAME, required = true)
067        private final String name;
068    
069        @XmlElement(name = Elements.APPLICATION_ID, required = false)
070        private final String applicationId;
071    
072        @XmlElement(name = Elements.LABEL, required = false)
073        private final String label;
074    
075        @XmlElement(name = Elements.DESCRIPTION, required = false)
076        private final String description;
077    
078        @XmlElement(name = Elements.TYPE, required = true)
079        private final String type;
080    
081        @XmlElement(name = Elements.RESOURCE_DESCRIPTOR, required = true)
082        private final String resourceDescriptor;
083    
084        @XmlElement(name = Elements.CONFIGURATION, required = false)
085        @XmlJavaTypeAdapter(MapStringStringAdapter.class)
086        private final Map<String, String> configuration;
087    
088        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
089        private final Long versionNumber;
090    
091        @SuppressWarnings("unused")
092        @XmlAnyElement
093        private final Collection<Element> _futureElements = null;
094    
095        /**
096         * Private constructor used only by JAXB.
097         */
098        @SuppressWarnings("unused")
099        private ExtensionDefinition() {
100            this.id = null;
101            this.name = null;
102            this.applicationId = null;
103            this.label = null;
104            this.description = null;
105            this.type = null;
106            this.resourceDescriptor = null;
107            this.configuration = null;
108            this.versionNumber = null;
109        }
110    
111        private ExtensionDefinition(Builder builder) {
112            this.id = builder.getId();
113            this.name = builder.getName();
114            this.applicationId = builder.getApplicationId();
115            this.label = builder.getLabel();
116            this.description = builder.getDescription();
117            this.type = builder.getType();
118            this.resourceDescriptor = builder.getResourceDescriptor();
119            if (builder.getConfiguration() == null) {
120                this.configuration = Collections.emptyMap();
121            } else {
122                this.configuration = Collections.unmodifiableMap(new HashMap<String, String>(builder.getConfiguration()));
123            }
124            this.versionNumber = builder.getVersionNumber();
125        }
126    
127        @Override
128        public String getId() {
129            return this.id;
130        }
131    
132        @Override
133        public String getName() {
134            return this.name;
135        }
136    
137        @Override
138        public String getApplicationId() {
139            return this.applicationId;
140        }
141    
142        @Override
143        public String getLabel() {
144            return this.label;
145        }
146    
147        @Override
148        public String getDescription() {
149            return this.description;
150        }
151    
152        @Override
153        public String getType() {
154            return this.type;
155        }
156    
157        @Override
158        public String getResourceDescriptor() {
159            return this.resourceDescriptor;
160        }
161    
162        @Override
163        public Map<String, String> getConfiguration() {
164            return this.configuration;
165        }
166    
167        @Override
168        public Long getVersionNumber() {
169            return this.versionNumber;
170        }
171    
172        /**
173         * A builder which can be used to construct {@link ExtensionDefinition} instances.  Enforces the constraints of the
174         * {@link ExtensionDefinitionContract}.
175         */
176        public final static class Builder implements Serializable, ModelBuilder, ExtensionDefinitionContract {
177    
178            private String id;
179            private String name;
180            private String applicationId;
181            private String label;
182            private String description;
183            private String type;
184            private String resourceDescriptor;
185            private Map<String, String> configuration;
186            private Long versionNumber;
187    
188            private Builder(String name, String type, String resourceDescriptor) {
189                setName(name);
190                setType(type);
191                setResourceDescriptor(resourceDescriptor);
192                setConfiguration(new HashMap<String, String>());
193            }
194    
195            public static Builder create(String name, String type, String resourceDescriptor) {
196                return new Builder(name, type, resourceDescriptor);
197            }
198    
199            public static Builder create(ExtensionDefinitionContract contract) {
200                if (contract == null) {
201                    throw new IllegalArgumentException("contract was null");
202                }
203                Builder builder = create(contract.getName(), contract.getType(), contract.getResourceDescriptor());
204                builder.setId(contract.getId());
205                builder.setApplicationId(contract.getApplicationId());
206                builder.setLabel(contract.getLabel());
207                builder.setDescription(contract.getDescription());
208                builder.setConfiguration(contract.getConfiguration());
209                builder.setVersionNumber(contract.getVersionNumber());
210                return builder;
211            }
212    
213            public ExtensionDefinition build() {
214                return new ExtensionDefinition(this);
215            }
216    
217            @Override
218            public String getId() {
219                return this.id;
220            }
221    
222            @Override
223            public String getName() {
224                return this.name;
225            }
226    
227            @Override
228            public String getApplicationId() {
229                return this.applicationId;
230            }
231    
232            @Override
233            public String getLabel() {
234                return this.label;
235            }
236    
237            @Override
238            public String getDescription() {
239                return this.description;
240            }
241    
242            @Override
243            public String getType() {
244                return this.type;
245            }
246    
247            @Override
248            public String getResourceDescriptor() {
249                return this.resourceDescriptor;
250            }
251    
252            @Override
253            public Map<String, String> getConfiguration() {
254                return this.configuration;
255            }
256    
257            @Override
258            public Long getVersionNumber() {
259                return this.versionNumber;
260            }
261    
262            public void setId(String id) {
263                this.id = id;
264            }
265    
266            public void setName(String name) {
267                if (StringUtils.isBlank(name)) {
268                    throw new IllegalArgumentException("name was null or blank");
269                }
270                this.name = name;
271            }
272    
273            public void setApplicationId(String applicationId) {
274                this.applicationId = applicationId;
275            }
276    
277            public void setLabel(String label) {
278                this.label = label;
279            }
280    
281            public void setDescription(String description) {
282                this.description = description;
283            }
284    
285            public void setType(String type) {
286                if (StringUtils.isBlank(type)) {
287                    throw new IllegalArgumentException("type was null or blank");
288                }
289    
290                this.type = type;
291            }
292    
293            public void setResourceDescriptor(String resourceDescriptor) {
294                if (StringUtils.isBlank(resourceDescriptor)) {
295                    throw new IllegalArgumentException("descriptor was null or blank");
296                }
297                this.resourceDescriptor = resourceDescriptor;
298            }
299    
300            public void setConfiguration(Map<String, String> configuration) {
301                this.configuration = configuration;
302            }
303    
304            public void setVersionNumber(Long versionNumber) {
305                this.versionNumber = versionNumber;
306            }
307    
308        }
309    
310        /**
311         * Defines some internal constants used on this class.
312         */
313        static class Constants {
314            final static String ROOT_ELEMENT_NAME = "extensionDefinition";
315            final static String TYPE_NAME = "ExtensionDefinitionType";
316        }
317    
318        /**
319         * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
320         */
321        static class Elements {
322            final static String ID = "id";
323            final static String NAME = "name";
324            final static String APPLICATION_ID = "applicationId";
325            final static String LABEL = "label";
326            final static String DESCRIPTION = "description";
327            final static String TYPE = "type";
328            final static String RESOURCE_DESCRIPTOR = "resourceDescriptor";
329            final static String CONFIGURATION = "configuration";
330        }
331        
332        public static class Cache {
333            public static final String NAME = KewApiConstants.Namespaces.KEW_NAMESPACE_2_0 + "/" + ExtensionDefinition.Constants.TYPE_NAME;
334        }
335    }