KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > ant > RepositoryVerifierHandler


1 package org.apache.ojb.broker.ant;
2
3 /* Copyright 2002-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.lang.reflect.Constructor JavaDoc;
19 import java.lang.reflect.InvocationTargetException JavaDoc;
20 import java.net.MalformedURLException JavaDoc;
21 import java.sql.Driver JavaDoc;
22 import java.sql.DriverManager JavaDoc;
23 import java.sql.SQLException JavaDoc;
24 import java.sql.SQLWarning JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27
28 import org.apache.ojb.broker.PersistenceBrokerException;
29 import org.apache.ojb.broker.locking.IsolationLevels;
30 import org.apache.ojb.broker.metadata.*;
31 import org.apache.ojb.broker.util.logging.Logger;
32 import org.apache.ojb.broker.util.logging.LoggerFactory;
33 import org.xml.sax.Attributes JavaDoc;
34 import org.xml.sax.SAXException JavaDoc;
35 import org.xml.sax.SAXParseException JavaDoc;
36 import org.xml.sax.helpers.DefaultHandler JavaDoc;
37
38 /**
39  * A SAX parser handler used by the Ant VerifyMappingsTask to process an
40  * OJB DescriptorRepository xml file.
41  *
42  * @author <a HREF="mailto:daren@softwarearena.com">Daren Drummond</a>
43  * @version $Id: RepositoryVerifierHandler.java,v 1.16.2.2 2005/12/21 22:24:16 tomdz Exp $
44  */

