All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.acegisecurity.acl.basic.jdbc.JdbcExtendedDaoImpl Maven / Gradle / Ivy

There is a newer version: 1.0.7
Show newest version
/* 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.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.acegisecurity.acl.basic.jdbc;

import org.acegisecurity.acl.basic.AclObjectIdentity;
import org.acegisecurity.acl.basic.BasicAclEntry;
import org.acegisecurity.acl.basic.BasicAclEntryCache;
import org.acegisecurity.acl.basic.BasicAclExtendedDao;
import org.acegisecurity.acl.basic.cache.NullAclEntryCache;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.context.ApplicationContextException;

import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DataRetrievalFailureException;

import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.jdbc.object.SqlUpdate;

import org.springframework.util.Assert;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import java.util.Iterator;
import java.util.List;

import javax.sql.DataSource;


/**
 * 

* 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. *

* *

* If you are using a cache with BasicAclProvider, you should * specify that cache via {@link #setBasicAclEntryCache(BasicAclEntryCache)}. * This will cause cache evictions (removals) to take place whenever a DAO * mutator method is called. *

* *

* This implementation works with String based recipients and * {@link org.acegisecurity.acl.basic.NamedEntityObjectIdentity} only. The * latter can be changed by overriding {@link * #convertAclObjectIdentityToString(AclObjectIdentity)}. *

* * @author Ben Alex * @version $Id: JdbcExtendedDaoImpl.java,v 1.9 2006/01/27 04:42:39 benalex Exp $ */ public class JdbcExtendedDaoImpl extends JdbcDaoImpl implements BasicAclExtendedDao { //~ Static fields/initializers ============================================= private static final Log logger = LogFactory.getLog(JdbcExtendedDaoImpl.class); public static final String DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT = "DELETE FROM acl_object_identity WHERE id = ?"; public static final String DEF_ACL_OBJECT_IDENTITY_INSERT_STATEMENT = "INSERT INTO acl_object_identity (object_identity, parent_object, acl_class) VALUES (?, ?, ?)"; public static final String DEF_ACL_PERMISSION_DELETE_STATEMENT = "DELETE FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?"; public static final String DEF_ACL_PERMISSION_INSERT_STATEMENT = "INSERT INTO acl_permission (acl_object_identity, recipient, mask) VALUES (?, ?, ?)"; public static final String DEF_ACL_PERMISSION_UPDATE_STATEMENT = "UPDATE acl_permission SET mask = ? WHERE id = ?"; public static final String DEF_LOOKUP_PERMISSION_ID_QUERY = "SELECT id FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?"; //~ Instance fields ======================================================== private AclObjectIdentityDelete aclObjectIdentityDelete; private AclObjectIdentityInsert aclObjectIdentityInsert; private AclPermissionDelete aclPermissionDelete; private AclPermissionInsert aclPermissionInsert; private AclPermissionUpdate aclPermissionUpdate; private BasicAclEntryCache basicAclEntryCache = new NullAclEntryCache(); private MappingSqlQuery lookupPermissionIdMapping; private String aclObjectIdentityDeleteStatement; private String aclObjectIdentityInsertStatement; private String aclPermissionDeleteStatement; private String aclPermissionInsertStatement; private String aclPermissionUpdateStatement; private String lookupPermissionIdQuery; //~ Constructors =========================================================== public JdbcExtendedDaoImpl() { aclObjectIdentityDeleteStatement = DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT; aclObjectIdentityInsertStatement = DEF_ACL_OBJECT_IDENTITY_INSERT_STATEMENT; aclPermissionDeleteStatement = DEF_ACL_PERMISSION_DELETE_STATEMENT; aclPermissionInsertStatement = DEF_ACL_PERMISSION_INSERT_STATEMENT; aclPermissionUpdateStatement = DEF_ACL_PERMISSION_UPDATE_STATEMENT; lookupPermissionIdQuery = DEF_LOOKUP_PERMISSION_ID_QUERY; } //~ Methods ================================================================ public void changeMask(AclObjectIdentity aclObjectIdentity, Object recipient, Integer newMask) throws DataAccessException { basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity); // Retrieve acl_object_identity record details AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity); // Retrieve applicable acl_permission.id long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), recipient.toString()); if (permissionId == -1) { throw new DataRetrievalFailureException( "Could not locate existing acl_permission for aclObjectIdentity: " + aclObjectIdentity + ", recipient: " + recipient.toString()); } // Change permission aclPermissionUpdate.update(new Long(permissionId), newMask); } public void create(BasicAclEntry basicAclEntry) throws DataAccessException { // Create acl_object_identity record if required createAclObjectIdentityIfRequired(basicAclEntry); // Only continue if a recipient is specifed (null recipient indicates // just wanted to ensure the acl_object_identity was created) if (basicAclEntry.getRecipient() == null) { return; } // Retrieve acl_object_identity record details AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(basicAclEntry .getAclObjectIdentity()); // Ensure there isn't an existing record for this recipient long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(), basicAclEntry.getRecipient()); if (permissionId != -1) { throw new DataIntegrityViolationException("Recipient '" + basicAclEntry.getRecipient() + "' already exists for aclObjectIdentity ID " + aclDetailsHolder.getForeignKeyId() + " (permission ID " + ")"); } // Create acl_permission aclPermissionInsert.insert(new Long(aclDetailsHolder.getForeignKeyId()), basicAclEntry.getRecipient().toString(), new Integer(basicAclEntry.getMask())); } /** * 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 { basicAclEntryCache.removeEntriesFromCache(basicAclEntry .getAclObjectIdentity()); 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 Long(parentDetails.getForeignKeyId()), basicAclEntry.getClass().getName()); } else { // Must create the acl_object_identity record aclObjectIdentityInsert.insert(aclObjectIdentityString, null, basicAclEntry.getClass().getName()); } } } public void delete(AclObjectIdentity aclObjectIdentity) throws DataAccessException { basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity); // Retrieve acl_object_identity record details AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity); // Retrieve all acl_permissions applying to this acl_object_identity Iterator acls = aclsByObjectIdentity.execute(aclDetailsHolder .getForeignKeyId()).iterator(); // Delete all existing acl_permissions applying to this acl_object_identity while (acls.hasNext()) { AclDetailsHolder permission = (AclDetailsHolder) acls.next(); delete(aclObjectIdentity, permission.getRecipient()); } // Delete acl_object_identity aclObjectIdentityDelete.delete(new Long( aclDetailsHolder.getForeignKeyId())); } public void delete(AclObjectIdentity aclObjectIdentity, Object recipient) throws DataAccessException { basicAclEntryCache.removeEntriesFromCache(aclObjectIdentity); // Retrieve acl_object_identity record details AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity); // Delete acl_permission aclPermissionDelete.delete(new Long(aclDetailsHolder.getForeignKeyId()), recipient.toString()); } public AclObjectIdentityDelete getAclObjectIdentityDelete() { return aclObjectIdentityDelete; } public String getAclObjectIdentityDeleteStatement() { return aclObjectIdentityDeleteStatement; } public AclObjectIdentityInsert getAclObjectIdentityInsert() { return aclObjectIdentityInsert; } public String getAclObjectIdentityInsertStatement() { return aclObjectIdentityInsertStatement; } public AclPermissionDelete getAclPermissionDelete() { return aclPermissionDelete; } public String getAclPermissionDeleteStatement() { return aclPermissionDeleteStatement; } public AclPermissionInsert getAclPermissionInsert() { return aclPermissionInsert; } public String getAclPermissionInsertStatement() { return aclPermissionInsertStatement; } public AclPermissionUpdate getAclPermissionUpdate() { return aclPermissionUpdate; } public String getAclPermissionUpdateStatement() { return aclPermissionUpdateStatement; } public BasicAclEntryCache getBasicAclEntryCache() { return basicAclEntryCache; } public MappingSqlQuery getLookupPermissionIdMapping() { return lookupPermissionIdMapping; } public String getLookupPermissionIdQuery() { return lookupPermissionIdQuery; } 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 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 long lookupPermissionId(long aclObjectIdentityId, Object recipient) throws DataAccessException { List list = lookupPermissionIdMapping.execute(new Object[] {new Long( aclObjectIdentityId), recipient}); if (list.size() == 0) { return -1; } return ((Long) list.get(0)).longValue(); } public void setAclObjectIdentityDelete( AclObjectIdentityDelete aclObjectIdentityDelete) { this.aclObjectIdentityDelete = aclObjectIdentityDelete; } public void setAclObjectIdentityDeleteStatement( String aclObjectIdentityDeleteStatement) { this.aclObjectIdentityDeleteStatement = aclObjectIdentityDeleteStatement; } public void setAclObjectIdentityInsert( AclObjectIdentityInsert aclObjectIdentityInsert) { this.aclObjectIdentityInsert = aclObjectIdentityInsert; } public void setAclObjectIdentityInsertStatement( String aclObjectIdentityInsertStatement) { this.aclObjectIdentityInsertStatement = aclObjectIdentityInsertStatement; } public void setAclPermissionDelete(AclPermissionDelete aclPermissionDelete) { this.aclPermissionDelete = aclPermissionDelete; } public void setAclPermissionDeleteStatement( String aclPermissionDeleteStatement) { this.aclPermissionDeleteStatement = aclPermissionDeleteStatement; } public void setAclPermissionInsert(AclPermissionInsert aclPermissionInsert) { this.aclPermissionInsert = aclPermissionInsert; } public void setAclPermissionInsertStatement( String aclPermissionInsertStatement) { this.aclPermissionInsertStatement = aclPermissionInsertStatement; } public void setAclPermissionUpdate(AclPermissionUpdate aclPermissionUpdate) { this.aclPermissionUpdate = aclPermissionUpdate; } public void setAclPermissionUpdateStatement( String aclPermissionUpdateStatement) { this.aclPermissionUpdateStatement = aclPermissionUpdateStatement; } public void setBasicAclEntryCache(BasicAclEntryCache basicAclEntryCache) { Assert.notNull(basicAclEntryCache, "Cache cannot be set to null"); this.basicAclEntryCache = basicAclEntryCache; } public void setLookupPermissionIdMapping( MappingSqlQuery lookupPermissionIdMapping) { this.lookupPermissionIdMapping = lookupPermissionIdMapping; } public void setLookupPermissionIdQuery(String lookupPermissionIdQuery) { this.lookupPermissionIdQuery = lookupPermissionIdQuery; } //~ Inner Classes ========================================================== protected class AclObjectIdentityDelete extends SqlUpdate { protected AclObjectIdentityDelete(DataSource ds) { super(ds, aclObjectIdentityDeleteStatement); declareParameter(new SqlParameter(Types.BIGINT)); compile(); } protected void delete(Long aclObjectIdentity) throws DataAccessException { super.update(aclObjectIdentity.intValue()); } } protected class AclObjectIdentityInsert extends SqlUpdate { protected AclObjectIdentityInsert(DataSource ds) { super(ds, aclObjectIdentityInsertStatement); declareParameter(new SqlParameter(Types.VARCHAR)); declareParameter(new SqlParameter(Types.BIGINT)); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); } protected void insert(String objectIdentity, Long parentAclObjectIdentity, String aclClass) throws DataAccessException { Object[] objs = new Object[] {objectIdentity, parentAclObjectIdentity, aclClass}; super.update(objs); } } protected class AclPermissionDelete extends SqlUpdate { protected AclPermissionDelete(DataSource ds) { super(ds, aclPermissionDeleteStatement); declareParameter(new SqlParameter(Types.BIGINT)); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); } protected void delete(Long 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.BIGINT)); declareParameter(new SqlParameter(Types.VARCHAR)); declareParameter(new SqlParameter(Types.INTEGER)); compile(); } protected void insert(Long aclObjectIdentity, String recipient, Integer mask) throws DataAccessException { Object[] objs = new Object[] {aclObjectIdentity, recipient, mask}; super.update(objs); } } protected class AclPermissionUpdate extends SqlUpdate { protected AclPermissionUpdate(DataSource ds) { super(ds, aclPermissionUpdateStatement); declareParameter(new SqlParameter(Types.BIGINT)); declareParameter(new SqlParameter(Types.INTEGER)); compile(); } protected void update(Long aclPermissionId, Integer newMask) throws DataAccessException { super.update(newMask.intValue(), aclPermissionId.intValue()); } } protected class LookupPermissionIdMapping extends MappingSqlQuery { protected LookupPermissionIdMapping(DataSource ds) { super(ds, lookupPermissionIdQuery); declareParameter(new SqlParameter(Types.BIGINT)); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { return new Long(rs.getLong(1)); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy