1 package org.apache.archiva.redback.rbac.jdo;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.archiva.redback.rbac.Permission;
23 import org.apache.archiva.redback.rbac.RBACManagerListener;
24 import org.apache.archiva.redback.rbac.RbacManagerException;
25 import org.apache.archiva.redback.rbac.RbacObjectNotFoundException;
26 import org.apache.archiva.redback.rbac.Role;
27 import org.apache.archiva.redback.components.jdo.JdoFactory;
28 import org.codehaus.plexus.util.StringUtils;
29 import org.springframework.stereotype.Service;
31 import javax.annotation.PostConstruct;
32 import javax.annotation.Resource;
33 import javax.jdo.Extent;
34 import javax.jdo.JDOException;
35 import javax.jdo.JDOHelper;
36 import javax.jdo.JDOObjectNotFoundException;
37 import javax.jdo.JDOUserException;
38 import javax.jdo.PersistenceManager;
39 import javax.jdo.PersistenceManagerFactory;
40 import javax.jdo.Query;
41 import javax.jdo.Transaction;
42 import javax.jdo.datastore.DataStoreCache;
43 import javax.jdo.listener.DeleteLifecycleListener;
44 import javax.jdo.listener.InstanceLifecycleEvent;
45 import javax.jdo.listener.StoreLifecycleListener;
46 import javax.jdo.spi.Detachable;
47 import javax.jdo.spi.PersistenceCapable;
48 import java.io.PrintStream;
49 import java.util.Collection;
50 import java.util.Iterator;
51 import java.util.List;
54 * JdoTool - RBAC JDO Tools.
56 * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
61 implements DeleteLifecycleListener, StoreLifecycleListener
64 @Resource(name="jdoFactory#users")
65 private JdoFactory jdoFactory;
67 private PersistenceManagerFactory pmf;
69 private RBACManagerListener listener;
72 public void initialize()
74 pmf = jdoFactory.getPersistenceManagerFactory();
76 pmf.addInstanceLifecycleListener( this, null );
79 public static void dumpObjectState( PrintStream out, Object o )
81 final String STATE = "[STATE] ";
82 final String INDENT = " ";
86 out.println( STATE + "Object is null." );
90 out.println( STATE + "Object " + o.getClass().getName() );
92 if ( !( o instanceof PersistenceCapable ) )
94 out.println( INDENT + "is NOT PersistenceCapable (not a jdo object?)" );
98 out.println( INDENT + "is PersistenceCapable." );
99 if ( o instanceof Detachable )
101 out.println( INDENT + "is Detachable" );
104 out.println( INDENT + "is new : " + Boolean.toString( JDOHelper.isNew( o ) ) );
105 out.println( INDENT + "is transactional : " + Boolean.toString( JDOHelper.isTransactional( o ) ) );
106 out.println( INDENT + "is deleted : " + Boolean.toString( JDOHelper.isDeleted( o ) ) );
107 out.println( INDENT + "is detached : " + Boolean.toString( JDOHelper.isDetached( o ) ) );
108 out.println( INDENT + "is dirty : " + Boolean.toString( JDOHelper.isDirty( o ) ) );
109 out.println( INDENT + "is persistent : " + Boolean.toString( JDOHelper.isPersistent( o ) ) );
111 out.println( INDENT + "object id : " + JDOHelper.getObjectId( o ) );
114 public PersistenceManager getPersistenceManager()
116 PersistenceManager pm = pmf.getPersistenceManager();
118 pm.getFetchPlan().setMaxFetchDepth( -1 );
125 private boolean hasTriggeredInit = false;
127 @SuppressWarnings("unchecked")
128 public void triggerInit()
130 if ( !hasTriggeredInit )
132 hasTriggeredInit = true;
134 List<Role> roles = (List<Role>) getAllObjects( JdoRole.class );
136 listener.rbacInit( roles.isEmpty() );
140 public void enableCache( Class<?> clazz )
142 DataStoreCache cache = pmf.getDataStoreCache();
143 if ( cache.getClass().getName().equals( "org.jpox.cache.EhcacheClassBasedLevel2Cache" )
144 || cache.getClass().getName().equals( "org.jpox.cache.EhcacheLevel2Cache" ) )
146 /* Ehcache adapters don't support pinAll, the caching is handled in the configuration */
149 cache.pinAll( clazz, false ); // Pin all objects of type clazz from now on
152 public Object saveObject( Object object )
154 return saveObject( object, null );
157 public Object saveObject( Object object, String[] fetchGroups )
159 PersistenceManager pm = getPersistenceManager();
160 Transaction tx = pm.currentTransaction();
166 if ( ( JDOHelper.getObjectId( object ) != null ) && !JDOHelper.isDetached( object ) )
168 // This is a fatal error that means we need to fix our code.
169 // Leave it as a JDOUserException, it's intentional.
170 throw new JDOUserException( "Existing object is not detached: " + object, object );
173 if ( fetchGroups != null )
175 for ( int i = 0; i >= fetchGroups.length; i++ )
177 pm.getFetchPlan().addGroup( fetchGroups[i] );
181 pm.makePersistent( object );
183 object = pm.detachCopy( object );
191 rollbackIfActive( tx );
195 public List<?> getAllObjects( Class<?> clazz )
197 return getAllObjects( clazz, null, null );
200 public List<?> getAllObjects( Class<?> clazz, String ordering )
202 return getAllObjects( clazz, ordering, null );
205 public List<?> getAllObjects( Class<?> clazz, String ordering, String fetchGroup )
207 PersistenceManager pm = getPersistenceManager();
208 Transaction tx = pm.currentTransaction();
214 Extent extent = pm.getExtent( clazz, true );
216 Query query = pm.newQuery( extent );
218 if ( ordering != null )
220 query.setOrdering( ordering );
223 if ( fetchGroup != null )
225 pm.getFetchPlan().addGroup( fetchGroup );
228 List<?> result = (List<?>) query.execute();
230 result = (List<?>) pm.detachCopyAll( result );
238 rollbackIfActive( tx );
242 public List<?> getUserAssignmentsForRoles( Class<?> clazz, String ordering, Collection<String> roleNames )
244 PersistenceManager pm = getPersistenceManager();
245 Transaction tx = pm.currentTransaction();
251 Extent extent = pm.getExtent( clazz, true );
253 Query query = pm.newQuery( extent );
255 if ( ordering != null )
257 query.setOrdering( ordering );
260 query.declareImports( "import java.lang.String" );
262 StringBuffer filter = new StringBuffer();
264 if ( roleNames.size() > 0 )
266 Iterator<String> i = roleNames.iterator();
268 filter.append( "this.roleNames.contains(\"" ).append( i.next() ).append( "\")" );
270 while ( i.hasNext() )
272 filter.append( " || this.roleNames.contains(\"" ).append( i.next() ).append( "\")" );
275 query.setFilter( filter.toString() );
278 List<?> result = (List<?>) query.execute();
280 result = (List<?>) pm.detachCopyAll( result );
288 rollbackIfActive( tx );
292 public Object getObjectById( Class<?> clazz, String id, String fetchGroup )
293 throws RbacObjectNotFoundException, RbacManagerException
295 if ( StringUtils.isEmpty( id ) )
297 throw new RbacObjectNotFoundException(
298 "Unable to get object '" + clazz.getName() + "' from jdo using null/empty id." );
301 PersistenceManager pm = getPersistenceManager();
302 Transaction tx = pm.currentTransaction();
308 if ( fetchGroup != null )
310 pm.getFetchPlan().addGroup( fetchGroup );
313 Object objectId = pm.newObjectIdInstance( clazz, id );
315 Object object = pm.getObjectById( objectId );
317 object = pm.detachCopy( object );
323 catch ( JDOObjectNotFoundException e )
325 throw new RbacObjectNotFoundException( "Unable to find RBAC Object '" + id + "' of type " +
326 clazz.getName() + " using fetch-group '" + fetchGroup + "'", e, id );
328 catch ( JDOException e )
330 throw new RbacManagerException( "Error in JDO during get of RBAC object id '" + id + "' of type " +
331 clazz.getName() + " using fetch-group '" + fetchGroup + "'", e );
335 rollbackIfActive( tx );
339 public boolean objectExists( Object object )
341 return ( JDOHelper.getObjectId( object ) != null );
344 public boolean objectExistsById( Class<?> clazz, String id )
345 throws RbacManagerException
349 Object o = getObjectById( clazz, id, null );
350 return ( o != null );
352 catch ( RbacObjectNotFoundException e )
358 public Object removeObject( Object o )
359 throws RbacManagerException
363 throw new RbacManagerException( "Unable to remove null object" );
366 PersistenceManager pm = getPersistenceManager();
367 Transaction tx = pm.currentTransaction();
373 o = pm.getObjectById( pm.getObjectId( o ) );
375 pm.deletePersistent( o );
383 rollbackIfActive( tx );
387 public void rollbackIfActive( Transaction tx )
389 PersistenceManager pm = tx.getPersistenceManager();
400 closePersistenceManager( pm );
404 public void closePersistenceManager( PersistenceManager pm )
410 catch ( JDOUserException e )
416 public RBACManagerListener getListener()
421 public void setListener( RBACManagerListener listener )
423 this.listener = listener;
426 public void postDelete( InstanceLifecycleEvent evt )
428 PersistenceCapable obj = ( (PersistenceCapable) evt.getSource() );
432 // Do not track null objects.
433 // These events are typically a product of an internal lifecycle event.
437 if ( obj instanceof Role )
439 listener.rbacRoleRemoved( (Role) obj );
441 else if ( obj instanceof Permission )
443 listener.rbacPermissionRemoved( (Permission) obj );
447 public void preDelete( InstanceLifecycleEvent evt )
452 public void postStore( InstanceLifecycleEvent evt )
454 PersistenceCapable obj = ( (PersistenceCapable) evt.getSource() );
456 if ( obj instanceof Role )
458 listener.rbacRoleSaved( (Role) obj );
460 else if ( obj instanceof Permission )
462 listener.rbacPermissionSaved( (Permission) obj );
466 public void preStore( InstanceLifecycleEvent evt )
471 public void removeAll( Class<?> aClass )
473 PersistenceManager pm = getPersistenceManager();
474 Transaction tx = pm.currentTransaction();
480 Query query = pm.newQuery( aClass );
481 query.deletePersistentAll();
487 rollbackIfActive( tx );
491 public JdoFactory getJdoFactory()
496 public void setJdoFactory( JdoFactory jdoFactory )
498 this.jdoFactory = jdoFactory;