EMMA Coverage Report (generated Sun May 02 20:42:29 CEST 2010)
[all classes][hu.netmind.beankeeper.service.impl]

COVERAGE SUMMARY FOR SOURCE FILE [StoreContextImpl.java]

nameclass, %method, %block, %line, %
StoreContextImpl.java67%  (2/3)69%  (9/13)76%  (401/530)81%  (74.8/92)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class StoreContextImpl$10%   (0/1)100% (0/0)100% (0/0)100% (0/0)
     
class StoreContextImpl$ShutdownProcess100% (1/1)67%  (2/3)53%  (10/19)25%  (1/4)
run (): void 0%   (0/1)0%   (0/9)0%   (0/3)
StoreContextImpl$ShutdownProcess (StoreContextImpl): void 100% (1/1)100% (6/6)100% (1/1)
StoreContextImpl$ShutdownProcess (StoreContextImpl, StoreContextImpl$1): void 100% (1/1)100% (4/4)100% (1/1)
     
class StoreContextImpl100% (1/1)70%  (7/10)77%  (391/511)84%  (74.8/89)
access$102 (StoreContextImpl, boolean): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
getParameters (): Map 0%   (0/1)0%   (0/3)0%   (0/1)
hasService (String): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
injectServices (Object): void 100% (1/1)58%  (50/86)81%  (13/16)
init (Map): void 100% (1/1)75%  (125/167)82%  (27/33)
getServiceInterfaces (Class): Set 100% (1/1)76%  (44/58)92%  (11/12)
release (): void 100% (1/1)80%  (48/60)87%  (13/15)
<static initializer> 100% (1/1)100% (91/91)100% (2/2)
StoreContextImpl (): void 100% (1/1)100% (27/27)100% (8/8)
getService (String): Service 100% (1/1)100% (6/6)100% (1/1)

