001    /*
002     * Copyright 2011 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 1.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/ecl1.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.permission;
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.common.template.Template;
025    import org.w3c.dom.Element;
026    
027    import javax.xml.bind.annotation.XmlAccessType;
028    import javax.xml.bind.annotation.XmlAccessorType;
029    import javax.xml.bind.annotation.XmlAnyElement;
030    import javax.xml.bind.annotation.XmlElement;
031    import javax.xml.bind.annotation.XmlRootElement;
032    import javax.xml.bind.annotation.XmlType;
033    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
034    import java.io.Serializable;
035    import java.util.Collection;
036    import java.util.Collections;
037    import java.util.Map;
038    
039    /**
040     * An immutable representation of a {@link PermissionContract}.
041     *
042     * <p>To construct an instance of a Permission, use the {@link Permission.Builder} class.<p/>
043     *
044     * @see PermissionContract
045     */
046    @XmlRootElement(name = Permission.Constants.ROOT_ELEMENT_NAME)
047    @XmlAccessorType(XmlAccessType.NONE)
048    @XmlType(name = Permission.Constants.TYPE_NAME, propOrder = {
049                    Permission.Elements.ID,
050                    Permission.Elements.NAMESPACE_CODE,
051                    Permission.Elements.NAME,
052                    Permission.Elements.DESCRIPTION,
053                    Permission.Elements.TEMPLATE,
054            Permission.Elements.ACTIVE,
055            Permission.Elements.ATTRIBUTES,
056            CoreConstants.CommonElements.VERSION_NUMBER,
057            CoreConstants.CommonElements.OBJECT_ID,
058            CoreConstants.CommonElements.FUTURE_ELEMENTS
059    })
060    public final class Permission extends AbstractDataTransferObject implements PermissionContract{
061    
062            private static final long serialVersionUID = 1L;
063    
064        @XmlElement(name = Permission.Elements.ID, required = true)
065        private final String id;
066    
067        @XmlElement(name = Permission.Elements.NAMESPACE_CODE, required = true)
068        private final String namespaceCode;
069    
070        @XmlElement(name = Permission.Elements.NAME, required = true)
071        private final String name;
072    
073        @XmlElement(name = Permission.Elements.DESCRIPTION, required = false)
074        private final String description;
075    
076        @XmlElement(name = Permission.Elements.TEMPLATE, required = true)
077        private final Template template;
078    
079        @XmlElement(name = Permission.Elements.ATTRIBUTES, required = false)
080        @XmlJavaTypeAdapter(value = MapStringStringAdapter.class)
081        private final Map<String, String> attributes;
082    
083        @XmlElement(name = Permission.Elements.ACTIVE, required = false)
084        private boolean active;
085    
086        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
087        private final Long versionNumber;
088    
089        @XmlElement(name = CoreConstants.CommonElements.OBJECT_ID, required = false)
090        private final String objectId;
091    
092        @SuppressWarnings("unused")
093        @XmlAnyElement
094        private final Collection<Element> _futureElements = null;
095    
096        /**
097             *  A constructor to be used only by JAXB unmarshalling.
098             *
099             */
100        @SuppressWarnings("unused")
101            private Permission() {
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 Permission(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 org.kuali.rice.kim.api.permission.PermissionContract#getId()
132             */
133            @Override
134            public String getId() {
135                    return id;
136            }
137    
138            /**
139             * @see org.kuali.rice.kim.api.permission.PermissionContract#getNamespaceCode()
140             */
141            @Override
142            public String getNamespaceCode() {
143                    return namespaceCode;
144            }
145    
146            /**
147             * @see org.kuali.rice.kim.api.permission.PermissionContract#getName()
148             */
149            @Override
150            public String getName() {
151                    return name;
152            }
153    
154            /**
155             * @see org.kuali.rice.kim.api.permission.PermissionContract#getDescription()
156             */
157            @Override
158            public String getDescription() {
159                    return description;
160            }
161    
162            /**
163             * @see org.kuali.rice.kim.api.permission.PermissionContract#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 org.kuali.rice.kim.api.permission.PermissionContract#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 Permission enforcing the constraints of the {@link PermissionContract}.
205         */
206        public static final class Builder implements PermissionContract, 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 Permission 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 Permission from an existing {@link PermissionContract}.
231             */
232            public static Builder create(PermissionContract 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                    builder.setTemplate(Template.Builder.create(contract.getTemplate()));
244                }            
245    
246                return builder;
247            }
248    
249            @Override
250            public String getId() {
251                return id;
252            }
253    
254            public void setId(final String id) {
255                    this.id = id;
256            }
257            
258            @Override
259            public String getNamespaceCode() {
260                return namespaceCode;
261            }
262    
263            public void setNamespaceCode(final String namespaceCode) {
264                    if (StringUtils.isBlank(namespaceCode)) {
265                    throw new IllegalArgumentException("namespaceCode is blank");
266                }
267                    this.namespaceCode = namespaceCode;
268            }
269    
270            @Override
271            public String getName() {
272                return name;
273            }
274    
275            public void setName(final String name) {
276                    if (StringUtils.isBlank(name)) {
277                    throw new IllegalArgumentException("name is blank");
278                }
279                    this.name = name;
280            }
281    
282                    @Override
283                    public String getDescription() {
284                            return description;
285                    }
286                    
287                    public void setDescription(final String description) {
288                            this.description = description;
289                    }
290    
291                    @Override
292                    public Template.Builder getTemplate() {
293                            return template;
294                    }
295                    
296                    public void setTemplate(final Template.Builder template) {
297                            if (template == null) {
298                    throw new IllegalArgumentException("template is null");
299                }
300                            this.template = template;
301                    }
302                    
303                    @Override
304                    public boolean isActive() {
305                            return active;
306                    }
307                    
308                    public void setActive(final boolean active) {
309                this.active = active;
310            }
311    
312                    @Override
313                    public Long getVersionNumber() {
314                            return versionNumber;
315                    }
316    
317                    public void setVersionNumber(final Long versionNumber) {
318                            if (versionNumber == null || versionNumber <= 0) {
319                        throw new IllegalArgumentException("versionNumber is invalid");
320                    }
321                            this.versionNumber = versionNumber;
322                }
323                     
324                    @Override
325                    public String getObjectId() {
326                            return objectId;
327                    }
328    
329            public void setObjectId(final String objectId) {
330                this.objectId = objectId;
331            }
332    
333                    @Override
334                    public Map<String, String> getAttributes() {
335                            return attributes;
336                    }
337                    
338                    public void setAttributes(Map<String, String> attributes) {
339                this.attributes = Collections.unmodifiableMap(Maps.newHashMap(attributes));
340            }
341                    
342            @Override
343            public Permission build() {
344                return new Permission(this);
345            }
346        }
347        
348        /**
349         * Defines some internal constants used on this class.
350         */
351        static class Constants {
352            static final String ROOT_ELEMENT_NAME = "permission";
353            static final String TYPE_NAME = "PermissionType";
354        }
355    
356        /**
357         * A private class which exposes constants which define the XML element names to use
358         * when this object is marshalled to XML.
359         */
360        static class Elements {
361            static final String ID = "id";
362            static final String NAMESPACE_CODE = "namespaceCode";
363            static final String NAME = "name";
364            static final String DESCRIPTION = "description";
365            static final String TEMPLATE = "template";
366            static final String ATTRIBUTES = "attributes";
367            static final String ACTIVE = "active";
368        }
369    }