001    /**
002     * Copyright 2005-2012 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.kim.api.responsibility;
017    
018    import com.google.common.collect.Maps;
019    import org.apache.commons.lang.StringUtils;
020    import org.kuali.rice.core.api.CoreConstants;
021    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
022    import org.kuali.rice.core.api.mo.ModelBuilder;
023    import org.kuali.rice.core.api.util.jaxb.MapStringStringAdapter;
024    import org.kuali.rice.kim.api.KimConstants;
025    import org.kuali.rice.kim.api.common.template.Template;
026    import org.w3c.dom.Element;
027    
028    import javax.xml.bind.annotation.XmlAccessType;
029    import javax.xml.bind.annotation.XmlAccessorType;
030    import javax.xml.bind.annotation.XmlAnyElement;
031    import javax.xml.bind.annotation.XmlElement;
032    import javax.xml.bind.annotation.XmlRootElement;
033    import javax.xml.bind.annotation.XmlType;
034    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
035    import java.io.Serializable;
036    import java.util.Collection;
037    import java.util.Collections;
038    import java.util.Map;
039    
040    /**
041     * An immutable representation of a {@link ResponsibilityContract}.
042     *
043     * <p>To construct an instance of a Permission, use the {@link org.kuali.rice.kim.api.responsibility.Responsibility.Builder} class.<p/>
044     *
045     * @see ResponsibilityContract
046     */
047    @XmlRootElement(name = Responsibility.Constants.ROOT_ELEMENT_NAME)
048    @XmlAccessorType(XmlAccessType.NONE)
049    @XmlType(name = Responsibility.Constants.TYPE_NAME, propOrder = {
050                    Responsibility.Elements.ID,
051                    Responsibility.Elements.NAMESPACE_CODE,
052                    Responsibility.Elements.NAME,
053                    Responsibility.Elements.DESCRIPTION,
054                    Responsibility.Elements.TEMPLATE,
055            Responsibility.Elements.ACTIVE,
056            Responsibility.Elements.ATTRIBUTES,
057            CoreConstants.CommonElements.VERSION_NUMBER,
058            CoreConstants.CommonElements.OBJECT_ID,
059            CoreConstants.CommonElements.FUTURE_ELEMENTS
060    })
061    public final class Responsibility extends AbstractDataTransferObject implements ResponsibilityContract {
062    
063            private static final long serialVersionUID = 1L;
064    
065        @XmlElement(name = Responsibility.Elements.ID, required = false)
066        private final String id;
067    
068        @XmlElement(name = Responsibility.Elements.NAMESPACE_CODE, required = true)
069        private final String namespaceCode;
070    
071        @XmlElement(name = Responsibility.Elements.NAME, required = true)
072        private final String name;
073    
074        @XmlElement(name = Responsibility.Elements.DESCRIPTION, required = false)
075        private final String description;
076    
077        @XmlElement(name = Responsibility.Elements.TEMPLATE, required = false)
078        private final Template template;
079    
080        @XmlElement(name = Responsibility.Elements.ATTRIBUTES, required = false)
081        @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
082        private final Map<String, String> attributes;
083    
084        @XmlElement(name = Responsibility.Elements.ACTIVE, required = false)
085        private boolean active;
086    
087        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
088        private final Long versionNumber;
089    
090        @XmlElement(name = CoreConstants.CommonElements.OBJECT_ID, required = false)
091        private final String objectId;
092    
093        @SuppressWarnings("unused")
094        @XmlAnyElement
095        private final Collection<Element> _futureElements = null;
096    
097        /**
098             *  A constructor to be used only by JAXB unmarshalling.
099             *
100             */
101            private Responsibility() {
102                    this.id = null;
103            this.namespaceCode = null;
104            this.name = null;
105            this.description = null;
106            this.template = null;
107            this.attributes = null;
108            this.active = false;
109            this.versionNumber = Long.valueOf(1L);
110            this.objectId = null;
111            }
112    
113        /**
114             * A constructor using the Builder.
115             *
116             * @param builder
117             */
118            private Responsibility(Builder builder) {
119                    this.id = builder.getId();
120            this.namespaceCode = builder.getNamespaceCode();
121            this.name = builder.getName();
122            this.description = builder.getDescription();
123            this.template = builder.getTemplate() != null ? builder.getTemplate().build() : null;
124            this.attributes = builder.getAttributes() != null ? builder.getAttributes() : Collections.<String, String>emptyMap();
125            this.active = builder.isActive();
126            this.versionNumber = builder.getVersionNumber();
127            this.objectId = builder.getObjectId();
128            }
129    
130            /**
131             * @see ResponsibilityContract#getId()
132             */
133            @Override
134            public String getId() {
135                    return id;
136            }
137    
138            /**
139             * @see ResponsibilityContract#getNamespaceCode()
140             */
141            @Override
142            public String getNamespaceCode() {
143                    return namespaceCode;
144            }
145    
146            /**
147             * @see ResponsibilityContract#getName()
148             */
149            @Override
150            public String getName() {
151                    return name;
152            }
153    
154            /**
155             * @see ResponsibilityContract#getDescription()
156             */
157            @Override
158            public String getDescription() {
159                    return description;
160            }
161    
162            /**
163             * @see ResponsibilityContract#getTemplate()
164             */
165            @Override
166            public Template getTemplate() {
167                    return template;
168            }
169    
170            /**
171             * @see org.kuali.rice.core.api.mo.common.active.Inactivatable#isActive()
172             */
173            @Override
174            public boolean isActive() {
175                    return active;
176            }
177    
178            /**
179             *
180             * @see ResponsibilityContract#getAttributes()
181             */
182            @Override
183            public Map<String, String> getAttributes() {
184                    return this.attributes;
185            }
186    
187            /**
188             * @see org.kuali.rice.core.api.mo.common.Versioned#getVersionNumber()
189             */
190            @Override
191            public Long getVersionNumber() {
192                    return versionNumber;
193            }
194    
195            /**
196             * @see org.kuali.rice.core.api.mo.common.GloballyUnique#getObjectId()
197             */
198            @Override
199            public String getObjectId() {
200                    return objectId;
201            }
202    
203        /**
204         * This builder constructs a Responsibility enforcing the constraints of the {@link ResponsibilityContract}.
205         */
206        public static final class Builder implements ResponsibilityContract, ModelBuilder, Serializable {
207            private String id;
208            private String namespaceCode;
209            private String name;
210            private String description;
211            private Template.Builder template;
212            private Map<String, String> attributes;
213            private Long versionNumber = 1L;
214            private String objectId;
215            private boolean active;
216    
217            private Builder(String namespaceCode, String name) {
218                setNamespaceCode(namespaceCode);
219                setName(name);
220            }
221    
222            /**
223             * Creates a Responsibility with the required fields.
224             */
225            public static Builder create(String namespaceCode, String name) {
226                return new Builder(namespaceCode, name);
227            }
228    
229            /**
230             * Creates a Responsibility from an existing {@link ResponsibilityContract}.
231             */
232            public static Builder create(ResponsibilityContract contract) {
233                Builder builder = new Builder(contract.getNamespaceCode(), contract.getName());
234                builder.setId(contract.getId());
235                builder.setDescription(contract.getDescription());
236                if (contract.getAttributes() != null) {
237                    builder.setAttributes(contract.getAttributes());
238                }
239                builder.setActive(contract.isActive());
240                builder.setVersionNumber(contract.getVersionNumber());
241                builder.setObjectId(contract.getObjectId());
242                if (contract.getTemplate() != null
243                        && contract.getTemplate().getName() != null
244                        && contract.getTemplate().getNamespaceCode() != null) {
245                    builder.setTemplate(Template.Builder.create(contract.getTemplate()));
246                }
247    
248                return builder;
249            }
250    
251            @Override
252            public String getId() {
253                return id;
254            }
255    
256            public void setId(final String id) {
257                    this.id = id;
258            }
259            
260            @Override
261            public String getNamespaceCode() {
262                return namespaceCode;
263            }
264    
265            public void setNamespaceCode(final String namespaceCode) {
266                    if (StringUtils.isBlank(namespaceCode)) {
267                    throw new IllegalArgumentException("namespaceCode is blank");
268                }
269                    this.namespaceCode = namespaceCode;
270            }
271    
272            @Override
273            public String getName() {
274                return name;
275            }
276    
277            public void setName(final String name) {
278                    if (StringUtils.isBlank(name)) {
279                    throw new IllegalArgumentException("name is blank");
280                }
281                    this.name = name;
282            }
283    
284                    @Override
285                    public String getDescription() {
286                            return description;
287                    }
288                    
289                    public void setDescription(final String description) {
290                            this.description = description;
291                    }
292    
293                    @Override
294                    public Template.Builder getTemplate() {
295                            return template;
296                    }
297                    
298                    public void setTemplate(final Template.Builder template) {
299                            if (template == null) {
300                    throw new IllegalArgumentException("template is null");
301                }
302                if (StringUtils.isNotBlank(template.getName())
303                        && StringUtils.isNotBlank(template.getNamespaceCode())) {
304                                this.template = template;
305                } else {
306                    this.template = null;
307                }
308    
309                    }
310                    
311                    @Override
312                    public boolean isActive() {
313                            return active;
314                    }
315                    
316                    public void setActive(final boolean active) {
317                this.active = active;
318            }
319    
320                    @Override
321                    public Long getVersionNumber() {
322                            return versionNumber;
323                    }
324    
325                    public void setVersionNumber(final Long versionNumber) {
326                            if (versionNumber != null && versionNumber <= 0) {
327                        throw new IllegalArgumentException("versionNumber is invalid");
328                    }
329                            this.versionNumber = versionNumber;
330                }
331                     
332                    @Override
333                    public String getObjectId() {
334                            return objectId;
335                    }
336    
337            public void setObjectId(final String objectId) {
338                this.objectId = objectId;
339            }
340    
341                    @Override
342                    public Map<String, String> getAttributes() {
343                            return attributes;
344                    }
345                    
346                    public void setAttributes(Map<String, String> attributes) {
347                this.attributes = Collections.unmodifiableMap(Maps.newHashMap(attributes));
348            }
349                    
350            @Override
351            public Responsibility build() {
352                return new Responsibility(this);
353            }
354        }
355        
356        /**
357         * Defines some internal constants used on this class.
358         */
359        static class Constants {
360            static final String ROOT_ELEMENT_NAME = "responsibility";
361            static final String TYPE_NAME = "ResponsibilityType";
362        }
363    
364        /**
365         * A private class which exposes constants which define the XML element names to use
366         * when this object is marshalled to XML.
367         */
368        static class Elements {
369            static final String ID = "id";
370            static final String NAMESPACE_CODE = "namespaceCode";
371            static final String NAME = "name";
372            static final String DESCRIPTION = "description";
373            static final String TEMPLATE = "template";
374            static final String ATTRIBUTES = "attributes";
375            static final String ACTIVE = "active";
376        }
377    
378        public static class Cache {
379            public static final String NAME = KimConstants.Namespaces.KIM_NAMESPACE_2_0 + "/" + Responsibility.Constants.TYPE_NAME;
380        }
381    }