1 package org.andromda.core.common;
2
3 import java.net.URL;
4
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.HashMap;
8 import java.util.Iterator;
9 import java.util.Map;
10
11 import org.andromda.core.configuration.Namespaces;
12 import org.apache.commons.lang.StringUtils;
13 import org.apache.commons.lang.builder.ToStringBuilder;
14 import org.apache.log4j.Logger;
15
16
17 /***
18 * Contains the configuration of a template object which are objects that are
19 * made available to the cartridge templates.
20 *
21 * @author Chad Brandon
22 */
23 public class TemplateObject
24 {
25 private static Logger logger = Logger.getLogger(TemplateObject.class);
26
27 /***
28 * The name of this template object made available to the
29 * template.
30 */
31 private String name;
32
33 /***
34 * Gets the current name of this TemplateObject.
35 *
36 * @return String
37 */
38 public String getName()
39 {
40 final String methodName = "TemplateObject.getName";
41 if (StringUtils.isEmpty(this.name))
42 {
43 throw new TemplateObjectException(methodName + " - templateObject '" + this + "' has no name defined");
44 }
45 return this.name;
46 }
47
48 /***
49 * Caches the template objects.
50 */
51 private final Map objectCache = new HashMap();
52
53 /***
54 * Returns the actuall object instance described by this
55 * template object.
56 *
57 * @return the actual object instance.
58 */
59 public Object getObject()
60 {
61 final String methodName = "TemplateObject.getTemplateObject";
62 if (StringUtils.isEmpty(this.className))
63 {
64 throw new TemplateObjectException(methodName + " - templateObject '" + this + "' has no className defined");
65 }
66 Object templateObject = this.objectCache.get(this.className);
67 try
68 {
69 if (templateObject == null)
70 {
71 final Class templateObjectClass = ClassUtils.loadClass(this.className);
72 templateObject = templateObjectClass.newInstance();
73 this.objectCache.put(this.className, templateObject);
74 }
75
76
77 this.setProperties(templateObject);
78 }
79 catch (final Throwable throwable)
80 {
81 throw new TemplateObjectException(throwable);
82 }
83 return templateObject;
84 }
85
86 /***
87 * Sets all the nested properties on the templateObject object.
88 *
89 * @param templateObject the template object on which to populate properties.
90 */
91 protected void setProperties(final Object templateObject)
92 {
93 for (final Iterator iterator = propertyReferences.iterator(); iterator.hasNext();)
94 {
95 final String reference = (String)iterator.next();
96 String value = Namespaces.instance().getPropertyValue(
97 this.getNamespace(),
98 reference);
99 if (value != null)
100 {
101 if (this.getLogger().isDebugEnabled())
102 {
103 this.getLogger().debug(
104 "populating template object '" + this.name + "' property '" + reference + "' with value '" +
105 value + "' for namespace '" + namespace + "'");
106 }
107 try
108 {
109 Introspector.instance().setProperty(templateObject, reference, value);
110 }
111 catch (final Exception exception)
112 {
113
114 final String message =
115 "Error setting property '" + reference + "' with '" + value + "' on templateObject --> '" +
116 templateObject + "'";
117 logger.warn(message);
118 }
119 }
120 }
121 }
122
123 /***
124 * Sets the name of the template object (this name will be what the template class is stored under in the template)
125 *
126 * @param name the name of the template object.
127 */
128 public void setName(final String name)
129 {
130 this.name = StringUtils.trimToEmpty(name);
131 }
132
133 /***
134 * The name of the class for this template object.
135 */
136 private String className;
137
138 /***
139 * Sets the class of the transformation object.
140 *
141 * @param className the name of the template object class.
142 */
143 public void setClassName(final String className)
144 {
145 ExceptionUtils.checkEmpty("className", className);
146 this.className = className;
147 }
148
149 /***
150 * The property references that configure this template object.
151 */
152 private final Collection propertyReferences = new ArrayList();
153
154 /***
155 * Adds a templateObject property reference (used to customize templateObjects). Property references are used to
156 * populate bean like properties of template objects.
157 *
158 * @param reference the name of the property reference.
159 */
160 public void addPropertyReference(final String reference)
161 {
162 this.propertyReferences.add(reference);
163 }
164
165 /***
166 * The resource in which the template object was found.
167 */
168 private URL resource;
169
170 /***
171 * The resource in which the templateObject was found.
172 *
173 * @return the resource as a URL.
174 */
175 public URL getResource()
176 {
177 return resource;
178 }
179
180 /***
181 * Sets the resource in which the templateObject was defined.
182 *
183 * @param resource the resource on which this template object was defined.
184 */
185 public void setResource(final URL resource)
186 {
187 this.resource = resource;
188 }
189
190 /***
191 * The namespace to which this template object belongs.
192 */
193 private String namespace;
194
195 /***
196 * Gets the namespace to which this template object belongs.
197 *
198 * @return Returns the namespace.
199 */
200 public String getNamespace()
201 {
202 return namespace;
203 }
204
205 /***
206 * Sets the namespace to which this template object belongs.
207 *
208 * @param namespace The namespace to set.
209 */
210 public void setNamespace(final String namespace)
211 {
212 this.namespace = StringUtils.trimToEmpty(namespace);
213 }
214
215 /***
216 * Gets the namespace logger (the logger under which output for this
217 * template object should be written).
218 *
219 * @return the logger instance.
220 */
221 protected Logger getLogger()
222 {
223 return AndroMDALogger.getNamespaceLogger(this.namespace);
224 }
225
226 /***
227 * @see java.lang.Object#toString()
228 */
229 public String toString()
230 {
231 return ToStringBuilder.reflectionToString(this);
232 }
233 }