|
@@ -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
|
|
|
* <code>LookupStrategy</code>. This class does not support subclassing, as it is likely to change in future releases
|
|
|
* 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
|
|
|
* @version $Id$
|
|
|
*/
|
|
|
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 ================================================================================================
|
|
|
|
|
|
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 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 ===================================================================================================
|
|
|
|
|
|
/**
|
|
@@ -106,33 +148,12 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
|
|
|
|
|
//~ Methods ========================================================================================================
|
|
|
|
|
|
- private static String computeRepeatingSql(String repeatingSql, int requiredRepetitions) {
|
|
|
+ private String computeRepeatingSql(String repeatingSql, int requiredRepetitions) {
|
|
|
assert requiredRepetitions > 0 : "requiredRepetitions must be > 0";
|
|
|
|
|
|
- final String startSql = "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 ( ";
|
|
|
-
|
|
|
- final String endSql = ") order by acl_object_identity.object_id_identity"
|
|
|
- + " asc, acl_entry.ace_order asc";
|
|
|
+ final String startSql = selectClause;
|
|
|
+
|
|
|
+ final String endSql = orderByClause;
|
|
|
|
|
|
StringBuilder sqlStringBldr =
|
|
|
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.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,
|
|
|
new PreparedStatementSetter() {
|
|
@@ -358,7 +379,7 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
|
|
|
|
|
// Make the "acls" map contain all requested objectIdentities
|
|
|
// (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);
|
|
|
|
|
|
Set parentsToLookup = (Set) jdbcTemplate.query(sql,
|
|
@@ -400,11 +421,41 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
|
|
return resultMap;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
public void setBatchSize(int 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 ==================================================================================================
|
|
|
|
|
|
private class ProcessResultSet implements ResultSetExtractor<Set<Long>> {
|
|
@@ -479,13 +530,13 @@ public final class BasicLookupStrategy implements LookupStrategy {
|
|
|
if (acl == null) {
|
|
|
// Make an AclImpl and pop it into the Map
|
|
|
ObjectIdentity objectIdentity = new ObjectIdentityImpl(rs.getString("class"),
|
|
|
- new Long(rs.getLong("object_id_identity")));
|
|
|
+ Long.valueOf(rs.getLong("object_id_identity")));
|
|
|
|
|
|
Acl parentAcl = null;
|
|
|
long parentAclId = rs.getLong("parent_object");
|
|
|
|
|
|
if (parentAclId != 0) {
|
|
|
- parentAcl = new StubAclParent(new Long(parentAclId));
|
|
|
+ parentAcl = new StubAclParent(Long.valueOf(parentAclId));
|
|
|
}
|
|
|
|
|
|
boolean entriesInheriting = rs.getBoolean("entries_inheriting");
|