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
46
47
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
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
264
265
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 }