View Javadoc
1   package org.apache.fulcrum.security.torque;
2   /*
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   */
20  import java.sql.Connection;
21  import java.util.List;
22  
23  import org.apache.avalon.framework.configuration.Configuration;
24  import org.apache.avalon.framework.configuration.ConfigurationException;
25  import org.apache.fulcrum.security.entity.Role;
26  import org.apache.fulcrum.security.spi.AbstractRoleManager;
27  import org.apache.fulcrum.security.torque.security.TorqueAbstractSecurityEntity;
28  import org.apache.fulcrum.security.util.DataBackendException;
29  import org.apache.fulcrum.security.util.EntityExistsException;
30  import org.apache.fulcrum.security.util.RoleSet;
31  import org.apache.fulcrum.security.util.UnknownEntityException;
32  import org.apache.torque.NoRowsException;
33  import org.apache.torque.TooManyRowsException;
34  import org.apache.torque.TorqueException;
35  import org.apache.torque.util.Transaction;
36  /**
37   * This implementation persists to a database via Torque.
38   *
39   * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
40   * @version $Id:$
41   */
42  public abstract class TorqueAbstractRoleManager extends AbstractRoleManager implements LazyLoadable 
43  {
44      
45  	/** Serial version */
46  	private static final long serialVersionUID = 4258137881250800204L;
47  	
48  	private static final String LAZY_LOADING = "lazy";
49      protected Boolean lazyLoading = false;
50      
51      /**
52       * Avalon Service lifecycle method
53       */
54      @Override
55      public void configure(Configuration conf) throws ConfigurationException
56      {
57         super.configure( conf );
58         lazyLoading = conf.getAttributeAsBoolean( LAZY_LOADING, false);
59         getLogger().debug("setting lazyLoading: " + lazyLoading);
60      }
61  
62      
63      /**
64       * Get all specialized Roles
65       *
66       * @param con a database connection
67       *
68       * @return a List of Role instances
69       *
70       * @throws TorqueException  if any database error occurs
71       */
72      protected abstract <T extends Role> List<T> doSelectAllRoles(Connection con)
73          throws TorqueException;
74  
75      /**
76       * Get a specialized Role by name
77       *
78       * @param name the name of the group
79       * @param con a database connection
80       *
81       * @return a Role instance
82       *
83       * @throws NoRowsException if no such group exists
84       * @throws TooManyRowsException if multiple groups with the given name exist
85       * @throws TorqueException  if any database error occurs if any other database error occurs
86       */
87      protected abstract <T extends Role> T doSelectByName(String name, Connection con)
88          throws NoRowsException, TooManyRowsException, TorqueException;
89  
90      /**
91       * Get a specialized Role by id
92       *
93       * @param id the id of the group
94       * @param con a database connection
95       *
96       * @return a Role instance
97       *
98       * @throws NoRowsException if no such group exists
99       * @throws TooManyRowsException if multiple groups with the given id exist
100      * @throws TorqueException  if any database error occurs if any other database error occurs
101      */
102     protected abstract <T extends Role> T doSelectById(Integer id, Connection con)
103         throws NoRowsException, TooManyRowsException, TorqueException;
104 
105 
106     /**
107     * Renames an existing Role.
108     *
109     * @param role The object describing the role to be renamed.
110     * @param name the new name for the role.
111     * @throws DataBackendException if there was an error accessing the data
112     *         backend.
113     * @throws UnknownEntityException if the role does not exist.
114     */
115     @Override
116 	public synchronized void renameRole(Role role, String name) throws DataBackendException, UnknownEntityException
117     {
118         if (checkExists(role))
119         {
120             role.setName(name);
121 
122             try
123             {
124                 TorqueAbstractSecurityEntityg/apache/fulcrum/security/torque/security/TorqueAbstractSecurityEntity.html#TorqueAbstractSecurityEntity">TorqueAbstractSecurityEntity r = (TorqueAbstractSecurityEntity)role;
125                 r.setNew(false);
126                 r.save();
127             }
128             catch (Exception e)
129             {
130                 throw new DataBackendException("Renaming Role '" + role.getName() + "' failed", e);
131             }
132         }
133         else
134         {
135             throw new UnknownEntityException("Unknown Role '" + role.getName() + "'");
136         }
137     }
138 
139     /**
140     * Creates a new role with specified attributes.
141     *
142     * @param role the object describing the role to be created.
143     * @return a new Role object that has id set up properly.
144     * @throws DataBackendException if there was an error accessing the data
145     *         backend.
146     */
147     @Override
148 	protected synchronized <T extends Role> T persistNewRole(T role) throws DataBackendException
149     {
150         try
151         {
152             ((TorqueAbstractSecurityEntity)role).save();
153         }
154         catch (Exception e)
155         {
156             throw new DataBackendException("Adding Role '" + role.getName() + "' failed", e);
157         }
158 
159         return role;
160     }
161 
162     /**
163     * Removes a Role from the system.
164     *
165     * @param role The object describing the role to be removed.
166     * @throws DataBackendException if there was an error accessing the data
167     *         backend.
168     * @throws UnknownEntityException if the role does not exist.
169     */
170     @Override
171 	public synchronized void removeRole(Role role) throws DataBackendException, UnknownEntityException
172     {
173         if (checkExists(role))
174         {
175             try
176             {
177                 ((TorqueAbstractSecurityEntity)role).delete();
178             }
179             catch (TorqueException e)
180             {
181                 throw new DataBackendException("Removing Role '" + role.getName() + "' failed", e);
182             }
183         }
184         else
185         {
186             throw new UnknownEntityException("Unknown role '" + role.getName() + "'");
187         }
188     }
189 
190     /**
191       * Determines if the <code>Role</code> exists in the security system.
192       *
193       * @param roleName a <code>Role</code> value
194       * @return true if the role name exists in the system, false otherwise
195       * @throws DataBackendException when more than one Role with
196       *         the same name exists.
197       */
198     @Override
199 	public boolean checkExists(String roleName) throws DataBackendException
200     {
201         boolean exists = false;
202 
203         Connection con = null;
204 
205         try
206         {
207             con = Transaction.begin();
208 
209             doSelectByName(roleName, con);
210 
211             Transaction.commit(con);
212             con = null;
213 
214             exists = true;
215         }
216         catch (NoRowsException e)
217         {
218             exists = false;
219         }
220         catch (TooManyRowsException e)
221         {
222             throw new DataBackendException("Multiple roles with same name '" + roleName + "'");
223         }
224         catch (TorqueException e)
225         {
226             throw new DataBackendException("Error retrieving role information", e);
227         }
228         finally
229         {
230             if (con != null)
231             {
232                 Transaction.safeRollback(con);
233             }
234         }
235 
236         return exists;
237     }
238 
239     /**
240      * Retrieves all roles defined in the system.
241      *
242      * @return the names of all roles defined in the system.
243      * @throws DataBackendException if there was an error accessing the
244      *         data backend.
245      */
246     @Override
247 	public RoleSet getAllRoles() throws DataBackendException
248     {
249         RoleSet roleSet = new RoleSet();
250         Connection con = null;
251 
252         try
253         {
254             con = Transaction.begin();
255 
256             List<Role> roles = doSelectAllRoles(con);
257 
258             for (Role role : roles)
259             {
260                // Add attached objects if they exist
261                ((TorqueAbstractSecurityEntity)role).retrieveAttachedObjects(con, getLazyLoading());
262 
263                 roleSet.add(role);
264             }
265 
266             Transaction.commit(con);
267             con = null;
268         }
269         catch (TorqueException e)
270         {
271             throw new DataBackendException("Error retrieving role information", e);
272         }
273         finally
274         {
275             if (con != null)
276             {
277                 Transaction.safeRollback(con);
278             }
279         }
280 
281         return roleSet;
282     }
283 
284     /**
285      * Retrieve a Role object with specified id.
286      *
287      * @param id
288      *            the id of the Role.
289      * @return an object representing the Role with specified id.
290      * @throws DataBackendException
291      *             if there was an error accessing the data backend.
292      * @throws UnknownEntityException
293      *             if the role does not exist.
294      */
295     @Override
296 	public <T extends Role> T getRoleById(Object id) throws DataBackendException, UnknownEntityException
297     {
298         T role;
299 
300         if (id != null && id instanceof Integer)
301         {
302             Connection con = null;
303 
304             try
305             {
306                 con = Transaction.begin();
307 
308                 role = doSelectById((Integer)id, con);
309 
310                 // Add attached objects if they exist
311                 ((TorqueAbstractSecurityEntity)role).retrieveAttachedObjects(con, getLazyLoading());
312 
313                 Transaction.commit(con);
314                 con = null;
315             }
316             catch (NoRowsException e)
317             {
318                 throw new UnknownEntityException("Role with id '" + id + "' does not exist.", e);
319             }
320             catch (TorqueException e)
321             {
322                 throw new DataBackendException("Error retrieving role information", e);
323             }
324             finally
325             {
326                 if (con != null)
327                 {
328                     Transaction.safeRollback(con);
329                 }
330             }
331         }
332         else
333         {
334             throw new UnknownEntityException("Invalid role id '" + id + "'");
335         }
336 
337         return role;
338     }
339 
340     /**
341      * Retrieve a Role object with specified name.
342      *
343      * @param name the name of the Role.
344      * @return an object representing the Role with specified name.
345      * @throws DataBackendException if there was an error accessing the
346      *         data backend.
347      * @throws UnknownEntityException if the role does not exist.
348      */
349     @Override
350 	public <T extends Role> T getRoleByName(String name) throws DataBackendException, UnknownEntityException
351     {
352         T role = null;
353         Connection con = null;
354 
355         try
356         {
357             con = Transaction.begin();
358 
359             role = doSelectByName(name, con);
360 
361             // Add attached objects if they exist
362             ((TorqueAbstractSecurityEntity)role).retrieveAttachedObjects(con, getLazyLoading());
363 
364             Transaction.commit(con);
365             con = null;
366         }
367         catch (NoRowsException e)
368         {
369             throw new UnknownEntityException("Could not find role" + name);
370         }
371         catch (TooManyRowsException e)
372         {
373             throw new DataBackendException("Multiple Roles with same name '" + name + "'");
374         }
375         catch (TorqueException e)
376         {
377             throw new DataBackendException("Error retrieving role information", e);
378         }
379         finally
380         {
381             if (con != null)
382             {
383                 Transaction.safeRollback(con);
384             }
385         }
386 
387         return role;
388     }
389 
390 
391     /* (non-Javadoc)
392      * @see org.apache.fulcrum.security.torque.LazyLoadable#getLazyLoading()
393      */
394     @Override
395     public Boolean getLazyLoading()
396     {
397         return lazyLoading;
398     }
399 
400 
401     /* (non-Javadoc)
402      * @see org.apache.fulcrum.security.torque.LazyLoadable#setLazyLoading(java.lang.Boolean)
403      */
404     @Override
405     public void setLazyLoading( Boolean lazyLoading )
406     {
407         this.lazyLoading = lazyLoading;
408     }
409 }