Source Code Cross Referenced for JdbcMutableAclService.java in  » Security » acegi-security » org » acegisecurity » acls » jdbc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Security » acegi security » org.acegisecurity.acls.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002:         *
003:         * Licensed under the Apache License, Version 2.0 (the "License");
004:         * you may not use this file except in compliance with the License.
005:         * You may obtain a copy of the License at
006:         *
007:         *     http://www.apache.org/licenses/LICENSE-2.0
008:         *
009:         * Unless required by applicable law or agreed to in writing, software
010:         * distributed under the License is distributed on an "AS IS" BASIS,
011:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012:         * See the License for the specific language governing permissions and
013:         * limitations under the License.
014:         */
015:        package org.acegisecurity.acls.jdbc;
016:
017:        import org.acegisecurity.Authentication;
018:
019:        import org.acegisecurity.acls.AccessControlEntry;
020:        import org.acegisecurity.acls.Acl;
021:        import org.acegisecurity.acls.AlreadyExistsException;
022:        import org.acegisecurity.acls.ChildrenExistException;
023:        import org.acegisecurity.acls.MutableAcl;
024:        import org.acegisecurity.acls.MutableAclService;
025:        import org.acegisecurity.acls.NotFoundException;
026:        import org.acegisecurity.acls.domain.AccessControlEntryImpl;
027:        import org.acegisecurity.acls.objectidentity.ObjectIdentity;
028:        import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl;
029:        import org.acegisecurity.acls.sid.GrantedAuthoritySid;
030:        import org.acegisecurity.acls.sid.PrincipalSid;
031:        import org.acegisecurity.acls.sid.Sid;
032:
033:        import org.acegisecurity.context.SecurityContextHolder;
034:
035:        import org.springframework.dao.DataAccessException;
036:
037:        import org.springframework.jdbc.core.BatchPreparedStatementSetter;
038:
039:        import org.springframework.transaction.support.TransactionSynchronizationManager;
040:
041:        import org.springframework.util.Assert;
042:
043:        import java.lang.reflect.Array;
044:
045:        import java.sql.PreparedStatement;
046:        import java.sql.SQLException;
047:
048:        import java.util.List;
049:
050:        import javax.sql.DataSource;
051:
052:        /**
053:         * Provides a base implementation of {@link MutableAclService}.
054:         *
055:         * @author Ben Alex
056:         * @author Johannes Zlattinger
057:         * @version $Id: JdbcMutableAclService.java 1784 2007-02-24 21:00:24Z luke_t $
058:         */
059:        public class JdbcMutableAclService extends JdbcAclService implements 
060:                MutableAclService {
061:            //~ Instance fields ================================================================================================
062:
063:            private AclCache aclCache;
064:            private String deleteClassByClassNameString = "DELETE FROM acl_class WHERE class=?";
065:            private String deleteEntryByObjectIdentityForeignKey = "DELETE FROM acl_entry WHERE acl_object_identity=?";
066:            private String deleteObjectIdentityByPrimaryKey = "DELETE FROM acl_object_identity WHERE id=?";
067:            private String identityQuery = "call identity()";
068:            private String insertClass = "INSERT INTO acl_class (id, class) VALUES (null, ?)";
069:            private String insertEntry = "INSERT INTO acl_entry "
070:                    + "(id, acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure)"
071:                    + "VALUES (null, ?, ?, ?, ?, ?, ?, ?)";
072:            private String insertObjectIdentity = "INSERT INTO acl_object_identity "
073:                    + "(id, object_id_class, object_id_identity, owner_sid, entries_inheriting) "
074:                    + "VALUES (null, ?, ?, ?, ?)";
075:            private String insertSid = "INSERT INTO acl_sid (id, principal, sid) VALUES (null, ?, ?)";
076:            private String selectClassPrimaryKey = "SELECT id FROM acl_class WHERE class=?";
077:            private String selectCountObjectIdentityRowsForParticularClassNameString = "SELECT COUNT(acl_object_identity.id) "
078:                    + "FROM acl_object_identity, acl_class WHERE acl_class.id = acl_object_identity.object_id_class and class=?";
079:            private String selectObjectIdentityPrimaryKey = "SELECT acl_object_identity.id FROM acl_object_identity, acl_class "
080:                    + "WHERE acl_object_identity.object_id_class = acl_class.id and acl_class.class=? "
081:                    + "and acl_object_identity.object_id_identity = ?";
082:            private String selectSidPrimaryKey = "SELECT id FROM acl_sid WHERE principal=? AND sid=?";
083:            private String updateObjectIdentity = "UPDATE acl_object_identity SET "
084:                    + "parent_object = ?, owner_sid = ?, entries_inheriting = ?"
085:                    + "where id = ?";
086:
087:            //~ Constructors ===================================================================================================
088:
089:            public JdbcMutableAclService(DataSource dataSource,
090:                    LookupStrategy lookupStrategy, AclCache aclCache) {
091:                super (dataSource, lookupStrategy);
092:                Assert.notNull(aclCache, "AclCache required");
093:                this .aclCache = aclCache;
094:            }
095:
096:            //~ Methods ========================================================================================================
097:
098:            public MutableAcl createAcl(ObjectIdentity objectIdentity)
099:                    throws AlreadyExistsException {
100:                Assert.notNull(objectIdentity, "Object Identity required");
101:
102:                // Check this object identity hasn't already been persisted
103:                if (retrieveObjectIdentityPrimaryKey(objectIdentity) != null) {
104:                    throw new AlreadyExistsException("Object identity '"
105:                            + objectIdentity + "' already exists");
106:                }
107:
108:                // Need to retrieve the current principal, in order to know who "owns" this ACL (can be changed later on)
109:                Authentication auth = SecurityContextHolder.getContext()
110:                        .getAuthentication();
111:                PrincipalSid sid = new PrincipalSid(auth);
112:
113:                // Create the acl_object_identity row
114:                createObjectIdentity(objectIdentity, sid);
115:
116:                // Retrieve the ACL via superclass (ensures cache registration, proper retrieval etc)
117:                Acl acl = readAclById(objectIdentity);
118:                Assert.isInstanceOf(MutableAcl.class, acl,
119:                        "MutableAcl should be been returned");
120:
121:                return (MutableAcl) acl;
122:            }
123:
124:            /**
125:             * Creates a new row in acl_entry for every ACE defined in the passed MutableAcl object.
126:             *
127:             * @param acl containing the ACEs to insert
128:             */
129:            protected void createEntries(final MutableAcl acl) {
130:                jdbcTemplate.batchUpdate(insertEntry,
131:                        new BatchPreparedStatementSetter() {
132:                            public int getBatchSize() {
133:                                return acl.getEntries().length;
134:                            }
135:
136:                            public void setValues(PreparedStatement stmt, int i)
137:                                    throws SQLException {
138:                                AccessControlEntry entry_ = (AccessControlEntry) Array
139:                                        .get(acl.getEntries(), i);
140:                                Assert
141:                                        .isTrue(
142:                                                entry_ instanceof  AccessControlEntryImpl,
143:                                                "Unknown ACE class");
144:
145:                                AccessControlEntryImpl entry = (AccessControlEntryImpl) entry_;
146:
147:                                stmt.setLong(1, ((Long) acl.getId())
148:                                        .longValue());
149:                                stmt.setInt(2, i);
150:                                stmt.setLong(3, createOrRetrieveSidPrimaryKey(
151:                                        entry.getSid(), true).longValue());
152:                                stmt.setInt(4, entry.getPermission().getMask());
153:                                stmt.setBoolean(5, entry.isGranting());
154:                                stmt.setBoolean(6, entry.isAuditSuccess());
155:                                stmt.setBoolean(7, entry.isAuditFailure());
156:                            }
157:                        });
158:            }
159:
160:            /**
161:             * Creates an entry in the acl_object_identity table for the passed ObjectIdentity. The Sid is also
162:             * necessary, as acl_object_identity has defined the sid column as non-null.
163:             *
164:             * @param object to represent an acl_object_identity for
165:             * @param owner for the SID column (will be created if there is no acl_sid entry for this particular Sid already)
166:             */
167:            protected void createObjectIdentity(ObjectIdentity object, Sid owner) {
168:                Long sidId = createOrRetrieveSidPrimaryKey(owner, true);
169:                Long classId = createOrRetrieveClassPrimaryKey(object
170:                        .getJavaType(), true);
171:                jdbcTemplate.update(insertObjectIdentity, new Object[] {
172:                        classId, object.getIdentifier().toString(), sidId,
173:                        new Boolean(true) });
174:            }
175:
176:            /**
177:             * Retrieves the primary key from acl_class, creating a new row if needed and the allowCreate property is
178:             * true.
179:             *
180:             * @param clazz to find or create an entry for (this implementation uses the fully-qualified class name String)
181:             * @param allowCreate true if creation is permitted if not found
182:             *
183:             * @return the primary key or null if not found
184:             */
185:            protected Long createOrRetrieveClassPrimaryKey(Class clazz,
186:                    boolean allowCreate) {
187:                List classIds = jdbcTemplate.queryForList(
188:                        selectClassPrimaryKey,
189:                        new Object[] { clazz.getName() }, Long.class);
190:                Long classId = null;
191:
192:                if (classIds.isEmpty()) {
193:                    if (allowCreate) {
194:                        classId = null;
195:                        jdbcTemplate.update(insertClass, new Object[] { clazz
196:                                .getName() });
197:                        Assert.isTrue(TransactionSynchronizationManager
198:                                .isSynchronizationActive(),
199:                                "Transaction must be running");
200:                        classId = new Long(jdbcTemplate
201:                                .queryForLong(identityQuery));
202:                    }
203:                } else {
204:                    classId = (Long) classIds.iterator().next();
205:                }
206:
207:                return classId;
208:            }
209:
210:            /**
211:             * Retrieves the primary key from acl_sid, creating a new row if needed and the allowCreate property is
212:             * true.
213:             *
214:             * @param sid to find or create
215:             * @param allowCreate true if creation is permitted if not found
216:             *
217:             * @return the primary key or null if not found
218:             *
219:             * @throws IllegalArgumentException DOCUMENT ME!
220:             */
221:            protected Long createOrRetrieveSidPrimaryKey(Sid sid,
222:                    boolean allowCreate) {
223:                Assert.notNull(sid, "Sid required");
224:
225:                String sidName = null;
226:                boolean principal = true;
227:
228:                if (sid instanceof  PrincipalSid) {
229:                    sidName = ((PrincipalSid) sid).getPrincipal();
230:                } else if (sid instanceof  GrantedAuthoritySid) {
231:                    sidName = ((GrantedAuthoritySid) sid).getGrantedAuthority();
232:                    principal = false;
233:                } else {
234:                    throw new IllegalArgumentException(
235:                            "Unsupported implementation of Sid");
236:                }
237:
238:                List sidIds = jdbcTemplate.queryForList(selectSidPrimaryKey,
239:                        new Object[] { new Boolean(principal), sidName },
240:                        Long.class);
241:                Long sidId = null;
242:
243:                if (sidIds.isEmpty()) {
244:                    if (allowCreate) {
245:                        sidId = null;
246:                        jdbcTemplate.update(insertSid, new Object[] {
247:                                new Boolean(principal), sidName });
248:                        Assert.isTrue(TransactionSynchronizationManager
249:                                .isSynchronizationActive(),
250:                                "Transaction must be running");
251:                        sidId = new Long(jdbcTemplate
252:                                .queryForLong(identityQuery));
253:                    }
254:                } else {
255:                    sidId = (Long) sidIds.iterator().next();
256:                }
257:
258:                return sidId;
259:            }
260:
261:            public void deleteAcl(ObjectIdentity objectIdentity,
262:                    boolean deleteChildren) throws ChildrenExistException {
263:                Assert.notNull(objectIdentity, "Object Identity required");
264:                Assert.notNull(objectIdentity.getIdentifier(),
265:                        "Object Identity doesn't provide an identifier");
266:
267:                // Recursively call this method for children, or handle children if they don't want automatic recursion
268:                ObjectIdentity[] children = findChildren(objectIdentity);
269:
270:                if (deleteChildren) {
271:                    for (int i = 0; i < children.length; i++) {
272:                        deleteAcl(children[i], true);
273:                    }
274:                } else if (children.length > 0) {
275:                    throw new ChildrenExistException("Cannot delete '"
276:                            + objectIdentity + "' (has " + children.length
277:                            + " children)");
278:                }
279:
280:                // Delete this ACL's ACEs in the acl_entry table
281:                deleteEntries(objectIdentity);
282:
283:                // Delete this ACL's acl_object_identity row
284:                deleteObjectIdentityAndOptionallyClass(objectIdentity);
285:
286:                // Clear the cache
287:                aclCache.evictFromCache(objectIdentity);
288:            }
289:
290:            /**
291:             * Deletes all ACEs defined in the acl_entry table belonging to the presented ObjectIdentity
292:             *
293:             * @param oid the rows in acl_entry to delete
294:             */
295:            protected void deleteEntries(ObjectIdentity oid) {
296:                jdbcTemplate.update(deleteEntryByObjectIdentityForeignKey,
297:                        new Object[] { retrieveObjectIdentityPrimaryKey(oid) });
298:            }
299:
300:            /**
301:             * Deletes a single row from acl_object_identity that is associated with the presented ObjectIdentity. In
302:             * addition, deletes the corresponding row from acl_class if there are no more entries in acl_object_identity that
303:             * use that particular acl_class. This keeps the acl_class table reasonably small.
304:             *
305:             * @param oid to delete the acl_object_identity (and clean up acl_class for that class name if appropriate)
306:             */
307:            protected void deleteObjectIdentityAndOptionallyClass(
308:                    ObjectIdentity oid) {
309:                // Delete the acl_object_identity row
310:                jdbcTemplate.update(deleteObjectIdentityByPrimaryKey,
311:                        new Object[] { retrieveObjectIdentityPrimaryKey(oid) });
312:
313:                // Delete the acl_class row, assuming there are no other references to it in acl_object_identity
314:                Object[] className = { oid.getJavaType().getName() };
315:                long numObjectIdentities = jdbcTemplate
316:                        .queryForLong(
317:                                selectCountObjectIdentityRowsForParticularClassNameString,
318:                                className);
319:
320:                if (numObjectIdentities == 0) {
321:                    // No more rows
322:                    jdbcTemplate
323:                            .update(deleteClassByClassNameString, className);
324:                }
325:            }
326:
327:            /**
328:             * Retrieves the primary key from the acl_object_identity table for the passed ObjectIdentity. Unlike some
329:             * other methods in this implementation, this method will NOT create a row (use {@link
330:             * #createObjectIdentity(ObjectIdentity, Sid)} instead).
331:             *
332:             * @param oid to find
333:             *
334:             * @return the object identity or null if not found
335:             */
336:            protected Long retrieveObjectIdentityPrimaryKey(ObjectIdentity oid) {
337:                try {
338:                    return new Long(jdbcTemplate.queryForLong(
339:                            selectObjectIdentityPrimaryKey, new Object[] {
340:                                    oid.getJavaType().getName(),
341:                                    oid.getIdentifier() }));
342:                } catch (DataAccessException notFound) {
343:                    return null;
344:                }
345:            }
346:
347:            /**
348:             * This implementation will simply delete all ACEs in the database and recreate them on each invocation of
349:             * this method. A more comprehensive implementation might use dirty state checking, or more likely use ORM
350:             * capabilities for create, update and delete operations of {@link MutableAcl}.
351:             *
352:             * @param acl DOCUMENT ME!
353:             *
354:             * @return DOCUMENT ME!
355:             *
356:             * @throws NotFoundException DOCUMENT ME!
357:             */
358:            public MutableAcl updateAcl(MutableAcl acl)
359:                    throws NotFoundException {
360:                Assert.notNull(acl.getId(),
361:                        "Object Identity doesn't provide an identifier");
362:
363:                // Delete this ACL's ACEs in the acl_entry table
364:                deleteEntries(acl.getObjectIdentity());
365:
366:                // Create this ACL's ACEs in the acl_entry table
367:                createEntries(acl);
368:
369:                // Change the mutable columns in acl_object_identity
370:                updateObjectIdentity(acl);
371:
372:                // Clear the cache
373:                aclCache.evictFromCache(acl.getObjectIdentity());
374:
375:                // Retrieve the ACL via superclass (ensures cache registration, proper retrieval etc)
376:                return (MutableAcl) super .readAclById(acl.getObjectIdentity());
377:            }
378:
379:            /**
380:             * Updates an existing acl_object_identity row, with new information presented in the passed MutableAcl
381:             * object. Also will create an acl_sid entry if needed for the Sid that owns the MutableAcl.
382:             *
383:             * @param acl to modify (a row must already exist in acl_object_identity)
384:             *
385:             * @throws NotFoundException DOCUMENT ME!
386:             */
387:            protected void updateObjectIdentity(MutableAcl acl) {
388:                Long parentId = null;
389:
390:                if (acl.getParentAcl() != null) {
391:                    Assert.isInstanceOf(ObjectIdentityImpl.class, acl
392:                            .getParentAcl().getObjectIdentity(),
393:                            "Implementation only supports ObjectIdentityImpl");
394:
395:                    ObjectIdentityImpl oii = (ObjectIdentityImpl) acl
396:                            .getParentAcl().getObjectIdentity();
397:                    parentId = retrieveObjectIdentityPrimaryKey(oii);
398:                }
399:
400:                Assert.notNull(acl.getOwner(),
401:                        "Owner is required in this implementation");
402:
403:                Long ownerSid = createOrRetrieveSidPrimaryKey(acl.getOwner(),
404:                        true);
405:                int count = jdbcTemplate.update(updateObjectIdentity,
406:                        new Object[] { parentId, ownerSid,
407:                                new Boolean(acl.isEntriesInheriting()),
408:                                acl.getId() });
409:
410:                if (count != 1) {
411:                    throw new NotFoundException(
412:                            "Unable to locate ACL to update");
413:                }
414:            }
415:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.