View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.services.cache;
16  
17  import org.figure8.join.core.ContainerContextHandler;
18  import org.figure8.join.core.InfrastructureException;
19  import org.figure8.join.core.setup.BootstrapException;
20  import org.figure8.join.businessobjects.commons.Step;
21  import org.figure8.join.businessobjects.commons.Release;
22  import org.figure8.join.businessobjects.security.Role;
23  import org.figure8.join.businessobjects.artifact.DeliverableType;
24  import org.figure8.join.businessfacades.commons.IntegrationProcessManager;
25  import org.figure8.join.businessfacades.security.PermissionManager;
26  import org.figure8.join.businessfacades.artifact.ArtifactManager;
27  import org.figure8.join.util.LogUtil;
28  
29  import org.apache.commons.logging.Log;
30  
31  import javax.servlet.ServletContext;
32  
33  import java.util.List;
34  /**
35   * This object is responsible for loading the eternal caches of Join application.
36   * Once data are loaded, it exposes cached data to web tier registering a {@link EternalCacheAccessor}
37   * within application context and <code>ServletContext</code>.<br/>
38   * Because this registration is done during application context creation, we cannot
39   * use the registration method provided by the {@link ContainerContextHandler}
40   * (application context is still null) ... We have to do this in a Spring specific way
41   * by implementing <code>BeanFactoryAware</code> and using the registration method
42   * of the current <code>BeanFactory</code>.
43   * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
44   * @version $Revision: 1.2 $
45   */
46  public class CacheLoader{
47  
48     // Static -------------------------------------------------------------------
49  
50     /** Get a commons logger... */
51     private static final Log log = LogUtil.getLog(CacheLoader.class);
52  
53  
54     // Attributes ---------------------------------------------------------------
55  
56     /** Flag telling if loaded has laoded ...*/
57     private boolean loaded = false;
58     /** The registred eternal caches accessor */
59     private EternalCacheAccessor cacheAccessor = null;
60  
61     /** The CacheManager referencing caches */
62     protected CacheManager cacheManager = null;
63     /** The ArtifactManager for getting data to put in caches */
64     protected ArtifactManager artifactManager = null;
65     /** The PermissionManager for getting data to put in caches */
66     protected PermissionManager permissionManager = null;
67     /** The IntegrationProcessManager for gettnig data to put in caches */
68     protected IntegrationProcessManager processManager = null;
69  
70  
71     // Constructors -------------------------------------------------------------
72  
73     /** Creates a new instance of CacheLoader */
74     public CacheLoader(){
75     }
76  
77  
78     // Public -------------------------------------------------------------------
79  
80     /** @param cacheManager The cache manager instance to use for getting caches to load */
81     public void setCacheManager(CacheManager cacheManager){
82        this.cacheManager = cacheManager;
83     }
84     /** @param artifactManager The artifact manager instance to use for getting data */
85     public void setArtifactManager(ArtifactManager artifactManager){
86        this.artifactManager = artifactManager;
87     }
88     /** @param permissionManager The permission manager instance to use for getting data */
89     public void setPermissionManager(PermissionManager permissionManager){
90        this.permissionManager = permissionManager;
91     }
92     /** @param processManager The integration process manager instance to use for getting data */
93     public void setIntegrationProcessManager(IntegrationProcessManager processManager){
94        this.processManager = processManager;
95     }
96  
97     /** @return Flag telling if loader has already filled eternal caches */
98     public boolean hasLoadedCaches(){
99        return loaded;
100    }
101    /** @return The registred accessor for accessing eternal caches */
102    public EternalCacheAccessor getEternalCacheAccesor(){
103       return cacheAccessor;
104    }
105 
106    /**
107     * Load the eternal caches of Join application. Once data are loaded,
108     * it exposes cached data to web tier registering a {@link EternalCacheAccessor}
109     * within <code>ServletContext</code>. <br/>
110     * This method should called at application startup, after the supplied
111     * {@link CacheManager} instance has been initialized too (ex: by Spring Framework...)
112     * @throws BootstrapException if one of the eternal caches is not available
113     * of if an infrastructure exception occurs during data retrieval.
114     */
115    public void loadCaches() throws BootstrapException{
116       try{
117          // Load different caches using protected methods.
118          loadStepsCache();
119          loadRolesCache();
120          loadReleasesCache();
121          loadDeliverableTypesCache();
122          log.info("Eternal caches have been loaded.");
123          loaded = true;
124       }
125       catch (InfrastructureException ie){
126          loaded = false;
127          // Thrown by the dao layer. Maybe schema is not ready ?
128          log.warn("InfrastructureException thrown by the DAO layer: " + ie.getMessage());
129          log.warn("Here's the cause exception message: " + ie.getCause().getMessage());
130          log.warn("Mark caches as unload and do not propagate exception. Load will be retry");
131       }
132       catch (CacheException ce){
133          loaded = false;
134          // Thrown by cache implementation. Cache configuration problem ?
135          log.error("CacheException when loading caches with data: " + ce.getMessage());
136          log.error("Here's the cause exception message: " + ce.getCause().getMessage());
137          throw new BootstrapException("CacheException when loading caches with data!", ce);
138       }
139       catch (Exception e){
140          loaded = false;
141          // Unchecked exception. Propagate it as a BootstrapException ...
142          log.error("Exception in loadCaches(): " + e.getMessage());
143          if (e instanceof BootstrapException)
144             throw (BootstrapException)e;
145          throw new BootstrapException("Unchecked exception while loading caches", e);
146       }
147       try{
148          // Now register a cache accessor.
149          registerCacheAccessor();
150       }
151       catch (Exception e){
152          // Thrown by ContainerContextHandler during registration
153          log.error("Exception during the registration of the EternalCache accessor within context");
154          log.error("Here's the detailed exception message: " + e.getMessage());
155          throw new BootstrapException("Exception while registring the cache accessor", e);
156       }
157       log.info("Eternal cache accessor has been registred.");
158    }
159 
160 
161    // Protected ----------------------------------------------------------------
162 
163    /**
164     * Load the eternal cache containing {@link Step}s
165     * @throws CacheException if step cache cannot be filled with retrieved steps
166     * @throws BootstrapException if cache cannot be retrieved through its manager
167     */
168    protected void loadStepsCache() throws CacheException, BootstrapException{
169       log.info("Loading the eternal cache containing Steps...");
170       // Retrieve correct cache.
171       Cache stepsCache = cacheManager.getCache(EternalCacheKeys.STEP_ID_TO_STEP_KEY);
172       if (stepsCache != null){
173          // Get steps and put them in cache.
174          List steps = processManager.getSteps();
175          for (int i=0; i < steps.size(); i++){
176             Step step = (Step)steps.get(i);
177             stepsCache.put(new Long(step.getId()), step);
178          }
179       }
180       else{
181          log.error("The eternal cache for Steps cannot be retrieved from CacheManager");
182          log.error("Check its configuration ! (depending on the cache provider)");
183          throw new BootstrapException("The eternal cache for Steps cannot be retrieved from CacheManager");
184       }
185    }
186 
187    /**
188     * Load the eternal cache containing {@link Role}s
189     * @throws CacheException if role cache cannot be filled with retrieved roles
190     * @throws BootstrapException if cache cannot be retrieved through its manager
191     */
192    protected void loadRolesCache() throws CacheException, BootstrapException{
193       log.info("Loading the eternal cache containing security Roles...");
194       // Retrieve correct cache.
195       Cache rolesCache = cacheManager.getCache(EternalCacheKeys.ROLE_NAME_TO_ROLE_KEY);
196       if (rolesCache != null){
197          // Get roles and put them in cache.
198          List roles = permissionManager.getRoles();
199          for (int i=0; i < roles.size(); i++){
200             Role role = (Role)roles.get(i);
201             rolesCache.put(role.getName(), role);
202          }
203       }
204       else{
205          log.error("The eternal cache for Roles cannot be retrieved from CacheManager");
206          log.error("Check its configuration ! (depending on the cache provider)");
207          throw new BootstrapException("The eternal cache for Roles cannot be retrieved from CacheManager");
208       }
209    }
210 
211    /**
212     * Load the eternal cache containing {@link Release}s
213     * @throws CacheException if cache cannot be filled with retrieved releases
214     * @throws BootstrapException if cache cannot be retrieved through its manager
215     */
216    protected void loadReleasesCache() throws CacheException, BootstrapException{
217       log.info("Loading the eternal cache containing Releases...");
218       // Retrieve correct cache.
219       Cache releasesCache = cacheManager.getCache(EternalCacheKeys.RELEASE_NAME_TO_RELEASE_KEY);
220       if (releasesCache != null){
221          // Get releases and put them in cache.
222          List releases = processManager.getReleases();
223          for (int i=0; i < releases.size(); i++){
224             Release release = (Release)releases.get(i);
225             releasesCache.put(release.getName(), release);
226          }
227       }
228       else{
229          log.error("The eternal cache for Releases cannot be retrieved from CacheManager");
230          log.error("Check its configuration ! (depending on the cache provider)");
231          throw new BootstrapException("The eternal cache for Releases cannot be retrieved from CacheManager");
232       }
233    }
234 
235    /**
236     * Load the eternal cache containing {@link DeliverableType}s
237     * @throws CacheException if cache cannot be filled with retrieved types
238     * @throws BootstrapException if cache cannot be retrieves through its manager
239     */
240    protected void loadDeliverableTypesCache() throws CacheException, BootstrapException{
241       log.info("Loading the eternal cache containing DeliverableTypes...");
242       // Retrieve correct cache.
243       Cache deliverableTypesCache = cacheManager.getCache(EternalCacheKeys.DELTYPE_KEY_TO_DELTYPE_KEY);
244       if (deliverableTypesCache != null){
245          // Get deliverable types and put them in cache.
246          List deliverableTypes = artifactManager.getDeliverableTypes();
247          for (int i=0; i < deliverableTypes.size(); i++){
248             DeliverableType type = (DeliverableType)deliverableTypes.get(i);
249             deliverableTypesCache.put(type.getKey(), type);
250          }
251       }
252       else{
253          log.error("The eternal cache for DeliverableTypes cannot be retrieved from CacheManager");
254          log.error("Check its configuration ! (depending on the cache provider)");
255          throw new BootstrapException("The eternal cache for DeliverableTypes cannot be retrieved from CacheManager");
256       }
257    }
258 
259    /**
260     * Simply build an {@link EternalCacheAccessor} instance and register
261     * it within ServletContext using the {@link EternalCacheAccessor.CONTEXT_KEY}.<br/>
262     * Subclasses may override this method to allow some more specific registration
263     * or a more evolved cache accessor implementation.
264     */
265    protected void registerCacheAccessor(){
266       log.info("Registering the cacheAccessor within web-tier...");
267       // Build cacheAccessor and register it into servlet context.
268       cacheAccessor = new EternalCacheAccessor(cacheManager, this);
269       ServletContext ctx = ContainerContextHandler.getInstance().getServletContext();
270       ctx.setAttribute(EternalCacheAccessor.CONTEXT_KEY, cacheAccessor);
271    }
272 }