001: /*
002: * Copyright 2008 Outerthought bvba and Schaubroeck nv
003: *
004: * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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.outerj.daisy.repository.commonimpl.acl;
017:
018: import org.outerj.daisy.repository.acl.AccessDetails;
019: import org.outerj.daisy.repository.acl.AclActionType;
020: import org.outerj.daisy.repository.acl.AclDetailPermission;
021: import static org.outerj.daisy.repository.acl.AclActionType.*;
022: import static org.outerj.daisy.repository.acl.AclDetailPermission.*;
023: import org.outerx.daisy.x10.AccessDetailsDocument;
024:
025: import java.util.Set;
026: import java.util.Collections;
027: import java.util.HashSet;
028: import java.util.EnumMap;
029:
030: // To add a new property:
031: // - update the "copy constructor"
032: // - update the makeUnion method
033: // - update the XML Schema and the getXml and setFromXml methods
034: // - update the persistence code in LocalAclStrategy
035:
036: public class AccessDetailsImpl implements AccessDetails {
037: private Set<String> partNames;
038: private Set<String> fieldNames;
039: private EnumMap<AclDetailPermission, AclActionType> permissions = new EnumMap<AclDetailPermission, AclActionType>(
040: AclDetailPermission.class);
041: private AclImpl ownerAcl;
042: private boolean isAdded;
043:
044: public AccessDetailsImpl(AclImpl ownerAcl) {
045: this .ownerAcl = ownerAcl;
046: }
047:
048: public AccessDetailsImpl(AclImpl ownerAcl,
049: AclActionType initialAction) {
050: this .ownerAcl = ownerAcl;
051: for (AclDetailPermission permission : AclDetailPermission
052: .values()) {
053: permissions.put(permission, initialAction);
054: }
055: }
056:
057: /**
058: * Copy constructor.
059: */
060: public AccessDetailsImpl(AclImpl ownerAcl,
061: AccessDetails accessDetails) {
062: this .ownerAcl = ownerAcl;
063:
064: for (AclDetailPermission permission : AclDetailPermission
065: .values()) {
066: permissions.put(permission, accessDetails.get(permission));
067: }
068:
069: Set<String> accessibleFields = accessDetails
070: .getAccessibleFields();
071: if (!accessibleFields.isEmpty()) {
072: fieldNames = new HashSet<String>();
073: fieldNames.addAll(accessibleFields);
074: }
075:
076: Set<String> accessibleParts = accessDetails
077: .getAccessibleParts();
078: if (!accessibleParts.isEmpty()) {
079: partNames = new HashSet<String>();
080: partNames.addAll(accessibleParts);
081: }
082: }
083:
084: public AclImpl getOwner() {
085: return ownerAcl;
086: }
087:
088: public boolean isFullAccess() {
089: return isFullLiveAccess() && !liveOnly();
090: }
091:
092: public boolean isFullLiveAccess() {
093: for (AclDetailPermission permission : AclDetailPermission
094: .values()) {
095: if (permission != NON_LIVE && get(permission) != GRANT)
096: return false;
097: }
098: return true;
099: }
100:
101: public void set(AclDetailPermission permission, AclActionType action) {
102: checkReadOnly();
103: permissions.put(permission, action);
104:
105: if (permission == ALL_FIELDS && action != AclActionType.DENY)
106: fieldNames = null;
107:
108: if (permission == ALL_PARTS && action != AclActionType.DENY)
109: partNames = null;
110: }
111:
112: public AclActionType get(AclDetailPermission permission) {
113: if (!permissions.containsKey(permission))
114: return DO_NOTHING;
115: else
116: return permissions.get(permission);
117: }
118:
119: public boolean isGranted(AclDetailPermission permission) {
120: return get(permission) == GRANT;
121: }
122:
123: public boolean canAccessField(String fieldTypeName) {
124: return get(ALL_FIELDS) == GRANT
125: || (fieldNames != null && fieldNames
126: .contains(fieldTypeName));
127: }
128:
129: public boolean canAccessPart(String partTypeName) {
130: return get(ALL_PARTS) == GRANT
131: || (partNames != null && partNames
132: .contains(partTypeName));
133: }
134:
135: public Set<String> getAccessibleFields() {
136: return fieldNames == null ? Collections.<String> emptySet()
137: : Collections.unmodifiableSet(fieldNames);
138: }
139:
140: public void clearAccessibleFields() {
141: checkReadOnly();
142:
143: if (fieldNames != null)
144: fieldNames.clear();
145: }
146:
147: public Set<String> getAccessibleParts() {
148: return partNames == null ? Collections.<String> emptySet()
149: : Collections.unmodifiableSet(partNames);
150: }
151:
152: public void addAccessibleField(String fieldTypeName) {
153: checkReadOnly();
154:
155: if (get(ALL_FIELDS) != AclActionType.DENY)
156: throw new IllegalStateException(
157: "Accessible fields can only be specified if access to all fields is denied.");
158:
159: if (fieldNames == null)
160: fieldNames = new HashSet<String>();
161:
162: fieldNames.add(fieldTypeName);
163: }
164:
165: public void addAccessibleFields(Set<String> fieldTypeNames) {
166: checkReadOnly();
167:
168: if (get(ALL_FIELDS) != AclActionType.DENY)
169: throw new IllegalStateException(
170: "Accessible fields can only be specified if access to all fields is denied.");
171:
172: if (fieldNames == null)
173: fieldNames = new HashSet<String>();
174:
175: fieldNames.addAll(fieldTypeNames);
176: }
177:
178: public void addAccessiblePart(String partTypeName) {
179: checkReadOnly();
180:
181: if (get(ALL_PARTS) != AclActionType.DENY)
182: throw new IllegalStateException(
183: "Accessible parts can only be specified if access to all parts is denied.");
184:
185: if (partNames == null)
186: partNames = new HashSet<String>();
187:
188: partNames.add(partTypeName);
189: }
190:
191: public void addAccessibleParts(Set<String> partTypeNames) {
192: checkReadOnly();
193:
194: if (get(ALL_PARTS) != AclActionType.DENY)
195: throw new IllegalStateException(
196: "Accessible parts can only be specified if access to all parts is denied.");
197:
198: if (partNames == null)
199: partNames = new HashSet<String>();
200:
201: partNames.addAll(partTypeNames);
202: }
203:
204: public void clearAccessibleParts() {
205: checkReadOnly();
206:
207: if (partNames != null)
208: partNames.clear();
209: }
210:
211: public boolean liveOnly() {
212: return !permissions.containsKey(AclDetailPermission.NON_LIVE)
213: || permissions.get(AclDetailPermission.NON_LIVE) != AclActionType.GRANT;
214: }
215:
216: public void overwrite(AccessDetails accessDetails) {
217: checkReadOnly();
218:
219: for (AclDetailPermission permission : AclDetailPermission
220: .values()) {
221: AclActionType action = accessDetails.get(permission);
222: if (action != DO_NOTHING) {
223: set(permission, action);
224: }
225: }
226:
227: Set<String> accessibleFields = accessDetails
228: .getAccessibleFields();
229: if (!accessibleFields.isEmpty()) {
230: addAccessibleFields(accessibleFields);
231: }
232:
233: Set<String> accessibleParts = accessDetails
234: .getAccessibleParts();
235: if (!accessibleParts.isEmpty()) {
236: addAccessibleParts(accessibleParts);
237: }
238: }
239:
240: public void makeUnion(AccessDetails accessDetails) {
241: checkReadOnly();
242:
243: for (AclDetailPermission permission : AclDetailPermission
244: .values()) {
245: if (get(permission) == DENY
246: && accessDetails.get(permission) == GRANT) {
247: set(permission, GRANT);
248: }
249: }
250:
251: if (get(ALL_FIELDS) == AclActionType.DENY) {
252: Set<String> accessibleFields = accessDetails
253: .getAccessibleFields();
254: if (!accessibleFields.isEmpty())
255: addAccessibleFields(accessibleFields);
256: }
257:
258: if (get(ALL_PARTS) == AclActionType.DENY) {
259: Set<String> accessibleParts = accessDetails
260: .getAccessibleParts();
261: if (!accessibleParts.isEmpty())
262: addAccessibleParts(accessibleParts);
263: }
264: }
265:
266: public AccessDetailsDocument getXml() {
267: AccessDetailsDocument doc = AccessDetailsDocument.Factory
268: .newInstance();
269: AccessDetailsDocument.AccessDetails xml = doc
270: .addNewAccessDetails();
271:
272: for (AclDetailPermission permission : AclDetailPermission
273: .values()) {
274: AccessDetailsDocument.AccessDetails.Permission permissionXml = xml
275: .addNewPermission();
276: permissionXml.setType(permission.toString());
277: permissionXml.setAction(get(permission).toString());
278: }
279:
280: for (String field : getAccessibleFields()) {
281: xml.addNewAllowFieldAccess().setName(field);
282: }
283:
284: for (String part : getAccessibleParts()) {
285: xml.addNewAllowPartAccess().setName(part);
286: }
287:
288: return doc;
289: }
290:
291: public void setFromXml(
292: AccessDetailsDocument.AccessDetails detailsXml) {
293: checkReadOnly();
294:
295: for (AccessDetailsDocument.AccessDetails.Permission permissionXml : detailsXml
296: .getPermissionList()) {
297: AclDetailPermission permission = AclDetailPermission
298: .fromString(permissionXml.getType());
299: AclActionType action = AclActionType
300: .fromString(permissionXml.getAction());
301: set(permission, action);
302: }
303:
304: clearAccessibleFields();
305: for (AccessDetailsDocument.AccessDetails.AllowFieldAccess fieldXml : detailsXml
306: .getAllowFieldAccessList()) {
307: addAccessibleField(fieldXml.getName());
308: }
309:
310: clearAccessibleParts();
311: for (AccessDetailsDocument.AccessDetails.AllowPartAccess partXml : detailsXml
312: .getAllowPartAccessList()) {
313: addAccessiblePart(partXml.getName());
314: }
315: }
316:
317: private void checkReadOnly() {
318: if (ownerAcl != null && ownerAcl.isReadOnly())
319: throw new RuntimeException(AclImpl.READ_ONLY_MESSAGE);
320: }
321:
322: protected boolean isAdded() {
323: return isAdded;
324: }
325:
326: protected void setIsAdded(boolean isAdded) {
327: this.isAdded = isAdded;
328: }
329: }
|