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