1/**
2 * Copyright (C) 2006 NetMind Consulting Bt.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 
19package hu.netmind.beankeeper.service.impl;
20 
21import hu.netmind.beankeeper.service.StoreContext;
22import hu.netmind.beankeeper.service.Service;
23import hu.netmind.beankeeper.service.ServiceFactory;
24import hu.netmind.beankeeper.common.StoreException;
25import java.util.*;
26import java.lang.reflect.Field;
27import org.apache.log4j.Logger;
28 
29/**
30 * This is the context for all the services. Basically a mini
31 * dependency injection engine.
32 * @author Brautigam Robert
33 * @version Revision: $Revision$
34 */
35public class StoreContextImpl implements StoreContext
36{
37   private static final String[] SERVICES = 
38   {
39      "hu.netmind.beankeeper.event.impl.EventDispatcherImpl",
40      "hu.netmind.beankeeper.management.impl.ManagementTrackerImpl",
41      "hu.netmind.beankeeper.config.impl.ConfigurationTrackerImpl",
42      "hu.netmind.beankeeper.logging.impl.SnapshotLoggerImpl",
43      "hu.netmind.beankeeper.logging.impl.AggregatorLoggerImpl",
44      "hu.netmind.beankeeper.db.impl.DatabaseFactory",
45      "hu.netmind.beankeeper.transaction.impl.InternalTransactionTrackerImpl",
46      "hu.netmind.beankeeper.node.impl.NodeManagerImpl",
47      "hu.netmind.beankeeper.serial.impl.SerialTrackerImpl",
48      "hu.netmind.beankeeper.operation.impl.OperationTrackerImpl",
49      "hu.netmind.beankeeper.transaction.impl.TransactionTrackerImpl",
50      "hu.netmind.beankeeper.type.impl.TypeHandlerTrackerImpl",
51      "hu.netmind.beankeeper.model.impl.ClassTrackerImpl",
52      "hu.netmind.beankeeper.schema.impl.SchemaManagerImpl",
53      "hu.netmind.beankeeper.object.impl.ObjectTrackerImpl",
54      "hu.netmind.beankeeper.cache.impl.MinimalResultsCache",
55      "hu.netmind.beankeeper.query.impl.QueryServiceImpl",
56      "hu.netmind.beankeeper.modification.impl.ModificationTrackerImpl",
57      "hu.netmind.beankeeper.lock.impl.LockTrackerImpl",
58      "hu.netmind.beankeeper.type.impl.DefaultHandlersService",
59      "hu.netmind.beankeeper.store.impl.StoreServiceImpl",
60   };
61   private static final Logger logger = Logger.getLogger(StoreContext.class);
62 
63   private Map parameters = new HashMap();
64   private Map<String,Service> services = new HashMap<String,Service>();
65   private List<Service> initOrder = new ArrayList<Service>();
66   private Thread shutdownHook = null;
67   private boolean shutdownRunning = false;
68   private boolean released = false;
69 
70   /**
71    * Initialize this context. This method populates the services
72    * and registers the shutdown hook.
73    */
74   public void init(Map parameters)
75   {
76      logger.debug("initializing store context with parameters: "+parameters);
77      this.parameters.putAll(parameters);
78      // First, insert self as a service
79      services.put(StoreContext.class.getName(),this);
80      // Initialize dependencies as given in the list
81      logger.debug("initializing services");
82      for ( String serviceClassName : SERVICES )
83      {
84         try
85         {
86            // Get the implementation class
87            Class serviceClass = Class.forName(serviceClassName);
88            // Initialize the service
89            if ( logger.isDebugEnabled() )
90               logger.debug("initializing service: "+serviceClassName);
91            // Creating and adding the service
92            Service service = (Service) serviceClass.newInstance();
93            // Inject & Initialize
94            injectServices(service);
95            service.init(parameters);
96            // If this is a factory, then create real service object
97            if ( service instanceof ServiceFactory )
98            {
99               Service realService = ((ServiceFactory) service).getService();
100               injectServices(realService);
101               realService.init(parameters);
102               service.release();
103               service = realService;
104               serviceClass = realService.getClass();
105            }
106            // Initialization ok, add
107            Set<Class> serviceInterfaces = getServiceInterfaces(serviceClass);
108            for ( Class serviceInterface : serviceInterfaces )
109               services.put(serviceInterface.getName(),service);
110            initOrder.add(service);
111            if ( logger.isDebugEnabled() )
112               logger.debug("initialized service '"+serviceClass.getName()+"' which implements: "+serviceInterfaces);
113         } catch ( StoreException e ) {
114            throw e;
115         } catch ( Exception e ) {
116            throw new StoreException("could not initialize service: "+serviceClassName,e);
117         }
118      }
119      // Proper shutdown
120      shutdownHook = new Thread(new ShutdownProcess());
121      Runtime.getRuntime().addShutdownHook(shutdownHook);
122      // Ok
123      logger.debug("store initialization complete, good luck");
124   }
125 
126   /**
127    * Determine all the interfaces a service provides.
128    */
129   private Set<Class> getServiceInterfaces(Class serviceClass)
130   {
131      Class originalClass = serviceClass;
132      // Find and register all service interfaces
133      Set<Class> result = new HashSet<Class>();
134      while ( serviceClass != null )
135      {
136         Class[] interfaces = serviceClass.getInterfaces();
137         for ( Class interfaceClass : interfaces )
138         {
139            if ( Service.class.isAssignableFrom(interfaceClass) )
140               result.add(interfaceClass);
141         }
142         serviceClass = serviceClass.getSuperclass();
143      }
144      if ( logger.isDebugEnabled() )
145         logger.debug("service '"+originalClass+"' had following interfaces: "+result);
146      return result;
147   }
148 
149   /**
150    * Inject services into the object given.
151    */
152   public void injectServices(Object obj)
153   {
154      Class objectClass = obj.getClass();
155      while ( objectClass != null )
156      {
157         Field[] fields = objectClass.getDeclaredFields();
158         for ( Field field : fields )
159         {
160            // Inject a single field
161            if ( Service.class.isAssignableFrom(field.getType()) )
162            {
163               Service service = getService(field.getType().getName());
164               if ( service == null )
165                  throw new StoreException("missing service for field: "+field.getType().getName()+", into: "+obj+", class: "+objectClass);
166               try
167               {
168                  field.setAccessible(true);
169                  field.set(obj,service);
170               } catch ( IllegalAccessException e ) {
171                  throw new StoreException("no permission to inject service to: "+field,e);
172               }
173            }
174         }
175         objectClass = objectClass.getSuperclass();
176      }
177   }
178 
179   /**
180    * Return whether the given service is available.
181    * @return True if service is available.
182    */
183   public boolean hasService(String name)
184   {
185      return getService(name) != null;
186   }
187 
188   /**
189    * Get the service under the given name.
190    * @param name The name of the service to return.
191    * @return The service under the given name.
192    */
193   public Service getService(String name)
194   {
195      return services.get(name);
196   }
197 
198   /**
199    * Close this context and release all allocated resources.
200    */
201   public void release()
202   {
203      if ( released )
204         return; // Don't release twice
205      released = true;
206      // Call release on all services in reverse order of initialization
207      List<Service> closeOrder = new ArrayList<Service>(initOrder);
208      Collections.reverse(closeOrder);
209      for ( Service service : closeOrder )
210      {
211         try
212         {
213            service.release();
214         } catch ( Exception e ) {
215            logger.error("error while releasing service: "+service,e);
216         }
217      }
218      // Clear everything
219      initOrder = new ArrayList<Service>();
220      services = new HashMap<String,Service>();
221      // Remove shutdown hook when complete
222      if ( ! shutdownRunning )
223         Runtime.getRuntime().removeShutdownHook(shutdownHook); // Do not run twice
224   }
225 
226   /**
227    * Get the parameters this context was created with.
228    */
229   public Map getParameters()
230   {
231      return parameters;
232   }
233 
234   /**
235    * This is a shutdown logic, which simply calls <code>close()</code>
236    * when the JVM exists.
237    */
238   private class ShutdownProcess implements Runnable
239   {
240      public void run()
241      {
242         shutdownRunning=true;
243         release();
244      }
245   }
246 
247}
248 
249 

[all classes][hu.netmind.beankeeper.service.impl]
EMMA 2.0.5312debian (C) Vladimir Roubtsov