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.kim.api.responsibility;
017
018import com.google.common.collect.Maps;
019import org.apache.commons.lang.StringUtils;
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.MapStringStringAdapter;
024import org.kuali.rice.kim.api.KimConstants;
025import org.kuali.rice.kim.api.common.template.Template;
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.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})
061public 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}