Source Code Cross Referenced for JdbcDaoImpl.java in  » Security » acegi-security » org » acegisecurity » acl » basic » 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.acl.basic.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:
016:        package org.acegisecurity.acl.basic.jdbc;
017:
018:        import org.acegisecurity.acl.basic.AclObjectIdentity;
019:        import org.acegisecurity.acl.basic.BasicAclDao;
020:        import org.acegisecurity.acl.basic.BasicAclEntry;
021:        import org.acegisecurity.acl.basic.NamedEntityObjectIdentity;
022:
023:        import org.apache.commons.logging.Log;
024:        import org.apache.commons.logging.LogFactory;
025:
026:        import org.springframework.context.ApplicationContextException;
027:
028:        import org.springframework.jdbc.core.SqlParameter;
029:        import org.springframework.jdbc.core.support.JdbcDaoSupport;
030:        import org.springframework.jdbc.object.MappingSqlQuery;
031:
032:        import org.springframework.util.Assert;
033:
034:        import java.sql.ResultSet;
035:        import java.sql.SQLException;
036:        import java.sql.Types;
037:
038:        import java.util.List;
039:        import java.util.Vector;
040:
041:        import javax.sql.DataSource;
042:
043:        /**
044:         * Retrieves ACL details from a JDBC location.
045:         * <p>
046:         * A default database structure is assumed. This may be overridden by setting the default query strings to use.
047:         * If this does not provide enough flexibility, another strategy would be to subclass this class and override the
048:         * {@link MappingSqlQuery} instance used, via the {@link #initMappingSqlQueries()} extension point.
049:         * </p>
050:         */
051:        public class JdbcDaoImpl extends JdbcDaoSupport implements  BasicAclDao {
052:            //~ Static fields/initializers =====================================================================================
053:
054:            public static final String RECIPIENT_USED_FOR_INHERITENCE_MARKER = "___INHERITENCE_MARKER_ONLY___";
055:            public static final String DEF_ACLS_BY_OBJECT_IDENTITY_QUERY = "SELECT RECIPIENT, MASK FROM acl_permission WHERE acl_object_identity = ?";
056:            public static final String DEF_OBJECT_PROPERTIES_QUERY = "SELECT CHILD.ID, "
057:                    + "CHILD.OBJECT_IDENTITY, "
058:                    + "CHILD.ACL_CLASS, "
059:                    + "PARENT.OBJECT_IDENTITY as PARENT_OBJECT_IDENTITY "
060:                    + "FROM acl_object_identity as CHILD "
061:                    + "LEFT OUTER JOIN acl_object_identity as PARENT ON CHILD.parent_object=PARENT.id "
062:                    + "WHERE CHILD.object_identity = ?";
063:            private static final Log logger = LogFactory
064:                    .getLog(JdbcDaoImpl.class);
065:
066:            //~ Instance fields ================================================================================================
067:
068:            protected MappingSqlQuery aclsByObjectIdentity;
069:            protected MappingSqlQuery objectProperties;
070:            private String aclsByObjectIdentityQuery;
071:            private String objectPropertiesQuery;
072:
073:            //~ Constructors ===================================================================================================
074:
075:            public JdbcDaoImpl() {
076:                aclsByObjectIdentityQuery = DEF_ACLS_BY_OBJECT_IDENTITY_QUERY;
077:                objectPropertiesQuery = DEF_OBJECT_PROPERTIES_QUERY;
078:            }
079:
080:            //~ Methods ========================================================================================================
081:
082:            /**
083:             * Responsible for covering a <code>AclObjectIdentity</code> to a <code>String</code> that can be located
084:             * in the RDBMS.
085:             *
086:             * @param aclObjectIdentity to locate
087:             *
088:             * @return the object identity as a <code>String</code>
089:             */
090:            protected String convertAclObjectIdentityToString(
091:                    AclObjectIdentity aclObjectIdentity) {
092:                // Ensure we can process this type of AclObjectIdentity
093:                Assert
094:                        .isInstanceOf(
095:                                NamedEntityObjectIdentity.class,
096:                                aclObjectIdentity,
097:                                "Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: "
098:                                        + aclObjectIdentity + ")");
099:
100:                NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity;
101:
102:                // Compose the String we expect to find in the RDBMS
103:                return neoi.getClassname() + ":" + neoi.getId();
104:            }
105:
106:            /**
107:             * Constructs an individual <code>BasicAclEntry</code> from the passed <code>AclDetailsHolder</code>s.<P>Guarantees
108:             * to never return <code>null</code> (exceptions are thrown in the event of any issues).</p>
109:             *
110:             * @param propertiesInformation mandatory information about which instance to create, the object identity, and the
111:             *        parent object identity (<code>null</code> or empty <code>String</code>s prohibited for
112:             *        <code>aclClass</code> and <code>aclObjectIdentity</code>
113:             * @param aclInformation optional information about the individual ACL record (if <code>null</code> only an
114:             *        "inheritence marker" instance is returned which will include a recipient of {@link
115:             *        #RECIPIENT_USED_FOR_INHERITENCE_MARKER} ; if not <code>null</code>, it is prohibited to present
116:             *        <code>null</code> or an empty <code>String</code> for <code>recipient</code>)
117:             *
118:             * @return a fully populated instance suitable for use by external objects
119:             *
120:             * @throws IllegalArgumentException if the indicated ACL class could not be created
121:             */
122:            private BasicAclEntry createBasicAclEntry(
123:                    AclDetailsHolder propertiesInformation,
124:                    AclDetailsHolder aclInformation) {
125:                BasicAclEntry entry;
126:
127:                try {
128:                    entry = (BasicAclEntry) propertiesInformation.getAclClass()
129:                            .newInstance();
130:                } catch (InstantiationException ie) {
131:                    throw new IllegalArgumentException(ie.getMessage());
132:                } catch (IllegalAccessException iae) {
133:                    throw new IllegalArgumentException(iae.getMessage());
134:                }
135:
136:                entry.setAclObjectIdentity(propertiesInformation
137:                        .getAclObjectIdentity());
138:                entry.setAclObjectParentIdentity(propertiesInformation
139:                        .getAclObjectParentIdentity());
140:
141:                if (aclInformation == null) {
142:                    // this is an inheritence marker instance only
143:                    entry.setMask(0);
144:                    entry.setRecipient(RECIPIENT_USED_FOR_INHERITENCE_MARKER);
145:                } else {
146:                    // this is an individual ACL entry
147:                    entry.setMask(aclInformation.getMask());
148:                    entry.setRecipient(aclInformation.getRecipient());
149:                }
150:
151:                return entry;
152:            }
153:
154:            /**
155:             * Returns the ACLs associated with the requested <code>AclObjectIdentity</code>.<P>The {@link
156:             * BasicAclEntry}s returned by this method will have <code>String</code>-based recipients. This will not be a
157:             * problem if you are using the <code>GrantedAuthorityEffectiveAclsResolver</code>, which is the default
158:             * configured against <code>BasicAclProvider</code>.</p>
159:             *  <P>This method will only return ACLs for requests where the <code>AclObjectIdentity</code> is of type
160:             * {@link NamedEntityObjectIdentity}. Of course, you can subclass or replace this class and support your own
161:             * custom <code>AclObjectIdentity</code> types.</p>
162:             *
163:             * @param aclObjectIdentity for which ACL information is required (cannot be <code>null</code> and must be an
164:             *        instance of <code>NamedEntityObjectIdentity</code>)
165:             *
166:             * @return the ACLs that apply (without any <code>null</code>s inside the array), or <code>null</code> if not found
167:             *         or if an incompatible <code>AclObjectIdentity</code> was requested
168:             */
169:            public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
170:                String aclObjectIdentityString;
171:
172:                try {
173:                    aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
174:                } catch (IllegalArgumentException unsupported) {
175:                    return null; // pursuant to contract described in JavaDocs above
176:                }
177:
178:                // Lookup the object's main properties from the RDBMS (guaranteed no nulls)
179:                List objects = objectProperties
180:                        .execute(aclObjectIdentityString);
181:
182:                if (objects.size() == 0) {
183:                    // this is an unknown object identity string
184:                    return null;
185:                }
186:
187:                // Cast to an object properties holder (there should only be one record)
188:                AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects
189:                        .get(0);
190:
191:                // Lookup the object's ACLs from RDBMS (guaranteed no nulls)
192:                List acls = aclsByObjectIdentity.execute(propertiesInformation
193:                        .getForeignKeyId());
194:
195:                if (acls.size() == 0) {
196:                    // return merely an inheritence marker (as we know about the object but it has no related ACLs)
197:                    return new BasicAclEntry[] { createBasicAclEntry(
198:                            propertiesInformation, null) };
199:                } else {
200:                    // return the individual ACL instances
201:                    AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls
202:                            .toArray(new AclDetailsHolder[] {});
203:                    List toReturnAcls = new Vector();
204:
205:                    for (int i = 0; i < aclHolders.length; i++) {
206:                        toReturnAcls.add(createBasicAclEntry(
207:                                propertiesInformation, aclHolders[i]));
208:                    }
209:
210:                    return (BasicAclEntry[]) toReturnAcls
211:                            .toArray(new BasicAclEntry[] {});
212:                }
213:            }
214:
215:            public MappingSqlQuery getAclsByObjectIdentity() {
216:                return aclsByObjectIdentity;
217:            }
218:
219:            public String getAclsByObjectIdentityQuery() {
220:                return aclsByObjectIdentityQuery;
221:            }
222:
223:            public String getObjectPropertiesQuery() {
224:                return objectPropertiesQuery;
225:            }
226:
227:            protected void initDao() throws ApplicationContextException {
228:                initMappingSqlQueries();
229:            }
230:
231:            /**
232:             * Extension point to allow other MappingSqlQuery objects to be substituted in a subclass
233:             */
234:            protected void initMappingSqlQueries() {
235:                setAclsByObjectIdentity(new AclsByObjectIdentityMapping(
236:                        getDataSource()));
237:                setObjectProperties(new ObjectPropertiesMapping(getDataSource()));
238:            }
239:
240:            public void setAclsByObjectIdentity(
241:                    MappingSqlQuery aclsByObjectIdentityQuery) {
242:                this .aclsByObjectIdentity = aclsByObjectIdentityQuery;
243:            }
244:
245:            /**
246:             * Allows the default query string used to retrieve ACLs based on object identity to be overriden, if
247:             * default table or column names need to be changed. The default query is {@link
248:             * #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying this query, ensure that all returned columns are mapped
249:             * back to the same column names as in the default query.
250:             *
251:             * @param queryString The query string to set
252:             */
253:            public void setAclsByObjectIdentityQuery(String queryString) {
254:                aclsByObjectIdentityQuery = queryString;
255:            }
256:
257:            public void setObjectProperties(
258:                    MappingSqlQuery objectPropertiesQuery) {
259:                this .objectProperties = objectPropertiesQuery;
260:            }
261:
262:            public void setObjectPropertiesQuery(String queryString) {
263:                objectPropertiesQuery = queryString;
264:            }
265:
266:            //~ Inner Classes ==================================================================================================
267:
268:            /**
269:             * Used to hold details of a domain object instance's properties, or an individual ACL entry.<P>Not all
270:             * properties will be set. The actual properties set will depend on which <code>MappingSqlQuery</code> creates the
271:             * object.</p>
272:             *  <P>Does not enforce <code>null</code>s or empty <code>String</code>s as this is performed by the
273:             * <code>MappingSqlQuery</code> objects (or preferably the backend RDBMS via schema constraints).</p>
274:             */
275:            protected final class AclDetailsHolder {
276:                private AclObjectIdentity aclObjectIdentity;
277:                private AclObjectIdentity aclObjectParentIdentity;
278:                private Class aclClass;
279:                private Object recipient;
280:                private int mask;
281:                private long foreignKeyId;
282:
283:                /**
284:                 * Record details of an individual ACL entry (usually from the
285:                 * ACL_PERMISSION table)
286:                 *
287:                 * @param recipient the recipient
288:                 * @param mask the integer to be masked
289:                 */
290:                public AclDetailsHolder(Object recipient, int mask) {
291:                    this .recipient = recipient;
292:                    this .mask = mask;
293:                }
294:
295:                /**
296:                 * Record details of a domain object instance's properties (usually
297:                 * from the ACL_OBJECT_IDENTITY table)
298:                 *
299:                 * @param foreignKeyId used by the
300:                 *        <code>AclsByObjectIdentityMapping</code> to locate the
301:                 *        individual ACL entries
302:                 * @param aclObjectIdentity the object identity of the domain object
303:                 *        instance
304:                 * @param aclObjectParentIdentity the object identity of the domain
305:                 *        object instance's parent
306:                 * @param aclClass the class of which a new instance which should be
307:                 *        created for each individual ACL entry (or an inheritence
308:                 *        "holder" class if there are no ACL entries)
309:                 */
310:                public AclDetailsHolder(long foreignKeyId,
311:                        AclObjectIdentity aclObjectIdentity,
312:                        AclObjectIdentity aclObjectParentIdentity,
313:                        Class aclClass) {
314:                    this .foreignKeyId = foreignKeyId;
315:                    this .aclObjectIdentity = aclObjectIdentity;
316:                    this .aclObjectParentIdentity = aclObjectParentIdentity;
317:                    this .aclClass = aclClass;
318:                }
319:
320:                public Class getAclClass() {
321:                    return aclClass;
322:                }
323:
324:                public AclObjectIdentity getAclObjectIdentity() {
325:                    return aclObjectIdentity;
326:                }
327:
328:                public AclObjectIdentity getAclObjectParentIdentity() {
329:                    return aclObjectParentIdentity;
330:                }
331:
332:                public long getForeignKeyId() {
333:                    return foreignKeyId;
334:                }
335:
336:                public int getMask() {
337:                    return mask;
338:                }
339:
340:                public Object getRecipient() {
341:                    return recipient;
342:                }
343:            }
344:
345:            /**
346:             * Query object to look up individual ACL entries.<P>Returns the generic <code>AclDetailsHolder</code>
347:             * object.</p>
348:             *  <P>Guarantees to never return <code>null</code> (exceptions are thrown in the event of any issues).</p>
349:             *  <P>The executed SQL requires the following information be made available from the indicated
350:             * placeholders: 1. RECIPIENT, 2. MASK.</p>
351:             */
352:            protected class AclsByObjectIdentityMapping extends MappingSqlQuery {
353:                protected AclsByObjectIdentityMapping(DataSource ds) {
354:                    super (ds, aclsByObjectIdentityQuery);
355:                    declareParameter(new SqlParameter(Types.BIGINT));
356:                    compile();
357:                }
358:
359:                protected Object mapRow(ResultSet rs, int rownum)
360:                        throws SQLException {
361:                    String recipient = rs.getString(1);
362:                    int mask = rs.getInt(2);
363:                    Assert.hasText(recipient, "recipient required");
364:
365:                    return new AclDetailsHolder(recipient, mask);
366:                }
367:            }
368:
369:            /**
370:             * Query object to look up properties for an object identity.<P>Returns the generic
371:             * <code>AclDetailsHolder</code> object.</p>
372:             *  <P>Guarantees to never return <code>null</code> (exceptions are thrown in the event of any issues).</p>
373:             *  <P>The executed SQL requires the following information be made available from the indicated
374:             * placeholders: 1. ID, 2. OBJECT_IDENTITY, 3. ACL_CLASS and 4. PARENT_OBJECT_IDENTITY.</p>
375:             */
376:            protected class ObjectPropertiesMapping extends MappingSqlQuery {
377:                protected ObjectPropertiesMapping(DataSource ds) {
378:                    super (ds, objectPropertiesQuery);
379:                    declareParameter(new SqlParameter(Types.VARCHAR));
380:                    compile();
381:                }
382:
383:                private AclObjectIdentity buildIdentity(String identity) {
384:                    if (identity == null) {
385:                        // Must be an empty parent, so return null
386:                        return null;
387:                    }
388:
389:                    int delim = identity.lastIndexOf(":");
390:                    String classname = identity.substring(0, delim);
391:                    String id = identity.substring(delim + 1);
392:
393:                    return new NamedEntityObjectIdentity(classname, id);
394:                }
395:
396:                protected Object mapRow(ResultSet rs, int rownum)
397:                        throws SQLException {
398:                    long id = rs.getLong(1); // required
399:                    String objectIdentity = rs.getString(2); // required
400:                    String aclClass = rs.getString(3); // required
401:                    String parentObjectIdentity = rs.getString(4); // optional
402:                    Assert
403:                            .hasText(
404:                                    objectIdentity,
405:                                    "required DEF_OBJECT_PROPERTIES_QUERY value (objectIdentity) returned null or empty");
406:                    Assert
407:                            .hasText(aclClass,
408:                                    "required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty");
409:
410:                    Class aclClazz;
411:
412:                    try {
413:                        aclClazz = this .getClass().getClassLoader().loadClass(
414:                                aclClass);
415:                    } catch (ClassNotFoundException cnf) {
416:                        throw new IllegalArgumentException(cnf.getMessage());
417:                    }
418:
419:                    return new AclDetailsHolder(id,
420:                            buildIdentity(objectIdentity),
421:                            buildIdentity(parentObjectIdentity), aclClazz);
422:                }
423:            }
424:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.