1 22 23 package org.xquark.mapper.dbms; 24 25 26 import java.lang.reflect.Constructor ; 27 import java.lang.reflect.InvocationTargetException ; 28 import java.net.URL ; 29 import java.sql.SQLException ; 30 import java.util.*; 31 32 import org.xml.sax.InputSource ; 33 import org.xml.sax.SAXException ; 34 import org.xml.sax.XMLReader ; 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 50 public final class RepositoryConnectionImpl implements _RepositoryConnection 51 { 52 private static final String RCSRevision = "$Revision: 1.4 $"; 53 private static final String RCSName = "$Name: $"; 54 55 private static Constructor stmtConstructor = null; 57 58 private AbstractConnection connection; 59 private Repository rep; 60 61 private Object [] params = new Object [2]; 62 63 64 private DestructionToken destructor; 65 private ArrayList XMLCollections = new ArrayList(); private HashSet XMLStatements = new HashSet(); private InputSource source; 68 69 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 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 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 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 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 135 public RepositoryReader getMappingReader() throws XMLDBCException 136 { 137 return ((_RepositoryCollection)getMappingCollection()).getReader(); 138 } 139 140 public String getURL() 141 { 142 return RepositoryDriver.REPOSITORY_URL_PREFIX + rep.getURL(); 143 } 144 145 public String toString() 146 { 147 return rep.toString(); 148 } 149 150 public String 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 public Configurable createCollectionConfig() throws XMLDBCException, XMLDBCNotSupportedException 169 { 170 return new CollectionInfo(false); 171 } 172 173 public XMLCollection createCollection(String name, String 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 )config.getProperty(MAPPING_ID_PROPERTY)); 179 rep.createCollection(name, colInfo, mapFactory); 180 return getCollection(name); 181 } 182 183 public XMLCollection getCollection(String name) throws XMLDBCException, XMLDBCNotSupportedException 184 { 185 return getRepositoryCollection(name); 186 } 187 188 189 public void renameCollection(String oldname, String newname) throws XMLDBCException, XMLDBCNotSupportedException 190 { 191 protectReadOnlyMethod(); 192 rep.renameCollection(oldname, newname); 193 } 194 195 public void deleteCollection(String name) throws XMLDBCException, XMLDBCNotSupportedException 196 { 197 protectReadOnlyMethod(); 198 name = name.toUpperCase(); 199 200 Iterator it = ((List)XMLCollections.clone()).iterator(); RepositoryCollection collection; 203 while (it.hasNext()) 204 { 205 collection = (RepositoryCollection)it.next(); 206 if (collection.getName().equals(name)) 207 collection.close(); } 209 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 e) 261 { 262 } 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 ("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 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 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 query) throws XMLDBCException, XMLDBCNotSupportedException 309 { 310 throw new XMLDBCNotSupportedException("Not Supported yet"); 311 } 312 313 public void setBaseURI(String baseURI) { 314 } 316 317 326 public RepositoryCollection getRepositoryCollection(String name) throws XMLDBCException 327 { 328 if (name == null) 329 throw new RepositoryException(RepositoryException.PERMISSION_DENIED, "A collection name must be provided."); 330 331 _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); 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(); 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 mappingID) 407 throws XMLDBCException 408 { 409 return rep.getCollectionsUsingMapping(mappingID); 410 } 411 412 public List getCollectionsUsingNamespace(String namespace) 413 throws XMLDBCException 414 { 415 return rep.getCollectionsUsingNamespace(namespace); 416 } 417 418 public List getMappingsUsingNamespace(String namespace) 419 throws XMLDBCException 420 { 421 return Collections.EMPTY_LIST; } 423 424 428 public void clearSchemaLocations() 429 { 430 } 432 433 public Iterator getSchemaLocations(String namespace) 434 { 435 return null; 436 } 437 438 public void addSchemaLocation(String namespace, String location) 439 { 440 } 442 443 public XMLReader getSchemaReader() throws SAXException 444 { 445 try { 446 return new DisposableReaderFilter(((_RepositoryCollection)getSchemaCollection()).getReader()); 447 } 448 catch (XMLDBCException e) 449 { 450 throw new SAXException ("Could not catch reader for the schema system XML collection.", e); 451 } 452 } 453 454 public InputSource resolveLocation(String namespace, String location) 455 { 456 if (namespace == null) 457 namespace = RepositoryConstants.NO_NAMESPACE_SCHEMA_ID; 458 if (source == null) 459 source = new InputSource (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 resolveLocation(String namespace, URL location) 476 { 477 return resolveLocation(namespace, (String )null); 478 } 479 480 public String resolveInclude(String location) { 481 return location; 482 } 483 484 private class XMLCollectionDestructor implements DestructionToken 488 { 489 public void destruct(Object 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 o) 510 { 511 XMLStatements.remove(o); 512 } 513 } 514 515 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(); while(it.hasNext()) 568 ((_RepositoryCollection)it.next()).close(); 569 570 XMLCollections.clear(); } 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) { 589 Class stmtImpl = null; 590 try 591 { 592 stmtImpl = Class.forName("org.xquark.mapper.xquery.XStatementImpl"); 593 } 594 catch (ClassNotFoundException e) 595 { 596 throw new RuntimeException ("Repository XQuery module is missing in your CLASSPATH: " 597 + e.getMessage()); 598 } 599 Class [] paramTypes = new Class [] 600 {RepositoryConnection.class, DestructionToken.class}; 601 try 602 { 603 stmtConstructor = stmtImpl.getConstructor(paramTypes); 604 } 605 catch (NoSuchMethodException e) 606 { 607 throw new RuntimeException ("Repository XQuery statement constructor not found: " 608 + e.getMessage()); 609 } 610 } 611 } 612 } 613 | Popular Tags |