1 package org.weda.tapestry.renderer.impl;
2
3 import java.util.HashMap;
4 import java.util.List;
5 import java.util.Map;
6 import org.apache.commons.lang.StringUtils;
7 import org.weda.enhance.ObjectEnhancer;
8 import org.weda.property.PropertyDescriptor;
9 import org.weda.tapestry.renderer.Renderer;
10 import org.weda.tapestry.RendererInitializer;
11 import org.weda.tapestry.RendererRegistry;
12 import org.weda.tapestry.RendererRegistryException;
13
14 /**
15 *
16 * @author Mikhail Titov
17 */
18 public class RendererRegistryImpl implements RendererRegistry {
19 private static final String DEFAULT_NAME = "_";
20 private static final char ELEMENT_SEPARATOR = ':';
21
22 private ObjectEnhancer objectEnhancer;
23 private List<RendererInfo> rendererInfoList;
24 private List<RendererInitializer> initializers;
25 private Map<String, Renderer> renderers = new HashMap<String, Renderer>();
26 private Map<String, Renderer> renderersCache =
27 new HashMap<String, Renderer>();
28
29 private Map<Class, Class> rendererClasses = new HashMap<Class, Class>();
30
31 public void init() throws RendererRegistryException {
32 try{
33 for (RendererInfo info: rendererInfoList){
34 String rendererId =
35 formRendererName(
36 info.getRendererClass().getName()
37 , info.getDefaultPattern());
38 Renderer renderer = renderersCache.get(rendererId);
39 if (renderer==null){
40 renderer = createRenderer(
41 info.getRendererClass(), info.getDefaultPattern());
42 renderersCache.put(rendererId, renderer);
43 }
44 String rendererName = formRendererName(
45 info.getObjectClass()==null
46 ? null : info.getObjectClass().getName()
47 , info.getPropertyName()
48 , info.getValueClass()==null
49 ? null : info.getValueClass().getName()
50 , info.getMimeType());
51 if (renderers.containsKey(rendererName))
52 throw new RendererRegistryException(
53 String.format(
54 "Renderer with name (%s) already exists " +
55 "in registry"
56 , rendererName));
57 renderers.put(rendererName, renderer);
58 }
59 }catch(RendererRegistryException e){
60 throw new RendererRegistryException(
61 "Error in initializing cycle of the rernderer registry " +
62 "service"
63 , e);
64 }
65 }
66
67 private String formRendererName(String... elems){
68 return StringUtils.join(elems, ELEMENT_SEPARATOR);
69 }
70
71 public Renderer getRenderer(PropertyDescriptor pd) {
72 String[] elems = new String[]{
73 pd.getObjectClass()==null ? null : pd.getObjectClass().getName()
74 , pd.getName()
75 , pd.getPropertyClass().getName()
76 , pd.getMimeType()
77 };
78 Renderer renderer = null;
79 String rendererName = null;
80 for (int i=-1; i<elems.length; ++i){
81 if (i!=-1)
82 elems[i]=null;
83 rendererName = formRendererName(elems);
84 renderer = renderers.get(rendererName);
85 if (renderer!=null)
86 break;
87 }
88 return renderer;
89 }
90
91 public Renderer getRenderer(
92 Class<Renderer> rendererClass, String defaultPattern)
93 throws RendererRegistryException
94 {
95 String id = formRendererName(rendererClass.getName(), defaultPattern);
96 Renderer renderer = renderersCache.get(id);
97 if (renderer==null){
98 renderer = createRenderer(rendererClass, defaultPattern);
99 renderersCache.put(id, renderer);
100 }
101 return renderer;
102 }
103
104 private Renderer createRenderer(
105 Class<Renderer> rendererClass, String defaultPattern)
106 throws RendererRegistryException
107 {
108 try{
109 Class enhancedRenderer = objectEnhancer.enhanceClass(rendererClass);
110 Renderer renderer =
111 (Renderer)objectEnhancer.newInstance(enhancedRenderer);
112 rendererClasses.put(rendererClass, enhancedRenderer);
113 renderer.setDefaultPattern(defaultPattern);
114 if (initializers!=null)
115 for (RendererInitializer initializer: initializers)
116 if (initializer.getBaseRendererClass().isAssignableFrom(
117 renderer.getClass()))
118 {
119 initializer.initRenderer(renderer);
120 }
121 return renderer;
122 }catch(Exception e){
123 throw new RendererRegistryException(
124 String.format(
125 "Can't create renderer instance for renderer class (%s)"
126 , rendererClass.getName())
127 , e);
128 }
129 }
130
131 public void setRenderers(List<RendererInfo> rendererInfoList){
132 this.rendererInfoList=rendererInfoList;
133 }
134
135 public void setInitializers(List<RendererInitializer> initializers) {
136 this.initializers = initializers;
137 }
138
139 public void setObjectEnhancer(ObjectEnhancer objectEnhancer) {
140 this.objectEnhancer = objectEnhancer;
141 }
142 }