45 public class RepositoryVerifierHandler
46     extends DefaultHandler JavaDoc
47     implements RepositoryElements, IsolationLevels
48 {
49     private Logger logger;
50
51     private DescriptorRepository m_repository;
52     private JdbcConnectionDescriptor m_CurrentJCD;
53     private ClassDescriptor m_CurrentCLD;
54     private FieldDescriptor m_CurrentFLD;
55     private ObjectReferenceDescriptor m_CurrentORD;
56     private CollectionDescriptor m_CurrentCOD;
57     private String JavaDoc m_CurrentString;
58     private VerifyMappingsTask m_callingTask;
59     private DBUtility m_dBUtility;
60
61     //ClassDescriptor members;
62
//private String m_CurrentClass = "";
63
private Class JavaDoc m_currentClass = null;
64     private String JavaDoc m_CurrentTable = null;
65     private boolean m_currentTableExists = false;
66
67     /** the default isolation level*/
68     private int defIsoLevel = IL_DEFAULT;
69
70     /**
71      * All known xml tags are kept in this table.
72      * The tags table allows lookup from literal to id
73      * and from id to literal.
74      */

75     private RepositoryTags tags = RepositoryTags.getInstance();
76
77     private Collection JavaDoc m_VerifyExceptions = new ArrayList JavaDoc(69);
78     private Collection JavaDoc m_VerifyWarnings = new ArrayList JavaDoc(69);
79     
80     /**
81      * Allows not to specify field id.
82      */

83     private int m_lastId = 0;
84
85
86     /**
87      * The only public constructor for RepositoryVerifierHandler.
88      *
89      * @param callingTask A reference to the ant task using this parser.
90      */

91     public RepositoryVerifierHandler(VerifyMappingsTask callingTask)
92     {
93         m_callingTask = callingTask;
94         m_callingTask.logWarning("Loaded RepositoryVerifierHandler.");
95         logger = LoggerFactory.getLogger(this.getClass());
96     }
97
98     /**
99      * returns the XmlCapable id associated with the literal.
100      * OJB maintains a RepositoryTags table that provides
101      * a mapping from xml-tags to XmlCapable ids.
102      *
103      * @param literal the literal to lookup
104      * @return the int value representing the XmlCapable
105      *
106      * @throws MetadataException if no literal was found in tags mapping
107      */

108     private int getLiteralId(String JavaDoc literal) throws PersistenceBrokerException
109     {
110         ////logger.debug("lookup: " + literal);
111
try
112         {
113             return tags.getIdByTag(literal);
114         }
115         catch (NullPointerException JavaDoc t)
116         {
117             throw new MetadataException("unknown literal: '" + literal + "'",t);
118         }
119
120     }
121
122     /**
123      * startDocument callback, nothing to do here.
124      */

125     public void startDocument()
126     {
127         //logger.debug("startDoc");
128
}
129
130     /**
131      * endDocument callback, nothing to do here.
132      */

133     public void endDocument()
134     {
135         //logger.debug("endDoc");
136
}
137
138
139     public void startElement(String JavaDoc uri, String JavaDoc name, String JavaDoc qName, Attributes JavaDoc atts)
140     {
141         m_CurrentString = null;
142         try
143         {
144
145             switch (getLiteralId(qName))
146             {
147                 case MAPPING_REPOSITORY :
148                     {
149                         String JavaDoc defIso = atts.getValue(tags.getTagById(ISOLATION_LEVEL));
150                         if (defIso != null)
151                         {
152                             defIsoLevel = getIsoLevel(defIso);
153                         }
154
155                         break;
156                     }
157                 case JDBC_CONNECTION_DESCRIPTOR :
158                     {
159                         m_CurrentJCD = new JdbcConnectionDescriptor();
160
161                         // set platform attribute
162
String JavaDoc platform = atts.getValue(tags.getTagById(DBMS_NAME));
163                         //logger.debug(" " + tags.getTagById(Dbms_name) + ": " + platform);
164
m_CurrentJCD.setDbms(platform);
165
166                         // set jdbc-level attribute
167
String JavaDoc level = atts.getValue(tags.getTagById(JDBC_LEVEL));
168                         //logger.debug(" " + tags.getTagById(Jdbc_level) + ": " + level);
169
m_CurrentJCD.setJdbcLevel(level);
170
171                         // set driver attribute
172
String JavaDoc driver = atts.getValue(tags.getTagById(DRIVER_NAME));
173                         //logger.debug(" " + tags.getTagById(Driver_name) + ": " + driver);
174
m_CurrentJCD.setDriver(driver);
175
176                         // set protocol attribute
177
String JavaDoc protocol = atts.getValue(tags.getTagById(URL_PROTOCOL));
178                         //logger.debug(" " + tags.getTagById(Url_protocol) + ": " + protocol);
179
m_CurrentJCD.setProtocol(protocol);
180
181                         // set subprotocol attribute
182
String JavaDoc subprotocol = atts.getValue(tags.getTagById(URL_SUBPROTOCOL));
183                         //logger.debug(" " + tags.getTagById(Url_subprotocol) + ": " + subprotocol);
184
m_CurrentJCD.setSubProtocol(subprotocol);
185
186                         // set the dbalias attribute
187
String JavaDoc dbalias = atts.getValue(tags.getTagById(URL_DBALIAS));
188                         //logger.debug(" " + tags.getTagById(Url_dbalias) + ": " + dbalias);
189
m_CurrentJCD.setDbAlias(dbalias);
190
191                         // set the datasource attribute
192
String JavaDoc datasource = atts.getValue(tags.getTagById(DATASOURCE_NAME));
193                         //logger.debug(" " + tags.getTagById(Datasource_name) + ": " + datasource);
194
m_CurrentJCD.setDatasourceName(datasource);
195
196                         // set the user attribute
197
String JavaDoc user = atts.getValue(tags.getTagById(USER_NAME));
198                         //logger.debug(" " + tags.getTagById(User_name) + ": " + user);
199
m_CurrentJCD.setUserName(user);
200
201                         // set the password attribute
202
String JavaDoc password = atts.getValue(tags.getTagById(USER_PASSWD));
203                         //logger.debug(" " + tags.getTagById(User_passwd) + ": " + password);
204
m_CurrentJCD.setPassWord(password);
205
206                         //connect to the database
207
m_dBUtility = getDBUtility(m_CurrentJCD);
208
209                         break;
210                     }
211                 case CLASS_DESCRIPTOR :
212                     {
213                         String JavaDoc isoLevel = atts.getValue(tags.getTagById(ISOLATION_LEVEL));
214
215                         // set class attribute
216
String JavaDoc classname = atts.getValue(tags.getTagById(CLASS_NAME));
217
218                         try
219                         {
220                             m_currentClass = m_callingTask.loadClass(classname);
221                         }
222                         catch (ClassNotFoundException JavaDoc ex)
223                         {
224                             //logger.error(ex);
225
throw new MetadataException("Can't load class-descriptor class '" + classname + "'.");
226                         }
227
228                         m_CurrentTable = atts.getValue(tags.getTagById(TABLE_NAME));
229
230                         if (m_CurrentTable != null)
231                         {
232                             m_currentTableExists = m_dBUtility.exists(m_CurrentTable);
233                             if(!m_currentTableExists)
234                             {
235                                 throw new MetadataException("The table '" + m_CurrentTable + "' does not exist in the database.");
236                             }
237                         }
238
239
240                         break;
241                     }
242
243                 case CLASS_EXTENT :
244                     {
245
246                         String JavaDoc classname = atts.getValue("class-ref");
247
248                         try
249                         {
250                             Class JavaDoc classExtent = m_callingTask.loadClass(classname);
251                         }
252                         catch (ClassNotFoundException JavaDoc ex)
253                         {
254                             //logger.error(ex);
255
throw new MetadataException("Can't load extent-class class '" + classname + "'.");
256                         }
257                         break;
258                     }
259
260                 case FIELD_DESCRIPTOR :
261                     {
262             String JavaDoc strId = atts.getValue("id");
263                         m_lastId = (strId == null ? m_lastId + 1 : Integer.parseInt(strId));
264                         m_CurrentFLD = new FieldDescriptor(null, m_lastId);
265
266                         String JavaDoc fieldName = atts.getValue(tags.getTagById(FIELD_NAME));
267
268                         if (m_currentClass != null)
269                         {
270                             //this.m_callingTask.logWarning("Verifying " + fieldName + " in class " + m_currentClass.toString());
271
confirmFieldExists(m_currentClass, fieldName);
272
273                             String JavaDoc columnName = atts.getValue(tags.getTagById(COLUMN_NAME));
274                             m_CurrentFLD.setColumnName(columnName);
275
276                             String JavaDoc jdbcType = atts.getValue(tags.getTagById(JDBC_TYPE));
277                             m_CurrentFLD.setColumnType(jdbcType);
278
279                             //check that the field exists in the database
280
if(m_currentTableExists)
281                             {
282                                 if(this.m_callingTask.getUseStrictTypeChecking())
283                                 {
284                                     m_dBUtility.exists(m_CurrentTable, columnName, jdbcType, m_callingTask.getIgnoreFieldNameCase());
285                                 }
286                                 else
287                                 {
288                                     m_dBUtility.existsUseWarnings(m_CurrentTable, columnName, jdbcType, m_callingTask.getIgnoreFieldNameCase());
289                                 }
290                             }
291
292                         }
293
294                         break;
295                     }
296                 case REFERENCE_DESCRIPTOR :
297                     {
298                         if (m_currentClass != null)
299                         {
300                             //Confirm that this field exists in the class
301
name = atts.getValue(tags.getTagById(FIELD_NAME));
302                             confirmFieldExists(m_currentClass, name);
303
304                             String JavaDoc classRef = atts.getValue(tags.getTagById(REFERENCED_CLASS));
305                             try
306                             {
307                                 //Confirm that class 'class-ref' can be loaded.
308
Class JavaDoc refClass = m_callingTask.loadClass(classRef);
309                             }
310                             catch (ClassNotFoundException JavaDoc ex)
311                             {
312                                 //logger.error(ex);
313
throw new MetadataException("Can't find class-ref '" + classRef + "' in reference-descriptor '" + name + "'.");
314                             }
315
316                         }
317
318                         break;
319                     }
320
321                 case COLLECTION_DESCRIPTOR :
322                     {
323
324                         if (m_currentClass != null)
325                         {
326                             //Confirm that this field exists in the class
327
name = atts.getValue(tags.getTagById(FIELD_NAME));
328                             confirmFieldExists(m_currentClass, name);
329
330                             String JavaDoc collectionClass = atts.getValue(tags.getTagById(COLLECTION_CLASS));
331                             //logger.debug(" " + tags.getTagById(Collection_class) + ": " + collectionClass);
332
if (collectionClass != null)
333                             {
334                                 try
335                                 {
336                                     //Confirm that class 'class-ref' can be loaded.
337
Class JavaDoc oCollectionClass = m_callingTask.loadClass(collectionClass);
338                                 }
339                                 catch (ClassNotFoundException JavaDoc ex)
340                                 {
341                                     //logger.error(ex);
342
throw new MetadataException("Can't find collection-class '" + collectionClass + "' in collection-descriptor '" + name + "'.");
343                                 }
344                             }
345                             // set element-class-ref attribute
346
String JavaDoc elementClassRef = atts.getValue(tags.getTagById(ITEMS_CLASS));
347                             //logger.debug(" " + tags.getTagById(Items_class) + ": " + elementClassRef);
348
if (elementClassRef != null)
349                             {
350                                 try
351                                 {
352                                     //Confirm that class 'class-ref' can be loaded.
353
Class JavaDoc oElementClassRef = m_callingTask.loadClass(elementClassRef);
354                                 }
355                                 catch (ClassNotFoundException JavaDoc ex)
356                                 {
357                                     //logger.error(ex);
358
throw new MetadataException("Can't find element-class-ref '" + elementClassRef + "' in collection-descriptor '" + name + "'.");
359                                 }
360                              }
361                         }
362
363
364                         break;
365                     }
366
367                 default :
368                     {
369                         // nop
370
}
371             }
372         }
373         catch(MetadataException mde)
374         {
375             this.m_callingTask.logWarning(" --> Mapping Error: " + mde.getMessage());
376             m_VerifyExceptions.add(mde);
377         }
378         catch(NullPointerException JavaDoc garbage)
379         {
380             //eat it.
381
}
382         catch(SQLWarning JavaDoc sqlw)
383         {
384             this.m_callingTask.logInfo(" --> DB Mapping Warning: " + sqlw.getMessage());
385             m_VerifyWarnings.add(sqlw);
386         }
387         catch(SQLException JavaDoc sqle)
388         {
389             this.m_callingTask.logWarning(" --> DB Mapping Error: " + sqle.getMessage());
390             m_VerifyExceptions.add(sqle);
391         }
392         catch (Exception JavaDoc ex)
393         {
394             logger.error(ex);
395             throw new PersistenceBrokerException(ex);
396         }
397     }
398
399
400     public void endElement(String JavaDoc uri, String JavaDoc name, String JavaDoc qName)
401     {
402         try
403         {
404             switch (getLiteralId(qName))
405             {
406                 case MAPPING_REPOSITORY :
407                     {
408                         //release the any db connections
409
if(m_dBUtility != null) m_dBUtility.release();
410                         break;
411                     }
412                 case JDBC_CONNECTION_DESCRIPTOR :
413                     {
414                         //logger.debug(" < " + tags.getTagById(JdbcConnectionDescriptor));
415
break;
416                     }
417                 case CLASS_DESCRIPTOR :
418                     {
419                         //logger.debug(" < " + tags.getTagById(ClassDescriptor));
420
m_currentClass = null;
421                         m_CurrentTable = null;
422                         m_currentTableExists = false;
423                         m_CurrentCLD = null;
424                         break;
425                     }
426                 case CLASS_EXTENT :
427                     {
428                         break;
429                     }
430
431                 case FIELD_DESCRIPTOR :
432                     {
433                         //logger.debug(" < " + tags.getTagById(FIELDDESCRIPTOR));
434
m_CurrentFLD = null;
435                         break;
436                     }
437                 case REFERENCE_DESCRIPTOR :
438                     {
439                         //logger.debug(" < " + tags.getTagById(ReferenceDescriptor));
440
m_CurrentORD = null;
441                         break;
442                     }
443                 case FOREIGN_KEY :
444                     {
445                         //logger.debug(" < " + tags.getTagById(FOREIGN_KEY));
446
}
447
448                 case COLLECTION_DESCRIPTOR :
449                     {
450                         //logger.debug(" < " + tags.getTagById(CollectionDescriptor));
451
m_CurrentCOD = null;
452                         break;
453                     }
454
455                 case INVERSE_FK :
456                     {
457                         //logger.debug(" < " + tags.getTagById(Inverse_fk));
458
break;
459                     }
460
461                 case FK_POINTING_TO_THIS_CLASS :
462                     {
463                         //logger.debug(" < " + tags.getTagById(Fk_pointing_to_this_class));
464
break;
465                     }
466                 case FK_POINTING_TO_ITEMS_CLASS :
467                     {
468                         //logger.debug(" < " + tags.getTagById(Fk_pointing_to_items_class));
469
break;
470                     }
471
472                     // handle failure:
473
default :
474                     {
475                         //logger.error("Ignoring unknown Element " + qName);
476
}
477             }
478         }
479         catch (Exception JavaDoc ex)
480         {
481             //logger.error(ex);
482
throw new PersistenceBrokerException(ex);
483         }
484     }
485
486     public void characters(char ch[], int start, int length)
487     {
488         if (m_CurrentString == null)
489             m_CurrentString = new String JavaDoc(ch, start, length);
490         else
491             m_CurrentString += new String JavaDoc(ch, start, length);
492     }
493
494     public void error(SAXParseException JavaDoc e) throws SAXException JavaDoc
495     {
496         //logger.error(e);
497
//release the any db connections
498
try
499         {
500             if(m_dBUtility != null) m_dBUtility.release();
501         }
502         catch(Exception JavaDoc ex)
503         {
504             ex.printStackTrace();
505         }
506         throw e;
507     }
508
509     public void fatalError(SAXParseException JavaDoc e) throws SAXException JavaDoc
510     {
511         //logger.fatal(e);
512
//release the any db connections
513
try
514         {
515             if(m_dBUtility != null) m_dBUtility.release();
516         }
517         catch(Exception JavaDoc ex)
518         {
519             ex.printStackTrace();
520         }
521         throw e;
522     }
523
524     public void warning(SAXParseException JavaDoc e) throws SAXException JavaDoc
525     {
526         //logger.warn(e);
527
throw e;
528     }
529
530     /**
531      * maps IsolationLevel literals to the corresponding id
532      * @param isoLevel
533      * @return the id
534      */

535     private int getIsoLevel(String JavaDoc isoLevel)
536     {
537         if (isoLevel.equalsIgnoreCase(LITERAL_IL_READ_UNCOMMITTED))
538         {
539             return IL_READ_UNCOMMITTED;
540         }
541         else if (isoLevel.equalsIgnoreCase(LITERAL_IL_READ_COMMITTED))
542         {
543             return IL_READ_COMMITTED;
544         }
545         else if (isoLevel.equalsIgnoreCase(LITERAL_IL_REPEATABLE_READ))
546         {
547             return IL_REPEATABLE_READ;
548         }
549         else if (isoLevel.equalsIgnoreCase(LITERAL_IL_SERIALIZABLE))
550         {
551             return IL_SERIALIZABLE;
552         }
553         else if (isoLevel.equalsIgnoreCase(LITERAL_IL_OPTIMISTIC))
554         {
555             return IL_OPTIMISTIC;
556         }
557         //logger.warn("unknown isolation-level: " + isoLevel + " using RW_UNCOMMITTED as default");
558
return defIsoLevel;
559     }
560
561
562     public int getErrorCount()
563     {
564         return m_VerifyExceptions.size();
565     }
566
567     public int getWarningCount()
568     {
569         return m_VerifyWarnings.size();
570     }
571
572
573     private DBUtility getDBUtility(JdbcConnectionDescriptor jcd)
574     throws MetadataException, MalformedURLException JavaDoc, ClassNotFoundException JavaDoc
575     {
576         DBUtility retval = null;
577         String JavaDoc driver;
578         String JavaDoc userName;
579         String JavaDoc password;
580         String JavaDoc url;
581         //if the Tag provided the connection info use that, else
582
//try to connect with the info in the connectionDescriptor
583
if (m_callingTask.hasConnectionInfo())
584         {
585             m_callingTask.logWarning("Using DB conection info from Ant task.");
586             driver = m_callingTask.getJdbcDriver();
587             userName = m_callingTask.getLogon();
588             password = m_callingTask.getPassword();
589             url = m_callingTask.getUrl();
590         }
591         else
592         {
593             m_callingTask.logWarning("Using DB conection info from ojb repository connection descriptor.");
594             driver = jcd.getDriver();
595             userName = jcd.getUserName();
596             password = jcd.getPassWord();
597             url = jcd.getProtocol() + ":" + jcd.getSubProtocol() + ":" + jcd.getDbAlias();
598         }
599
600         try
601         {
602             Class JavaDoc jdbcDriver = m_callingTask.loadClass(driver);
603
604             // not every jdbc driver registers itself with the driver manager
605
// so we do it explicitly
606
DriverManager.registerDriver((Driver JavaDoc)jdbcDriver.newInstance());
607             retval = new DBUtility(url, userName, password);
608         }
609         catch(ClassNotFoundException JavaDoc cnfe)
610         {
611             throw cnfe;
612         }
613         catch (Exception JavaDoc e)
614         {
615             e.printStackTrace();
616             throw new MetadataException("Could not connect to database with url (" +
617             url + "), driver (" + driver + "), logon (" + userName +
618             "), password (" + password + ").", e);
619         }
620
621         return retval;
622     }
623
624     private Constructor JavaDoc m_persistConstructor = null;
625     private Constructor JavaDoc getPersistenceClassConstructor() throws NoSuchMethodException JavaDoc
626     {
627         if(m_persistConstructor == null)
628         {
629             //load the persistent class specified in the OJB.properties file
630
Class JavaDoc persistentClass = m_callingTask.getPersistentFieldClass();
631             Class JavaDoc[] aConTypes = new Class JavaDoc[2];
632             aConTypes[0] = Class JavaDoc.class;
633             aConTypes[1] = String JavaDoc.class;
634             m_persistConstructor = persistentClass.getConstructor(aConTypes);
635         }
636         return m_persistConstructor;
637     }
638
639     protected void confirmFieldExists(Class JavaDoc classToCheck, String JavaDoc fieldName)
640     throws MetadataException, NoSuchMethodException JavaDoc,
641             InstantiationException JavaDoc, IllegalAccessException JavaDoc
642     {
643         Object JavaDoc[] aConParams = new Object JavaDoc[2];
644         aConParams[0] = classToCheck;
645         aConParams[1] = fieldName;
646
647         try
648         {
649             getPersistenceClassConstructor().newInstance(aConParams);
650         }
651         catch(InvocationTargetException JavaDoc ite)
652         {
653             throw new MetadataException(ite.getTargetException().getMessage());
654         }
655     }
656
657 }
658
Popular Tags