1 /**
2 * $Id: SpringResourceManagerImpl.java 79 2006-12-15 21:39:11Z maldito_orco $
3 * $Revision: 79 $
4 * $Date: 2006-12-15 18:39:11 -0300 (Fri, 15 Dec 2006) $
5 *
6 * =========================================================================
7 *
8 * Copyright 2005 Tubo
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22 package org.tubo.resource.springimpl;
23
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import org.apache.velocity.VelocityContext;
29 import org.apache.velocity.Template;
30 import org.apache.velocity.exception.ResourceNotFoundException;
31 import org.apache.velocity.exception.ParseErrorException;
32 import org.apache.velocity.app.Velocity;
33
34 import org.springframework.beans.factory.BeanFactory;
35 import org.springframework.beans.factory.BeanFactoryAware;
36 import org.springframework.beans.factory.xml.XmlBeanFactory;
37 import org.springframework.beans.BeansException;
38 import org.springframework.core.io.ByteArrayResource;
39
40 import org.tubo.configuration.def.*;
41 import org.tubo.resource.Manager;
42 import org.tubo.resource.flow.FlowExecutor;
43 import org.tubo.resource.flow.FlowContext;
44 import org.tubo.resource.baseimpl.BaseAbstractResourceManager;
45 import org.tubo.exception.TuboResourceException;
46 import org.tubo.exception.ExceptionManager;
47 import org.tubo.exception.TuboException;
48 import org.tubo.item.Item;
49 import org.tubo.event.Event;
50 import org.tubo.kernel.Kernel;
51
52 import java.util.Map;
53 import java.util.Iterator;
54 import java.util.Properties;
55 import java.util.HashMap;
56
57 import java.io.StringWriter;
58
59 /**
60 *
61 * Created: Dec 1, 2005 6:02:44 AM
62 * Last Modification Date: $Date: 2006-12-15 18:39:11 -0300 (Fri, 15 Dec 2006) $
63 *
64 * @author maldito_orco (maldito_orco@users.sourceforge.net)
65 * @version $Revision: 79 $
66 */
67 public class SpringResourceManagerImpl extends BaseAbstractResourceManager implements BeanFactoryAware {
68 public static final String RCS_ID = "$Id: SpringResourceManagerImpl.java 79 2006-12-15 21:39:11Z maldito_orco $";
69 private static Log log = LogFactory.getLog(SpringResourceManagerImpl.class);
70
71 /** Template file for beans based on exceptions */
72 public final static String BEAN_EXCEPTION_MANAGER_TEMPLATE = "META-INF/templates/exception-manager-template.vm";
73
74 /** Template file for beans based on exceptions */
75 public final static String BEAN_EXCEPTION_TEMPLATE = "META-INF/templates/exception-template.vm";
76
77 /** Template file for beans based on consumers */
78 public final static String BEAN_CONSUMER_TEMPLATE = "META-INF/templates/bean-consumer-template.vm";
79
80 /** Template file for beans based on components */
81 public final static String BEAN_COMPONENT_TEMPLATE = "META-INF/templates/bean-component-template.vm";
82
83 /** Template file for beans based on flows */
84 public final static String BEAN_DEFAULT_TEMPLATE = "META-INF/templates/bean-default-template.vm";
85
86 /** Template file for beans based on flows */
87 public final static String BEAN_FLOW_TEMPLATE = "META-INF/templates/bean-flow-template.vm";
88
89 /** Header for every spring xml context file */
90 public static final String SPRING_CONTEXT_HEADFILE =
91 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
92 "<!DOCTYPE beans PUBLIC \"-//SPRING//DTD BEAN//EN\" \"http://www.springframework.org/dtd/spring-beans.dtd\">";
93
94 /** Kernel bean ID */
95 public static final String SPRING_KERNEL_BEAN_ID = "kernel";
96
97 /** ResourceManager bean ID */
98 public static final String SPRING_RESOURCE_MANAGER_BEAN_ID = "resourceManager";
99
100 /** Item bean ID */
101 public static final String SPRING_ITEM_BEAN_ID = "item";
102
103 /** Event bean ID */
104 public static final String SPRING_EVENT_BEAN_ID = "event";
105
106 /** FlowContext bean ID */
107 public static final String SPRING_FLOW_CONTEXT_BEAN_ID = "flowContext";
108
109 /** ExceptionManager bean ID */
110 public static final String SPRING_EXCEPTION_MANAGER_BEAN_ID = "exceptionManager";
111
112 /** FlowExecutor bean ID */
113 public static final String SPRING_FLOW_EXECUTOR_BEAN_ID = "flowExecutor";
114
115 /** Spring bean factory */
116 private BeanFactory beanFactory;
117
118
119 /**
120 * Default constructor protected. Used by test cases.
121 * Don't change. USED ONLY BY TEST CASES!
122 * @throws TuboResourceException
123 */
124 protected SpringResourceManagerImpl() throws TuboException {
125 }
126
127 public BeanFactory getBeanFactory() {
128 return beanFactory;
129 }
130
131 public void setBeanFactory(BeanFactory beanFactory) {
132 this.beanFactory = beanFactory;
133 }
134
135
136 /**
137 * <p>
138 * Get kernel instance
139 * </p>
140 * @return kernel instance
141 * @throws TuboException
142 */
143 public Kernel getKernel() throws TuboException {
144 Kernel kernel = null;
145 try {
146
147
148 kernel = (Kernel)beanFactory.getBean(SPRING_KERNEL_BEAN_ID);
149 } catch (BeansException e) {
150
151
152 log.error("Error trying to get a KERNEL", e);
153
154
155 throw new TuboResourceException("Error trying to get a Kernel",e);
156 }
157
158
159 return kernel;
160 }
161
162
163 /**
164 * <p>
165 * Create a new Item instance
166 * </p>
167 * @return new Item instance
168 * @throws TuboException
169 */
170 public Item getNewItem() throws TuboException {
171 Item item = null;
172 try {
173
174
175 item = (Item)beanFactory.getBean(SPRING_ITEM_BEAN_ID);
176 } catch (BeansException e) {
177
178
179 log.error("Error trying to get an Item", e);
180
181
182 throw new TuboResourceException("Error trying to get an Item",e);
183 }
184
185
186 return item;
187 }
188
189 /**
190 * <p>
191 * Create a new Item instance
192 * </p>
193 * @return new Item instance
194 * @throws TuboException
195 */
196 public Event getNewEvent() throws TuboException {
197 Event event = null;
198 try {
199
200
201 event = (Event)beanFactory.getBean(SPRING_EVENT_BEAN_ID);
202 } catch (BeansException e) {
203
204
205 log.error("Error trying to get an Event", e);
206
207
208 throw new TuboResourceException("Error trying to get an Event",e);
209 }
210
211
212 return event;
213 }
214
215 /**
216 * <p>
217 * Create a new FlowContext instance
218 * </p>
219 * @return new FlowContext instance
220 * @throws TuboException
221 */
222 public FlowContext getNewFlowContext() throws TuboException {
223 FlowContext flowContext = null;
224 try {
225
226
227 flowContext = (FlowContext)beanFactory.getBean(SPRING_FLOW_CONTEXT_BEAN_ID);
228 } catch (BeansException e) {
229
230
231 log.error("Error trying to get a FlowContext", e);
232
233
234 throw new TuboResourceException("Error trying to get a FlowContext",e);
235 }
236
237
238 return flowContext;
239 }
240
241 public ExceptionManager getExceptionManager() throws TuboException {
242 ExceptionManager manager = null;
243 try {
244
245
246 manager = (ExceptionManager)beanFactory.getBean(SPRING_EXCEPTION_MANAGER_BEAN_ID);
247 } catch (BeansException e) {
248
249
250 log.error("Error trying to get ExceptionManager", e);
251
252
253 throw new TuboResourceException("Error trying to get ExceptionManager '"+SPRING_EXCEPTION_MANAGER_BEAN_ID+"'",e);
254 }
255
256
257 if (manager == null) {
258
259
260 log.error("Error when returning ExceptionManager, return null");
261
262
263 throw new TuboResourceException("Error when returning ExceptionManager, return null");
264 }
265
266
267 return manager;
268 }
269
270 public FlowExecutor getFlowExecutor() throws TuboException {
271 FlowExecutor manager = null;
272 try {
273
274
275 manager = (FlowExecutor)beanFactory.getBean(SPRING_FLOW_EXECUTOR_BEAN_ID);
276 } catch (BeansException e) {
277
278
279 log.error("Error trying to get FlowExecutor", e);
280
281
282 throw getExceptionManager().getException(1302,SPRING_FLOW_EXECUTOR_BEAN_ID,e);
283 }
284 return manager;
285 }
286
287 /**
288 * get a bean manager from spring
289 * @param id
290 * @return
291 */
292 public Manager getManager(String id) throws TuboException {
293
294
295 id = id+"Manager";
296
297
298 Manager manager = null;
299 try {
300
301
302 manager = (Manager)beanFactory.getBean(id);
303 } catch (BeansException e) {
304
305
306 log.error("Error trying to get Manager identified by '"+id+"'", e);
307
308
309 throw getExceptionManager().getException(1303,id,e);
310 }
311
312
313 return manager;
314 }
315
316
317
318
319 public static SpringResourceManagerImpl newInstance(Configuration config) {
320
321
322 if (log.isTraceEnabled()) log.trace(".newInstance() - Enter");
323
324
325 initVelocity();
326
327
328 String stringResource = null;
329 try {
330 stringResource = createSpringContext(config);
331 } catch (TuboResourceException e) {
332 throw new TuboResourceException("Tubo configuration can't be created",e);
333 }
334
335
336 ByteArrayResource byteResource = new ByteArrayResource(stringResource.getBytes());
337 BeanFactory beanFactory = new XmlBeanFactory(byteResource);
338
339
340 SpringResourceManagerImpl rm = null;
341 try {
342
343
344 rm = (SpringResourceManagerImpl)beanFactory.getBean(SPRING_RESOURCE_MANAGER_BEAN_ID);
345 } catch (BeansException e) {
346
347
348 log.error("Error trying to get ResourceManager", e);
349
350
351 throw new TuboResourceException("Error trying to get Spring ResourceManager",e);
352 }
353
354
355
356 rm.setConfiguration(config);
357
358
359 if (log.isTraceEnabled()) log.trace(".newInstance() - Leave");
360
361
362 return rm;
363 }
364
365
366
367
368 /**
369 *
370 */
371 private static void initVelocity() throws TuboResourceException {
372
373
374
375 Properties p = new Properties();
376 p.setProperty("resource.loader", "class");
377 p.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
378 try {
379 Velocity.init(p);
380 } catch (Exception e) {
381 throw new TuboResourceException("Velocity can't be initialized",e);
382 }
383 }
384
385 /**
386 * Create a Spring Context (Spring configuration) based on Configuration object.
387 * @param config Configuration
388 * @return A String with Spring representation of Configuration object.
389 */
390 protected static String createSpringContext(Configuration config) throws TuboResourceException {
391
392
393 StringBuffer buffer = new StringBuffer();
394
395
396 buffer.append(SPRING_CONTEXT_HEADFILE);
397
398
399 buffer.append("<beans>");
400
401
402
403
404 appendSpringDefaultConfiguration(buffer,config);
405
406
407
408
409 appendSpringExceptionManagerDefinition(buffer);
410
411
412
413
414 appendSpringFlowDefinition(buffer,config);
415
416
417 Map exceptionMap = config.getExceptionDefs();
418
419
420 for (Iterator it=exceptionMap.values().iterator(); it.hasNext();) {
421 ExceptionDef def = (ExceptionDef)it.next();
422
423
424 buffer = appendSpringDefinition(buffer,def);
425 }
426
427
428
429
430 Map consumersMap = config.getConsumerDefs();
431
432
433 for (Iterator it=consumersMap.values().iterator(); it.hasNext();) {
434 ConsumerDef def = (ConsumerDef)it.next();
435
436
437 buffer = appendSpringDefinition(buffer,def);
438 }
439
440
441
442
443 Map componentsMap = config.getComponentDefs();
444
445
446 for (Iterator it=componentsMap.values().iterator(); it.hasNext();) {
447 ComponentDef def = (ComponentDef)it.next();
448
449
450 buffer = appendSpringDefinition(buffer,def);
451 }
452
453
454 buffer.append("</beans>");
455
456
457 return buffer.toString();
458 }
459
460 protected static StringBuffer appendSpringDefaultConfiguration(StringBuffer buffer, Configuration config) throws TuboResourceException {
461
462
463 Map props = new HashMap();
464 props.put("config",config);
465
466
467 buffer = appendSpringDefinition(buffer,null,BEAN_DEFAULT_TEMPLATE,props);
468 return buffer;
469 }
470
471 protected static StringBuffer appendSpringFlowDefinition(StringBuffer buffer, Configuration config) throws TuboResourceException {
472
473
474 Map props = new HashMap();
475 props.put("config",config);
476
477
478 buffer = appendSpringDefinition(buffer,null,BEAN_FLOW_TEMPLATE,props);
479 return buffer;
480 }
481
482 protected static StringBuffer appendSpringExceptionManagerDefinition(StringBuffer buffer) throws TuboResourceException {
483
484
485 Map props = new HashMap();
486 props.put("id",BEAN_EXCEPTION_MANAGER_TEMPLATE);
487
488
489 buffer = appendSpringDefinition(buffer,null,BEAN_EXCEPTION_MANAGER_TEMPLATE,props);
490 return buffer;
491 }
492
493 protected static StringBuffer appendSpringDefinition(StringBuffer buffer, Definition def) throws TuboResourceException {
494 if (def instanceof ExceptionDef) {
495 buffer = appendSpringDefinition(buffer,def,BEAN_EXCEPTION_TEMPLATE,null);
496 return buffer;
497 }
498 if (def instanceof ConsumerDef) {
499 buffer = appendSpringDefinition(buffer,def,BEAN_CONSUMER_TEMPLATE,null);
500 return buffer;
501 }
502 if (def instanceof ComponentDef) {
503 buffer = appendSpringDefinition(buffer,def,BEAN_COMPONENT_TEMPLATE,null);
504 return buffer;
505 }
506 throw new TuboResourceException("Definition type not know.");
507 }
508
509 /**
510 * Append a Spring configuration of ComponentDef instance.
511 * @param buffer Spring configuration
512 * @param def A ComponentDef instance
513 * @return The same StringBuffer but with a new component (bean) definition append to end;
514 */
515 protected static StringBuffer appendSpringDefinition(StringBuffer buffer, Definition def, String templateFile, Map props) throws TuboResourceException {
516 try {
517
518
519
520
521 VelocityContext context = new VelocityContext();
522 context.put("def", def);
523
524
525 if (props!=null)
526 for(Iterator it=props.keySet().iterator(); it.hasNext();) {
527 String key = (String)it.next();
528 Object value = props.get(key);
529 context.put(key,value);
530 }
531
532
533
534
535
536
537
538 Template template = null;
539 try {
540 template = Velocity.getTemplate(templateFile);
541 } catch( ResourceNotFoundException rnfe ) {
542 throw new TuboResourceException("Velocity template "+templateFile+" can't be founded",rnfe);
543 } catch( ParseErrorException pee ) {
544 throw new TuboResourceException("Velocity parsing error procesing template "+templateFile,pee);
545 }
546
547
548
549
550 StringWriter writer = new StringWriter();
551 if ( template != null)
552 template.merge(context, writer);
553
554
555 writer.flush();
556 writer.close();
557
558 buffer.append(writer.toString());
559 } catch (Exception e) {
560 throw new TuboResourceException("Error creating spring definition",e);
561 }
562 return buffer;
563 }
564
565 }