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
49
50 /** Get a commons logger... */
51 private static final Log log = LogUtil.getLog(CacheLoader.class);
52
53
54
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
72
73 /** Creates a new instance of CacheLoader */
74 public CacheLoader(){
75 }
76
77
78
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
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
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
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
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
149 registerCacheAccessor();
150 }
151 catch (Exception e){
152
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
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
171 Cache stepsCache = cacheManager.getCache(EternalCacheKeys.STEP_ID_TO_STEP_KEY);
172 if (stepsCache != null){
173
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
195 Cache rolesCache = cacheManager.getCache(EternalCacheKeys.ROLE_NAME_TO_ROLE_KEY);
196 if (rolesCache != null){
197
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
219 Cache releasesCache = cacheManager.getCache(EternalCacheKeys.RELEASE_NAME_TO_RELEASE_KEY);
220 if (releasesCache != null){
221
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
243 Cache deliverableTypesCache = cacheManager.getCache(EternalCacheKeys.DELTYPE_KEY_TO_DELTYPE_KEY);
244 if (deliverableTypesCache != null){
245
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
268 cacheAccessor = new EternalCacheAccessor(cacheManager, this);
269 ServletContext ctx = ContainerContextHandler.getInstance().getServletContext();
270 ctx.setAttribute(EternalCacheAccessor.CONTEXT_KEY, cacheAccessor);
271 }
272 }