KickJava   Java API By Example, From Geeks To Geeks.

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


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 package org.xquark.mapper.dbms;
24
25
26 import java.lang.reflect.Constructor JavaDoc;
27 import java.lang.reflect.InvocationTargetException JavaDoc;
28 import java.net.URL JavaDoc;
29 import java.sql.SQLException JavaDoc;
30 import java.util.*;
31
32 import org.xml.sax.InputSource JavaDoc;
33 import org.xml.sax.SAXException JavaDoc;
34 import org.xml.sax.XMLReader JavaDoc;
35 import org.xquark.mapper.*;
36 import org.xquark.mapper.mapping.MappingFactory;
37 import org.xquark.mapper.metadata.*;
38 import org.xquark.mapper.storage.*;
39 import org.xquark.mapper.util.DestructionToken;
40 import org.xquark.mapper.util.DisposableReaderFilter;
41 import org.xquark.mapper.util.RepositoryRuntimeException;
42 import org.xquark.schema.SchemaManager;
43 import org.xquark.xml.xdbc.*;
44
45
46 /**
47  * @see org.xquark.mapper.AccessManager
48  * @see org.xquark.mapper.XMLCollection
49  */

50 public final class RepositoryConnectionImpl implements _RepositoryConnection
51 {
52     private static final String JavaDoc RCSRevision = "$Revision: 1.4 $";
53     private static final String JavaDoc RCSName = "$Name: $";
54
55     // Static variables (to be independant from XQuery package)
56
private static Constructor JavaDoc stmtConstructor = null;
57              
58     private AbstractConnection connection;
59     private Repository rep;
60     /* param for dynamic instantiation of statement */
61     private Object JavaDoc[] params = new Object JavaDoc[2];
62     
63     /** Destruction token given by the AccessManager */
64     private DestructionToken destructor;
65     private ArrayList XMLCollections = new ArrayList(); // to close XMLCollections when closing & set modes
66
private HashSet XMLStatements = new HashSet(); // to close XMLStatements
67
private InputSource JavaDoc source;
68     
69     // Options
70
//
71
private boolean autoCommit = true;
72     private boolean readOnly = false;
73     private boolean interactiveQueries = true;
74
75     public RepositoryConnectionImpl(Repository rep, AbstractConnection connection, DestructionToken destructor)
76     throws RepositoryException
77     {
78         this.rep = rep;
79         this.destructor = destructor;
80         this.connection = connection;
81         // dynamic instantiation of XQuery statement (removed from static statement
82
// because QA loads classes to check RCS IDs...)
83
loadXQueryStatementClass();
84         params[0] = this;
85     }
86     
87     public _Repository getMetadata()
88     {
89         return rep;
90     }
91     public SchemaManager getSchemaManager()
92     {
93         return rep.getSchemaManager();
94     }
95     
96     public void commit() throws XMLDBCException, XMLDBCNotSupportedException
97     {
98         flush();
99         try {
100             connection.getConnection().commit();
101             broadcastCommit();
102         }
103         catch (SQLException JavaDoc e) {
104             throw new RepositoryException(RepositoryException.DB_ERROR, "Could not commit the underlying JDBC connection.", e);
105         }
106     }
107         
108     public void rollback() throws XMLDBCException, XMLDBCNotSupportedException
109     {
110         try {
111             connection.getConnection().rollback();
112             broadcastRollback();
113         }
114         catch (SQLException JavaDoc e) {
115             throw new RepositoryException(RepositoryException.DB_ERROR, "Could not rollback the underlying JDBC connection.", e);
116         }
117      }
118     
119     public void setAutoCommit(boolean mode) throws XMLDBCException
120     {
121         autoCommit = mode;
122         try {
123             connection.getConnection().setAutoCommit(mode);
124         }
125         catch (SQLException JavaDoc e) {
126             throw new RepositoryException(RepositoryException.DB_ERROR, "Could not set the autoommit mode on the underlying JDBC connection.", e);
127         }
128             
129     }
130     
131     ///////////////////////////////////////////////////////////////////////////
132
// Wrapping of Repository
133
///////////////////////////////////////////////////////////////////////////
134

135     public RepositoryReader getMappingReader() throws XMLDBCException
136     {
137         return ((_RepositoryCollection)getMappingCollection()).getReader();
138     }
139
140     public String JavaDoc getURL()
141     {
142         return RepositoryDriver.REPOSITORY_URL_PREFIX + rep.getURL();
143     }
144
145     public String JavaDoc toString()
146     {
147         return rep.toString();
148     }
149     
150     public String JavaDoc getUserName()
151     {
152        return rep.getUserName();
153     }
154     
155     public AbstractConnection getConnection()
156     {
157         return connection;
158     }
159     
160     public boolean getAutoCommit()
161     {
162         return autoCommit;
163     }
164     
165     ///////////////////////////////////////////////////////////////////////////
166
// XMLConnection implementation
167
///////////////////////////////////////////////////////////////////////////
168
public Configurable createCollectionConfig() throws XMLDBCException, XMLDBCNotSupportedException
169     {
170         return new CollectionInfo(false);
171     }
172     
173     public XMLCollection createCollection(String JavaDoc name, String JavaDoc description, Configurable config) throws XMLDBCException, XMLDBCNotSupportedException
174     {
175         protectReadOnlyMethod();
176         CollectionInfo colInfo = new CollectionInfo(config);
177         colInfo.setDescription(description);
178         MappingFactory mapFactory = rep.getMapping((String JavaDoc)config.getProperty(MAPPING_ID_PROPERTY));
179         rep.createCollection(name, colInfo, mapFactory);
180         return getCollection(name);
181     }
182     
183     public XMLCollection getCollection(String JavaDoc name) throws XMLDBCException, XMLDBCNotSupportedException
184     {
185         return getRepositoryCollection(name);
186     }
187     
188     
189     public void renameCollection(String JavaDoc oldname, String JavaDoc newname) throws XMLDBCException, XMLDBCNotSupportedException
190     {
191         protectReadOnlyMethod();
192         rep.renameCollection(oldname, newname);
193     }
194
195     public void deleteCollection(String JavaDoc name) throws XMLDBCException, XMLDBCNotSupportedException
196     {
197         protectReadOnlyMethod();
198         name = name.toUpperCase();
199         
200         // close all opened XMLCollections
201
Iterator it = ((List)XMLCollections.clone()).iterator(); // clone because of destructor
202
RepositoryCollection collection;
203         while (it.hasNext())
204         {
205             collection = (RepositoryCollection)it.next();
206             if (collection.getName().equals(name))
207                 collection.close(); // will remove from the original list
208
}
209         // Close metadata if possible (another connection could use it)
210
rep.deleteCollection(name);
211     }
212     
213     public int deleteAllCollections() throws XMLDBCException, XMLDBCNotSupportedException
214     {
215         protectReadOnlyMethod();
216         return rep.deleteAllCollections();
217     }
218     
219     public void setTransactionIsolation(short level) throws XMLDBCException, XMLDBCNotSupportedException
220     {
221         throw new XMLDBCNotSupportedException("Not Supported yet");
222     }
223     
224     public short getTransactionIsolation() throws XMLDBCException, XMLDBCNotSupportedException
225     {
226         throw new XMLDBCNotSupportedException("Not Supported yet");
227     }
228     
229     public void setReadOnly(boolean readOnlyMode) throws XMLDBCException, XMLDBCNotSupportedException
230     {
231         if (readOnlyMode)
232             broadcastReadOnly();
233         readOnly = readOnlyMode;
234     }
235     
236     public boolean isReadOnly() throws XMLDBCException
237     {
238         return readOnly;
239     }
240     
241     public XMLDataSourceMetaData getMetaData() throws XMLDBCException
242     {
243         return new DataSourceMetaData(this);
244     }
245     
246     public XMLDataSourceMetaData getMetaData(boolean refresh) throws XMLDBCException
247     {
248         return new DataSourceMetaData(this, refresh);
249     }
250
251     public void close() throws XMLDBCException
252     {
253         if (!isClosed())
254         {
255             _close();
256             try
257             {
258                connection.close();
259             }
260             catch (SQLException JavaDoc e)
261             {
262                 // TO SEE
263
}
264             destructor.destruct(this);
265             destructor = null;
266             XMLCollections = null;
267             XMLStatements = null;
268             rep = null;
269             connection = null;
270         }
271     }
272     
273     public boolean isClosed() throws XMLDBCException
274     {
275         return (destructor == null);
276     }
277     
278     public XMLStatement createStatement(short queryType) throws XMLDBCException
279     {
280         if (queryType == XQUERY_STRING_TYPE)
281             return createStatement();
282         else
283             throw new UnsupportedOperationException JavaDoc("Query type is not Supported.");
284     }
285     
286     public XMLStatement createStatement() throws XMLDBCException
287     {
288         params[1] = new XMLStatementDestructor();
289         XMLStatement stmt = null;
290         try {
291             stmt = (XMLStatement)stmtConstructor.newInstance(params);
292         }
293         catch (InvocationTargetException JavaDoc e) {
294             if (e.getTargetException() instanceof XMLDBCException)
295                 throw (XMLDBCException)e.getTargetException();
296             else
297                 throw new RepositoryException(RepositoryException.INTERNAL_ERROR,
298                 "Exception while creating XQuery statement.", e.getTargetException());
299         }
300         catch (Exception JavaDoc e) {
301             throw new RepositoryException(RepositoryException.INTERNAL_ERROR,
302                 "Repository XQuery module is missing in your CLASSPATH.", e);
303         }
304         XMLStatements.add(stmt);
305         return stmt;
306     }
307     
308     public PreparedXMLStatement prepareStatement(String JavaDoc query) throws XMLDBCException, XMLDBCNotSupportedException
309     {
310         throw new XMLDBCNotSupportedException("Not Supported yet");
311     }
312
313     public void setBaseURI(String JavaDoc baseURI) {
314         //throw new XMLDBCNotSupportedException("Not Supported yet");
315
}
316     
317     ///////////////////////////////////////////////////////////////////////////
318
// RepositoryConnection implementation
319
///////////////////////////////////////////////////////////////////////////
320
/** Open an existing user collection. Compared to the XDBC
321      * {@link XMLConnection#getCollection(String) getCollection()} method, this
322      * method avoids the cast operation
323      * @return a {@link RepositoryCollection XMLCollection} object.
324      * @throws RepositoryException API exception.
325      */

326     public RepositoryCollection getRepositoryCollection(String JavaDoc name) throws XMLDBCException
327     {
328         if (name == null)
329             throw new RepositoryException(RepositoryException.PERMISSION_DENIED, "A collection name must be provided.");
330         
331         // system collections opened by name
332
_RepositoryCollection collection;
333         
334         if (name.equals(SCHEMA_COLLECTION))
335         {
336             collection = new SchemaXMLCollection(
337                     rep.getSchemaCollection(),
338                     this,
339                     new XMLCollectionDestructor()
340                     );
341         }
342         else if (name.equals(MAPPING_COLLECTION))
343         {
344             collection = new MappingXMLCollection(
345                     rep.getMappingCollection(),
346                     this,
347                     new XMLCollectionDestructor()
348                     );
349         }
350         else
351         {
352             collection = new XMLCollectionImpl(
353                                         rep.openCollection(name),
354                                         this,
355                                         new XMLCollectionDestructor()
356                                         );
357         }
358         collection.setReadOnly(readOnly);
359         XMLCollections.add(collection); // name is not taken because of uppercase conversion
360
return collection;
361     }
362     
363     public RepositoryCollection getMappingCollection() throws XMLDBCException
364     {
365         return getRepositoryCollection(MAPPING_COLLECTION);
366     }
367     
368     public RepositoryCollection getSchemaCollection() throws XMLDBCException
369     {
370         return getRepositoryCollection(SCHEMA_COLLECTION);
371     }
372     
373     public void resetRepository() throws XMLDBCException
374     {
375         protectReadOnlyMethod();
376         _close();
377         rep.resetRepository();
378     }
379     
380     public void deleteRepository() throws XMLDBCException
381     {
382         protectReadOnlyMethod();
383         _close(); // close collection before close() try it after Reepository deleted
384
rep.deleteRepository();
385         close();
386     }
387     
388     public void deleteConfiguration() throws XMLDBCException
389     {
390         protectReadOnlyMethod();
391         rep.deleteConfiguration();
392         close();
393     }
394     
395     public void setInteractiveMode(boolean interactive)
396     {
397         interactiveQueries = interactive;
398     }
399     
400     public boolean getInteractiveMode()
401     {
402         return interactiveQueries;
403     }
404     
405     
406     public List getCollectionsUsingMapping(String JavaDoc mappingID)
407     throws XMLDBCException
408     {
409         return rep.getCollectionsUsingMapping(mappingID);
410     }
411     
412     public List getCollectionsUsingNamespace(String JavaDoc namespace)
413     throws XMLDBCException
414     {
415         return rep.getCollectionsUsingNamespace(namespace);
416     }
417
418     public List getMappingsUsingNamespace(String JavaDoc namespace)
419     throws XMLDBCException
420     {
421         return Collections.EMPTY_LIST; // TO IMPLEMENT using XQuery ?
422
}
423
424     ///////////////////////////////////////////////////////////////////////////
425
// ShemaLocator implementation
426
///////////////////////////////////////////////////////////////////////////
427

428     public void clearSchemaLocations()
429     {
430     // no op
431
}
432     
433     public Iterator getSchemaLocations(String JavaDoc namespace)
434     {
435         return null;
436     }
437     
438     public void addSchemaLocation(String JavaDoc namespace, String JavaDoc location)
439     {
440         // no op
441
}
442     
443     public XMLReader JavaDoc getSchemaReader() throws SAXException JavaDoc
444     {
445         try {
446             return new DisposableReaderFilter(((_RepositoryCollection)getSchemaCollection()).getReader());
447         }
448         catch (XMLDBCException e)
449         {
450             throw new SAXException JavaDoc("Could not catch reader for the schema system XML collection.", e);
451         }
452     }
453     
454     public InputSource JavaDoc resolveLocation(String JavaDoc namespace, String JavaDoc location)
455     {
456         if (namespace == null)
457             namespace = RepositoryConstants.NO_NAMESPACE_SCHEMA_ID;
458         if (source == null)
459             source = new InputSource JavaDoc(namespace);
460         else
461             source.setSystemId(namespace);
462         try
463         {
464             if (getSchemaCollection().containsDocument(namespace))
465                 return source;
466             else
467                 return null;
468         }
469         catch (XMLDBCException e)
470         {
471             return null;
472         }
473     }
474     
475     public InputSource JavaDoc resolveLocation(String JavaDoc namespace, URL JavaDoc location)
476     {
477         return resolveLocation(namespace, (String JavaDoc)null);
478     }
479     
480     public String JavaDoc resolveInclude(String JavaDoc location) {
481         return location;
482     }
483  
484     ///////////////////////////////////////////////////////////////////////////
485
// INNER CLASSES
486
///////////////////////////////////////////////////////////////////////////
487
private class XMLCollectionDestructor implements DestructionToken
488     {
489         public void destruct(Object JavaDoc o)
490         {
491             XMLCollections.remove(o);
492             if (!(o instanceof SchemaXMLCollection)
493                     && !(o instanceof MappingXMLCollection))
494             {
495                 try
496                 {
497                     rep.releaseCollectionMetadata(((_RepositoryCollection)o).getCollectionName());
498                 }
499                 catch (RepositoryException e)
500                 {
501                     throw new RepositoryRuntimeException(e);
502                 }
503             }
504         }
505     }
506
507     private class XMLStatementDestructor implements DestructionToken
508     {
509         public void destruct(Object JavaDoc o)
510         {
511             XMLStatements.remove(o);
512         }
513     }
514     
515     ///////////////////////////////////////////////////////////////////////////
516
// PRIVATE
517
///////////////////////////////////////////////////////////////////////////
518
private void protectReadOnlyMethod() throws RepositoryException
519     {
520         if (readOnly)
521             throw new RepositoryException(RepositoryException.NOT_ALLOWED,
522             "Such operation is forbidden because connection is read-only.");
523     }
524     
525     private void flush() throws XMLDBCException
526     {
527         Iterator it = XMLCollections.iterator();
528         while (it.hasNext())
529         {
530             ((_RepositoryCollection)it.next()).flushFilers();
531         }
532     }
533     
534     private void broadcastReadOnly() throws XMLDBCException
535     {
536         Iterator it = XMLCollections.iterator();
537         while (it.hasNext())
538         {
539             ((XMLCollection)it.next()).setReadOnly(true);
540         }
541     }
542     
543     private void broadcastCommit() throws XMLDBCException
544     {
545         Iterator it = XMLCollections.iterator();
546         while (it.hasNext())
547         {
548             ((_RepositoryCollection)it.next()).commitPerformed();
549         }
550     }
551     
552     private void broadcastRollback() throws XMLDBCException
553     {
554         Iterator it = XMLCollections.iterator();
555         while (it.hasNext())
556         {
557             ((_RepositoryCollection)it.next()).rollbackPerformed();
558         }
559     }
560     
561     private void _close() throws XMLDBCException
562     {
563         Iterator it;
564         if (XMLCollections.size() > 0)
565         {
566             it = ((List)XMLCollections.clone()).iterator(); // because of destructor
567
while(it.hasNext())
568                 ((_RepositoryCollection)it.next()).close();
569             
570             XMLCollections.clear(); // in case (should not be necessary)
571
}
572         
573         if (XMLStatements.size() > 0)
574         {
575             it = ((HashSet)XMLStatements.clone()).iterator();
576             while(it.hasNext())
577             {
578                 ((XMLStatement)it.next()).close();
579                 it.remove();
580             }
581             XMLStatements.clear();
582         }
583     }
584     
585     private static synchronized void loadXQueryStatementClass()
586     {
587         if (stmtConstructor == null) // not synchronized
588
{
589             Class JavaDoc stmtImpl = null;
590             try
591             {
592                 stmtImpl = Class.forName("org.xquark.mapper.xquery.XStatementImpl");
593             }
594             catch (ClassNotFoundException JavaDoc e)
595             {
596                 throw new RuntimeException JavaDoc("Repository XQuery module is missing in your CLASSPATH: "
597                 + e.getMessage());
598             }
599             Class JavaDoc[] paramTypes = new Class JavaDoc[]
600             {RepositoryConnection.class, DestructionToken.class};
601             try
602             {
603                 stmtConstructor = stmtImpl.getConstructor(paramTypes);
604             }
605             catch (NoSuchMethodException JavaDoc e)
606             {
607                 throw new RuntimeException JavaDoc("Repository XQuery statement constructor not found: "
608                 + e.getMessage());
609             }
610         }
611     }
612 }
613
Popular Tags