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 }