Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/aendvari/satyr/tools/ComponentGenerator.java


1   /*
2    * ComponentGenerator.java
3    *
4    * Copyright (c) 2001, 2002 Aendvari, Ltd. All Rights Reserved.
5    *
6    * See the file LICENSE for terms of use.
7    *
8    */
9   
10  package com.aendvari.satyr.tools;
11  
12  import java.io.*;
13  
14  import java.util.Collection;
15  import java.util.Iterator;
16  
17  import com.aendvari.cerberus.component.assembly.*;
18  import com.aendvari.cerberus.component.descriptor.*;
19  import com.aendvari.cerberus.component.descriptor.parser.*;
20  
21  import com.aendvari.common.model.*;
22  import com.aendvari.common.model.osm.*;
23  
24  /**
25   * <p>Generates classes and message listener stubs described in assembly descriptor.</p>
26   *
27   * @author  Trevor Milne
28   *
29   */
30  
31  public class ComponentGenerator
32  {
33    public static void main(String args[])
34    {
35      // check parameters
36      if (args.length != 2)
37      {
38        System.err.println("usage: ComponentGenerator assembly source");
39        System.err.println();
40        System.exit(1);
41      }
42  
43      // read source directory
44      File rootSource = new File(args[1]);
45  
46      if (!rootSource.exists() || !rootSource.isDirectory())
47      {
48        System.err.println("Could not access '" + args[1] + "'.");
49        System.exit(1);
50      }
51  
52      // get full path
53      String sourcePath = null;
54  
55      try
56      {
57        sourcePath = rootSource.getCanonicalPath();
58      }
59      catch (IOException exception)
60      {
61        System.err.println("Could not determine source path.");
62        System.exit(1);
63      }
64  
65      try
66      {
67        // open assembly descriptor
68        File assemblyFile = new File(args[0]);
69        FileInputStream inputStream = new FileInputStream(assemblyFile);
70  
71        // parse the descriptor
72        AssemblyParser parser = new AssemblyParser();
73        AssemblyDescriptor assembly = parser.parse(inputStream);
74  
75        // retrieve the definitions
76        Collection definitions = assembly.getDefinitions();
77  
78        // generate classes for components
79        Iterator definitionIterator = definitions.iterator();
80  
81        while (definitionIterator.hasNext())
82        {
83          ComponentDefinition definition = (ComponentDefinition)definitionIterator.next();
84  
85          // generator component class
86          generateComponent(definition, sourcePath);
87        }
88      }
89      catch (IOException ioException)
90      {
91        System.err.println("Could not read '" + args[0] + "'.");
92      }
93      catch (ParserException parserException)
94      {
95        System.err.println(parserException);
96      }
97    }
98  
99    /**
100    * Generates a java class file containing method stubs for the supplied component.
101    *
102    * @param    definition            The {@link ComponentDefinition} of the component.
103    * @param    sourcePath            The base directory of the java class packages.
104    *
105    * @exception  IOException            A I/O error occured.
106    *
107    */
108 
109   protected static void generateComponent(ComponentDefinition definition, String sourcePath)
110     throws IOException
111   {
112     String definitionClass = definition.getBackingClass();
113 
114     // create full class file path
115     String classPath =
116       sourcePath + File.separator +
117       definitionClass.replace('.', File.separatorChar) + ".java";
118 
119     // extract class name
120     int nameIndex = definitionClass.lastIndexOf('.');
121     String className = definitionClass.substring(nameIndex + 1, definitionClass.length());
122 
123     // extract package name
124     String packageName = definitionClass.substring(0, nameIndex);
125 
126     // create output object
127     File outputFile = new File(classPath);
128 
129     System.out.println("Generating " + definition.getBackingClass() + "...");
130 
131     // check for existing output
132     if (outputFile.exists())
133     {
134       System.err.println("Class already exists, skipping.");
135       return;
136     }
137 
138     // create output file
139     outputFile.createNewFile();
140 
141     // create output stream
142     FileOutputStream outputStream = new FileOutputStream(outputFile);
143     PrintWriter outputWriter = new PrintWriter(outputStream);
144 
145     // file header
146     outputWriter.println("/*");
147     outputWriter.print(" * ");
148     outputWriter.print(className);
149     outputWriter.println(".java");
150     outputWriter.println(" *");
151     outputWriter.println(" */");
152     outputWriter.println();
153 
154     // package
155     outputWriter.print("package ");
156     outputWriter.print(packageName);
157     outputWriter.println(";");
158     outputWriter.println();
159 
160     // imports
161     outputWriter.println("import com.aendvari.cerberus.component.assembly.AssembledComponent;");
162     outputWriter.println("import com.aendvari.cerberus.component.assembly.AssemblyContext;");
163     outputWriter.println();
164     outputWriter.println("import com.aendvari.cerberus.component.descriptor.ComponentDescriptor;");
165     outputWriter.println();
166     outputWriter.println("import com.aendvari.hermes.broker.*;");
167     outputWriter.println();
168 
169     // generate class
170     generateClass(className, definition, outputWriter);
171 
172     // end file
173     outputWriter.println();
174 
175     outputWriter.flush();
176     outputStream.close();
177   }
178 
179   /**
180    * Generates the java implementation.
181    *
182    * @param    className            The name of the class to generate.
183    * @param    definition            The {@link ComponentDefinition} of the component.
184    * @param    outputWriter          The output stream to write the java source to.
185    *
186    * @exception  IOException            A I/O error occured.
187    *
188    */
189 
190   protected static void generateClass(String className, ComponentDefinition definition, PrintWriter outputWriter)
191     throws IOException
192   {
193     // class comment
194     outputWriter.println("/**");
195 
196     if (definition.getDescription() != null)
197     {
198       outputWriter.print(" * <p>");
199       outputWriter.print(definition.getDescription());
200       outputWriter.println("</p>");
201     }
202     else
203     {
204       outputWriter.print(" * <p>Implementation of the ");
205       outputWriter.print(definition.getName());
206       outputWriter.print(" component");
207       outputWriter.println(".</p>");
208     }
209 
210     outputWriter.println(" *");
211     outputWriter.print(" * @author ");
212     outputWriter.println(ComponentGenerator.class);
213     outputWriter.println(" *");
214     outputWriter.println(" */");
215     outputWriter.println();
216 
217     // class definition
218     outputWriter.print("public class ");
219     outputWriter.print(className);
220     outputWriter.println(" implements AssembledComponent");
221     outputWriter.println("{");
222 
223     // output attributes
224     outputWriter.println("    /** Contains the definition for this component. */");
225     outputWriter.println("    protected ComponentDescriptor descriptor;");
226     outputWriter.println();
227 
228     Iterator attributeIterator = definition.getAttributes().iterator();
229 
230     while (attributeIterator.hasNext())
231     {
232       ComponentAttribute attribute = (ComponentAttribute)attributeIterator.next();
233 
234       // output description
235       if (attribute.getDescription() != null)
236       {
237         // output description from definition
238         outputWriter.print("    /** ");
239         outputWriter.print(attribute.getDescription());
240         outputWriter.println(" */");
241       }
242       else
243       {
244         // output default description
245         outputWriter.print("    /** Contains the value of the '");
246         outputWriter.print(attribute.getName());
247         outputWriter.println("' component attribute. */");
248       }
249 
250       // output declaration
251       outputWriter.print("    protected String ");
252       outputWriter.print(attribute.getName());
253       outputWriter.println(";");
254 
255       outputWriter.println();
256     }
257 
258     // generate createComponent() method
259     generateCreateComponent(definition, outputWriter);
260 
261     // generate message listener classes
262     Iterator messageIterator = definition.getMessages().iterator();
263 
264     while (messageIterator.hasNext())
265     {
266       ComponentMessage message = (ComponentMessage)messageIterator.next();
267 
268       // only subscribe to receive messages
269       if (message.getType() != ComponentMessage.Type.Receive)
270       {
271         continue;
272       }
273 
274       // output space between classes
275       outputWriter.println();
276 
277       // generate listener class
278       generateMessageListener(message, outputWriter);
279     }
280 
281     // end class
282     outputWriter.println("}");
283   }
284 
285   /**
286    * Generates the createComponent() method. Listeners and attributes are extracted.
287    *
288    * @param    definition            The {@link ComponentDefinition} of the component.
289    * @param    outputWriter          The output stream to write the java source to.
290    *
291    * @exception  IOException            A I/O error occured.
292    *
293    */
294 
295   protected static void generateCreateComponent(ComponentDefinition definition, PrintWriter outputWriter)
296     throws IOException
297   {
298     // comment
299     outputWriter.println("    /**");
300     outputWriter.println("     * Creates the component based on the provided descriptor.");
301     outputWriter.println("     *");
302     outputWriter.println("     * @param     context                     The {@link AssemblyContext} for this component.");
303     outputWriter.println("     * @param     descriptor                  The {@link ComponentDescriptor} for this component.");
304     outputWriter.println("     *");
305     outputWriter.println("     */");
306     outputWriter.println();
307 
308     // declaration
309     outputWriter.println("    public void createComponent(AssemblyContext context, ComponentDescriptor descriptor)");
310     outputWriter.println("    {");
311 
312     // body
313 
314     // message broker connection
315     outputWriter.println("        // create a connection to the message broker");
316     outputWriter.println("        MessageBrokerConnection connection = context.getMessageBroker().createConnection();");
317     outputWriter.println();
318 
319     // descriptor
320     outputWriter.println("        // store the component descriptor");
321     outputWriter.println("        this.descriptor = descriptor;");
322     outputWriter.println();
323 
324     // attributes
325     outputWriter.println("        // retrieve attribute values");
326 
327     Iterator attributeIterator = definition.getAttributes().iterator();
328 
329     while (attributeIterator.hasNext())
330     {
331       ComponentAttribute attribute = (ComponentAttribute)attributeIterator.next();
332 
333       // output code
334       outputWriter.print("        ");
335       outputWriter.print(attribute.getName());
336       outputWriter.print(" = descriptor.getAttribute(\"");
337       outputWriter.print(attribute.getName());
338       outputWriter.println("\").getValue();");
339     }
340 
341     outputWriter.println();
342 
343     // messages
344     outputWriter.println("        // subscribe to receive message topics");
345 
346     Iterator messageIterator = definition.getMessages().iterator();
347 
348     while (messageIterator.hasNext())
349     {
350       ComponentMessage message = (ComponentMessage)messageIterator.next();
351 
352       // only subscribe to receive messages
353       if (message.getType() != ComponentMessage.Type.Receive)
354       {
355         continue;
356       }
357 
358       // create name of message listener
359       String listenerName =
360         Character.toUpperCase(message.getName().charAt(0)) +
361         message.getName().substring(1) +
362         "Listener";
363 
364       // output code
365       outputWriter.print("        connection.subscribe(descriptor.getMessage(\"");
366       outputWriter.print(message.getName());
367       outputWriter.print("\").getTopic(), new ");
368       outputWriter.print(listenerName);
369       outputWriter.println("());");
370     }
371 
372     // end method
373     outputWriter.println("    }");
374   }
375 
376   /**
377    * Generates a message listener internal class.
378    *
379    * @param    message              The {@link ComponentMessage} to generate code for.
380    * @param    outputWriter          The output stream to write the java source to.
381    *
382    * @exception  IOException            A I/O error occured.
383    *
384    */
385 
386   protected static void generateMessageListener(ComponentMessage message, PrintWriter outputWriter)
387     throws IOException
388   {
389     // class comment
390     outputWriter.println("    /**");
391     outputWriter.print("     * <p>");
392 
393     // output description
394     if (message.getDescription() != null)
395     {
396       // output description from definition
397       outputWriter.print(message.getDescription());
398     }
399     else
400     {
401       // output default comment
402       outputWriter.print("Listens for \"");
403       outputWriter.print(message.getName());
404       outputWriter.print("\" messages.");
405     }
406 
407     outputWriter.println("</p>");
408     outputWriter.println("     *");
409     outputWriter.print("     * @author ");
410     outputWriter.println(ComponentGenerator.class);
411     outputWriter.println("     *");
412     outputWriter.println("     */");
413     outputWriter.println();
414 
415     // class definition
416 
417     // create name of message listener
418     String listenerName =
419       Character.toUpperCase(message.getName().charAt(0)) +
420       message.getName().substring(1) +
421       "Listener";
422 
423     // output declaration
424     outputWriter.print("    protected class ");
425     outputWriter.print(listenerName);
426     outputWriter.println(" implements MessageListener");
427     outputWriter.println("    {");
428 
429     // output onMessage() method
430     outputWriter.println("        /**");
431     outputWriter.println("         * Receives a message from the {@link MessageBroker}.");
432     outputWriter.println("         *");
433     outputWriter.println("         * @param    message            The {@link Message} received.");
434     outputWriter.println("         *");
435     outputWriter.println("         */");
436     outputWriter.println();
437     outputWriter.println("        public void onMessage(Message message)");
438     outputWriter.println("        {");
439     outputWriter.println("        }");
440 
441     // end class
442     outputWriter.println("    }");
443   }
444 }
445