KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > mapper > dbms > TableSpecLoader


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 /*
24  * TableSpecLoader.java
25  *
26  * Created on 12 janvier 2001, 09:25
27  */

28
29 package org.xquark.mapper.dbms;
30
31 import java.net.URL JavaDoc;
32 import java.util.*;
33
34 import javax.xml.parsers.SAXParserFactory JavaDoc;
35
36 import org.xml.sax.*;
37 import org.xml.sax.helpers.DefaultHandler JavaDoc;
38 import org.xquark.mapper.metadata.RepositoryConstants;
39 import org.xquark.schema.validation.*;
40
41 /**
42  *
43  */

44 public class TableSpecLoader extends DefaultHandler JavaDoc
45 {
46     private static final String JavaDoc RCSRevision = "$Revision: 1.1 $";
47     private static final String JavaDoc RCSName = "$Name: $";
48
49     
50     /** Use to "filter" repositories, in order to ignore repositories for
51      * which the current software is unsuited.
52      * <p><B>This version is not necessarily the repository runtime version
53      * but the last version since any modification to the dbms data structure
54      * has been made. IT IS A DATA_COMPATIBILITY VERSION</B></p>
55      */

56     public static String JavaDoc REPOSITORY_DATA_VERSION;
57
58     /////////////////////////
59
// Constants
60
/////////////////////////
61
/* Element names */
62     private final static String JavaDoc SCHEMA_FILENAME = "TableSpec.xsd";
63     private final static String JavaDoc DATA_FILENAME = "TableSpec.xml";
64     private final static String JavaDoc ROOT_ELEMENT = "tables";
65     private final static String JavaDoc VERSION_ATTR = "version";
66     private final static String JavaDoc TABLE_ELEMENT = "table";
67     private final static String JavaDoc TYPE_ATTR = "type";
68     private final static String JavaDoc SUFFIX_ATTR = "suffix";
69     private final static String JavaDoc SEQ_ATTR = "sequence";
70     private final static String JavaDoc CAT_ATTR = "cat";
71     private final static String JavaDoc DBMS_ATTR = "dbms";
72     private final static String JavaDoc DBMS_TYPE_ATTR = "dbmsType";
73     
74     private final static String JavaDoc COLUMN_ELEMENT = "column";
75     private final static String JavaDoc NAME_ATTR = "name";
76     private final static String JavaDoc NULLABLE_ATTR = "nullable";
77     private final static String JavaDoc KEY_ATTR = "key";
78     
79     private final static String JavaDoc JDBC_TYPE_ELEMENT = "type";
80     private final static String JavaDoc JDBC_TYPE_ATTR = "jdbc";
81     private final static String JavaDoc MAX_LEN_ELEMENT = "maxLen";
82     private final static String JavaDoc PRECISION_ELEMENT = "precision";
83     private final static String JavaDoc SCALE_ELEMENT = "scale";
84     private final static String JavaDoc PARAM_ATTR = "param";
85     
86     private final static short ANY_DBMS = 0;
87
88     private final static String JavaDoc CONSTRAINT_ELEMENT = "constraint";
89     private final static String JavaDoc COLUMNS_ATTR = "columns";
90     
91     private final static String JavaDoc INDEX_ELEMENT = "index";
92     
93     /* Automaton status */
94     private final static short UNKNOWN = 0;
95     private final static short ROOT = 1;
96     private final static short TABLE = 2;
97     private final static short COLUMN = 3;
98     private final static short JDBC_TYPE = 4;
99     private final static short KEY = 5;
100     private final static short NULLABLE = 6;
101     private final static short CONSTRAINT = 7;
102     private final static short INDEX = 8;
103     private final static short MAX_LEN = 9;
104     private final static short PRECISION = 10;
105     private final static short SCALE = 11;
106     
107     /////////////////////////
108
// Global variables
109
/////////////////////////
110
private static TableSpecLoader singleton;
111     private List[] tables = new List[TableSpec.CAT_COUNT]; // index is category number
112
// accès à liste pour une catégorie
113
// plus accès pour une categorie, type, sequence (parcours de liste)
114
private SchemaValidationContext context;
115     private short status = UNKNOWN;
116     private TableSpec wTable;
117     private ColumnSpec wColumn;
118     private List columns = new ArrayList();
119     private Map columnMap = new HashMap();
120     private List constraints = new ArrayList();
121     private List indexes = new ArrayList();
122     
123     static
124     {
125         singleton = new TableSpecLoader();
126     }
127     
128     private TableSpecLoader()
129     {
130         for(int i = 0; i < TableSpec.CAT_COUNT; i++)
131             tables[i] = new ArrayList();
132         load();
133     }
134     
135     public static TableSpecLoader getInstance()
136     {
137         return singleton;
138     }
139     
140     private void load()
141     {
142         // use URL to provide a base URI for schema loading (relative URI)
143
URL JavaDoc in = TableSpecLoader.class.getResource(RepositoryConstants.RESOURCES_FOLDER + DATA_FILENAME);
144         if (in == null)
145             throw new RuntimeException JavaDoc("Resource " + DATA_FILENAME + " couldn't be found.");
146         InputSource resource = new InputSource(in.toString());
147         XMLReader parser;
148         try
149         {
150             SAXParserFactory JavaDoc factory = SAXParserFactory.newInstance();
151             factory.setNamespaceAware(true);
152             parser = factory.newSAXParser().getXMLReader();
153         }
154         catch (Exception JavaDoc e)
155         {
156             throw new RuntimeException JavaDoc("JAXP exception while intantiating a SAX parser for internal use (" + e.getMessage() + ").");
157         }
158         
159         context = new SchemaValidationContext();
160         ValidatingSchemaFilter filter = new ValidatingSchemaFilter(parser, context);
161         filter.setContentHandler(this);
162         try
163         {
164             filter.parse(resource);
165         }
166         catch (Exception JavaDoc e)
167         {
168             throw new RuntimeException JavaDoc("Exception while parsing Repository table specifications (" + e.getMessage() + ").");
169         }
170         // parser.parse(resource); why does not work ? Why ValidatingSchemaFilter extends DecoratorFilter
171
}
172     
173     /* this method only works if tableSpec.xml is unmodified */
174     public List getTableSpecs(byte cat)
175     {
176         return tables[cat];
177     }
178     
179     /* this method only works if tableSpec.xml is unmodified */
180     public List getTableSpecs(byte cat, short vendor)
181     {
182         ArrayList res = new ArrayList();
183         TableSpec wTable;
184         Iterator it = tables[cat].iterator();
185         while (it.hasNext())
186         {
187             wTable = (TableSpec)it.next();
188             if (wTable.getDBMSVendor() == ANY_DBMS || wTable.getDBMSVendor() == vendor )
189                 res.add(wTable);
190         }
191         return res;
192     }
193     
194     /* this method only works if tableSpec.xml is unmodified */
195     public TableSpec getTableSpec(byte cat, byte tableType)
196     {
197         TableSpec res = null, wTable;
198         Iterator it = tables[cat].iterator();
199         while (it.hasNext())
200         {
201             wTable = (TableSpec)it.next();
202             if (wTable.getType() == tableType)
203             {
204                 res = wTable;
205                 break;
206             }
207         }
208         return res;
209     }
210     
211     public void startElement(String JavaDoc ns, String JavaDoc local, String JavaDoc qName, Attributes atts)
212     throws SAXException
213     {
214         /* Setting automaton status */
215         switch (status)
216         {
217             case UNKNOWN:
218                 if (local.equals(ROOT_ELEMENT))
219                     status = ROOT;
220                 break;
221             case ROOT:
222                 if (local.equals(TABLE_ELEMENT))
223                     status = TABLE;
224                break;
225             case TABLE:
226                 if (local.equals(COLUMN_ELEMENT))
227                     status = COLUMN;
228                 else if (local.equals(CONSTRAINT_ELEMENT))
229                     status = CONSTRAINT;
230                 else if (local.equals(INDEX_ELEMENT))
231                     status = INDEX;
232                 break;
233             case COLUMN:
234                 if (local.equals(JDBC_TYPE_ELEMENT))
235                     status = JDBC_TYPE;
236                 break;
237             case JDBC_TYPE:
238                 if (local.equals(MAX_LEN_ELEMENT))
239                     status = MAX_LEN;
240                 else if (local.equals(PRECISION_ELEMENT))
241                     status = PRECISION;
242                 else if (local.equals(SCALE_ELEMENT))
243                     status = SCALE;
244                 break;
245              default:
246         }
247         
248         /* Creating parent objects */
249         ElementPSVInfoset infoset = context.getCurrentInfoset();
250         switch (status)
251         {
252             case ROOT:
253                 REPOSITORY_DATA_VERSION = context.getCurrentInfoset().getAttributePSVInfoset(null, VERSION_ATTR).getNormalizedValue();
254                 break;
255             case TABLE:
256                 wTable = new TableSpec(); // because IndexSpec objects reference it
257
break;
258             case COLUMN:
259                 wColumn = new ColumnSpec();
260                break;
261             default:
262         }
263         
264       }
265     
266     public void endElement(String JavaDoc ns, String JavaDoc local, String JavaDoc qName)
267     throws SAXException
268     {
269         /* processing leaf elements */
270         ElementPSVInfoset infoset = context.getCurrentInfoset();
271         switch (status)
272         {
273             case TABLE:
274                 completeTable(infoset);
275                 break;
276                 
277             case COLUMN:
278                 completeColumn(infoset);
279                 break;
280                 
281             case JDBC_TYPE:
282                 fillColumnType(infoset);
283                 break;
284
285             case MAX_LEN:
286                 fillSize(infoset);
287                 break;
288
289             case PRECISION:
290                 fillPrecision(infoset);
291                 break;
292
293             case SCALE:
294                 fillScale(infoset);
295                 break;
296
297             case INDEX:
298                 createIndex(infoset);
299                 break;
300                 
301             case CONSTRAINT:
302                 createConstraint(infoset);
303                 break;
304              default:
305         }
306         
307         /* Setting automaton status */
308         switch (status)
309         {
310             case ROOT:
311                 status = UNKNOWN;
312             break;
313             case TABLE:
314                 status = ROOT;
315             break;
316             case COLUMN:
317             case INDEX:
318             case CONSTRAINT:
319                 status = TABLE;
320             break;
321             case JDBC_TYPE:
322             case KEY:
323             case NULLABLE:
324                 status = COLUMN;
325             break;
326             case MAX_LEN:
327             case PRECISION:
328             case SCALE:
329                 status = JDBC_TYPE;
330             break;
331             default:
332         }
333     }
334     
335     void completeTable(ElementPSVInfoset infoset)
336     {
337         String JavaDoc dbmsType = null;
338         String JavaDoc suffix = null;
339         boolean seq = false;
340         byte cat = -1;
341         short dbms = -1;
342         byte tableType = -1;
343         
344         int attCount = infoset.getAttributeCount();
345         PSVInfoset attInfoSet = null;
346         
347         for (int i = 0; i < attCount; i++)
348         {
349             attInfoSet = infoset.getAttributePSVInfoset(i);
350             if (attInfoSet.getLocalName().equals(DBMS_TYPE_ATTR))
351                 dbmsType = attInfoSet.getNormalizedValue();
352             else if (attInfoSet.getLocalName().equals(TYPE_ATTR))
353                 tableType = ((Number JavaDoc)attInfoSet.getActualValue()).byteValue();
354             else if (attInfoSet.getLocalName().equals(CAT_ATTR))
355                 cat = ((Number JavaDoc)attInfoSet.getActualValue()).byteValue();
356             else if (attInfoSet.getLocalName().equals(DBMS_ATTR))
357                 dbms = ((Number JavaDoc)attInfoSet.getActualValue()).byteValue();
358             else if (attInfoSet.getLocalName().equals(SUFFIX_ATTR))
359                 suffix = attInfoSet.getNormalizedValue();
360             else if (attInfoSet.getLocalName().equals(SEQ_ATTR))
361                 seq = ((Boolean JavaDoc)attInfoSet.getActualValue()).booleanValue();
362         }
363         
364         wTable.set(cat, tableType, seq, suffix, dbms, dbmsType);
365         wTable.setColumns((ColumnSpec[])columns.toArray(new ColumnSpec[columns.size()]));
366         wTable.setConstraints((ConstraintSpec[])constraints.toArray(new ConstraintSpec[constraints.size()]));
367         wTable.setIndexes((IndexSpec[])indexes.toArray(new IndexSpec[indexes.size()]));
368
369         /* registrating column */
370         ((List)tables[cat]).add(wTable);
371         
372         /* cleaning lists */
373         columns.clear();
374         indexes.clear();
375         constraints.clear();
376     }
377     
378     void fillColumnType(ElementPSVInfoset infoset)
379     {
380         wColumn.setDataType(infoset.getAttributePSVInfoset(
381                                         null, JDBC_TYPE_ATTR).getNormalizedValue());
382     }
383     
384     void fillSize(ElementPSVInfoset infoset)
385     {
386         wColumn.setSize (
387         ((Number JavaDoc)infoset.getActualValue()).longValue(),
388         ((Number JavaDoc)infoset.getAttributePSVInfoset(null, PARAM_ATTR).getActualValue()).shortValue()
389         );
390     }
391     
392     void fillPrecision(ElementPSVInfoset infoset)
393     {
394         wColumn.setPrecision (
395         ((Number JavaDoc)infoset.getActualValue()).intValue(),
396         ((Number JavaDoc)infoset.getAttributePSVInfoset(null, PARAM_ATTR).getActualValue()).shortValue()
397         );
398     }
399     
400     void fillScale(ElementPSVInfoset infoset)
401     {
402         wColumn.setScale (
403         ((Number JavaDoc)infoset.getActualValue()).intValue(),
404         ((Number JavaDoc)infoset.getAttributePSVInfoset(null, PARAM_ATTR).getActualValue()).shortValue()
405         );
406     }
407
408     void completeColumn(ElementPSVInfoset infoset)
409     {
410         int attCount = infoset.getAttributeCount();
411         PSVInfoset attInfoSet = null;
412         
413         String JavaDoc name = null;
414         
415         for (int i = 0; i < attCount; i++)
416         {
417             attInfoSet = infoset.getAttributePSVInfoset(i);
418             if (attInfoSet.getLocalName().equals(NAME_ATTR))
419             {
420                 name = attInfoSet.getNormalizedValue();
421                 wColumn.setName(name);
422             }
423             else if (attInfoSet.getLocalName().equals(KEY_ATTR))
424                 wColumn.setKeyRole(((Boolean JavaDoc)attInfoSet.getActualValue()).booleanValue());
425             else if (attInfoSet.getLocalName().equals(NULLABLE_ATTR))
426                 wColumn.setNullable(((Boolean JavaDoc)attInfoSet.getActualValue()).booleanValue());
427         }
428         /* registrating column */
429         if (name != null)
430         {
431             columnMap.put(name, wColumn);
432             columns.add(wColumn);
433         }
434     }
435     
436     void createIndex(ElementPSVInfoset infoset)
437     {
438         String JavaDoc type = null;
439         String JavaDoc suffix = null;
440         List indexColumns = new ArrayList();
441         
442         int attCount = infoset.getAttributeCount();
443         PSVInfoset attInfoSet = null;
444         
445         for (int i = 0; i < attCount; i++)
446         {
447             attInfoSet = infoset.getAttributePSVInfoset(i);
448             if (attInfoSet.getLocalName().equals(TYPE_ATTR))
449                 type = attInfoSet.getNormalizedValue();
450             else if (attInfoSet.getLocalName().equals(SUFFIX_ATTR))
451                 suffix = attInfoSet.getNormalizedValue();
452             else if (attInfoSet.getLocalName().equals(COLUMNS_ATTR))
453             {
454                 List columnNames = (List)attInfoSet.getActualValue();
455                 for (Iterator it = columnNames.iterator();it.hasNext();) {
456                     String JavaDoc columnName = (String JavaDoc)it.next();
457                     wColumn = (ColumnSpec)columnMap.get(columnName);
458                     if (wColumn == null)
459                         throw new RuntimeException JavaDoc("The " + columnName
460                         + " column used in an index defined in tableSpec.xml does not exist.");
461                     else
462                         indexColumns.add(wColumn);
463                 }
464                 /*
465                 String columnNames = (String)attInfoSet.getActualValue();
466                 StringTokenizer tokenizer = new StringTokenizer(columnNames);
467                 String columnName;
468                 while (tokenizer.hasMoreTokens())
469                 {
470                     columnName = tokenizer.nextToken();
471                     wColumn = (ColumnSpec)columnMap.get(columnName);
472                     if (wColumn == null)
473                         throw new RuntimeException("The " + columnName
474                         + " column used in an index defined in tableSpec.xml does not exist.");
475                     else
476                         indexColumns.add(wColumn);
477                 }
478                 */

479             }
480         }
481         IndexSpec wIndex = new IndexSpec(wTable, type, suffix);
482         wIndex.setColumns((ColumnSpec[])indexColumns.toArray(new ColumnSpec[indexColumns.size()]));
483         indexes.add(wIndex);
484     }
485     
486     void createConstraint(ElementPSVInfoset infoset)
487     {
488         String JavaDoc type = null;
489         List constraintColumns = new ArrayList();
490         
491         int attCount = infoset.getAttributeCount();
492         PSVInfoset attInfoSet = null;
493         
494         for (int i = 0; i < attCount; i++)
495         {
496             attInfoSet = infoset.getAttributePSVInfoset(i);
497             if (attInfoSet.getLocalName().equals(TYPE_ATTR))
498                 type = attInfoSet.getNormalizedValue();
499             else if (attInfoSet.getLocalName().equals(COLUMNS_ATTR))
500             {
501                 List columnNames = (List)attInfoSet.getActualValue();
502                 for (Iterator it = columnNames.iterator();it.hasNext();) {
503                     String JavaDoc columnName = (String JavaDoc)it.next();
504                     wColumn = (ColumnSpec)columnMap.get(columnName);
505                     if (wColumn == null)
506                         throw new RuntimeException JavaDoc("The " + columnName
507                         + " column used in an index defined in tableSpec.xml does not exist.");
508                     else
509                     constraintColumns.add(wColumn);
510                 }
511                 /*
512                 String columnNames = (String)attInfoSet.getActualValue();
513                 StringTokenizer tokenizer = new StringTokenizer(columnNames);
514                 String columnName;
515                 while (tokenizer.hasMoreTokens())
516                 {
517                     columnName = tokenizer.nextToken();
518                     wColumn = (ColumnSpec)columnMap.get(columnName);
519                     if (wColumn == null)
520                         throw new RuntimeException("The " + columnName
521                         + " column used in a constraint defined in tableSpec.xml does not exist.");
522                     else
523                         constraintColumns.add(wColumn);
524                 }
525                 */

526             }
527         }
528         ConstraintSpec wIndex = new ConstraintSpec(type);
529         wIndex.setColumns((ColumnSpec[])constraintColumns.toArray(new ColumnSpec[constraintColumns.size()]));
530         constraints.add(wIndex);
531     }
532     
533 }
534
Popular Tags