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.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 }