📄 jdbcmutableaclservice.java
字号:
/* 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.acls.jdbc;import org.acegisecurity.Authentication;import org.acegisecurity.acls.AccessControlEntry;import org.acegisecurity.acls.Acl;import org.acegisecurity.acls.AlreadyExistsException;import org.acegisecurity.acls.ChildrenExistException;import org.acegisecurity.acls.MutableAcl;import org.acegisecurity.acls.MutableAclService;import org.acegisecurity.acls.NotFoundException;import org.acegisecurity.acls.domain.AccessControlEntryImpl;import org.acegisecurity.acls.objectidentity.ObjectIdentity;import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl;import org.acegisecurity.acls.sid.GrantedAuthoritySid;import org.acegisecurity.acls.sid.PrincipalSid;import org.acegisecurity.acls.sid.Sid;import org.acegisecurity.context.SecurityContextHolder;import org.springframework.dao.DataAccessException;import org.springframework.jdbc.core.BatchPreparedStatementSetter;import org.springframework.transaction.support.TransactionSynchronizationManager;import org.springframework.util.Assert;import java.lang.reflect.Array;import java.sql.PreparedStatement;import java.sql.SQLException;import java.util.List;import javax.sql.DataSource;/** * Provides a base implementation of {@link MutableAclService}. * * @author Ben Alex * @author Johannes Zlattinger * @version $Id: JdbcMutableAclService.java 1784 2007-02-24 21:00:24Z luke_t $ */public class JdbcMutableAclService extends JdbcAclService implements MutableAclService { //~ Instance fields ================================================================================================ private AclCache aclCache; private String deleteClassByClassNameString = "DELETE FROM acl_class WHERE class=?"; private String deleteEntryByObjectIdentityForeignKey = "DELETE FROM acl_entry WHERE acl_object_identity=?"; private String deleteObjectIdentityByPrimaryKey = "DELETE FROM acl_object_identity WHERE id=?"; private String identityQuery = "call identity()"; private String insertClass = "INSERT INTO acl_class (id, class) VALUES (null, ?)"; private String insertEntry = "INSERT INTO acl_entry " + "(id, acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure)" + "VALUES (null, ?, ?, ?, ?, ?, ?, ?)"; private String insertObjectIdentity = "INSERT INTO acl_object_identity " + "(id, object_id_class, object_id_identity, owner_sid, entries_inheriting) " + "VALUES (null, ?, ?, ?, ?)"; private String insertSid = "INSERT INTO acl_sid (id, principal, sid) VALUES (null, ?, ?)"; private String selectClassPrimaryKey = "SELECT id FROM acl_class WHERE class=?"; private String selectCountObjectIdentityRowsForParticularClassNameString = "SELECT COUNT(acl_object_identity.id) " + "FROM acl_object_identity, acl_class WHERE acl_class.id = acl_object_identity.object_id_class and class=?"; private String selectObjectIdentityPrimaryKey = "SELECT acl_object_identity.id FROM acl_object_identity, acl_class " + "WHERE acl_object_identity.object_id_class = acl_class.id and acl_class.class=? " + "and acl_object_identity.object_id_identity = ?"; private String selectSidPrimaryKey = "SELECT id FROM acl_sid WHERE principal=? AND sid=?"; private String updateObjectIdentity = "UPDATE acl_object_identity SET " + "parent_object = ?, owner_sid = ?, entries_inheriting = ?" + "where id = ?"; //~ Constructors =================================================================================================== public JdbcMutableAclService(DataSource dataSource, LookupStrategy lookupStrategy, AclCache aclCache) { super(dataSource, lookupStrategy); Assert.notNull(aclCache, "AclCache required"); this.aclCache = aclCache; } //~ Methods ======================================================================================================== public MutableAcl createAcl(ObjectIdentity objectIdentity) throws AlreadyExistsException { Assert.notNull(objectIdentity, "Object Identity required"); // Check this object identity hasn't already been persisted if (retrieveObjectIdentityPrimaryKey(objectIdentity) != null) { throw new AlreadyExistsException("Object identity '" + objectIdentity + "' already exists"); } // Need to retrieve the current principal, in order to know who "owns" this ACL (can be changed later on) Authentication auth = SecurityContextHolder.getContext().getAuthentication(); PrincipalSid sid = new PrincipalSid(auth); // Create the acl_object_identity row createObjectIdentity(objectIdentity, sid); // Retrieve the ACL via superclass (ensures cache registration, proper retrieval etc) Acl acl = readAclById(objectIdentity); Assert.isInstanceOf(MutableAcl.class, acl, "MutableAcl should be been returned"); return (MutableAcl) acl; } /** * Creates a new row in acl_entry for every ACE defined in the passed MutableAcl object. * * @param acl containing the ACEs to insert */ protected void createEntries(final MutableAcl acl) { jdbcTemplate.batchUpdate(insertEntry, new BatchPreparedStatementSetter() { public int getBatchSize() { return acl.getEntries().length; } public void setValues(PreparedStatement stmt, int i) throws SQLException { AccessControlEntry entry_ = (AccessControlEntry) Array.get(acl.getEntries(), i); Assert.isTrue(entry_ instanceof AccessControlEntryImpl, "Unknown ACE class"); AccessControlEntryImpl entry = (AccessControlEntryImpl) entry_; stmt.setLong(1, ((Long) acl.getId()).longValue()); stmt.setInt(2, i); stmt.setLong(3, createOrRetrieveSidPrimaryKey(entry.getSid(), true).longValue()); stmt.setInt(4, entry.getPermission().getMask()); stmt.setBoolean(5, entry.isGranting()); stmt.setBoolean(6, entry.isAuditSuccess()); stmt.setBoolean(7, entry.isAuditFailure()); } }); } /** * Creates an entry in the acl_object_identity table for the passed ObjectIdentity. The Sid is also * necessary, as acl_object_identity has defined the sid column as non-null. * * @param object to represent an acl_object_identity for * @param owner for the SID column (will be created if there is no acl_sid entry for this particular Sid already) */ protected void createObjectIdentity(ObjectIdentity object, Sid owner) { Long sidId = createOrRetrieveSidPrimaryKey(owner, true); Long classId = createOrRetrieveClassPrimaryKey(object.getJavaType(), true); jdbcTemplate.update(insertObjectIdentity, new Object[] {classId, object.getIdentifier().toString(), sidId, new Boolean(true)}); } /** * Retrieves the primary key from acl_class, creating a new row if needed and the allowCreate property is * true. * * @param clazz to find or create an entry for (this implementation uses the fully-qualified class name String) * @param allowCreate true if creation is permitted if not found * * @return the primary key or null if not found */ protected Long createOrRetrieveClassPrimaryKey(Class clazz, boolean allowCreate) { List classIds = jdbcTemplate.queryForList(selectClassPrimaryKey, new Object[] {clazz.getName()}, Long.class); Long classId = null; if (classIds.isEmpty()) { if (allowCreate) { classId = null; jdbcTemplate.update(insertClass, new Object[] {clazz.getName()}); Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(), "Transaction must be running"); classId = new Long(jdbcTemplate.queryForLong(identityQuery)); } } else { classId = (Long) classIds.iterator().next(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -