From af5917b6855ffe90a263723413fabc6192983567 Mon Sep 17 00:00:00 2001
From: Ben Alex
+ * BasicAclExtendedDao
implementations are responsible for interpreting a
+ * a given {@link AclObjectIdentity}.
+ * AclObjectIdentity
.
+ *
+ * @param aclObjectIdentity to delete, including any BasicAclEntry
s
+ */
+ public void delete(AclObjectIdentity aclObjectIdentity) throws DataAccessException;
+
+ /**
+ * Deletes the BasicAclEntry
associated with the specified
+ * AclObjectIdentity
and recipient Object
.
+ *
+ * @param aclObjectIdentity to delete
+ * @param recipient to delete
+ */
+ public void delete(AclObjectIdentity aclObjectIdentity, Object recipient) throws DataAccessException;
+
+ /**
+ * Changes the permission mask assigned to the BasicAclEntry
+ * associated with the specified
+ * AclObjectIdentity
and recipient Object
.
+ *
+ * @param aclObjectIdentity to locate the relevant BasicAclEntry
+ * @param recipient to locate the relevant BasicAclEntry
+ * @param newMask indicating the new permission
+ */
+ public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask) throws DataAccessException;
+}
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 1fe10e7a71..44298a6eb2 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
@@ -61,12 +61,12 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
public static final String RECIPIENT_USED_FOR_INHERITENCE_MARKER = "___INHERITENCE_MARKER_ONLY___";
public static final String DEF_ACLS_BY_OBJECT_IDENTITY_QUERY = "SELECT RECIPIENT, MASK FROM acl_permission WHERE acl_object_identity = ?";
public static final String DEF_OBJECT_PROPERTIES_QUERY = "SELECT ID, OBJECT_IDENTITY, ACL_CLASS, PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY FROM acl_object_identity LEFT OUTER JOIN acl_object_identity as PARENT ON acl_object_identity.parent_object=parent.id WHERE parent.id=acl_object_identity.parent_object and object_identity = ?";
- private static final Log logger = LogFactory.getLog(JdbcDaoSupport.class);
+ private static final Log logger = LogFactory.getLog(JdbcDaoImpl.class);
//~ Instance fields ========================================================
- private MappingSqlQuery aclsByObjectIdentity;
- private MappingSqlQuery objectProperties;
+ protected MappingSqlQuery aclsByObjectIdentity;
+ protected MappingSqlQuery objectProperties;
private String aclsByObjectIdentityQuery;
private String objectPropertiesQuery;
@@ -375,7 +375,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
* preferably the backend RDBMS via schema constraints).
*
+ * Extension of the base {@link JdbcDaoImpl}, which implements {@link + * BasicAclExtendedDao}. + *
+ * + *+ * A default database structure is assumed. This may be overridden by setting + * the default query strings to use. + *
+ * + *
+ * This implementation works with String
based recipients and
+ * {@link net.sf.acegisecurity.acl.basic.NamedEntityObjectIdentity} only. The
+ * latter can be changed by overriding {@link
+ * #convertAclObjectIdentityToString(AclObjectIdentity)}.
+ *
AclObjectIdentity
to a
+ * String
that can be located in the RDBMS.
+ *
+ * @param aclObjectIdentity to locate
+ *
+ * @return the object identity as a String
+ *
+ * @throws IllegalArgumentException DOCUMENT ME!
+ */
+ protected String convertAclObjectIdentityToString(
+ AclObjectIdentity aclObjectIdentity) {
+ // Ensure we can process this type of AclObjectIdentity
+ if (!(aclObjectIdentity instanceof NamedEntityObjectIdentity)) {
+ throw new IllegalArgumentException(
+ "Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: "
+ + aclObjectIdentity + ")");
+ }
+
+ NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity;
+
+ // Compose the String we expect to find in the RDBMS
+ return neoi.getClassname() + ":" + neoi.getId();
+ }
+
+ protected void initDao() throws ApplicationContextException {
+ super.initDao();
+ lookupPermissionIdMapping = new LookupPermissionIdMapping(getDataSource());
+ aclPermissionInsert = new AclPermissionInsert(getDataSource());
+ aclObjectIdentityInsert = new AclObjectIdentityInsert(getDataSource());
+ aclPermissionDelete = new AclPermissionDelete(getDataSource());
+ aclObjectIdentityDelete = new AclObjectIdentityDelete(getDataSource());
+ aclPermissionUpdate = new AclPermissionUpdate(getDataSource());
+ }
+
+ /**
+ * Convenience method that creates an acl_object_identity record if
+ * required.
+ *
+ * @param basicAclEntry containing the AclObjectIdentity
to
+ * create
+ *
+ * @throws DataAccessException
+ */
+ private void createAclObjectIdentityIfRequired(BasicAclEntry basicAclEntry)
+ throws DataAccessException {
+ String aclObjectIdentityString = convertAclObjectIdentityToString(basicAclEntry
+ .getAclObjectIdentity());
+
+ // Lookup the object's main properties from the RDBMS (guaranteed no nulls)
+ List objects = objectProperties.execute(aclObjectIdentityString);
+
+ if (objects.size() == 0) {
+ if (basicAclEntry.getAclObjectParentIdentity() != null) {
+ AclDetailsHolder parentDetails = lookupAclDetailsHolder(basicAclEntry
+ .getAclObjectParentIdentity());
+
+ // Must create the acl_object_identity record
+ aclObjectIdentityInsert.insert(aclObjectIdentityString,
+ new Integer(parentDetails.getForeignKeyId()),
+ basicAclEntry.getClass().getName());
+ } else {
+ // Must create the acl_object_identity record
+ aclObjectIdentityInsert.insert(aclObjectIdentityString, null,
+ basicAclEntry.getClass().getName());
+ }
+ }
+ }
+
+ /**
+ * Convenience method that obtains a given acl_object_identity record.
+ *
+ * @param aclObjectIdentity to lookup
+ *
+ * @return details of the record
+ *
+ * @throws DataRetrievalFailureException if record could not be found
+ */
+ private AclDetailsHolder lookupAclDetailsHolder(
+ AclObjectIdentity aclObjectIdentity)
+ throws DataRetrievalFailureException {
+ String aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
+
+ // Lookup the object's main properties from the RDBMS (guaranteed no nulls)
+ List objects = objectProperties.execute(aclObjectIdentityString);
+
+ if (objects.size() == 0) {
+ throw new DataRetrievalFailureException(
+ "aclObjectIdentity not found: " + aclObjectIdentityString);
+ }
+
+ // Should only be one record
+ return (AclDetailsHolder) objects.get(0);
+ }
+
+ /**
+ * Convenience method to lookup the acl_permission applying to a given
+ * acl_object_identity.id and acl_permission.recipient.
+ *
+ * @param aclObjectIdentityId to locate
+ * @param recipient to locate
+ *
+ * @return the acl_permission.id of the record, or -1 if not found
+ *
+ * @throws DataAccessException DOCUMENT ME!
+ */
+ private int lookupPermissionId(int aclObjectIdentityId, Object recipient)
+ throws DataAccessException {
+ List list = lookupPermissionIdMapping.execute(new Object[] {new Integer(
+ aclObjectIdentityId), recipient});
+
+ if (list.size() == 0) {
+ return -1;
+ }
+
+ return ((Integer) list.get(0)).intValue();
+ }
+
+ //~ Inner Classes ==========================================================
+
+ protected class AclObjectIdentityDelete extends SqlUpdate {
+ protected AclObjectIdentityDelete(DataSource ds) {
+ super(ds, aclObjectIdentityDeleteStatement);
+ declareParameter(new SqlParameter(Types.INTEGER));
+ compile();
+ }
+
+ protected void delete(Integer aclObjectIdentity)
+ throws DataAccessException {
+ super.update(aclObjectIdentity.intValue());
+ }
+ }
+
+ protected class AclObjectIdentityInsert extends SqlUpdate {
+ protected AclObjectIdentityInsert(DataSource ds) {
+ super(ds, aclObjectIdentityInsertStatement);
+ declareParameter(new SqlParameter(Types.INTEGER));
+ declareParameter(new SqlParameter(Types.VARCHAR));
+ declareParameter(new SqlParameter(Types.INTEGER));
+ declareParameter(new SqlParameter(Types.VARCHAR));
+ compile();
+ }
+
+ protected void insert(String objectIdentity,
+ Integer parentAclObjectIdentity, String aclClass)
+ throws DataAccessException {
+ Object[] objs = new Object[] {null, objectIdentity, parentAclObjectIdentity, aclClass};
+ super.update(objs);
+ }
+ }
+
+ protected class AclPermissionDelete extends SqlUpdate {
+ protected AclPermissionDelete(DataSource ds) {
+ super(ds, aclPermissionDeleteStatement);
+ declareParameter(new SqlParameter(Types.INTEGER));
+ declareParameter(new SqlParameter(Types.VARCHAR));
+ compile();
+ }
+
+ protected void delete(Integer aclObjectIdentity, String recipient)
+ throws DataAccessException {
+ super.update(new Object[] {aclObjectIdentity, recipient});
+ }
+ }
+
+ protected class AclPermissionInsert extends SqlUpdate {
+ protected AclPermissionInsert(DataSource ds) {
+ super(ds, aclPermissionInsertStatement);
+ declareParameter(new SqlParameter(Types.INTEGER));
+ declareParameter(new SqlParameter(Types.INTEGER));
+ declareParameter(new SqlParameter(Types.VARCHAR));
+ declareParameter(new SqlParameter(Types.INTEGER));
+ compile();
+ }
+
+ protected void insert(Integer aclObjectIdentity, String recipient,
+ Integer mask) throws DataAccessException {
+ Object[] objs = new Object[] {null, aclObjectIdentity, recipient, mask};
+ super.update(objs);
+ }
+ }
+
+ protected class AclPermissionUpdate extends SqlUpdate {
+ protected AclPermissionUpdate(DataSource ds) {
+ super(ds, aclPermissionUpdateStatement);
+ declareParameter(new SqlParameter(Types.INTEGER));
+ declareParameter(new SqlParameter(Types.INTEGER));
+ compile();
+ }
+
+ protected void update(Integer aclPermissionId, Integer newMask)
+ throws DataAccessException {
+ super.update(aclPermissionId.intValue(), newMask.intValue());
+ }
+ }
+
+ protected class LookupPermissionIdMapping extends MappingSqlQuery {
+ protected LookupPermissionIdMapping(DataSource ds) {
+ super(ds, lookupPermissionIdQuery);
+ declareParameter(new SqlParameter(Types.INTEGER));
+ declareParameter(new SqlParameter(Types.VARCHAR));
+ compile();
+ }
+
+ protected Object mapRow(ResultSet rs, int rownum)
+ throws SQLException {
+ return new Integer(rs.getInt(1));
+ }
+ }
+}