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.Group;
26  import org.apache.fulcrum.security.spi.AbstractGroupManager;
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.GroupSet;
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  /**
38   * This implementation persists to a database via Torque.
39   *
40   * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
41   * @version $Id:$
42   */
43  public abstract class TorqueAbstractGroupManager extends AbstractGroupManager implements LazyLoadable 
44  {
45      
46  	/** Serial version */
47  	private static final long serialVersionUID = -3735730556110100621L;
48  	
49      private static final String LAZY_LOADING = "lazy";
50      protected Boolean lazyLoading = false;
51  	
52      /**
53       * Avalon Service lifecycle method
54       */
55      @Override
56      public void configure(Configuration conf) throws ConfigurationException
57      {
58         super.configure( conf );
59         lazyLoading = conf.getAttributeAsBoolean( LAZY_LOADING, false);
60         getLogger().debug("setting lazyLoading: " + lazyLoading);
61      }
62      
63      /**
64       * Get all specialized Groups
65       *
66       * @param con a database connection
67       *
68       * @return a List of Group instances
69       *
70       * @throws TorqueException  if any database error occurs
71       */
72      protected abstract <T extends Group> List<T> doSelectAllGroups(Connection con)
73          throws TorqueException;
74  
75      /**
76       * Get a specialized Group by name
77       *
78       * @param name the name of the group
79       * @param con a database connection
80       *
81       * @return a Group 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 Group> T doSelectByName(String name, Connection con)
88          throws NoRowsException, TooManyRowsException, TorqueException;
89  
90      /**
91       * Get a specialized Group by id
92       *
93       * @param id the id of the group
94       * @param con a database connection
95       *
96       * @return a Group 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 Group> T doSelectById(Integer id, Connection con)
103         throws NoRowsException, TooManyRowsException, TorqueException;
104 
105     /**
106     * Creates a new group with specified attributes.
107     *
108     * @param group the object describing the group to be created.
109     * @return a new Group object that has id set up properly.
110     * @throws DataBackendException if there was an error accessing the data
111     *         backend.
112     */
113     @Override
114 	protected synchronized <T extends Group> T persistNewGroup(T group) throws DataBackendException
115     {
116         try
117         {
118         	
119             ((TorqueAbstractSecurityEntity)group).save();
120         }
121         catch (Exception e)
122         {
123             throw new DataBackendException("Adding Group '" + group.getName() + "' failed", e);
124         }
125 
126         return group;
127     }
128 
129     /**
130     * Renames an existing Group.
131     *
132     * @param group The object describing the group to be renamed.
133     * @param name the new name for the group.
134     * @throws DataBackendException if there was an error accessing the data
135     *         backend.
136     * @throws UnknownEntityException if the group does not exist.
137     */
138     @Override
139 	public synchronized void renameGroup(Group group, String name) throws DataBackendException, UnknownEntityException
140     {
141         if (checkExists(group))
142         {
143             group.setName(name);
144 
145             try
146             {
147                 TorqueAbstractSecurityEntityg/apache/fulcrum/security/torque/security/TorqueAbstractSecurityEntity.html#TorqueAbstractSecurityEntity">TorqueAbstractSecurityEntity g = (TorqueAbstractSecurityEntity)group;
148                 g.setNew(false);
149                 g.save();
150             }
151             catch (Exception e)
152             {
153                 throw new DataBackendException("Renaming Group '" + group.getName() + "' failed", e);
154             }
155         }
156         else
157         {
158             throw new UnknownEntityException("Unknown group '" + group.getName() + "'");
159         }
160     }
161 
162     /**
163     * Removes a Group from the system.
164     *
165     * @param group The object describing the group to be removed.
166     * @throws DataBackendException if there was an error accessing the data
167     *         backend.
168     * @throws UnknownEntityException if the group does not exist.
169     */
170     @Override
171 	public synchronized void removeGroup(Group group) throws DataBackendException, UnknownEntityException
172     {
173         try
174         {
175             ((TorqueAbstractSecurityEntity)group).delete();
176         }
177         catch (TorqueException e)
178         {
179             throw new DataBackendException("Removing Group '" + group.getName() + "' failed", e);
180         }
181     }
182 
183     /**
184      * Retrieve a Group object with specified name.
185      *
186      * @param name the name of the Group.
187      * @return an object representing the Group with specified name.
188      * @throws DataBackendException if there was an error accessing the
189      *         data backend.
190      * @throws UnknownEntityException if the group does not exist.
191      */
192     @Override
193 	public <T extends Group> T getGroupByName(String name) throws DataBackendException, UnknownEntityException
194     {
195         T group = null;
196         Connection con = null;
197 
198         try
199         {
200             con = Transaction.begin();
201 
202             group = doSelectByName(name, con);
203 
204             // Add dependent objects if they exist
205             ((TorqueAbstractSecurityEntity)group).retrieveAttachedObjects(con, getLazyLoading());
206 
207             Transaction.commit(con);
208             con = null;
209         }
210         catch (NoRowsException e)
211         {
212             throw new UnknownEntityException("Could not find group " + name);
213         }
214         catch (TooManyRowsException e)
215         {
216             throw new DataBackendException("Multiple Groups with same name '" + name + "'");
217         }
218         catch (TorqueException e)
219         {
220             throw new DataBackendException("Error retrieving group information", e);
221         }
222         finally
223         {
224             if (con != null)
225             {
226                 Transaction.safeRollback(con);
227             }
228         }
229 
230         return group;
231     }
232 
233     /**
234      * Retrieves all groups defined in the system.
235      *
236      * @return the names of all groups defined in the system.
237      * @throws DataBackendException if there was an error accessing the
238      *         data backend.
239      */
240     @Override
241 	public GroupSet getAllGroups() throws DataBackendException
242     {
243         GroupSet groupSet = new GroupSet();
244         Connection con = null;
245 
246         try
247         {
248         
249             con = Transaction.begin();
250 
251             List<Group> groups = doSelectAllGroups(con);
252 
253             for (Group group : groups)
254             {
255                 // Add dependent objects if they exist
256                 ((TorqueAbstractSecurityEntity)group).retrieveAttachedObjects(con, getLazyLoading());
257 
258                 groupSet.add(group);
259             }
260 
261             Transaction.commit(con);
262             con = null;
263         }
264         catch (TorqueException e)
265         {
266             throw new DataBackendException("Error retrieving group information", e);
267         }
268         finally
269         {
270             if (con != null)
271             {
272                 Transaction.safeRollback(con);
273             }
274         }
275 
276         return groupSet;
277     }
278 
279     /**
280      * Determines if the <code>Group</code> exists in the security system.
281      *
282      * @param groupName a <code>Group</code> value
283      * @return true if the group name exists in the system, false otherwise
284      * @throws DataBackendException when more than one Group with
285      *         the same name exists.
286      */
287     @Override
288 	public boolean checkExists(String groupName) throws DataBackendException
289     {
290         boolean exists = false;
291 
292         Connection con = null;
293 
294         try
295         {
296             con = Transaction.begin();
297 
298             doSelectByName(groupName, con);
299 
300             Transaction.commit(con);
301             con = null;
302 
303             exists = true;
304         }
305         catch (NoRowsException e)
306         {
307             exists = false;
308         }
309         catch (TooManyRowsException e)
310         {
311             throw new DataBackendException(
312                     "Multiple groups with same name '" + groupName + "'");
313         }
314         catch (TorqueException e)
315         {
316             throw new DataBackendException("Error retrieving group information", e);
317         }
318         finally
319         {
320             if (con != null)
321             {
322                 Transaction.safeRollback(con);
323             }
324         }
325 
326         return exists;
327     }
328 
329     /**
330      * Retrieve a Group object with specified id.
331      *
332      * @param id
333      *            the id of the Group.
334      * @return an object representing the Group with specified id.
335      * @throws DataBackendException
336      *             if there was an error accessing the data backend.
337      * @throws UnknownEntityException
338      *             if the group does not exist.
339      */
340     @Override
341 	public <T extends Group> T getGroupById(Object id) throws DataBackendException, UnknownEntityException
342     {
343         T group;
344 
345         if (id != null && id instanceof Integer)
346         {
347             Connection con = null;
348 
349             try
350             {
351                 con = Transaction.begin();
352 
353                 group = doSelectById((Integer)id, con);
354 
355                 // Add dependent objects if they exist
356                 ((TorqueAbstractSecurityEntity)group).retrieveAttachedObjects(con, getLazyLoading());
357 
358                 Transaction.commit(con);
359                 con = null;
360             }
361             catch (NoRowsException e)
362             {
363                 throw new UnknownEntityException("Group with id '" + id + "' does not exist.", e);
364             }
365             catch (TorqueException e)
366             {
367                 throw new DataBackendException("Error retrieving group information", e);
368             }
369             finally
370             {
371                 if (con != null)
372                 {
373                     Transaction.safeRollback(con);
374                 }
375             }
376         }
377         else
378         {
379             throw new UnknownEntityException("Invalid group id '" + id + "'");
380         }
381 
382         return group;
383     }
384 
385     public Boolean getLazyLoading()
386     {
387         return lazyLoading;
388     }
389 
390     public void setLazyLoading( Boolean lazyLoading )
391     {
392         this.lazyLoading = lazyLoading;
393     }
394 }