View Javadoc

1   package org.andromda.core.common;
2   
3   import java.io.File;
4   import java.net.URL;
5   import java.util.ArrayList;
6   import java.util.Collection;
7   import java.util.Iterator;
8   import java.util.LinkedHashMap;
9   import java.util.List;
10  import java.util.Map;
11  
12  import org.andromda.core.configuration.NamespaceProperties;
13  import org.andromda.core.configuration.Namespaces;
14  import org.andromda.core.configuration.Property;
15  import org.andromda.core.namespace.BaseNamespaceComponent;
16  import org.andromda.core.templateengine.TemplateEngine;
17  import org.apache.log4j.Logger;
18  
19  
20  /***
21   * Represents the base plugin of AndroMDA. All Plugin instances inherit from this class.
22   *
23   * @author Chad Brandon
24   */
25  public abstract class BasePlugin
26      extends BaseNamespaceComponent
27      implements Plugin
28  {
29      /***
30       * Property references made available to the plugin
31       */
32      private final Collection propertyReferences = new ArrayList();
33  
34      /***
35       * The template objects made available to templates of this BasePlugin.
36       */
37      private final Collection templateObjects = new ArrayList();
38  
39      /***
40       * @see org.andromda.core.common.Plugin#initialize()
41       */
42      public void initialize()
43          throws Exception
44      {
45          // set the template engine merge location (this needs to be
46          // set before the template engine is initialized) so that the
47          // merge property can be set once on the template engine.
48          final Property mergeProperty =
49              Namespaces.instance().getProperty(
50                  this.getNamespace(),
51                  NamespaceProperties.MERGE_LOCATION,
52                  false);
53          this.mergeLocation = mergeProperty != null ? new File(mergeProperty.getValue()).toURL() : null;
54          if (this.mergeLocation != null)
55          {
56              this.getTemplateEngine().setMergeLocation(this.getMergeLocation().getFile());
57          }
58          this.getTemplateEngine().initialize(this.getNamespace());
59          for (final Iterator iterator = this.templateObjects.iterator(); iterator.hasNext();)
60          {
61              final TemplateObject templateObject = (TemplateObject)iterator.next();
62              templateObject.setResource(this.getResource());
63              templateObject.setNamespace(this.getNamespace());
64          }
65      }
66  
67      /***
68       * The current cartridge merge location.
69       */
70      private URL mergeLocation;
71  
72      /***
73       * Gets the current merge location for this plugin.
74       *
75       * @return the merge location (a file path).
76       */
77      protected URL getMergeLocation()
78      {
79          return this.mergeLocation;
80      }
81  
82      /***
83       * @see org.andromda.core.common.Plugin#shutdown()
84       */
85      public void shutdown()
86      {
87          this.getTemplateEngine().shutdown();
88      }
89  
90      /***
91       * Adds the <code>templateObject</code> to the collection of template objects that will be made available to the
92       * plugin during processing.
93       *
94       * @param templateObject the TemplateObject to add.
95       */
96      public void addTemplateObject(final TemplateObject templateObject)
97      {
98          if (templateObject != null)
99          {
100             this.templateObjects.add(templateObject);
101         }
102     }
103 
104     /***
105      * Adds a macro library to the TemplateEngine used by this BasePlugin.
106      *
107      * @param macrolibrary
108      */
109     public void addMacrolibrary(final String macrolibrary)
110     {
111         this.getTemplateEngine().addMacroLibrary(macrolibrary);
112     }
113 
114     /***
115      * @see org.andromda.core.common.Plugin#getTemplateObjects()
116      */
117     public Collection getTemplateObjects()
118     {
119         return this.templateObjects;
120     }
121 
122     private String templateEngineClass;
123 
124     /***
125      * Sets the template engine class for this cartridge.
126      *
127      * @param templateEngineClass the Class of the template engine implementation.
128      */
129     public void setTemplateEngineClass(final String templateEngineClass)
130     {
131         this.templateEngineClass = templateEngineClass;
132     }
133 
134     /***
135      * The template engine that this plugin will use.
136      */
137     private TemplateEngine templateEngine = null;
138 
139     /***
140      * @see org.andromda.core.common.Plugin#getTemplateEngine()
141      */
142     public TemplateEngine getTemplateEngine()
143     {
144         if (this.templateEngine == null)
145         {
146             this.templateEngine =
147                 (TemplateEngine)ComponentContainer.instance().newComponent(
148                     this.templateEngineClass, TemplateEngine.class);
149         }
150         return this.templateEngine;
151     }
152 
153     /***
154      * @see org.andromda.core.common.Plugin#getPropertyReferences()
155      */
156     public String[] getPropertyReferences()
157     {
158         return (String[])this.propertyReferences.toArray(new String[0]);
159     }
160 
161     /***
162      * Adds a property reference. Property references are those properties that are expected to be supplied by the
163      * calling client. These supplied properties are made available to the template during processing.
164      *
165      * @param reference the namespace of the reference.
166      */
167     public void addPropertyReference(final String reference)
168     {
169         this.propertyReferences.add(reference);
170     }
171 
172     /***
173      * Populates the <code>templateContext</code> with the properties and template objects defined in the
174      * <code>plugin</code>'s descriptor. If the <code>templateContext</code> is null, a new Map instance will be created
175      * before populating the context.
176      *
177      * @param templateContext the context of the template to populate.
178      */
179     protected void populateTemplateContext(Map templateContext)
180     {
181         if (templateContext == null)
182         {
183             templateContext = new LinkedHashMap();
184         }
185         this.addTemplateObjectsToContext(templateContext);
186         this.addPropertyReferencesToContext(templateContext);
187     }
188 
189     /***
190      * Takes all the template objects defined in the plugin's descriptor and places them in the
191      * <code>templateContext</code>.
192      *
193      * @param templateContext the template context
194      */
195     private void addTemplateObjectsToContext(final Map templateContext)
196     {
197         // add all the TemplateObject objects to the template context
198         final Collection templateObjects = this.getTemplateObjects();
199         if (templateObjects != null && !templateObjects.isEmpty())
200         {
201             for (final Iterator iterator = templateObjects.iterator(); iterator.hasNext();)
202             {
203                 final TemplateObject templateObject = (TemplateObject)iterator.next();
204                 templateContext.put(
205                     templateObject.getName(),
206                     templateObject.getObject());
207             }
208         }
209     }
210 
211     /***
212      * Takes all the property references defined in the plugin's descriptor and looks up the corresponding values
213      * supplied by the calling client and supplies them to the <code>templateContext</code>.
214      *
215      * @param templateContext the template context
216      */
217     private void addPropertyReferencesToContext(final Map templateContext)
218     {
219         final String[] propertyReferences = this.getPropertyReferences();
220         if (propertyReferences != null && propertyReferences.length > 0)
221         {
222             final Namespaces namespaces = Namespaces.instance();
223             for (int ctr = 0; ctr < propertyReferences.length; ctr++)
224             {
225                 final String reference = propertyReferences[ctr];
226                 templateContext.put(
227                     reference,
228                     namespaces.getPropertyValue(
229                         this.getNamespace(),
230                         reference));
231             }
232         }
233     }
234 
235     /***
236      * Stores the contents of the plugin.
237      */
238     private List contents = null;
239 
240     /***
241      * @see org.andromda.core.common.Plugin#getContents()
242      */
243     public List getContents()
244     {
245         if (this.contents == null)
246         {
247             if (ResourceUtils.isArchive(this.getResource()))
248             {
249                 this.contents = ResourceUtils.getClassPathArchiveContents(this.getResource());
250                 if (this.getMergeLocation() != null)
251                 {
252                     final Collection mergeContents = ResourceUtils.getDirectoryContents(
253                             this.getMergeLocation(),
254                             0);
255                     if (mergeContents != null && !mergeContents.isEmpty())
256                     {
257                         this.contents.addAll(mergeContents);
258                     }
259                 }
260             }
261             else
262             {
263                 // we step down 1 level if its a directory (instead of an
264                 // archive since we get the contents relative to the plugin
265                 // resource which is in the META-INF directory
266                 this.contents = ResourceUtils.getDirectoryContents(
267                         this.getResource(),
268                         2);
269             }
270         }
271         return contents;
272     }
273 
274     /***
275      * Retrieves the logger instance that should be used for logging output for the plugin sub classes.
276      *
277      * @return the logger.
278      */
279     protected Logger getLogger()
280     {
281         return AndroMDALogger.getNamespaceLogger(this.getNamespace());
282     }
283 
284     /***
285      * @see java.lang.Object#toString()
286      */
287     public String toString()
288     {
289         return super.toString() + "[" + this.getNamespace() + "]";
290     }
291 }