001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.acl.basic;
017:
018: import org.springframework.util.Assert;
019: import org.springframework.util.ClassUtils;
020:
021: import java.lang.reflect.InvocationTargetException;
022: import java.lang.reflect.Method;
023:
024: /**
025: * Simple implementation of {@link AclObjectIdentity}.<P>Uses <code>String</code>s to store the identity of the
026: * domain object instance. Also offers a constructor that uses reflection to build the identity information.</p>
027: */
028: public class NamedEntityObjectIdentity implements AclObjectIdentity {
029: //~ Instance fields ================================================================================================
030:
031: private String classname;
032: private String id;
033:
034: //~ Constructors ===================================================================================================
035:
036: public NamedEntityObjectIdentity(String classname, String id) {
037: Assert.hasText(classname, "classname required");
038: Assert.hasText(id, "id required");
039: this .classname = classname;
040: this .id = id;
041: }
042:
043: /**
044: * Creates the <code>NamedEntityObjectIdentity</code> based on the passed
045: * object instance. The passed object must provide a <code>getId()</code>
046: * method, otherwise an exception will be thrown.
047: *
048: * @param object the domain object instance to create an identity for
049: *
050: * @throws IllegalAccessException
051: * @throws InvocationTargetException
052: * @throws IllegalArgumentException
053: */
054: public NamedEntityObjectIdentity(Object object)
055: throws IllegalAccessException, InvocationTargetException {
056: Assert.notNull(object, "object cannot be null");
057:
058: this .classname = (getPackageName(object.getClass().getName()) == null) ? ClassUtils
059: .getShortName(object.getClass())
060: : (getPackageName(object.getClass().getName()) + "." + ClassUtils
061: .getShortName(object.getClass()));
062:
063: Class clazz = object.getClass();
064:
065: try {
066: Method method = clazz.getMethod("getId", new Class[] {});
067: Object result = method.invoke(object, new Object[] {});
068: this .id = result.toString();
069: } catch (NoSuchMethodException nsme) {
070: throw new IllegalArgumentException(
071: "Object of class '"
072: + clazz
073: + "' does not provide the required getId() method: "
074: + object);
075: }
076: }
077:
078: //~ Methods ========================================================================================================
079:
080: /**
081: * Important so caching operates properly.<P>Considers an object of the same class equal if it has the same
082: * <code>classname</code> and <code>id</code> properties.</p>
083: *
084: * @param arg0 object to compare
085: *
086: * @return <code>true</code> if the presented object matches this object
087: */
088: public boolean equals(Object arg0) {
089: if (arg0 == null) {
090: return false;
091: }
092:
093: if (!(arg0 instanceof NamedEntityObjectIdentity)) {
094: return false;
095: }
096:
097: NamedEntityObjectIdentity other = (NamedEntityObjectIdentity) arg0;
098:
099: if (this .getId().equals(other.getId())
100: && this .getClassname().equals(other.getClassname())) {
101: return true;
102: }
103:
104: return false;
105: }
106:
107: /**
108: * Indicates the classname portion of the object identity.
109: *
110: * @return the classname (never <code>null</code>)
111: */
112: public String getClassname() {
113: return classname;
114: }
115:
116: /**
117: * Indicates the instance identity portion of the object identity.
118: *
119: * @return the instance identity (never <code>null</code>)
120: */
121: public String getId() {
122: return id;
123: }
124:
125: private String getPackageName(String className) {
126: Assert.hasLength(className, "class name must not be empty");
127:
128: int lastDotIndex = className.lastIndexOf(".");
129:
130: if (lastDotIndex == -1) {
131: return null;
132: }
133:
134: return className.substring(0, lastDotIndex);
135: }
136:
137: /**
138: * Important so caching operates properly.
139: *
140: * @return the hash of the classname and id
141: */
142: public int hashCode() {
143: StringBuffer sb = new StringBuffer();
144: sb.append(this .classname).append(this .id);
145:
146: return sb.toString().hashCode();
147: }
148:
149: public String toString() {
150: StringBuffer sb = new StringBuffer();
151: sb.append(this .getClass().getName()).append("[");
152: sb.append("Classname: ").append(this .classname);
153: sb.append("; Identity: ").append(this .id).append("]");
154:
155: return sb.toString();
156: }
157: }
|