KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > sync4j > syncclient > sps > common > SPSGenerator


1 /**
2  * Copyright (C) 2003-2005 Funambol
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package sync4j.syncclient.sps.common;
20
21 import java.io.*;
22 import java.util.Properties JavaDoc;
23 import java.util.Hashtable JavaDoc;
24 import java.util.Vector JavaDoc;
25 import java.util.StringTokenizer JavaDoc;
26 import org.apache.xerces.parsers.*;
27 import org.w3c.dom.*;
28 import org.w3c.dom.traversal.*;
29 import org.xml.sax.ErrorHandler JavaDoc;
30 import org.xml.sax.SAXException JavaDoc;
31 import org.xml.sax.SAXParseException JavaDoc;
32 import org.w3c.dom.Document JavaDoc;
33 import org.w3c.dom.Element JavaDoc;
34 import org.w3c.dom.EntityReference JavaDoc;
35 import org.w3c.dom.Node JavaDoc;
36 import org.w3c.dom.NodeList JavaDoc;
37 import org.w3c.dom.Text JavaDoc;
38
39 import java.text.MessageFormat JavaDoc;
40 import java.net.URL JavaDoc;
41
42
43 import java.io.IOException JavaDoc;
44
45 import sync4j.syncclient.common.StringTools;
46
47
48 /**
49  *
50  * This class generate java source by parsing template with XML descriptor. It can be used in two
51  * manners: creating an instance and calling <i>getContent()</i> or as a
52  * standalone program. In the latter case the syntax is the following:<br>
53  *
54  * <pre>
55  * java SPSGenerator {javaTokenTemplate1FileName} {javaTokenTemplate2FileName}
56                          {javaClassTemplateFileName} {xmlDescriptorFileName} {dataStoreManagerFileName}
57  * </pre>
58  *
59  * The compiled source is saved in file with {source_java} name.
60  *
61  * DTD of XML file
62  *
63  * <!DOCTYPE SPS-definition[
64  * <!ELEMENT SPS-definition (header, datastore+)>
65  * <!ELEMENT application-creator-id (#PCDATA)>
66  * <!ELEMENT application-datastore-type (#PCDATA)>
67  * <!ELEMENT application-description (#PCDATA)>
68  * <!ELEMENT application-display-name (#PCDATA)>
69  * <!ELEMENT application-support-mail (#PCDATA)>
70  * <!ELEMENT application-support-url (#PCDATA)>
71  * <!ELEMENT application-name (#PCDATA)>
72  * <!ELEMENT application-author (#PCDATA)>
73  * <!ELEMENT content-id (#PCDATA)>
74  * <!ELEMENT attributes (function, size, display-name)>
75  * <!ELEMENT datastore (name, display-name, default-sync, record, store-volume)>
76  * <!ELEMENT default-sync (#PCDATA)>
77  * <!ELEMENT display-name (#PCDATA)>
78  * <!ELEMENT application-version (#PCDATA)>
79  * <!ELEMENT field (name, type, attributes)>
80  * <!ELEMENT function (#PCDATA)>
81  * <!ELEMENT header (store-manager-package, application-uri, application-version, application-author, application-creator-id, application-datastore-type, content-id, application-display-name, application-description, application-support-url, application-support-mail)>
82  * <!ELEMENT name (#PCDATA)>
83  * <!ELEMENT record (field+)>
84  * <!ELEMENT size (#PCDATA)>
85  * <!ELEMENT store-manager-package (#PCDATA)>
86  * <!ELEMENT store-volume (#PCDATA)>
87  * <!ELEMENT type (#PCDATA)>
88  * ]>
89  *
90  *
91  * @author Fabio Maggi @ Funambol
92  * $Id: SPSGenerator.java,v 1.3 2005/01/19 11:18:36 fabius Exp $
93  */

