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