|
|
|
@ -64,11 +64,47 @@ import org.springframework.util.Assert; |
|
|
|
* you are likely to achieve better performance. In such situations you will need to provide your own custom |
|
|
|
* you are likely to achieve better performance. In such situations you will need to provide your own custom |
|
|
|
* <code>LookupStrategy</code>. This class does not support subclassing, as it is likely to change in future releases |
|
|
|
* <code>LookupStrategy</code>. This class does not support subclassing, as it is likely to change in future releases |
|
|
|
* and therefore subclassing is unsupported. |
|
|
|
* and therefore subclassing is unsupported. |
|
|
|
|
|
|
|
* <p> |
|
|
|
|
|
|
|
* There are two SQL queries executed, one in the <tt>lookupPrimaryKeys</tt> method and one in |
|
|
|
|
|
|
|
* <tt>lookupObjectIdentities</tt>. These are built from the same select and "order by" clause, using a different |
|
|
|
|
|
|
|
* where clause in each case. In order to use custom schema or column names, each of these SQL clauses can be |
|
|
|
|
|
|
|
* customized, but they must be consistent with each other and with the expected result set |
|
|
|
|
|
|
|
* generated by the the default values. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Ben Alex |
|
|
|
* @author Ben Alex |
|
|
|
* @version $Id$ |
|
|
|
* @version $Id$ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public final class BasicLookupStrategy implements LookupStrategy { |
|
|
|
public final class BasicLookupStrategy implements LookupStrategy { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public final static String DEFAULT_SELECT_CLAUSE = "select acl_object_identity.object_id_identity, " |
|
|
|
|
|
|
|
+ "acl_entry.ace_order, " |
|
|
|
|
|
|
|
+ "acl_object_identity.id as acl_id, " |
|
|
|
|
|
|
|
+ "acl_object_identity.parent_object, " |
|
|
|
|
|
|
|
+ "acl_object_identity.entries_inheriting, " |
|
|
|
|
|
|
|
+ "acl_entry.id as ace_id, " |
|
|
|
|
|
|
|
+ "acl_entry.mask, " |
|
|
|
|
|
|
|
+ "acl_entry.granting, " |
|
|
|
|
|
|
|
+ "acl_entry.audit_success, " |
|
|
|
|
|
|
|
+ "acl_entry.audit_failure, " |
|
|
|
|
|
|
|
+ "acl_sid.principal as ace_principal, " |
|
|
|
|
|
|
|
+ "acl_sid.sid as ace_sid, " |
|
|
|
|
|
|
|
+ "acli_sid.principal as acl_principal, " |
|
|
|
|
|
|
|
+ "acli_sid.sid as acl_sid, " |
|
|
|
|
|
|
|
+ "acl_class.class " |
|
|
|
|
|
|
|
+ "from acl_object_identity " |
|
|
|
|
|
|
|
+ "left join acl_sid acli_sid on acli_sid.id = acl_object_identity.owner_sid " |
|
|
|
|
|
|
|
+ "left join acl_class on acl_class.id = acl_object_identity.object_id_class " |
|
|
|
|
|
|
|
+ "left join acl_entry on acl_object_identity.id = acl_entry.acl_object_identity " |
|
|
|
|
|
|
|
+ "left join acl_sid on acl_entry.sid = acl_sid.id " |
|
|
|
|
|
|
|
+ "where ( "; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final static String DEFAULT_LOOKUP_KEYS_WHERE_CLAUSE = "(acl_object_identity.id = ?)"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final static String DEFAULT_LOOKUP_IDENTITIES_WHERE_CLAUSE = "(acl_object_identity.object_id_identity = ? and acl_class.class = ?)"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public final static String DEFAULT_ORDER_BY_CLAUSE = ") order by acl_object_identity.object_id_identity" |
|
|
|
|
|
|
|
+ " asc, acl_entry.ace_order asc"; |
|
|
|
|
|
|
|
|
|
|
|
//~ Instance fields ================================================================================================
|
|
|
|
//~ Instance fields ================================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
private AclAuthorizationStrategy aclAuthorizationStrategy; |
|
|
|
private AclAuthorizationStrategy aclAuthorizationStrategy; |
|
|
|
@ -81,6 +117,12 @@ public final class BasicLookupStrategy implements LookupStrategy { |
|
|
|
private final Field fieldAces = FieldUtils.getField(AclImpl.class, "aces"); |
|
|
|
private final Field fieldAces = FieldUtils.getField(AclImpl.class, "aces"); |
|
|
|
private final Field fieldAcl = FieldUtils.getField(AccessControlEntryImpl.class, "acl"); |
|
|
|
private final Field fieldAcl = FieldUtils.getField(AccessControlEntryImpl.class, "acl"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// SQL Customization fields
|
|
|
|
|
|
|
|
private String selectClause = DEFAULT_SELECT_CLAUSE; |
|
|
|
|
|
|
|
private String lookupPrimaryKeysWhereClause = DEFAULT_LOOKUP_KEYS_WHERE_CLAUSE; |
|
|
|
|
|
|
|
private String lookupObjectIdentitiesWhereClause = DEFAULT_LOOKUP_IDENTITIES_WHERE_CLAUSE; |
|
|
|
|
|
|
|
private String orderByClause = DEFAULT_ORDER_BY_CLAUSE; |
|
|
|
|
|
|
|
|
|
|
|
//~ Constructors ===================================================================================================
|
|
|
|
//~ Constructors ===================================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -106,33 +148,12 @@ public final class BasicLookupStrategy implements LookupStrategy { |
|
|
|
|
|
|
|
|
|
|
|
//~ Methods ========================================================================================================
|
|
|
|
//~ Methods ========================================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
private static String computeRepeatingSql(String repeatingSql, int requiredRepetitions) { |
|
|
|
private String computeRepeatingSql(String repeatingSql, int requiredRepetitions) { |
|
|
|
assert requiredRepetitions > 0 : "requiredRepetitions must be > 0"; |
|
|
|
assert requiredRepetitions > 0 : "requiredRepetitions must be > 0"; |
|
|
|
|
|
|
|
|
|
|
|
final String startSql = "select acl_object_identity.object_id_identity, " |
|
|
|
final String startSql = selectClause; |
|
|
|
+ "acl_entry.ace_order, " |
|
|
|
|
|
|
|
+ "acl_object_identity.id as acl_id, " |
|
|
|
|
|
|
|
+ "acl_object_identity.parent_object, " |
|
|
|
|
|
|
|
+ "acl_object_identity.entries_inheriting, " |
|
|
|
|
|
|
|
+ "acl_entry.id as ace_id, " |
|
|
|
|
|
|
|
+ "acl_entry.mask, " |
|
|
|
|
|
|
|
+ "acl_entry.granting, " |
|
|
|
|
|
|
|
+ "acl_entry.audit_success, " |
|
|
|
|
|
|
|
+ "acl_entry.audit_failure, " |
|
|
|
|
|
|
|
+ "acl_sid.principal as ace_principal, " |
|
|
|
|
|
|
|
+ "acl_sid.sid as ace_sid, " |
|
|
|
|
|
|
|
+ "acli_sid.principal as acl_principal, " |
|
|
|
|
|
|
|
+ "acli_sid.sid as acl_sid, " |
|
|
|
|
|
|
|
+ "acl_class.class " |
|
|
|
|
|
|
|
+ "from acl_object_identity " |
|
|
|
|
|
|
|
+ "left join acl_sid acli_sid on acli_sid.id = acl_object_identity.owner_sid " |
|
|
|
|
|
|
|
+ "left join acl_class on acl_class.id = acl_object_identity.object_id_class " |
|
|
|
|
|
|
|
+ "left join acl_entry on acl_object_identity.id = acl_entry.acl_object_identity " |
|
|
|
|
|
|
|
+ "left join acl_sid on acl_entry.sid = acl_sid.id " |
|
|
|
|
|
|
|
+ "where ( "; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final String endSql = ") order by acl_object_identity.object_id_identity" |
|
|
|
final String endSql = orderByClause; |
|
|
|
+ " asc, acl_entry.ace_order asc"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StringBuilder sqlStringBldr = |
|
|
|
StringBuilder sqlStringBldr = |
|
|
|
new StringBuilder(startSql.length() + endSql.length() + requiredRepetitions * (repeatingSql.length() + 4)); |
|
|
|
new StringBuilder(startSql.length() + endSql.length() + requiredRepetitions * (repeatingSql.length() + 4)); |
|
|
|
@ -239,7 +260,7 @@ public final class BasicLookupStrategy implements LookupStrategy { |
|
|
|
Assert.notNull(acls, "ACLs are required"); |
|
|
|
Assert.notNull(acls, "ACLs are required"); |
|
|
|
Assert.notEmpty(findNow, "Items to find now required"); |
|
|
|
Assert.notEmpty(findNow, "Items to find now required"); |
|
|
|
|
|
|
|
|
|
|
|
String sql = computeRepeatingSql("(acl_object_identity.id = ?)", findNow.size()); |
|
|
|
String sql = computeRepeatingSql(lookupPrimaryKeysWhereClause, findNow.size()); |
|
|
|
|
|
|
|
|
|
|
|
Set<Long> parentsToLookup = jdbcTemplate.query(sql, |
|
|
|
Set<Long> parentsToLookup = jdbcTemplate.query(sql, |
|
|
|
new PreparedStatementSetter() { |
|
|
|
new PreparedStatementSetter() { |
|
|
|
@ -358,7 +379,7 @@ public final class BasicLookupStrategy implements LookupStrategy { |
|
|
|
|
|
|
|
|
|
|
|
// Make the "acls" map contain all requested objectIdentities
|
|
|
|
// Make the "acls" map contain all requested objectIdentities
|
|
|
|
// (including markers to each parent in the hierarchy)
|
|
|
|
// (including markers to each parent in the hierarchy)
|
|
|
|
String sql = computeRepeatingSql("(acl_object_identity.object_id_identity = ? and acl_class.class = ?)", |
|
|
|
String sql = computeRepeatingSql(lookupObjectIdentitiesWhereClause , |
|
|
|
objectIdentities.length); |
|
|
|
objectIdentities.length); |
|
|
|
|
|
|
|
|
|
|
|
Set parentsToLookup = (Set) jdbcTemplate.query(sql, |
|
|
|
Set parentsToLookup = (Set) jdbcTemplate.query(sql, |
|
|
|
@ -400,11 +421,41 @@ public final class BasicLookupStrategy implements LookupStrategy { |
|
|
|
return resultMap; |
|
|
|
return resultMap; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setBatchSize(int batchSize) { |
|
|
|
public void setBatchSize(int batchSize) { |
|
|
|
this.batchSize = batchSize; |
|
|
|
this.batchSize = batchSize; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* The SQL for the select clause. If customizing in order to modify |
|
|
|
|
|
|
|
* column names, schema etc, the other SQL customization fields must also be set to match. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param selectClause the select clause, which defaults to {@link #DEFAULT_SELECT_CLAUSE}. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void setSelectClause(String selectClause) { |
|
|
|
|
|
|
|
this.selectClause = selectClause; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* The SQL for the where clause used in the <tt>lookupPrimaryKey</tt> method. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void setLookupPrimaryKeysWhereClause(String lookupPrimaryKeysWhereClause) { |
|
|
|
|
|
|
|
this.lookupPrimaryKeysWhereClause = lookupPrimaryKeysWhereClause; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* The SQL for the where clause used in the <tt>lookupObjectIdentities</tt> method. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void setLookupObjectIdentitiesWhereClause(String lookupObjectIdentitiesWhereClause) { |
|
|
|
|
|
|
|
this.lookupObjectIdentitiesWhereClause = lookupObjectIdentitiesWhereClause; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* The SQL for the "order by" clause used in both queries. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void setOrderByClause(String orderByClause) { |
|
|
|
|
|
|
|
this.orderByClause = orderByClause; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//~ Inner Classes ==================================================================================================
|
|
|
|
//~ Inner Classes ==================================================================================================
|
|
|
|
|
|
|
|
|
|
|
|
private class ProcessResultSet implements ResultSetExtractor<Set<Long>> { |
|
|
|
private class ProcessResultSet implements ResultSetExtractor<Set<Long>> { |
|
|
|
@ -479,13 +530,13 @@ public final class BasicLookupStrategy implements LookupStrategy { |
|
|
|
if (acl == null) { |
|
|
|
if (acl == null) { |
|
|
|
// Make an AclImpl and pop it into the Map
|
|
|
|
// Make an AclImpl and pop it into the Map
|
|
|
|
ObjectIdentity objectIdentity = new ObjectIdentityImpl(rs.getString("class"), |
|
|
|
ObjectIdentity objectIdentity = new ObjectIdentityImpl(rs.getString("class"), |
|
|
|
new Long(rs.getLong("object_id_identity"))); |
|
|
|
Long.valueOf(rs.getLong("object_id_identity"))); |
|
|
|
|
|
|
|
|
|
|
|
Acl parentAcl = null; |
|
|
|
Acl parentAcl = null; |
|
|
|
long parentAclId = rs.getLong("parent_object"); |
|
|
|
long parentAclId = rs.getLong("parent_object"); |
|
|
|
|
|
|
|
|
|
|
|
if (parentAclId != 0) { |
|
|
|
if (parentAclId != 0) { |
|
|
|
parentAcl = new StubAclParent(new Long(parentAclId)); |
|
|
|
parentAcl = new StubAclParent(Long.valueOf(parentAclId)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
boolean entriesInheriting = rs.getBoolean("entries_inheriting"); |
|
|
|
boolean entriesInheriting = rs.getBoolean("entries_inheriting"); |
|
|
|
|