94 public class SPSGenerator {
95
96     //---------------------------------------------------------------- Constants
97

98     /** source generetor file properties */
99     public static final String JavaDoc SPSGENERATOR_PROPERTIES = "/sps.properties";
100
101     /**sps sync source class name */
102     public static final String JavaDoc SPS_SYNC_SOURCE_CLASS_NAME = "sync4j.syncclient.spds.source.SPSSyncSource";
103
104     /**sps sync item type */
105     public static final String JavaDoc SPS_SYNC_ITEM_TYPE = "plain/record";
106
107     public static final String JavaDoc IMPL_PALM = "palm" ;
108     public static final String JavaDoc IMPL_POCKETPC = "pocketpc";
109     public static final String JavaDoc IMPL_J2ME = "j2me" ;
110     public static final String JavaDoc IMPL_JDBC = "jdbc" ;
111
112     public static final String JavaDoc VALID_TARGETS = ','
113                                              + IMPL_PALM + ','
114                                              + IMPL_POCKETPC + ','
115                                              + IMPL_J2ME + ','
116                                              + IMPL_JDBC
117                                              + ','
118                                              ;
119
120     // ------------------------------------------------------------ Private data
121

122     private String JavaDoc javaTokenTemplate1FileName = null;
123     private String JavaDoc javaTokenTemplate2FileName = null;
124     private String JavaDoc javaTokenTemplate3FileName = null;
125     private String JavaDoc javaClassTemplateFileName = null;
126
127     private String JavaDoc xmlDescriptorFileName = null;
128     private String JavaDoc dataStoreManagerFileName = null;
129     private String JavaDoc dataStoreManagerPackage = null;
130
131     private String JavaDoc implementation = null;
132
133     private String JavaDoc dataStoreManagerTokenTemplate1 = null;
134     private String JavaDoc dataStoreManagerTokenTemplate2 = null;
135     private String JavaDoc dataStoreManagerTokenTemplate3 = null;
136     private String JavaDoc dataStoreManagerClassTemplate = null;
137
138     private String JavaDoc dataStoreManager = null;
139
140     private Vector JavaDoc htFieldsAttributesVector = new Vector JavaDoc();
141     private Vector JavaDoc htFieldsAttributesPutValueVector = new Vector JavaDoc();
142     private Vector JavaDoc fieldsMetadataVector = new Vector JavaDoc();
143     private Vector JavaDoc dataStoreNameVector = new Vector JavaDoc();
144     private Vector JavaDoc recordSizeVector = new Vector JavaDoc();
145
146     private int dataStoreCount = 0;
147
148     //------------------------------------------------------------- Constructors
149

150      /**
151      * @param javaTemplate the string to be logged
152      * @param init if true the existing content will be overwritten
153      *
154      */

155     SPSGenerator (String JavaDoc xmlDescriptorFileName, String JavaDoc implementation) throws IOException JavaDoc {
156
157             this.xmlDescriptorFileName = xmlDescriptorFileName;
158             this.implementation = implementation;
159
160             try {
161                 loadResources();
162                } catch (IOException JavaDoc e) {
163                 throw new IOException JavaDoc( "Error in the directory structure ("
164                 + e.getClass().getName()
165                 + "): "
166                 + e.getMessage()
167                 );
168             }
169     }
170
171     //----------------------------------------------------------- Private methods
172

173
174     /**
175      * Parsing xml descriptor and compose string to populate java template
176      **/

177     private void parsingXML() throws Exception JavaDoc {
178
179         try {
180
181             Document JavaDoc document;
182             DOMParser parser;
183
184             Class JavaDoc c;
185
186             c = this.getClass();
187
188             String JavaDoc dataStoreName = null;
189             String JavaDoc fieldName = null;
190             String JavaDoc fieldType = null;
191
192             String JavaDoc fieldMetadata = null;
193             String JavaDoc fieldsMetadata = null;
194
195             String JavaDoc htFieldAttributes = null;
196             String JavaDoc htFieldsAttributes = null;
197
198             String JavaDoc htFieldAttributesPutValue = null;
199             String JavaDoc htFieldsAttributesPutValue = null;
200
201             int recordCount = 0;
202             int fieldCount = 0;
203
204             parser = new DOMParser();
205             parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
206             parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
207
208             parser.parse(xmlDescriptorFileName);
209
210             document = parser.getDocument();
211
212             NodeList JavaDoc figlia=document.getChildNodes();
213
214             Node JavaDoc tempa;
215
216             for (int r=0; r < figlia.getLength(); r++) {
217
218                 tempa = figlia.item(r);
219
220                     if(tempa.getNodeName().equals("SPS-definition")) {
221
222                         NodeList JavaDoc figli0 = tempa.getChildNodes();
223
224                     Node JavaDoc temp0;
225
226                     for (int m=0; m < figli0.getLength(); m++) {
227
228                         temp0 = figli0.item(m);
229
230                         if (temp0.getNodeName().equals("header")) {
231
232                             NodeList JavaDoc figli1 = temp0.getChildNodes();
233
234                             Node JavaDoc temp1;
235
236                             for (int i=0; i < figli1.getLength(); i++) {
237
238                                 temp1 = figli1.item(i);
239
240                                 if (temp1.getNodeName().equals("store-manager-package")) {
241
242                                     dataStoreManagerPackage = temp1.getChildNodes().item(0).getNodeValue();
243
244                                     dataStoreManagerPackage = filterTagValue (dataStoreManagerPackage);
245
246                                 } else if (temp1.getNodeName().equals("application-name")) {
247                                     dataStoreManagerFileName =
248                                         createClassName(filterTagValue(temp1.getChildNodes().item(0).getNodeValue()));
249                                 }
250                             }
251                         }
252
253
254                         if (temp0.getNodeName().equals("datastore")) {
255
256                             NodeList JavaDoc figli1 = temp0.getChildNodes();
257
258                             Node JavaDoc temp1;
259
260                             for (int i=0; i < figli1.getLength(); i++) {
261
262                                 temp1 = figli1.item(i);
263
264                                 if (temp1.getNodeName().equals("name")) {
265                                     dataStoreName=temp1.getChildNodes().item(0).getNodeValue();
266                                 }
267
268                                 if (temp1.getNodeName().equals("record")) {
269
270                                     NodeList JavaDoc figli2 = temp1.getChildNodes();
271
272                                     Node JavaDoc temp2;
273
274                                     for (int j=0; j<figli2.getLength(); j++) {
275
276                                         temp2 = figli2.item(j);
277
278
279                                         if (temp2.getNodeName().equals("field")) {
280
281                                             recordCount++;
282
283                                             NodeList JavaDoc figli3 = temp2.getChildNodes();
284
285                                             Node JavaDoc temp3;
286
287                                             for (int k=0; k< figli3.getLength(); k++) {
288
289                                                 temp3 = figli3.item(k);
290
291                                                 if (temp3.getNodeName().equals("name")) {
292                                                     fieldName = temp3.getChildNodes().item(0).getNodeValue();
293                                                 }
294
295                                                 if (temp3.getNodeName().equals("type")) {
296                                                     fieldType = temp3.getChildNodes().item(0).getNodeValue();
297                                                 }
298
299                                                 if (temp3.getNodeName().equals("attributes")) {
300
301                                                     htFieldAttributes = "Hashtable fieldAttributes" + fieldCount+" = new Hashtable();";
302
303                                                     fieldMetadata = "fieldMetadata[" + fieldCount + "] = new FieldMetadataImpl(\"" + fieldName +"\", \"" + fieldType +"\", fieldAttributes" + fieldCount + ");";
304
305                                                     if (fieldsMetadata == null) {
306                                                         htFieldsAttributes = htFieldAttributes;
307                                                         fieldsMetadata = fieldMetadata;
308                                                     } else {
309                                                         htFieldsAttributes = htFieldsAttributes + "\n" + " " + htFieldAttributes;
310                                                         fieldsMetadata = fieldsMetadata + "\n" + " " + fieldMetadata;
311                                                     }
312
313                                                     NodeList JavaDoc figli4 = temp3.getChildNodes();
314
315                                                     Node JavaDoc temp4;
316
317                                                     for (int l=0; l< figli4.getLength(); l++) {
318
319                                                         temp4 = figli4.item(l);
320
321                                                         if (temp4.getNodeName().length() > 0 && temp4.getChildNodes().item(0) != null) {
322
323                                                             htFieldAttributesPutValue = "fieldAttributes" + fieldCount+".put(\"" + temp4.getNodeName() +"\", \""+ temp4.getChildNodes().item(0).getNodeValue() +"\");";
324
325                                                             if (htFieldsAttributesPutValue == null) {
326                                                                 htFieldsAttributesPutValue = htFieldAttributesPutValue;
327                                                             } else {
328                                                                 htFieldsAttributesPutValue = htFieldsAttributesPutValue + "\n" + " " + htFieldAttributesPutValue;
329                                                             }
330
331                                                         }
332
333                                                     }
334
335                                                     fieldCount++;
336
337                                                 }
338
339                                             }
340
341                                         }
342
343                                     }
344
345                                 }
346
347                             }
348
349                         }
350
351                         if (temp0.getNodeName().equals("datastore")) {
352
353                             dataStoreNameVector.addElement(dataStoreName);
354                             recordSizeVector.addElement(String.valueOf(fieldCount));
355                             htFieldsAttributesVector.addElement(htFieldsAttributes);
356                             htFieldsAttributesPutValueVector.addElement(htFieldsAttributesPutValue);
357                             fieldsMetadataVector.addElement(fieldsMetadata);
358
359
360                             htFieldsAttributes = null;
361                             htFieldsAttributesPutValue = null;
362                             fieldsMetadata = null;
363
364                             fieldCount = 0;
365                             dataStoreCount++;
366
367                         }
368
369                     }
370
371                 }
372
373             }
374
375         } catch (Exception JavaDoc e) {
376             System.out.println("Error in parsing operation.");
377             throw e;
378         }
379
380     }
381
382
383
384     /**
385      * Populate java template
386      * @param device implementation
387      */

388     private void compileSource(String JavaDoc implementation) {
389
390         String JavaDoc dataStoreManagerTmp1 = null;
391         String JavaDoc dataStoreManagerTmp2 = null;
392         String JavaDoc dataStoreManagerTmp3 = null;
393
394         String JavaDoc dataStoreManagerTmpA = null;
395         String JavaDoc dataStoreManagerTmpB = null;
396         String JavaDoc dataStoreManagerTmpC = null;
397
398
399         String JavaDoc classPrefix = "";
400         if (implementation.equalsIgnoreCase(IMPL_PALM)) {
401             classPrefix = "Palm";
402         } else if (implementation.equalsIgnoreCase(IMPL_POCKETPC)) {
403             classPrefix = "PPC";
404         } else if (implementation.equalsIgnoreCase(IMPL_J2ME)) {
405             classPrefix = "J2ME";
406         } else if (implementation.equalsIgnoreCase(IMPL_JDBC)) {
407             classPrefix = "JDBC";
408         }
409         for (int i=0; i < dataStoreCount; i++) {
410             dataStoreManagerTmpA = MessageFormat.format(dataStoreManagerTokenTemplate1, new Object JavaDoc[] {dataStoreNameVector.elementAt(i),
411                                                                                         htFieldsAttributesVector.elementAt(i),
412                                                                                         htFieldsAttributesPutValueVector.elementAt(i),
413                                                                                         recordSizeVector.elementAt(i),
414                                                                                         fieldsMetadataVector.elementAt(i),
415                                                                                         classPrefix});
416
417             dataStoreManagerTmpB = MessageFormat.format(dataStoreManagerTokenTemplate2, new Object JavaDoc[] {dataStoreNameVector.elementAt(i)});
418
419             dataStoreManagerTmpC = MessageFormat.format(dataStoreManagerTokenTemplate3, new Object JavaDoc[] {String.valueOf(i), dataStoreNameVector.elementAt(i)});
420
421             if (dataStoreManagerTmp1 == null) {
422                 dataStoreManagerTmp1 = dataStoreManagerTmpA;
423             } else {
424                 dataStoreManagerTmp1 = dataStoreManagerTmp1 + "\n" + "\n" + dataStoreManagerTmpA;
425             }
426
427
428             if (dataStoreManagerTmp2 == null) {
429                 dataStoreManagerTmp2 = dataStoreManagerTmpB;
430             } else {
431                 dataStoreManagerTmp2 = dataStoreManagerTmp2 + "\n" + "\n" + dataStoreManagerTmpB;
432             }
433
434             if (dataStoreManagerTmp3 == null) {
435                 dataStoreManagerTmp3 = dataStoreManagerTmpC;
436             } else {
437                 dataStoreManagerTmp3 = dataStoreManagerTmp3 + "\n" + "\n" + dataStoreManagerTmpC;
438             }
439
440         }
441
442
443         dataStoreManager = MessageFormat.format(dataStoreManagerClassTemplate, new Object JavaDoc[] {dataStoreManagerPackage, implementation, dataStoreManagerFileName, dataStoreManagerTmp1, dataStoreManagerTmp2,
444                                                                                              String.valueOf(dataStoreCount), dataStoreManagerTmp3});
445
446
447     }
448
449
450
451     /**
452      * Load java template
453      */

454     private void loadResources() throws IOException JavaDoc {
455
456         Class JavaDoc c;
457
458         InputStream is = null;
459         Properties JavaDoc prop = new Properties JavaDoc();
460
461         c = this.getClass();
462
463         is = c.getResourceAsStream(SPSGENERATOR_PROPERTIES);
464
465         prop.load(is);
466
467         is.close();
468
469         javaTokenTemplate1FileName = prop.getProperty("javaTokenTemplate1FileName");
470         javaTokenTemplate2FileName = prop.getProperty("javaTokenTemplate2FileName");
471         javaTokenTemplate3FileName = prop.getProperty("javaTokenTemplate3FileName");
472         javaClassTemplateFileName = prop.getProperty("javaClassTemplateFileName");
473         dataStoreManagerFileName = prop.getProperty("dataStoreManagerFileName");
474
475         dataStoreManagerTokenTemplate1 = read(c.getResourceAsStream(javaTokenTemplate1FileName));
476         dataStoreManagerTokenTemplate2 = read(c.getResourceAsStream(javaTokenTemplate2FileName));
477         dataStoreManagerTokenTemplate3 = read(c.getResourceAsStream(javaTokenTemplate3FileName));
478         dataStoreManagerClassTemplate = read(c.getResourceAsStream(javaClassTemplateFileName));
479
480
481     }
482
483
484
485     /**
486      * Save java source
487      * @param implementation device implementation
488      */

489     private void saveSource(String JavaDoc implementation)
490     throws IOException JavaDoc {
491         new File(implementation).mkdir();
492
493         String JavaDoc fileName =
494             implementation + File.separator + dataStoreManagerFileName + ".java";
495
496         FileOutputStream fo = new FileOutputStream(fileName);
497         fo.write(dataStoreManager.getBytes());
498     }
499
500
501     /**
502      * Save properties file
503      * with key, value
504      */

505     private void saveProperties() {
506
507         String JavaDoc content = null;
508
509         for (int i=0; i < dataStoreNameVector.size(); i++)
510
511         {
512
513             content = "sourceClass=" + SPS_SYNC_SOURCE_CLASS_NAME + "\n" +
514                       "storeManager=" + this.xmlDescriptorFileName.substring(0, this.xmlDescriptorFileName.indexOf(".")).substring(0,1).toUpperCase() + this.xmlDescriptorFileName.substring(0, this.xmlDescriptorFileName.indexOf(".")).substring(1).toLowerCase() + "\n" +
515                       "name=" + (String JavaDoc) dataStoreNameVector.elementAt(i) + "\n" +
516                       "type=" + SPS_SYNC_ITEM_TYPE + "\n" +
517                       "sourceURI=" + ((String JavaDoc) dataStoreNameVector.elementAt(i)).toLowerCase();
518
519             try {
520
521                 FileOutputStream fo = new FileOutputStream(((String JavaDoc) dataStoreNameVector.elementAt(i)).toLowerCase() + ".properties");
522                 fo.write(content.getBytes());
523
524             } catch(FileNotFoundException e1) {
525             } catch (IOException JavaDoc e2) {
526             }
527
528         }
529
530     }
531
532
533
534     /**
535      * Reads the content of the given input stream.
536      *
537      * @param is the input stream
538      *
539      **/

540     private String JavaDoc read(InputStream is) throws IOException JavaDoc {
541         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
542
543         try {
544             byte[] buf = new byte[1024];
545
546             int nbyte = -1;
547             while ((nbyte = is.read(buf)) >= 0) {
548                 sb.append(new String JavaDoc(buf, 0, nbyte));
549             }
550         } finally {
551             is.close();
552         }
553
554         return sb.toString();
555     }
556
557
558
559     //-------------------------------------------------------------------- Main
560

561     /**
562      * Main
563      */

564     public static void main (String JavaDoc[] args) throws Exception JavaDoc {
565
566         try {
567
568             SPSGenerator sGenerator = null;
569
570             checkSyntax(args);
571
572             sGenerator = new SPSGenerator(args[0], args[1]);
573
574             sGenerator.parsingXML();
575
576             sGenerator.compileSource(sGenerator.implementation);
577
578             sGenerator.saveSource(sGenerator.implementation);
579
580             //this values are generated by client,
581
//and saved by Device Management
582
//sGenerator.saveProperties();
583

584             System.out.println("Source generation OK");
585
586         } catch (Exception JavaDoc e) {
587             System.out.println("Source generation interruped.");
588             e.printStackTrace();
589         }
590
591     }
592
593
594     /**
595      * Check main parameters
596      *
597      * @param args main parameters
598      */

599     private static void checkSyntax(String JavaDoc[] args) throws Exception JavaDoc {
600        if (args.length != 2 || (VALID_TARGETS.indexOf(',' + args[1] + ',')<0)) {
601             String JavaDoc msg = "Syntax error.\n"
602             + "\n\tSyntax: "
603             + SPSGenerator.class.getName()
604             + "\n\txmlDescriptorFileName: name of xml descriptor file [e.g. ADF.xml]"
605             + "\n\timplementation: device profile implementation [" + VALID_TARGETS + "]\n"
606             ;
607             System.out.println(msg);
608             throw new Exception JavaDoc();
609         }
610     }
611
612
613
614     /**
615      * erase newline and init / end space from tag value
616      *
617      * @param tagValue value to filter
618      * @return filtered tagValue
619      */

620     private String JavaDoc filterTagValue(String JavaDoc tagValue) {
621
622         while (tagValue.indexOf("\n") != -1) {
623             tagValue = tagValue.substring(0, tagValue.indexOf("\n")) + tagValue.substring(tagValue.indexOf("\n") + 1);
624         }
625
626         return tagValue.trim();
627     }
628
629     /**
630      * Creates a class name replacing all special caracheters with an '_' (underscore)
631      * and appending DataStore.
632      *
633      * @param s input string
634      *
635      * @return the class name created as described above.
636      */

637     private String JavaDoc createClassName(String JavaDoc s) {
638         return StringTools.replaceSpecial(s) + "StoreManager";
639     }
640
641
642 }
Popular Tags