Clover coverage report - Acegi Security System for Spring - 1.0.0-RC1
Coverage timestamp: Mon Dec 5 2005 09:05:15 EST
file stats: LOC: 468   Methods: 45
NCLOC: 298   Classes: 7
 
 Source file Conditionals Statements Methods TOTAL
JdbcExtendedDaoImpl.java 100% 100% 100% 100%
coverage
 1    /* Copyright 2004, 2005 Acegi Technology Pty Limited
 2    *
 3    * Licensed under the Apache License, Version 2.0 (the "License");
 4    * you may not use this file except in compliance with the License.
 5    * You may obtain a copy of the License at
 6    *
 7    * http://www.apache.org/licenses/LICENSE-2.0
 8    *
 9    * Unless required by applicable law or agreed to in writing, software
 10    * distributed under the License is distributed on an "AS IS" BASIS,
 11    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    * See the License for the specific language governing permissions and
 13    * limitations under the License.
 14    */
 15   
 16    package org.acegisecurity.acl.basic.jdbc;
 17   
 18    import org.acegisecurity.acl.basic.AclObjectIdentity;
 19    import org.acegisecurity.acl.basic.BasicAclEntry;
 20    import org.acegisecurity.acl.basic.BasicAclExtendedDao;
 21   
 22    import org.apache.commons.logging.Log;
 23    import org.apache.commons.logging.LogFactory;
 24   
 25    import org.springframework.context.ApplicationContextException;
 26   
 27    import org.springframework.dao.DataAccessException;
 28    import org.springframework.dao.DataIntegrityViolationException;
 29    import org.springframework.dao.DataRetrievalFailureException;
 30   
 31    import org.springframework.jdbc.core.SqlParameter;
 32    import org.springframework.jdbc.object.MappingSqlQuery;
 33    import org.springframework.jdbc.object.SqlUpdate;
 34   
 35    import java.sql.ResultSet;
 36    import java.sql.SQLException;
 37    import java.sql.Types;
 38   
 39    import java.util.Iterator;
 40    import java.util.List;
 41   
 42    import javax.sql.DataSource;
 43   
 44   
 45    /**
 46    * <p>
 47    * Extension of the base {@link JdbcDaoImpl}, which implements {@link
 48    * BasicAclExtendedDao}.
 49    * </p>
 50    *
 51    * <p>
 52    * A default database structure is assumed. This may be overridden by setting
 53    * the default query strings to use.
 54    * </p>
 55    *
 56    * <p>
 57    * This implementation works with <code>String</code> based recipients and
 58    * {@link org.acegisecurity.acl.basic.NamedEntityObjectIdentity} only. The
 59    * latter can be changed by overriding {@link
 60    * #convertAclObjectIdentityToString(AclObjectIdentity)}.
 61    * </p>
 62    *
 63    * @author Ben Alex
 64    * @version $Id: JdbcExtendedDaoImpl.java,v 1.7 2005/11/17 00:56:10 benalex Exp $
 65    */
 66    public class JdbcExtendedDaoImpl extends JdbcDaoImpl
 67    implements BasicAclExtendedDao {
 68    //~ Static fields/initializers =============================================
 69   
 70    private static final Log logger = LogFactory.getLog(JdbcExtendedDaoImpl.class);
 71    public static final String DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT = "DELETE FROM acl_object_identity WHERE id = ?";
 72    public static final String DEF_ACL_OBJECT_IDENTITY_INSERT_STATEMENT = "INSERT INTO acl_object_identity (object_identity, parent_object, acl_class) VALUES (?, ?, ?)";
 73    public static final String DEF_ACL_PERMISSION_DELETE_STATEMENT = "DELETE FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?";
 74    public static final String DEF_ACL_PERMISSION_INSERT_STATEMENT = "INSERT INTO acl_permission (acl_object_identity, recipient, mask) VALUES (?, ?, ?)";
 75    public static final String DEF_ACL_PERMISSION_UPDATE_STATEMENT = "UPDATE acl_permission SET mask = ? WHERE id = ?";
 76    public static final String DEF_LOOKUP_PERMISSION_ID_QUERY = "SELECT id FROM acl_permission WHERE acl_object_identity = ? AND recipient = ?";
 77   
 78    //~ Instance fields ========================================================
 79   
 80    private AclObjectIdentityDelete aclObjectIdentityDelete;
 81    private AclObjectIdentityInsert aclObjectIdentityInsert;
 82    private AclPermissionDelete aclPermissionDelete;
 83    private AclPermissionInsert aclPermissionInsert;
 84    private AclPermissionUpdate aclPermissionUpdate;
 85    private MappingSqlQuery lookupPermissionIdMapping;
 86    private String aclObjectIdentityDeleteStatement;
 87    private String aclObjectIdentityInsertStatement;
 88    private String aclPermissionDeleteStatement;
 89    private String aclPermissionInsertStatement;
 90    private String aclPermissionUpdateStatement;
 91    private String lookupPermissionIdQuery;
 92   
 93    //~ Constructors ===========================================================
 94   
 95  9 public JdbcExtendedDaoImpl() {
 96  9 aclObjectIdentityDeleteStatement = DEF_ACL_OBJECT_IDENTITY_DELETE_STATEMENT;
 97  9 aclObjectIdentityInsertStatement = DEF_ACL_OBJECT_IDENTITY_INSERT_STATEMENT;
 98  9 aclPermissionDeleteStatement = DEF_ACL_PERMISSION_DELETE_STATEMENT;
 99  9 aclPermissionInsertStatement = DEF_ACL_PERMISSION_INSERT_STATEMENT;
 100  9 aclPermissionUpdateStatement = DEF_ACL_PERMISSION_UPDATE_STATEMENT;
 101  9 lookupPermissionIdQuery = DEF_LOOKUP_PERMISSION_ID_QUERY;
 102    }
 103   
 104    //~ Methods ================================================================
 105   
 106  1 public void setAclObjectIdentityDelete(
 107    AclObjectIdentityDelete aclObjectIdentityDelete) {
 108  1 this.aclObjectIdentityDelete = aclObjectIdentityDelete;
 109    }
 110   
 111  2 public AclObjectIdentityDelete getAclObjectIdentityDelete() {
 112  2 return aclObjectIdentityDelete;
 113    }
 114   
 115  1 public void setAclObjectIdentityDeleteStatement(
 116    String aclObjectIdentityDeleteStatement) {
 117  1 this.aclObjectIdentityDeleteStatement = aclObjectIdentityDeleteStatement;
 118    }
 119   
 120  2 public String getAclObjectIdentityDeleteStatement() {
 121  2 return aclObjectIdentityDeleteStatement;
 122    }
 123   
 124  1 public void setAclObjectIdentityInsert(
 125    AclObjectIdentityInsert aclObjectIdentityInsert) {
 126  1 this.aclObjectIdentityInsert = aclObjectIdentityInsert;
 127    }
 128   
 129  2 public AclObjectIdentityInsert getAclObjectIdentityInsert() {
 130  2 return aclObjectIdentityInsert;
 131    }
 132   
 133  1 public void setAclObjectIdentityInsertStatement(
 134    String aclObjectIdentityInsertStatement) {
 135  1 this.aclObjectIdentityInsertStatement = aclObjectIdentityInsertStatement;
 136    }
 137   
 138  2 public String getAclObjectIdentityInsertStatement() {
 139  2 return aclObjectIdentityInsertStatement;
 140    }
 141   
 142  1 public void setAclPermissionDelete(AclPermissionDelete aclPermissionDelete) {
 143  1 this.aclPermissionDelete = aclPermissionDelete;
 144    }
 145   
 146  2 public AclPermissionDelete getAclPermissionDelete() {
 147  2 return aclPermissionDelete;
 148    }
 149   
 150  1 public void setAclPermissionDeleteStatement(
 151    String aclPermissionDeleteStatement) {
 152  1 this.aclPermissionDeleteStatement = aclPermissionDeleteStatement;
 153    }
 154   
 155  2 public String getAclPermissionDeleteStatement() {
 156  2 return aclPermissionDeleteStatement;
 157    }
 158   
 159  1 public void setAclPermissionInsert(AclPermissionInsert aclPermissionInsert) {
 160  1 this.aclPermissionInsert = aclPermissionInsert;
 161    }
 162   
 163  2 public AclPermissionInsert getAclPermissionInsert() {
 164  2 return aclPermissionInsert;
 165    }
 166   
 167  1 public void setAclPermissionInsertStatement(
 168    String aclPermissionInsertStatement) {
 169  1 this.aclPermissionInsertStatement = aclPermissionInsertStatement;
 170    }
 171   
 172  2 public String getAclPermissionInsertStatement() {
 173  2 return aclPermissionInsertStatement;
 174    }
 175   
 176  1 public void setAclPermissionUpdate(AclPermissionUpdate aclPermissionUpdate) {
 177  1 this.aclPermissionUpdate = aclPermissionUpdate;
 178    }
 179   
 180  2 public AclPermissionUpdate getAclPermissionUpdate() {
 181  2 return aclPermissionUpdate;
 182    }
 183   
 184  1 public void setAclPermissionUpdateStatement(
 185    String aclPermissionUpdateStatement) {
 186  1 this.aclPermissionUpdateStatement = aclPermissionUpdateStatement;
 187    }
 188   
 189  2 public String getAclPermissionUpdateStatement() {
 190  2 return aclPermissionUpdateStatement;
 191    }
 192   
 193  1 public void setLookupPermissionIdMapping(
 194    MappingSqlQuery lookupPermissionIdMapping) {
 195  1 this.lookupPermissionIdMapping = lookupPermissionIdMapping;
 196    }
 197   
 198  2 public MappingSqlQuery getLookupPermissionIdMapping() {
 199  2 return lookupPermissionIdMapping;
 200    }
 201   
 202  1 public void setLookupPermissionIdQuery(String lookupPermissionIdQuery) {
 203  1 this.lookupPermissionIdQuery = lookupPermissionIdQuery;
 204    }
 205   
 206  2 public String getLookupPermissionIdQuery() {
 207  2 return lookupPermissionIdQuery;
 208    }
 209   
 210  3 public void changeMask(AclObjectIdentity aclObjectIdentity,
 211    Object recipient, Integer newMask) throws DataAccessException {
 212    // Retrieve acl_object_identity record details
 213  3 AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
 214   
 215    // Retrieve applicable acl_permission.id
 216  3 long permissionId = lookupPermissionId(aclDetailsHolder.getForeignKeyId(),
 217    recipient.toString());
 218   
 219  3 if (permissionId == -1) {
 220  1 throw new DataRetrievalFailureException(
 221    "Could not locate existing acl_permission for aclObjectIdentity: "
 222    + aclObjectIdentity + ", recipient: " + recipient.toString());
 223    }
 224   
 225    // Change permission
 226  2 aclPermissionUpdate.update(new Long(permissionId), newMask);
 227    }
 228   
 229  12 public void create(BasicAclEntry basicAclEntry) throws DataAccessException {
 230    // Create acl_object_identity record if required
 231  12 createAclObjectIdentityIfRequired(basicAclEntry);
 232   
 233    // Only continue if a recipient is specifed (null recipient indicates
 234    // just wanted to ensure the acl_object_identity was created)
 235  11 if (basicAclEntry.getRecipient() == null) {
 236  1 return;
 237    }
 238   
 239    // Retrieve acl_object_identity record details
 240  10 AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(basicAclEntry
 241    .getAclObjectIdentity());
 242   
 243    // Ensure there isn't an existing record for this recipient
 244  10 if (lookupPermissionId(aclDetailsHolder.getForeignKeyId(),
 245    basicAclEntry.getRecipient()) != -1) {
 246  1 throw new DataIntegrityViolationException(
 247    "This recipient already exists for this aclObjectIdentity");
 248    }
 249   
 250    // Create acl_permission
 251  9 aclPermissionInsert.insert(new Long(aclDetailsHolder.getForeignKeyId()),
 252    basicAclEntry.getRecipient().toString(),
 253    new Integer(basicAclEntry.getMask()));
 254    }
 255   
 256  2 public void delete(AclObjectIdentity aclObjectIdentity)
 257    throws DataAccessException {
 258    // Retrieve acl_object_identity record details
 259  2 AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
 260   
 261    // Retrieve all acl_permissions applying to this acl_object_identity
 262  2 Iterator acls = aclsByObjectIdentity.execute(aclDetailsHolder
 263    .getForeignKeyId()).iterator();
 264   
 265    // Delete all existing acl_permissions applying to this acl_object_identity
 266  2 while (acls.hasNext()) {
 267  2 AclDetailsHolder permission = (AclDetailsHolder) acls.next();
 268  2 delete(aclObjectIdentity, permission.getRecipient());
 269    }
 270   
 271    // Delete acl_object_identity
 272  2 aclObjectIdentityDelete.delete(new Long(
 273    aclDetailsHolder.getForeignKeyId()));
 274    }
 275   
 276  3 public void delete(AclObjectIdentity aclObjectIdentity, Object recipient)
 277    throws DataAccessException {
 278    // Retrieve acl_object_identity record details
 279  3 AclDetailsHolder aclDetailsHolder = lookupAclDetailsHolder(aclObjectIdentity);
 280   
 281    // Delete acl_permission
 282  3 aclPermissionDelete.delete(new Long(aclDetailsHolder.getForeignKeyId()),
 283    recipient.toString());
 284    }
 285   
 286  9 protected void initDao() throws ApplicationContextException {
 287  9 super.initDao();
 288  9 lookupPermissionIdMapping = new LookupPermissionIdMapping(getDataSource());
 289  9 aclPermissionInsert = new AclPermissionInsert(getDataSource());
 290  9 aclObjectIdentityInsert = new AclObjectIdentityInsert(getDataSource());
 291  9 aclPermissionDelete = new AclPermissionDelete(getDataSource());
 292  9 aclObjectIdentityDelete = new AclObjectIdentityDelete(getDataSource());
 293  9 aclPermissionUpdate = new AclPermissionUpdate(getDataSource());
 294    }
 295   
 296    /**
 297    * Convenience method that creates an acl_object_identity record if
 298    * required.
 299    *
 300    * @param basicAclEntry containing the <code>AclObjectIdentity</code> to
 301    * create
 302    *
 303    * @throws DataAccessException
 304    */
 305  12 private void createAclObjectIdentityIfRequired(BasicAclEntry basicAclEntry)
 306    throws DataAccessException {
 307  12 String aclObjectIdentityString = convertAclObjectIdentityToString(basicAclEntry
 308    .getAclObjectIdentity());
 309   
 310    // Lookup the object's main properties from the RDBMS (guaranteed no nulls)
 311  12 List objects = objectProperties.execute(aclObjectIdentityString);
 312   
 313  12 if (objects.size() == 0) {
 314  7 if (basicAclEntry.getAclObjectParentIdentity() != null) {
 315  6 AclDetailsHolder parentDetails = lookupAclDetailsHolder(basicAclEntry
 316    .getAclObjectParentIdentity());
 317   
 318    // Must create the acl_object_identity record
 319  5 aclObjectIdentityInsert.insert(aclObjectIdentityString,
 320    new Long(parentDetails.getForeignKeyId()),
 321    basicAclEntry.getClass().getName());
 322    } else {
 323    // Must create the acl_object_identity record
 324  1 aclObjectIdentityInsert.insert(aclObjectIdentityString, null,
 325    basicAclEntry.getClass().getName());
 326    }
 327    }
 328    }
 329   
 330    /**
 331    * Convenience method that obtains a given acl_object_identity record.
 332    *
 333    * @param aclObjectIdentity to lookup
 334    *
 335    * @return details of the record
 336    *
 337    * @throws DataRetrievalFailureException if record could not be found
 338    */
 339  24 private AclDetailsHolder lookupAclDetailsHolder(
 340    AclObjectIdentity aclObjectIdentity)
 341    throws DataRetrievalFailureException {
 342  24 String aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
 343   
 344    // Lookup the object's main properties from the RDBMS (guaranteed no nulls)
 345  24 List objects = objectProperties.execute(aclObjectIdentityString);
 346   
 347  24 if (objects.size() == 0) {
 348  1 throw new DataRetrievalFailureException(
 349    "aclObjectIdentity not found: " + aclObjectIdentityString);
 350    }
 351   
 352    // Should only be one record
 353  23 return (AclDetailsHolder) objects.get(0);
 354    }
 355   
 356    /**
 357    * Convenience method to lookup the acl_permission applying to a given
 358    * acl_object_identity.id and acl_permission.recipient.
 359    *
 360    * @param aclObjectIdentityId to locate
 361    * @param recipient to locate
 362    *
 363    * @return the acl_permission.id of the record, or -1 if not found
 364    *
 365    * @throws DataAccessException DOCUMENT ME!
 366    */
 367  13 private long lookupPermissionId(long aclObjectIdentityId, Object recipient)
 368    throws DataAccessException {
 369  13 List list = lookupPermissionIdMapping.execute(new Object[] {new Long(
 370    aclObjectIdentityId), recipient});
 371   
 372  13 if (list.size() == 0) {
 373  10 return -1;
 374    }
 375   
 376  3 return ((Long) list.get(0)).longValue();
 377    }
 378   
 379    //~ Inner Classes ==========================================================
 380   
 381    protected class AclObjectIdentityDelete extends SqlUpdate {
 382  9 protected AclObjectIdentityDelete(DataSource ds) {
 383  9 super(ds, aclObjectIdentityDeleteStatement);
 384  9 declareParameter(new SqlParameter(Types.BIGINT));
 385  9 compile();
 386    }
 387   
 388  2 protected void delete(Long aclObjectIdentity)
 389    throws DataAccessException {
 390  2 super.update(aclObjectIdentity.intValue());
 391    }
 392    }
 393   
 394    protected class AclObjectIdentityInsert extends SqlUpdate {
 395  9 protected AclObjectIdentityInsert(DataSource ds) {
 396  9 super(ds, aclObjectIdentityInsertStatement);
 397  9 declareParameter(new SqlParameter(Types.VARCHAR));
 398  9 declareParameter(new SqlParameter(Types.BIGINT));
 399  9 declareParameter(new SqlParameter(Types.VARCHAR));
 400  9 compile();
 401    }
 402   
 403  6 protected void insert(String objectIdentity,
 404    Long parentAclObjectIdentity, String aclClass)
 405    throws DataAccessException {
 406  6 Object[] objs = new Object[] {objectIdentity, parentAclObjectIdentity, aclClass};
 407  6 super.update(objs);
 408    }
 409    }
 410   
 411    protected class AclPermissionDelete extends SqlUpdate {
 412  9 protected AclPermissionDelete(DataSource ds) {
 413  9 super(ds, aclPermissionDeleteStatement);
 414  9 declareParameter(new SqlParameter(Types.BIGINT));
 415  9 declareParameter(new SqlParameter(Types.VARCHAR));
 416  9 compile();
 417    }
 418   
 419  3 protected void delete(Long aclObjectIdentity, String recipient)
 420    throws DataAccessException {
 421  3 super.update(new Object[] {aclObjectIdentity, recipient});
 422    }
 423    }
 424   
 425    protected class AclPermissionInsert extends SqlUpdate {
 426  9 protected AclPermissionInsert(DataSource ds) {
 427  9 super(ds, aclPermissionInsertStatement);
 428  9 declareParameter(new SqlParameter(Types.BIGINT));
 429  9 declareParameter(new SqlParameter(Types.VARCHAR));
 430  9 declareParameter(new SqlParameter(Types.INTEGER));
 431  9 compile();
 432    }
 433   
 434  9 protected void insert(Long aclObjectIdentity, String recipient,
 435    Integer mask) throws DataAccessException {
 436  9 Object[] objs = new Object[] {aclObjectIdentity, recipient, mask};
 437  9 super.update(objs);
 438    }
 439    }
 440   
 441    protected class AclPermissionUpdate extends SqlUpdate {
 442  9 protected AclPermissionUpdate(DataSource ds) {
 443  9 super(ds, aclPermissionUpdateStatement);
 444  9 declareParameter(new SqlParameter(Types.BIGINT));
 445  9 declareParameter(new SqlParameter(Types.INTEGER));
 446  9 compile();
 447    }
 448   
 449  2 protected void update(Long aclPermissionId, Integer newMask)
 450    throws DataAccessException {
 451  2 super.update(newMask.intValue(), aclPermissionId.intValue());
 452    }
 453    }
 454   
 455    protected class LookupPermissionIdMapping extends MappingSqlQuery {
 456  9 protected LookupPermissionIdMapping(DataSource ds) {
 457  9 super(ds, lookupPermissionIdQuery);
 458  9 declareParameter(new SqlParameter(Types.BIGINT));
 459  9 declareParameter(new SqlParameter(Types.VARCHAR));
 460  9 compile();
 461    }
 462   
 463  3 protected Object mapRow(ResultSet rs, int rownum)
 464    throws SQLException {
 465  3 return new Long(rs.getLong(1));
 466    }
 467    }
 468    }