diff --git a/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImpl.java b/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImpl.java
index 068d6030c8..7aef2cfec6 100644
--- a/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImpl.java
+++ b/core/src/main/java/org/acegisecurity/acl/basic/jdbc/JdbcDaoImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -138,336 +138,320 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
entry.setAclObjectIdentity(propertiesInformation.getAclObjectIdentity());
entry.setAclObjectParentIdentity(propertiesInformation
- .getAclObjectParentIdentity());
+ .getAclObjectParentIdentity());
- if (aclInformation == null) {
- // this is an inheritence marker instance only
- entry.setMask(0);
- entry.setRecipient(RECIPIENT_USED_FOR_INHERITENCE_MARKER);
- } else {
- // this is an individual ACL entry
- entry.setMask(aclInformation.getMask());
- entry.setRecipient(aclInformation.getRecipient());
+ if (aclInformation == null) {
+ // this is an inheritence marker instance only
+ entry.setMask(0);
+ entry.setRecipient(RECIPIENT_USED_FOR_INHERITENCE_MARKER);
+ } else {
+ // this is an individual ACL entry
+ entry.setMask(aclInformation.getMask());
+ entry.setRecipient(aclInformation.getRecipient());
+ }
+
+ return entry;
+ }
+
+ /**
+ * Returns the ACLs associated with the requested
+ * AclObjectIdentity.
+ *
+ *
+ * The {@link BasicAclEntry}s returned by this method will have
+ * String-based recipients. This will not be a problem if you
+ * are using the GrantedAuthorityEffectiveAclsResolver, which
+ * is the default configured against BasicAclProvider.
+ *
+ * This method will only return ACLs for requests where the
+ * AclObjectIdentity is of type {@link
+ * NamedEntityObjectIdentity}. Of course, you can subclass or replace this
+ * class and support your own custom AclObjectIdentity types.
+ *
null and must be an instance of
+ * NamedEntityObjectIdentity)
+ *
+ * @return the ACLs that apply (without any nulls inside the
+ * array), or null if not found or if an incompatible
+ * AclObjectIdentity was requested
+ */
+ public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
+ String aclObjectIdentityString;
+
+ try {
+ aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
+ } catch (IllegalArgumentException unsupported) {
+ return null; // pursuant to contract described in JavaDocs above
+ }
+
+ // Lookup the object's main properties from the RDBMS (guaranteed no nulls)
+ List objects = objectProperties.execute(aclObjectIdentityString);
+
+ if (objects.size() == 0) {
+ // this is an unknown object identity string
+ return null;
+ }
+
+ // Cast to an object properties holder (there should only be one record)
+ AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects.get(0);
+
+ // Lookup the object's ACLs from RDBMS (guaranteed no nulls)
+ List acls = aclsByObjectIdentity.execute(propertiesInformation
+ .getForeignKeyId());
+
+ if (acls.size() == 0) {
+ // return merely an inheritence marker (as we know about the object but it has no related ACLs)
+ return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation,
+ null)};
+ } else {
+ // return the individual ACL instances
+ AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls.toArray(new AclDetailsHolder[] {});
+ List toReturnAcls = new Vector();
+
+ for (int i = 0; i < aclHolders.length; i++) {
+ toReturnAcls.add(createBasicAclEntry(propertiesInformation,
+ aclHolders[i]));
}
- return entry;
+ return (BasicAclEntry[]) toReturnAcls.toArray(new BasicAclEntry[] {});
+ }
+ }
+
+ public MappingSqlQuery getAclsByObjectIdentity() {
+ return aclsByObjectIdentity;
+ }
+
+ public String getAclsByObjectIdentityQuery() {
+ return aclsByObjectIdentityQuery;
+ }
+
+ public String getObjectPropertiesQuery() {
+ return objectPropertiesQuery;
+ }
+
+ protected void initDao() throws ApplicationContextException {
+ initMappingSqlQueries();
+ }
+
+ /**
+ * Extension point to allow other MappingSqlQuery objects to be substituted
+ * in a subclass
+ */
+ protected void initMappingSqlQueries() {
+ setAclsByObjectIdentity(new AclsByObjectIdentityMapping(getDataSource()));
+ setObjectProperties(new ObjectPropertiesMapping(getDataSource()));
+ }
+
+ public void setAclsByObjectIdentity(
+ MappingSqlQuery aclsByObjectIdentityQuery) {
+ this.aclsByObjectIdentity = aclsByObjectIdentityQuery;
+ }
+
+ /**
+ * Allows the default query string used to retrieve ACLs based on object
+ * identity to be overriden, if default table or column names need to be
+ * changed. The default query is {@link
+ * #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying this query, ensure
+ * that all returned columns are mapped back to the same column names as
+ * in the default query.
+ *
+ * @param queryString The query string to set
+ */
+ public void setAclsByObjectIdentityQuery(String queryString) {
+ aclsByObjectIdentityQuery = queryString;
+ }
+
+ public void setObjectProperties(MappingSqlQuery objectPropertiesQuery) {
+ this.objectProperties = objectPropertiesQuery;
+ }
+
+ public void setObjectPropertiesQuery(String queryString) {
+ objectPropertiesQuery = queryString;
+ }
+
+ //~ Inner Classes ==========================================================
+
+ /**
+ * Used to hold details of a domain object instance's properties, or an
+ * individual ACL entry.
+ *
+ *
+ * Not all properties will be set. The actual properties set will depend on
+ * which MappingSqlQuery creates the object.
+ *
+ * Does not enforce nulls or empty Strings as
+ * this is performed by the MappingSqlQuery objects (or
+ * preferably the backend RDBMS via schema constraints).
+ *
AclObjectIdentity.
- *
- *
- * The {@link BasicAclEntry}s returned by this method will have
- * String-based recipients. This will not be a problem if
- * you are using the
- * GrantedAuthorityEffectiveAclsResolver, which is the
- * default configured against BasicAclProvider.
- *
- * This method will only return ACLs for requests where the
- * AclObjectIdentity is of type {@link
- * NamedEntityObjectIdentity}. Of course, you can subclass or replace
- * this class and support your own custom
- * AclObjectIdentity types.
- *
null and must be an instance of
- * NamedEntityObjectIdentity)
- *
- * @return the ACLs that apply (without any nulls inside
- * the array), or null if not found or if an
- * incompatible AclObjectIdentity was requested
+ * @param foreignKeyId used by the
+ * AclsByObjectIdentityMapping to locate the
+ * individual ACL entries
+ * @param aclObjectIdentity the object identity of the domain object
+ * instance
+ * @param aclObjectParentIdentity the object identity of the domain
+ * object instance's parent
+ * @param aclClass the class of which a new instance which should be
+ * created for each individual ACL entry (or an inheritence
+ * "holder" class if there are no ACL entries)
*/
- public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
- String aclObjectIdentityString;
+ public AclDetailsHolder(long foreignKeyId,
+ AclObjectIdentity aclObjectIdentity,
+ AclObjectIdentity aclObjectParentIdentity, Class aclClass) {
+ this.foreignKeyId = foreignKeyId;
+ this.aclObjectIdentity = aclObjectIdentity;
+ this.aclObjectParentIdentity = aclObjectParentIdentity;
+ this.aclClass = aclClass;
+ }
- try {
- aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
- } catch (IllegalArgumentException unsupported) {
- return null; // pursuant to contract described in JavaDocs above
- }
+ public Class getAclClass() {
+ return aclClass;
+ }
- // Lookup the object's main properties from the RDBMS (guaranteed no nulls)
- List objects = objectProperties.execute(aclObjectIdentityString);
+ public AclObjectIdentity getAclObjectIdentity() {
+ return aclObjectIdentity;
+ }
- if (objects.size() == 0) {
- // this is an unknown object identity string
+ public AclObjectIdentity getAclObjectParentIdentity() {
+ return aclObjectParentIdentity;
+ }
+
+ public long getForeignKeyId() {
+ return foreignKeyId;
+ }
+
+ public int getMask() {
+ return mask;
+ }
+
+ public Object getRecipient() {
+ return recipient;
+ }
+ }
+
+ /**
+ * Query object to look up individual ACL entries.
+ *
+ *
+ * Returns the generic AclDetailsHolder object.
+ *
+ * Guarantees to never return null (exceptions are thrown in
+ * the event of any issues).
+ *
+ * The executed SQL requires the following information be made available + * from the indicated placeholders: 1. RECIPIENT, 2. MASK. + *
+ */ + protected class AclsByObjectIdentityMapping extends MappingSqlQuery { + protected AclsByObjectIdentityMapping(DataSource ds) { + super(ds, aclsByObjectIdentityQuery); + declareParameter(new SqlParameter(Types.BIGINT)); + compile(); + } + + protected Object mapRow(ResultSet rs, int rownum) + throws SQLException { + String recipient = rs.getString(1); + int mask = rs.getInt(2); + Assert.hasText(recipient, "recipient required"); + + return new AclDetailsHolder(recipient, mask); + } + } + + /** + * Query object to look up properties for an object identity. + * + *
+ * Returns the generic AclDetailsHolder object.
+ *
+ * Guarantees to never return null (exceptions are thrown in
+ * the event of any issues).
+ *
+ * The executed SQL requires the following information be made available + * from the indicated placeholders: 1. ID, 2. OBJECT_IDENTITY, 3. + * ACL_CLASS and 4. PARENT_OBJECT_IDENTITY. + *
+ */ + protected class ObjectPropertiesMapping extends MappingSqlQuery { + protected ObjectPropertiesMapping(DataSource ds) { + super(ds, objectPropertiesQuery); + declareParameter(new SqlParameter(Types.VARCHAR)); + compile(); + } + + private AclObjectIdentity buildIdentity(String identity) { + if (identity == null) { + // Must be an empty parent, so return null return null; } - // Cast to an object properties holder (there should only be one record) - AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects - .get(0); + int delim = identity.lastIndexOf(":"); + String classname = identity.substring(0, delim); + String id = identity.substring(delim + 1); - // Lookup the object's ACLs from RDBMS (guaranteed no nulls) - List acls = aclsByObjectIdentity.execute(propertiesInformation - .getForeignKeyId()); + return new NamedEntityObjectIdentity(classname, id); + } - if (acls.size() == 0) { - // return merely an inheritence marker (as we know about the object but it has no related ACLs) - return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation, - null)}; - } else { - // return the individual ACL instances - AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls - .toArray(new AclDetailsHolder[] {}); - List toReturnAcls = new Vector(); + protected Object mapRow(ResultSet rs, int rownum) + throws SQLException { + long id = rs.getLong(1); // required + String objectIdentity = rs.getString(2); // required + String aclClass = rs.getString(3); // required + String parentObjectIdentity = rs.getString(4); // optional + Assert.hasText(objectIdentity, + "required DEF_OBJECT_PROPERTIES_QUERY value (objectIdentity) returned null or empty"); + Assert.hasText(aclClass, + "required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty"); - for (int i = 0; i < aclHolders.length; i++) { - toReturnAcls.add(createBasicAclEntry( - propertiesInformation, aclHolders[i])); - } + Class aclClazz; - return (BasicAclEntry[]) toReturnAcls.toArray(new BasicAclEntry[] {}); - } - } - - public MappingSqlQuery getAclsByObjectIdentity() { - return aclsByObjectIdentity; - } - - public String getAclsByObjectIdentityQuery() { - return aclsByObjectIdentityQuery; - } - - public String getObjectPropertiesQuery() { - return objectPropertiesQuery; - } - - protected void initDao() throws ApplicationContextException { - initMappingSqlQueries(); - } - - /** - * Extension point to allow other MappingSqlQuery objects to be - * substituted in a subclass - */ - protected void initMappingSqlQueries() { - setAclsByObjectIdentity(new AclsByObjectIdentityMapping( - getDataSource())); - setObjectProperties(new ObjectPropertiesMapping( - getDataSource())); - } - - public void setAclsByObjectIdentity( - MappingSqlQuery aclsByObjectIdentityQuery) { - this.aclsByObjectIdentity = aclsByObjectIdentityQuery; - } - - /** - * Allows the default query string used to retrieve ACLs based - * on object identity to be overriden, if default table or - * column names need to be changed. The default query is - * {@link #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying - * this query, ensure that all returned columns are mapped - * back to the same column names as in the default query. - * - * @param queryString The query string to set - */ - public void setAclsByObjectIdentityQuery(String queryString) { - aclsByObjectIdentityQuery = queryString; - } - - public void setObjectProperties( - MappingSqlQuery objectPropertiesQuery) { - this.objectProperties = objectPropertiesQuery; - } - - public void setObjectPropertiesQuery(String queryString) { - objectPropertiesQuery = queryString; - } - - //~ Inner Classes ========================================================== - - /** - * Used to hold details of a domain object instance's - * properties, or an individual ACL entry. - * - *
- * Not all properties will be set. The actual properties set
- * will depend on which MappingSqlQuery creates
- * the object.
- *
- * Does not enforce nulls or empty
- * Strings as this is performed by the
- * MappingSqlQuery objects (or preferably the
- * backend RDBMS via schema constraints).
- *
AclsByObjectIdentityMapping to
- * locate the individual ACL entries
- * @param aclObjectIdentity the object identity of the
- * domain object instance
- * @param aclObjectParentIdentity the object identity of
- * the domain object instance's parent
- * @param aclClass the class of which a new instance which
- * should be created for each individual ACL entry
- * (or an inheritence "holder" class if there are
- * no ACL entries)
- */
- public AclDetailsHolder(long foreignKeyId,
- AclObjectIdentity aclObjectIdentity,
- AclObjectIdentity aclObjectParentIdentity,
- Class aclClass) {
- this.foreignKeyId = foreignKeyId;
- this.aclObjectIdentity = aclObjectIdentity;
- this.aclObjectParentIdentity = aclObjectParentIdentity;
- this.aclClass = aclClass;
- }
-
- public Class getAclClass() {
- return aclClass;
- }
-
- public AclObjectIdentity getAclObjectIdentity() {
- return aclObjectIdentity;
- }
-
- public AclObjectIdentity getAclObjectParentIdentity() {
- return aclObjectParentIdentity;
- }
-
- public long getForeignKeyId() {
- return foreignKeyId;
- }
-
- public int getMask() {
- return mask;
- }
-
- public Object getRecipient() {
- return recipient;
- }
- }
-
- /**
- * Query object to look up individual ACL entries.
- *
- *
- * Returns the generic AclDetailsHolder object.
- *
- * Guarantees to never return null (exceptions are
- * thrown in the event of any issues).
- *
- * The executed SQL requires the following information be made - * available from the indicated placeholders: 1. RECIPIENT, 2. - * MASK. - *
- */ - protected class AclsByObjectIdentityMapping - extends MappingSqlQuery { - protected AclsByObjectIdentityMapping(DataSource ds) { - super(ds, aclsByObjectIdentityQuery); - declareParameter(new SqlParameter(Types.BIGINT)); - compile(); - } - - protected Object mapRow(ResultSet rs, int rownum) - throws SQLException { - String recipient = rs.getString(1); - int mask = rs.getInt(2); - Assert.hasText(recipient, "recipient required"); - - return new AclDetailsHolder(recipient, mask); - } - } - - /** - * Query object to look up properties for an object identity. - * - *
- * Returns the generic AclDetailsHolder object.
- *
- * Guarantees to never return null (exceptions are
- * thrown in the event of any issues).
- *
- * The executed SQL requires the following information be made - * available from the indicated placeholders: 1. ID, 2. - * OBJECT_IDENTITY, 3. ACL_CLASS and 4. - * PARENT_OBJECT_IDENTITY. - *
- */ - protected class ObjectPropertiesMapping extends MappingSqlQuery { - protected ObjectPropertiesMapping(DataSource ds) { - super(ds, objectPropertiesQuery); - declareParameter(new SqlParameter(Types.VARCHAR)); - compile(); - } - - private AclObjectIdentity buildIdentity(String identity) { - if (identity == null) { - // Must be an empty parent, so return null - return null; - } - - int delim = identity.lastIndexOf(":"); - String classname = identity.substring(0, delim); - String id = identity.substring(delim + 1); - - return new NamedEntityObjectIdentity(classname, id); - } - - protected Object mapRow(ResultSet rs, int rownum) - throws SQLException { - long id = rs.getLong(1); // required - String objectIdentity = rs.getString(2); // required - String aclClass = rs.getString(3); // required - String parentObjectIdentity = rs.getString(4); // optional - Assert.hasText(objectIdentity, - "required DEF_OBJECT_PROPERTIES_QUERY value (objectIdentity) returned null or empty"); - Assert.hasText(aclClass, - "required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty"); - - Class aclClazz; - - try { - aclClazz = this.getClass().getClassLoader() - .loadClass(aclClass); - } catch (ClassNotFoundException cnf) { - throw new IllegalArgumentException(cnf.getMessage()); - } - - return new AclDetailsHolder(id, - buildIdentity(objectIdentity), - buildIdentity(parentObjectIdentity), aclClazz); - } - } + try { + aclClazz = this.getClass().getClassLoader().loadClass(aclClass); + } catch (ClassNotFoundException cnf) { + throw new IllegalArgumentException(cnf.getMessage()); } + + return new AclDetailsHolder(id, buildIdentity(objectIdentity), + buildIdentity(parentObjectIdentity), aclClazz); + } + } +}