Skip to content
Browse files

import of core

  • Loading branch information...
1 parent a42fc37 commit c0b768c34c9ba778faa7e6b935a638f88b555762 @JohannesLichtenberger JohannesLichtenberger committed
Showing with 11,900 additions and 0 deletions.
  1. +5 −0 .gitignore
  2. +118 −0 bundles/sirix-core/pom.xml
  3. +118 −0 bundles/sirix-core/pom.xml~
  4. +61 −0 bundles/sirix-core/src/main/assembly/jarAssembly.xml
  5. +159 −0 bundles/sirix-core/src/main/java/org/treetank/access/AbsForwardingNodeReadTrx.java
  6. +147 −0 bundles/sirix-core/src/main/java/org/treetank/access/AbsForwardingNodeWriteTrx.java
  7. +41 −0 bundles/sirix-core/src/main/java/org/treetank/access/AbsKeyDatabase.java
  8. +101 −0 bundles/sirix-core/src/main/java/org/treetank/access/AbsVisitorSupport.java
  9. +372 −0 bundles/sirix-core/src/main/java/org/treetank/access/Database.java
  10. +361 −0 bundles/sirix-core/src/main/java/org/treetank/access/EInsertPos.java
  11. +157 −0 bundles/sirix-core/src/main/java/org/treetank/access/InsertSubtreeVisitor.java
  12. +283 −0 bundles/sirix-core/src/main/java/org/treetank/access/LockManager.java
  13. +465 −0 bundles/sirix-core/src/main/java/org/treetank/access/NodeReadTrx.java
  14. +1,974 −0 bundles/sirix-core/src/main/java/org/treetank/access/NodeWriteTrx.java
  15. +370 −0 bundles/sirix-core/src/main/java/org/treetank/access/PageReadTrx.java
  16. +506 −0 bundles/sirix-core/src/main/java/org/treetank/access/PageWriteTrx.java
  17. +424 −0 bundles/sirix-core/src/main/java/org/treetank/access/Session.java
  18. +134 −0 bundles/sirix-core/src/main/java/org/treetank/access/SynchWriteTransaction.java
  19. +193 −0 bundles/sirix-core/src/main/java/org/treetank/access/conf/DatabaseConfiguration.java
  20. +53 −0 bundles/sirix-core/src/main/java/org/treetank/access/conf/IConfigureSerializable.java
  21. +381 −0 bundles/sirix-core/src/main/java/org/treetank/access/conf/ResourceConfiguration.java
  22. +213 −0 bundles/sirix-core/src/main/java/org/treetank/access/conf/SessionConfiguration.java
  23. +52 −0 bundles/sirix-core/src/main/java/org/treetank/access/conf/package-info.java
  24. +98 −0 bundles/sirix-core/src/main/java/org/treetank/access/package-info.java
  25. +53 −0 bundles/sirix-core/src/main/java/org/treetank/api/IAxis.java
  26. +17 −0 bundles/sirix-core/src/main/java/org/treetank/api/IBuilder.java
  27. +122 −0 bundles/sirix-core/src/main/java/org/treetank/api/IDatabase.java
  28. +43 −0 bundles/sirix-core/src/main/java/org/treetank/api/IExpression.java
  29. +101 −0 bundles/sirix-core/src/main/java/org/treetank/api/IFilter.java
  30. +78 −0 bundles/sirix-core/src/main/java/org/treetank/api/IItemList.java
  31. +340 −0 bundles/sirix-core/src/main/java/org/treetank/api/INodeReadTrx.java
  32. +490 −0 bundles/sirix-core/src/main/java/org/treetank/api/INodeWriteTrx.java
  33. +79 −0 bundles/sirix-core/src/main/java/org/treetank/api/IPageReadTrx.java
  34. +105 −0 bundles/sirix-core/src/main/java/org/treetank/api/IPageWriteTrx.java
  35. +135 −0 bundles/sirix-core/src/main/java/org/treetank/api/ISession.java
  36. +62 −0 bundles/sirix-core/src/main/java/org/treetank/api/package-info.java
  37. +23 −0 bundles/sirix-core/src/main/java/org/treetank/api/visitor/EVisitResult.java
  38. +83 −0 bundles/sirix-core/src/main/java/org/treetank/api/visitor/IVisitor.java
  39. +33 −0 bundles/sirix-core/src/main/java/org/treetank/aspects/logging/LoggerAspect.java
  40. +5 −0 bundles/sirix-core/src/main/java/org/treetank/aspects/logging/Logging.java
  41. +216 −0 bundles/sirix-core/src/main/java/org/treetank/axis/AbsAxis.java
  42. +99 −0 bundles/sirix-core/src/main/java/org/treetank/axis/AncestorAxis.java
  43. +89 −0 bundles/sirix-core/src/main/java/org/treetank/axis/AttributeAxis.java
  44. +82 −0 bundles/sirix-core/src/main/java/org/treetank/axis/ChildAxis.java
  45. +147 −0 bundles/sirix-core/src/main/java/org/treetank/axis/DescendantAxis.java
  46. +36 −0 bundles/sirix-core/src/main/java/org/treetank/axis/EIncludeSelf.java
  47. +105 −0 bundles/sirix-core/src/main/java/org/treetank/axis/FilterAxis.java
  48. +179 −0 bundles/sirix-core/src/main/java/org/treetank/axis/FollowingAxis.java
  49. +93 −0 bundles/sirix-core/src/main/java/org/treetank/axis/FollowingSiblingAxis.java
  50. +122 −0 bundles/sirix-core/src/main/java/org/treetank/axis/ForAxis.java
  51. +176 −0 bundles/sirix-core/src/main/java/org/treetank/axis/LevelOrderAxis.java
  52. +120 −0 bundles/sirix-core/src/main/java/org/treetank/axis/NestedAxis.java
  53. +81 −0 bundles/sirix-core/src/main/java/org/treetank/axis/ParentAxis.java
  54. +109 −0 bundles/sirix-core/src/main/java/org/treetank/axis/PostOrderAxis.java
  55. +189 −0 bundles/sirix-core/src/main/java/org/treetank/axis/PrecedingAxis.java
  56. +112 −0 bundles/sirix-core/src/main/java/org/treetank/axis/PrecedingSiblingAxis.java
  57. +79 −0 bundles/sirix-core/src/main/java/org/treetank/axis/SelfAxis.java
  58. +250 −0 bundles/sirix-core/src/main/java/org/treetank/axis/VisitorDescendantAxis.java
  59. +71 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/AbsFilter.java
  60. +57 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/AttributeFilter.java
  61. +63 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/CommentFilter.java
  62. +57 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/DocumentRootNodeFilter.java
  63. +58 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/ElementFilter.java
  64. +58 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/ItemFilter.java
  65. +69 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/NameFilter.java
  66. +69 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/NestedFilter.java
  67. +58 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/NodeFilter.java
  68. +65 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/PIFilter.java
  69. +57 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/TextFilter.java
  70. +74 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/TypeFilter.java
  71. +101 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/ValueFilter.java
  72. +122 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/WildcardFilter.java
  73. +40 −0 bundles/sirix-core/src/main/java/org/treetank/axis/filter/package-info.java
  74. +42 −0 bundles/sirix-core/src/main/java/org/treetank/axis/package-info.java
Sorry, we could not display the entire diff because too many files (538) changed.
View
5 .gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+target
+.settings
+.project
+.classpath
View
118 bundles/sirix-core/pom.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (c) 2011, University of Konstanz, Distributed Systems Group
+ All rights reserved. Redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following conditions
+ are met: * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer. * Redistributions
+ in binary form must reproduce the above copyright notice, this list of conditions
+ and the following disclaimer in the documentation and/or other materials
+ provided with the distribution. * Neither the name of the University of Konstanz
+ nor the names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission. THIS
+ SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>sirix</groupId>
+ <artifactId>pom</artifactId>
+ <version>1.0.5-SNAPSHOT</version>
+ </parent>
+ <artifactId>core</artifactId>
+ <version>5.4.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>sirix-core</name>
+ <description>Sirix is a fully java-implemented native XML-Database.
+ It supports cursorlike access to all nodes stored in the tree plus
+ XPath 2.0 as query engine. Furthermore, Treetank is completely
+ versionable. That means that each update-operation results in a new
+ version.
+ These versions can be easily retrieved within the database itself.
+ </description>
+ <scm>
+ <connection>scm:svn:https://svn.uni-konstanz.de/disy/Treetank/trunk/treetank/bundles/treetank-core</connection>
+ <developerConnection>scm:svn:https://svn.uni-konstanz.de/disy/Treetank/trunk/treetank/bundles/treetank-core</developerConnection>
+ <url>scm:svn:https://svn.uni-konstanz.de/disy/Treetank/trunk/treetank/bundles/treetank-core</url>
+ </scm>
+ <repositories>
+ <repository>
+ <id>disyInternal</id>
+ <name>Internal Repository for the Distributed System Group</name>
+ <url>http://mavenrepo.disy.inf.uni-konstanz.de/repository/disyInternal/</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>disyInternalSnapshot</id>
+ <name>Internal Snapshot Repository for the Distributed System Group</name>
+ <url>http://mavenrepo.disy.inf.uni-konstanz.de/repository/disyInternalSnapshot/</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/jarAssembly.xml</descriptor>
+ </descriptors>
+ <archive>
+ <manifest>
+ <mainClass>org.treetank.utils.TreeTankCommandoLineExplorer</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>aspectj-maven-plugin</artifactId>
+ <version>1.3.1</version>
+ <configuration>
+ <complianceLevel>1.7</complianceLevel>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>treetank</groupId>
+ <artifactId>encryption</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>treetank</groupId>
+ <artifactId>encryption</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.xerial.snappy</groupId>
+ <artifactId>snappy-java</artifactId>
+ <version>1.0.4.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project>
View
118 bundles/sirix-core/pom.xml~
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (c) 2011, University of Konstanz, Distributed Systems Group
+ All rights reserved. Redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following conditions
+ are met: * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer. * Redistributions
+ in binary form must reproduce the above copyright notice, this list of conditions
+ and the following disclaimer in the documentation and/or other materials
+ provided with the distribution. * Neither the name of the University of Konstanz
+ nor the names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission. THIS
+ SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>treetank</groupId>
+ <artifactId>pom</artifactId>
+ <version>1.0.5-SNAPSHOT</version>
+ </parent>
+ <artifactId>core</artifactId>
+ <version>5.4.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>treetank-core</name>
+ <description>Treetank is a fully java-implemented native XML-Database.
+ It supports cursorlike access to all nodes stored in the tree plus
+ XPath 2.0 as query engine. Furthermore, Treetank is completely
+ versionable. That means that each update-operation results in a new
+ version.
+ These versions can be easily retrieved within the database itself.
+ </description>
+ <scm>
+ <connection>scm:svn:https://svn.uni-konstanz.de/disy/Treetank/trunk/treetank/bundles/treetank-core</connection>
+ <developerConnection>scm:svn:https://svn.uni-konstanz.de/disy/Treetank/trunk/treetank/bundles/treetank-core</developerConnection>
+ <url>scm:svn:https://svn.uni-konstanz.de/disy/Treetank/trunk/treetank/bundles/treetank-core</url>
+ </scm>
+ <repositories>
+ <repository>
+ <id>disyInternal</id>
+ <name>Internal Repository for the Distributed System Group</name>
+ <url>http://mavenrepo.disy.inf.uni-konstanz.de/repository/disyInternal/</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>disyInternalSnapshot</id>
+ <name>Internal Snapshot Repository for the Distributed System Group</name>
+ <url>http://mavenrepo.disy.inf.uni-konstanz.de/repository/disyInternalSnapshot/</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/jarAssembly.xml</descriptor>
+ </descriptors>
+ <archive>
+ <manifest>
+ <mainClass>org.treetank.utils.TreeTankCommandoLineExplorer</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>aspectj-maven-plugin</artifactId>
+ <version>1.3.1</version>
+ <configuration>
+ <complianceLevel>1.7</complianceLevel>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>treetank</groupId>
+ <artifactId>encryption</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>treetank</groupId>
+ <artifactId>encryption</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.xerial.snappy</groupId>
+ <artifactId>snappy-java</artifactId>
+ <version>1.0.4.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project>
View
61 bundles/sirix-core/src/main/assembly/jarAssembly.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2011, University of Konstanz, Distributed Systems Group
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the University of Konstanz nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-->
+
+<assembly xmlns:p="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/assembly-1.0.0.xsd ">
+ <!-- Name des jars...in dem Fall bla-jar-with-dependencies.jar -->
+ <id>jar-with-dependencies</id>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <!-- sollen drittjars mit reinfliessen? -->
+ <dependencySets>
+ <dependencySet>
+ <unpack>true</unpack>
+ <scope>runtime</scope>
+ </dependencySet>
+ </dependencySets>
+ <!-- das sind die Filterregeln..neben includes gibts auch noch excludes -->
+ <fileSets>
+ <fileSet>
+ <includes>
+ <include>changes*</include>
+ <include>conventions*</include>
+ <include>index*</include>
+ <include>license*</include>
+ <include>roadmap*</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>src/main/java</directory>
+ </fileSet>
+ </fileSets>
+</assembly>
View
159 bundles/sirix-core/src/main/java/org/treetank/access/AbsForwardingNodeReadTrx.java
@@ -0,0 +1,159 @@
+package org.treetank.access;
+
+import com.google.common.collect.ForwardingObject;
+
+import javax.xml.namespace.QName;
+
+import org.treetank.api.IItemList;
+import org.treetank.api.INodeReadTrx;
+import org.treetank.api.ISession;
+import org.treetank.exception.AbsTTException;
+import org.treetank.exception.TTIOException;
+import org.treetank.node.interfaces.INode;
+import org.treetank.node.interfaces.IStructNode;
+
+/**
+ * Forwards all methods to the delegate.
+ *
+ * @author Johannes Lichtenberger, University of Konstanz
+ *
+ */
+public abstract class AbsForwardingNodeReadTrx extends ForwardingObject implements INodeReadTrx {
+
+ /** Constructor for use by subclasses. */
+ protected AbsForwardingNodeReadTrx() {
+ }
+
+ @Override
+ protected abstract INodeReadTrx delegate();
+
+ @Override
+ public IItemList<INode> getItemList() {
+ return delegate().getItemList();
+ }
+
+ @Override
+ public long getMaxNodeKey() throws TTIOException {
+ return delegate().getMaxNodeKey();
+ }
+
+ @Override
+ public INode getNode() {
+ return delegate().getNode();
+ }
+
+ @Override
+ public void close() throws AbsTTException {
+ delegate().close();
+ }
+
+ @Override
+ public QName getQNameOfCurrentNode() {
+ return delegate().getQNameOfCurrentNode();
+ }
+
+ @Override
+ public long getRevisionNumber() throws TTIOException {
+ return delegate().getRevisionNumber();
+ }
+
+ @Override
+ public long getRevisionTimestamp() throws TTIOException {
+ return delegate().getRevisionTimestamp();
+ }
+
+ @Override
+ public ISession getSession() {
+ return delegate().getSession();
+ }
+
+ @Override
+ public IStructNode getStructuralNode() {
+ return delegate().getStructuralNode();
+ }
+
+ @Override
+ public long getTransactionID() {
+ return delegate().getTransactionID();
+ }
+
+ @Override
+ public String getTypeOfCurrentNode() {
+ return delegate().getTypeOfCurrentNode();
+ }
+
+ @Override
+ public String getValueOfCurrentNode() {
+ return delegate().getValueOfCurrentNode();
+ }
+
+ @Override
+ public boolean isClosed() {
+ return delegate().isClosed();
+ }
+
+ @Override
+ public int keyForName(String pName) {
+ return delegate().keyForName(pName);
+ }
+
+ @Override
+ public boolean moveTo(long pKey) {
+ return delegate().moveTo(pKey);
+ }
+
+ @Override
+ public boolean moveToAttribute(int pIndex) {
+ return delegate().moveToAttribute(pIndex);
+ }
+
+ @Override
+ public boolean moveToAttributeByNameKey(int pNameKey) {
+ return delegate().moveToAttributeByNameKey(pNameKey);
+ }
+
+ @Override
+ public boolean moveToDocumentRoot() {
+ return delegate().moveToDocumentRoot();
+ }
+
+ @Override
+ public boolean moveToFirstChild() {
+ return delegate().moveToFirstChild();
+ }
+
+ @Override
+ public boolean moveToLeftSibling() {
+ return delegate().moveToLeftSibling();
+ }
+
+ @Override
+ public boolean moveToNamespace(int pIndex) {
+ return delegate().moveToNamespace(pIndex);
+ }
+
+ @Override
+ public boolean moveToNextFollowing() {
+ return delegate().moveToNextFollowing();
+ }
+
+ @Override
+ public boolean moveToParent() {
+ return delegate().moveToParent();
+ }
+
+ @Override
+ public boolean moveToRightSibling() {
+ return delegate().moveToRightSibling();
+ }
+
+ @Override
+ public String nameForKey(int pKey) {
+ return delegate().nameForKey(pKey);
+ }
+
+ @Override
+ public byte[] rawNameForKey(int pKey) {
+ return delegate().rawNameForKey(pKey);
+ }
+}
View
147 bundles/sirix-core/src/main/java/org/treetank/access/AbsForwardingNodeWriteTrx.java
@@ -0,0 +1,147 @@
+package org.treetank.access;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+
+import org.treetank.access.NodeWriteTrx.EMove;
+import org.treetank.api.INodeReadTrx;
+import org.treetank.api.INodeWriteTrx;
+import org.treetank.exception.AbsTTException;
+import org.treetank.exception.TTIOException;
+import org.treetank.service.xml.shredder.EInsert;
+
+/**
+ * Forwards all methods to the delegate.
+ *
+ * @author Johannes Lichtenberger, University of Konstanz
+ *
+ */
+public abstract class AbsForwardingNodeWriteTrx extends AbsForwardingNodeReadTrx implements INodeWriteTrx {
+
+ /** Constructor for use by subclasses. */
+ protected AbsForwardingNodeWriteTrx() {
+ }
+
+ @Override
+ protected abstract INodeWriteTrx delegate();
+
+ @Override
+ public void abort() throws TTIOException {
+ delegate().abort();
+ }
+
+ @Override
+ public void close() throws AbsTTException {
+ delegate().close();
+ }
+
+ @Override
+ public void commit() throws AbsTTException {
+ delegate().commit();
+ }
+
+ @Override
+ public INodeWriteTrx moveSubtreeToLeftSibling(long pFromKey) throws AbsTTException {
+ return delegate().moveSubtreeToLeftSibling(pFromKey);
+ }
+
+ @Override
+ public INodeWriteTrx moveSubtreeToRightSibling(long pFromKey) throws AbsTTException {
+ return delegate().moveSubtreeToRightSibling(pFromKey);
+ }
+
+ @Override
+ public INodeWriteTrx moveSubtreeToFirstChild(long pFromKey) throws AbsTTException {
+ return delegate().moveSubtreeToFirstChild(pFromKey);
+ }
+
+ @Override
+ public INodeWriteTrx copySubtreeAsFirstChild(INodeReadTrx pRtx) throws AbsTTException {
+ return delegate().copySubtreeAsFirstChild(pRtx);
+ }
+
+ @Override
+ public INodeWriteTrx copySubtreeAsLeftSibling(INodeReadTrx pRtx) throws AbsTTException {
+ return delegate().copySubtreeAsLeftSibling(pRtx);
+ }
+
+ @Override
+ public INodeWriteTrx copySubtreeAsRightSibling(INodeReadTrx pRtx) throws AbsTTException {
+ return delegate().copySubtreeAsRightSibling(pRtx);
+ }
+
+ @Override
+ public INodeWriteTrx insertAttribute(QName pName, String pValue) throws AbsTTException {
+ return delegate().insertAttribute(pName, pValue);
+ }
+
+ @Override
+ public INodeWriteTrx insertAttribute(QName pName, String pValue, EMove pMove) throws AbsTTException {
+ return delegate().insertAttribute(pName, pValue, pMove);
+ }
+
+ @Override
+ public INodeWriteTrx insertElementAsFirstChild(QName pName) throws AbsTTException {
+ return delegate().insertElementAsFirstChild(pName);
+ }
+
+ @Override
+ public INodeWriteTrx insertElementAsLeftSibling(QName pQName) throws AbsTTException {
+ return delegate().insertElementAsLeftSibling(pQName);
+ }
+
+ @Override
+ public INodeWriteTrx insertElementAsRightSibling(QName pQName) throws AbsTTException {
+ return delegate().insertElementAsRightSibling(pQName);
+ }
+
+ @Override
+ public INodeWriteTrx insertNamespace(QName pName) throws AbsTTException {
+ return delegate().insertNamespace(pName);
+ }
+
+ @Override
+ public INodeWriteTrx insertNamespace(QName pQName, EMove pMove) throws AbsTTException {
+ return delegate().insertNamespace(pQName, pMove);
+ }
+
+ @Override
+ public INodeWriteTrx insertSubtree(XMLEventReader pReader, EInsert pInsert) throws AbsTTException {
+ return delegate().insertSubtree(pReader, pInsert);
+ }
+
+ @Override
+ public INodeWriteTrx insertTextAsFirstChild(String pValue) throws AbsTTException {
+ return delegate().insertTextAsFirstChild(pValue);
+ }
+
+ @Override
+ public INodeWriteTrx insertTextAsLeftSibling(String pValue) throws AbsTTException {
+ return delegate().insertTextAsLeftSibling(pValue);
+ }
+
+ @Override
+ public INodeWriteTrx insertTextAsRightSibling(String pValue) throws AbsTTException {
+ return delegate().insertTextAsRightSibling(pValue);
+ }
+
+ @Override
+ public void setQName(QName pName) throws AbsTTException {
+ delegate().setQName(pName);
+ }
+
+ @Override
+ public void setValue(String pValue) throws AbsTTException {
+ delegate().setValue(pValue);
+ }
+
+ @Override
+ public void setURI(String pUri) throws AbsTTException {
+ delegate().setURI(pUri);
+ }
+
+ @Override
+ public void remove() throws AbsTTException {
+ delegate().remove();
+ }
+}
View
41 bundles/sirix-core/src/main/java/org/treetank/access/AbsKeyDatabase.java
@@ -0,0 +1,41 @@
+package org.treetank.access;
+
+import java.io.File;
+
+import org.treetank.settings.EStoragePaths;
+
+/**
+ * Abstract class for holding common data for all key databases involved
+ * in encryption process. Each instance of this class stores the data in a
+ * place related to the {@link DatabaseConfiguration} at a different subfolder.
+ *
+ * @author Patrick Lang, University of Konstanz
+ */
+public abstract class AbsKeyDatabase {
+
+ /**
+ * Place to store the data.
+ */
+ protected final File place;
+
+ /**
+ * Counter to give every instance a different place.
+ */
+ private static int counter;
+
+ /**
+ * Constructor with the place to store the data.
+ *
+ * @param paramFile
+ * {@link File} which holds the place to store
+ * the data.
+ */
+ protected AbsKeyDatabase(final File paramFile) {
+ place =
+ new File(paramFile, new StringBuilder(EStoragePaths.KEYSELECTOR.getFile().getName()).append(
+ File.separator).append(counter).toString());
+ place.mkdirs();
+ counter++;
+ }
+
+}
View
101 bundles/sirix-core/src/main/java/org/treetank/access/AbsVisitorSupport.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2011, University of Konstanz, Distributed Systems Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the University of Konstanz nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.treetank.access;
+
+import org.treetank.api.visitor.EVisitResult;
+import org.treetank.api.visitor.IVisitor;
+import org.treetank.node.AttributeNode;
+import org.treetank.node.DocumentRootNode;
+import org.treetank.node.ElementNode;
+import org.treetank.node.NamespaceNode;
+import org.treetank.node.TextNode;
+
+/**
+ * <h1>AbsVisitorSupport</h1>
+ *
+ * <p>
+ * Inspired by the dom4j approach {@code VisitorSupport} is an abstract base class which is useful for
+ * implementation inheritence or when using anonymous inner classes to create simple {@link IVisitor}
+ * implementations.
+ * </p>
+ *
+ * <h2>Usage Examples:</h2>
+ *
+ * <code><pre>
+ * final IVisitor visitor = new NamespaceChangeVisitor(session);
+ * for (final IAxis axis = new DescendantAxis(rtx, EIncludeSelf.YES); axis.hasNext();) {
+ * axis.next();
+ * rtx.getItem().acceptVisitor(visitor);
+ * }
+ * </pre></code>
+ *
+ * <code><pre>
+ * final IVisitor visitor = new AbsVisitorSupport(rtx) {
+ * public void visit(final ElementNode pNode) {
+ * rtx.moveTo(pNode.getKey());
+ * System.out.println(
+ * "Element name: " + mRtx.getCurrentQName().getLocalName()
+ * );
+ * }
+ * };
+ *
+ * for (final AbsAxis axis = new DescendantAxis(rtx); axis.hasNext();) {
+ * axis.next();
+ * rtx.getItem().acceptVisitor(visitor);
+ * }
+ * </pre></code>
+ *
+ * @author Johannes Lichtenberger, University of Konstanz
+ *
+ */
+public abstract class AbsVisitorSupport implements IVisitor {
+ @Override
+ public EVisitResult visit(final ElementNode pNode) {
+ return EVisitResult.CONTINUE;
+ }
+
+ @Override
+ public EVisitResult visit(final TextNode pNode) {
+ return EVisitResult.CONTINUE;
+ }
+
+ @Override
+ public EVisitResult visit(final DocumentRootNode pNode) {
+ return EVisitResult.CONTINUE;
+ }
+
+ @Override
+ public EVisitResult visit(final AttributeNode pNode) {
+ return EVisitResult.CONTINUE;
+ }
+
+ @Override
+ public EVisitResult visit(final NamespaceNode pNode) {
+ return EVisitResult.CONTINUE;
+ }
+}
View
372 bundles/sirix-core/src/main/java/org/treetank/access/Database.java
@@ -0,0 +1,372 @@
+/**
+ * Copyright (c) 2011, University of Konstanz, Distributed Systems Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the University of Konstanz nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.treetank.access;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.annotation.Nonnull;
+
+import org.treetank.access.conf.DatabaseConfiguration;
+import org.treetank.access.conf.IConfigureSerializable;
+import org.treetank.access.conf.ResourceConfiguration;
+import org.treetank.access.conf.SessionConfiguration;
+import org.treetank.api.IDatabase;
+import org.treetank.api.ISession;
+import org.treetank.exception.AbsTTException;
+import org.treetank.exception.TTIOException;
+import org.treetank.exception.TTUsageException;
+import org.treetank.io.EStorage;
+
+/**
+ * This class represents one concrete database for enabling several {@link ISession} objects.
+ *
+ * @see IDatabase
+ * @author Sebastian Graf, University of Konstanz
+ */
+public final class Database implements IDatabase {
+
+ /** Central repository of all running databases. */
+ private static final ConcurrentMap<File, Database> DATABASEMAP = new ConcurrentHashMap<>();
+
+ /** Central repository of all running sessions. */
+ private final ConcurrentMap<File, Session> mSessions;
+
+ /** DatabaseConfiguration with fixed settings. */
+ private final DatabaseConfiguration mDBConfig;
+
+ /**
+ * Private constructor.
+ *
+ * @param pDBConf
+ * {@link ResourceConfiguration} reference to configure the {@link IDatabase}
+ * @throws AbsTTException
+ * if something weird happens
+ */
+ private Database(@Nonnull final DatabaseConfiguration pDBConf) throws AbsTTException {
+ mDBConfig = checkNotNull(pDBConf);
+ mSessions = new ConcurrentHashMap<>();
+ }
+
+ // //////////////////////////////////////////////////////////
+ // START Creation/Deletion of Databases /////////////////////
+ // //////////////////////////////////////////////////////////
+ /**
+ * Creating a database. This includes loading the database configuration,
+ * building up the structure and preparing everything for login.
+ *
+ * @param pDBConfig
+ * which are used for the database, including storage location
+ * @return true if creation is valid, false otherwise
+ * @throws TTIOException
+ * if something odd happens within the creation process.
+ */
+ public static synchronized boolean createDatabase(@Nonnull final DatabaseConfiguration pDBConfig)
+ throws TTIOException {
+ boolean returnVal = true;
+ // if file is existing, skipping
+ if (pDBConfig.getFile().exists()) {
+ return false;
+ } else {
+ returnVal = pDBConfig.getFile().mkdirs();
+ if (returnVal) {
+ // creation of folder structure
+ for (DatabaseConfiguration.Paths paths : DatabaseConfiguration.Paths.values()) {
+ final File toCreate = new File(pDBConfig.getFile().getAbsoluteFile(), paths.getFile().getName());
+ if (paths.isFolder()) {
+ returnVal = toCreate.mkdir();
+ } else {
+ try {
+ returnVal = toCreate.createNewFile();
+ } catch (final IOException exc) {
+ throw new TTIOException(exc);
+ }
+ }
+ if (!returnVal) {
+ break;
+ }
+ }
+ }
+ // serialization of the config
+ try {
+ serializeConfiguration(pDBConfig);
+ } catch (final IOException exc) {
+ throw new TTIOException(exc);
+ }
+ // if something was not correct, delete the partly created
+ // substructure
+ if (!returnVal) {
+ pDBConfig.getFile().delete();
+ }
+ return returnVal;
+ }
+ }
+
+ /**
+ * Truncate a database. This deletes all relevant data. All running sessions
+ * must be closed beforehand.
+ *
+ * @param pConf
+ * the database at this path should be deleted.
+ * @throws AbsTTException
+ * any kind of false Treetank behaviour
+ */
+ public static synchronized void truncateDatabase(@Nonnull final DatabaseConfiguration pConf)
+ throws AbsTTException {
+ // check that database must be closed beforehand
+ if (!DATABASEMAP.containsKey(pConf.getFile())) {
+ // if file is existing and folder is a tt-dataplace, delete it
+ if (pConf.getFile().exists() && DatabaseConfiguration.Paths.compareStructure(pConf.getFile()) == 0) {
+ // instantiate the database for deletion
+ EStorage.recursiveDelete(pConf.getFile());
+ }
+ }
+ }
+
+ // //////////////////////////////////////////////////////////
+ // END Creation/Deletion of Databases ///////////////////////
+ // //////////////////////////////////////////////////////////
+
+ // //////////////////////////////////////////////////////////
+ // START Creation/Deletion of Resources /////////////////////
+ // //////////////////////////////////////////////////////////
+
+ @Override
+ public synchronized boolean createResource(@Nonnull final ResourceConfiguration pResConf)
+ throws TTIOException {
+ boolean returnVal = true;
+ // Setting the missing parameters in the settings, this overrides already
+ // set data.
+ final File path =
+ new File(new File(mDBConfig.getFile().getAbsoluteFile(), DatabaseConfiguration.Paths.Data.getFile()
+ .getName()), pResConf.mPath.getName());
+ // if file is existing, skipping
+ if (path.exists()) {
+ return false;
+ } else {
+ returnVal = path.mkdir();
+ if (returnVal) {
+ // creation of the folder structure
+ for (ResourceConfiguration.Paths paths : ResourceConfiguration.Paths.values()) {
+ final File toCreate = new File(path, paths.getFile().getName());
+ if (paths.isFolder()) {
+ returnVal = toCreate.mkdir();
+ } else {
+ try {
+ returnVal = toCreate.createNewFile();
+ } catch (final IOException exc) {
+ throw new TTIOException(exc);
+ }
+ }
+ if (!returnVal) {
+ break;
+ }
+ }
+ }
+ // serialization of the config
+ try {
+ serializeConfiguration(pResConf);
+ } catch (final IOException exc) {
+ throw new TTIOException(exc);
+ }
+ // if something was not correct, delete the partly created
+ // substructure
+ if (!returnVal) {
+ pResConf.mPath.delete();
+ }
+ return returnVal;
+ }
+ }
+
+ @Override
+ public synchronized void truncateResource(final ResourceConfiguration pResConf) {
+ final File resourceFile =
+ new File(new File(mDBConfig.getFile(), DatabaseConfiguration.Paths.Data.getFile().getName()),
+ pResConf.mPath.getName());
+ // check that database must be closed beforehand
+ if (!mSessions.containsKey(resourceFile)) {
+ // if file is existing and folder is a tt-dataplace, delete it
+ if (resourceFile.exists() && ResourceConfiguration.Paths.compareStructure(resourceFile) == 0) {
+ // instantiate the database for deletion
+ EStorage.recursiveDelete(resourceFile);
+ }
+ }
+ }
+
+ // //////////////////////////////////////////////////////////
+ // END Creation/Deletion of Resources ///////////////////////
+ // //////////////////////////////////////////////////////////
+
+ // //////////////////////////////////////////////////////////
+ // START Opening of Databases ///////////////////////
+ // //////////////////////////////////////////////////////////
+ /**
+ * Open database. A database can be opened only once. Afterwards the
+ * singleton instance bound to the File is given back.
+ *
+ * @param pFile
+ * determines where the database is located sessionConf a {@link SessionConfiguration} object to
+ * set up the session
+ * @return {@link IDatabase} instance.
+ * @throws AbsTTException
+ * if something odd happens
+ */
+ public static synchronized IDatabase openDatabase(@Nonnull final File pFile) throws AbsTTException {
+ if (!pFile.exists()) {
+ throw new TTUsageException("DB could not be opened (since it was not created?) at location", pFile
+ .toString());
+ }
+ FileInputStream is = null;
+ DatabaseConfiguration config = null;
+ try {
+ is =
+ new FileInputStream(new File(pFile.getAbsoluteFile(), DatabaseConfiguration.Paths.ConfigBinary
+ .getFile().getName()));
+ final ObjectInputStream de = new ObjectInputStream(is);
+ config = (DatabaseConfiguration)de.readObject();
+ de.close();
+ is.close();
+ } catch (final IOException exc) {
+ throw new TTIOException(exc);
+ } catch (final ClassNotFoundException exc) {
+ throw new TTIOException(exc.toString());
+ }
+ final Database database = new Database(config);
+ final IDatabase returnVal = DATABASEMAP.putIfAbsent(pFile, database);
+ if (returnVal == null) {
+ return database;
+ } else {
+ return returnVal;
+ }
+ }
+
+ // //////////////////////////////////////////////////////////
+ // END Opening of Databases ///////////////////////
+ // //////////////////////////////////////////////////////////
+
+ // //////////////////////////////////////////////////////////
+ // START DB-Operations//////////////////////////////////
+ // /////////////////////////////////////////////////////////
+
+ @Override
+ public synchronized ISession getSession(final SessionConfiguration pSessionConf) throws AbsTTException {
+ final File resourceFile =
+ new File(new File(mDBConfig.getFile(), DatabaseConfiguration.Paths.Data.getFile().getName()),
+ pSessionConf.getResource());
+ Session returnVal = mSessions.get(resourceFile);
+ if (returnVal == null) {
+ if (!resourceFile.exists()) {
+ throw new TTUsageException("Resource could not be opened (since it was not created?) at location",
+ resourceFile.toString());
+ }
+ FileInputStream is = null;
+ ResourceConfiguration config = null;
+ try {
+ is =
+ new FileInputStream(new File(resourceFile, ResourceConfiguration.Paths.ConfigBinary.getFile()
+ .getName()));
+ final ObjectInputStream de = new ObjectInputStream(is);
+ config = (ResourceConfiguration)de.readObject();
+ de.close();
+ is.close();
+ } catch (final ClassNotFoundException exc) {
+ throw new TTIOException(exc.toString());
+ } catch (final IOException exc) {
+ throw new TTIOException(exc);
+ }
+
+ // Resource of session must be associated to this database
+ assert config.mPath.getParentFile().getParentFile().equals(mDBConfig.getFile());
+ returnVal = new Session(this, config, pSessionConf);
+ mSessions.put(resourceFile, returnVal);
+ }
+ return returnVal;
+ }
+
+ @Override
+ public synchronized void close() throws AbsTTException {
+ for (final ISession session : mSessions.values()) {
+ session.close();
+ }
+ DATABASEMAP.remove(mDBConfig.getFile());
+ }
+
+ // //////////////////////////////////////////////////////////
+ // End DB-Operations//////////////////////////////////
+ // /////////////////////////////////////////////////////////
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(mDBConfig);
+ return builder.toString();
+ }
+
+ /**
+ * Closing a resource. This callback is necessary due to centralized
+ * handling of all sessions within a database.
+ *
+ * @param pFile
+ * {@link File} to be closed
+ * @return {@code true} if close successful, {@code false} otherwise
+ */
+ protected boolean removeSession(@Nonnull final File pFile) {
+ return mSessions.remove(pFile) != null ? true : false;
+ }
+
+ /**
+ * Serializing any {@link IConfigureSerializable} instance to a denoted
+ * file.
+ *
+ * @param pConf
+ * to be serializied, containing the file
+ * @throws IOException
+ * if serialization fails
+ */
+ private static void serializeConfiguration(@Nonnull final IConfigureSerializable pConf) throws IOException {
+ FileOutputStream os = null;
+ os = new FileOutputStream(pConf.getConfigFile());
+ final ObjectOutputStream en = new ObjectOutputStream(os);
+ en.writeObject(pConf);
+ en.close();
+ os.close();
+ }
+
+ @Override
+ public DatabaseConfiguration getDatabaseConfig() {
+ return mDBConfig;
+ }
+}
View
361 bundles/sirix-core/src/main/java/org/treetank/access/EInsertPos.java
@@ -0,0 +1,361 @@
+/**
+ * Copyright (c) 2011, University of Konstanz, Distributed Systems Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the University of Konstanz nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.treetank.access;
+
+import javax.xml.namespace.QName;
+
+import org.treetank.api.INodeReadTrx;
+import org.treetank.api.INodeWriteTrx;
+import org.treetank.exception.AbsTTException;
+import org.treetank.node.ENode;
+import org.treetank.node.TextNode;
+import org.treetank.node.interfaces.IStructNode;
+import org.treetank.settings.EFixed;
+
+/**
+ * Determines the position of the insertion of nodes and appropriate methods for movement and the copy of
+ * whole subtrees.
+ *
+ * @author Johannes Lichtenberger, University of Konstanz
+ *
+ */
+enum EInsertPos {
+ /** Insert as first child. */
+ ASFIRSTCHILD {
+ @Override
+ void processMove(final IStructNode pFromNode, final IStructNode pToNode, final NodeWriteTrx pWtx)
+ throws AbsTTException {
+ assert pFromNode != null;
+ assert pToNode != null;
+ assert pWtx != null;
+
+ // Adapt childCount of parent where the subtree has to be inserted.
+ IStructNode newParent =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pToNode.getNodeKey());
+ if (pFromNode.getParentKey() != pToNode.getNodeKey()) {
+ newParent.incrementChildCount();
+ }
+ pWtx.getPageTransaction().finishNodeModification(newParent);
+
+ if (pToNode.hasFirstChild()) {
+ pWtx.moveTo(pToNode.getFirstChildKey());
+
+ if (pWtx.getNode().getKind() == ENode.TEXT_KIND && pFromNode.getKind() == ENode.TEXT_KIND) {
+ final StringBuilder builder = new StringBuilder(pWtx.getValueOfCurrentNode());
+
+ // Adapt right sibling key of moved node.
+ pWtx.moveTo(((TextNode)pWtx.getNode()).getRightSiblingKey());
+ final TextNode moved =
+ (TextNode)pWtx.getPageTransaction().prepareNodeForModification(pFromNode.getNodeKey());
+ moved.setRightSiblingKey(pWtx.getNode().getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(moved);
+
+ // Merge text nodes.
+ pWtx.moveTo(moved.getNodeKey());
+ builder.insert(0, pWtx.getValueOfCurrentNode() + " ");
+ pWtx.setValue(builder.toString());
+
+ // Remove first child.
+ pWtx.moveTo(pToNode.getFirstChildKey());
+ pWtx.remove();
+
+ // Adapt left sibling key of former right sibling of first child.
+ pWtx.moveTo(moved.getRightSiblingKey());
+ final IStructNode rightSibling =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pWtx.getNode().getNodeKey());
+ rightSibling.setLeftSiblingKey(pFromNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(rightSibling);
+ } else {
+ // Adapt left sibling key of former first child.
+ final IStructNode oldFirstChild =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pToNode.getFirstChildKey());
+ oldFirstChild.setLeftSiblingKey(pFromNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(oldFirstChild);
+
+ // Adapt right sibling key of moved node.
+ final IStructNode moved =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pFromNode.getNodeKey());
+ moved.setRightSiblingKey(oldFirstChild.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(moved);
+ }
+ } else {
+ // Adapt right sibling key of moved node.
+ final IStructNode moved =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pFromNode.getNodeKey());
+ moved.setRightSiblingKey(EFixed.NULL_NODE_KEY.getStandardProperty());
+ pWtx.getPageTransaction().finishNodeModification(moved);
+ }
+
+ // Adapt first child key of parent where the subtree has to be inserted.
+ newParent = (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pToNode.getNodeKey());
+ newParent.setFirstChildKey(pFromNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(newParent);
+
+ // Adapt left sibling key and parent key of moved node.
+ final IStructNode moved =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pFromNode.getNodeKey());
+ moved.setLeftSiblingKey(EFixed.NULL_NODE_KEY.getStandardProperty());
+ moved.setParentKey(pToNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(moved);
+ }
+
+ @Override
+ void insertNode(final INodeWriteTrx pWtx, final INodeReadTrx pRtx) throws AbsTTException {
+ assert pWtx != null;
+ assert pRtx != null;
+ assert pWtx.getNode().getKind() == ENode.ELEMENT_KIND || pWtx.getNode().getKind() == ENode.ROOT_KIND;
+ switch (pRtx.getNode().getKind()) {
+ case ELEMENT_KIND:
+ pWtx.insertElementAsFirstChild(pRtx.getQNameOfCurrentNode());
+ break;
+ case TEXT_KIND:
+ assert pWtx.getStructuralNode().getKind() == ENode.ELEMENT_KIND;
+ pWtx.insertTextAsFirstChild(pRtx.getValueOfCurrentNode());
+ break;
+ default:
+ throw new IllegalStateException("Node type not known!");
+ }
+
+ }
+ },
+ /** Insert as right sibling. */
+ ASRIGHTSIBLING {
+ @Override
+ void processMove(final IStructNode pFromNode, final IStructNode pToNode, final NodeWriteTrx pWtx)
+ throws AbsTTException {
+ assert pFromNode != null;
+ assert pToNode != null;
+ assert pWtx != null;
+
+ // Increment child count of parent node if moved node was not a child before.
+ if (pFromNode.getParentKey() != pToNode.getParentKey()) {
+ final IStructNode parentNode =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pToNode.getParentKey());
+ parentNode.incrementChildCount();
+ pWtx.getPageTransaction().finishNodeModification(parentNode);
+ }
+
+ final boolean hasMoved = pWtx.moveTo(pToNode.getRightSiblingKey());
+
+ if (pFromNode.getKind() == ENode.TEXT_KIND && pToNode.getKind() == ENode.TEXT_KIND) {
+ // Merge text: FROM and TO are of TEXT_KIND.
+ pWtx.moveTo(pToNode.getNodeKey());
+ final StringBuilder builder = new StringBuilder(pWtx.getValueOfCurrentNode()).append(" ");
+
+ // Adapt left sibling key of former right sibling of first child.
+ if (pToNode.hasRightSibling()) {
+ final IStructNode rightSibling =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(
+ ((TextNode)pWtx.getNode()).getRightSiblingKey());
+ rightSibling.setLeftSiblingKey(pFromNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(rightSibling);
+ }
+
+ // Adapt sibling keys of moved node.
+ final TextNode movedNode =
+ (TextNode)pWtx.getPageTransaction().prepareNodeForModification(pFromNode.getNodeKey());
+ movedNode.setRightSiblingKey(pToNode.getRightSiblingKey());
+ // Adapt left sibling key of moved node.
+ movedNode.setLeftSiblingKey(((TextNode)pWtx.getNode()).getLeftSiblingKey());
+ pWtx.getPageTransaction().finishNodeModification(movedNode);
+
+ // Merge text nodes.
+ pWtx.moveTo(movedNode.getNodeKey());
+ builder.append(pWtx.getValueOfCurrentNode());
+ pWtx.setValue(builder.toString());
+
+ final IStructNode insertAnchor =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pToNode.getNodeKey());
+ // Adapt right sibling key of node where the subtree has to be inserted.
+ insertAnchor.setRightSiblingKey(pFromNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(insertAnchor);
+
+ // Remove first child.
+ pWtx.moveTo(pToNode.getNodeKey());
+ pWtx.remove();
+ } else if (hasMoved && pFromNode.getKind() == ENode.TEXT_KIND
+ && pWtx.getNode().getKind() == ENode.TEXT_KIND) {
+ // Merge text: RIGHT and FROM are of TEXT_KIND.
+ final StringBuilder builder = new StringBuilder(pWtx.getValueOfCurrentNode());
+
+ // Adapt left sibling key of former right sibling of first child.
+ final IStructNode rightSibling =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pWtx.getNode().getNodeKey());
+ rightSibling.setLeftSiblingKey(pFromNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(rightSibling);
+
+ // Adapt sibling keys of moved node.
+ final TextNode movedNode =
+ (TextNode)pWtx.getPageTransaction().prepareNodeForModification(pFromNode.getNodeKey());
+ movedNode.setRightSiblingKey(rightSibling.getNodeKey());
+ movedNode.setLeftSiblingKey(pToNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(movedNode);
+
+ // Merge text nodes.
+ pWtx.moveTo(movedNode.getNodeKey());
+ builder.insert(0, pWtx.getValueOfCurrentNode() + " ");
+ pWtx.setValue(builder.toString());
+
+ // Remove right sibling.
+ pWtx.moveTo(pToNode.getRightSiblingKey());
+ pWtx.remove();
+
+ final IStructNode insertAnchor =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pToNode.getNodeKey());
+ // Adapt right sibling key of node where the subtree has to be inserted.
+ insertAnchor.setRightSiblingKey(pFromNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(insertAnchor);
+ } else {
+ // No text merging involved.
+ final IStructNode insertAnchor =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pToNode.getNodeKey());
+ final long rightSiblKey = insertAnchor.getRightSiblingKey();
+ // Adapt right sibling key of node where the subtree has to be inserted.
+ insertAnchor.setRightSiblingKey(pFromNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(insertAnchor);
+
+ if (rightSiblKey > -1) {
+ // Adapt left sibling key of former right sibling.
+ final IStructNode oldRightSibling =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(rightSiblKey);
+ oldRightSibling.setLeftSiblingKey(pFromNode.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(oldRightSibling);
+ }
+ // Adapt right- and left-sibling key of moved node.
+ final IStructNode movedNode =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pFromNode.getNodeKey());
+ movedNode.setRightSiblingKey(rightSiblKey);
+ movedNode.setLeftSiblingKey(insertAnchor.getNodeKey());
+ pWtx.getPageTransaction().finishNodeModification(movedNode);
+ }
+
+ // Adapt parent key of moved node.
+ final IStructNode movedNode =
+ (IStructNode)pWtx.getPageTransaction().prepareNodeForModification(pFromNode.getNodeKey());
+ movedNode.setParentKey(pToNode.getParentKey());
+ pWtx.getPageTransaction().finishNodeModification(movedNode);
+ }
+
+ @Override
+ void insertNode(final INodeWriteTrx pWtx, final INodeReadTrx pRtx) throws AbsTTException {
+ assert pWtx != null;
+ assert pRtx != null;
+ assert pWtx.getNode().getKind() == ENode.ELEMENT_KIND || pWtx.getNode().getKind() == ENode.TEXT_KIND;
+ switch (pRtx.getNode().getKind()) {
+ case ELEMENT_KIND:
+ pWtx.insertElementAsRightSibling(pRtx.getQNameOfCurrentNode());
+ break;
+ case TEXT_KIND:
+ pWtx.insertTextAsRightSibling(pRtx.getValueOfCurrentNode());
+ break;
+ default:
+ throw new IllegalStateException("Node type not known!");
+ }
+ }
+ },
+ /** Insert as a non structural node. */
+ ASNONSTRUCTURAL {
+ @Override
+ void processMove(final IStructNode pFromNode, final IStructNode pToNode, final NodeWriteTrx pWtx)
+ throws AbsTTException {
+ // Not allowed.
+ throw new AssertionError("May never be invoked!");
+ }
+
+ @Override
+ void insertNode(final INodeWriteTrx pWtx, final INodeReadTrx pRtx) throws AbsTTException {
+ assert pWtx != null;
+ assert pRtx != null;
+ assert pWtx.getNode().getKind() == ENode.ELEMENT_KIND;
+ switch (pRtx.getNode().getKind()) {
+ case NAMESPACE_KIND:
+ final QName name = pRtx.getQNameOfCurrentNode();
+ pWtx.insertNamespace(new QName(name.getNamespaceURI(), "", name.getLocalPart()));
+ pWtx.moveToParent();
+ break;
+ case ATTRIBUTE_KIND:
+ pWtx.insertAttribute(pRtx.getQNameOfCurrentNode(), pRtx.getValueOfCurrentNode());
+ pWtx.moveToParent();
+ break;
+ default:
+ throw new IllegalStateException("Only namespace- and attribute-nodes are permitted!");
+ }
+ }
+ },
+
+ ASLEFTSIBLING {
+ @Override
+ void processMove(final IStructNode pFromNode, final IStructNode pToNode, final NodeWriteTrx pWtx)
+ throws AbsTTException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ void insertNode(final INodeWriteTrx pWtx, final INodeReadTrx pRtx) throws AbsTTException {
+ assert pWtx != null;
+ assert pRtx != null;
+ assert pWtx.getNode().getKind() == ENode.ELEMENT_KIND || pWtx.getNode().getKind() == ENode.TEXT_KIND;
+ switch (pRtx.getNode().getKind()) {
+ case ELEMENT_KIND:
+ pWtx.insertElementAsLeftSibling(pRtx.getQNameOfCurrentNode());
+ break;
+ case TEXT_KIND:
+ pWtx.insertTextAsLeftSibling(pRtx.getValueOfCurrentNode());
+ break;
+ default:
+ throw new IllegalStateException("Node type not known!");
+ }
+ }
+ };
+
+ /**
+ * Process movement of a subtree.
+ *
+ * @param pFromNode
+ * root of subtree to move
+ * @param pToNode
+ * determines where the subtree has to be inserted
+ * @param pWtx
+ * write-transaction which implements the {@link INodeWriteTrx} interface
+ * @throws AbsTTException
+ * if an I/O error occurs
+ */
+ abstract void processMove(final IStructNode pFromNode, final IStructNode pToNode, final NodeWriteTrx pWtx)
+ throws AbsTTException;
+
+ /**
+ * Insert a node (copy operation).
+ *
+ * @param pRtx
+ * read-transaction which implements the {@link INodeReadTrx} interface
+ * @param pWtx
+ * write-transaction which implements the {@link INodeWriteTrx} interface
+ * @throws AbsTTException
+ * if insertion of node fails
+ */
+ abstract void insertNode(final INodeWriteTrx pWtx, final INodeReadTrx pRtx) throws AbsTTException;
+}
View
157 bundles/sirix-core/src/main/java/org/treetank/access/InsertSubtreeVisitor.java
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2011, University of Konstanz, Distributed Systems Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the University of Konstanz nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.treetank.access;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Nonnull;
+
+import org.treetank.api.INodeReadTrx;
+import org.treetank.api.INodeWriteTrx;
+import org.treetank.api.visitor.EVisitResult;
+import org.treetank.exception.AbsTTException;
+import org.treetank.node.ElementNode;
+import org.treetank.node.TextNode;
+
+/**
+ * Allows insertion of subtrees.
+ *
+ * @author Johannes Lichtenberger, University of Konstanz
+ *
+ */
+class InsertSubtreeVisitor extends AbsVisitorSupport {
+ /**
+ * Read-transaction which implements the {@link INodeReadTrx} interface.
+ */
+ private final INodeReadTrx mRtx;
+
+ /**
+ * Write-transaction which implements the {@link INodeWriteTrx} interface.
+ */
+ private final INodeWriteTrx mWtx;
+
+ /** Determines how to insert a node. */
+ private EInsertPos mInsert;
+
+ /** First visitor step. */
+ private boolean mFirst;
+
+ /** Depth starting at 0. */
+ private int mDepth;
+
+ /**
+ * Constructor.
+ *
+ * @param pRtx
+ * read-transaction which implements the {@link INodeReadTrx} interface
+ * @param pWtx
+ * write-transaction which implements the {@link INodeWriteTrx} interface
+ * @param pInsert
+ * determines how to insert a node
+ */
+ @Nonnull
+ InsertSubtreeVisitor(final INodeReadTrx pRtx, final INodeWriteTrx pWtx, final EInsertPos pInsert) {
+ mRtx = checkNotNull(pRtx);
+ mWtx = checkNotNull(pWtx);
+ mInsert = checkNotNull(pInsert);
+ mFirst = true;
+ }
+
+ @Override
+ public EVisitResult visit(final ElementNode pNode) {
+ mRtx.moveTo(pNode.getNodeKey());
+ try {
+ mInsert.insertNode(mWtx, mRtx);
+ mInsert = EInsertPos.ASNONSTRUCTURAL;
+
+ for (int i = 0, nspCount = pNode.getNamespaceCount(); i < nspCount; i++) {
+ mRtx.moveToNamespace(i);
+ mInsert.insertNode(mWtx, mRtx);
+ mRtx.moveToParent();
+ }
+
+ for (int i = 0, attrCount = pNode.getAttributeCount(); i < attrCount; i++) {
+ mRtx.moveToAttribute(i);
+ mInsert.insertNode(mWtx, mRtx);
+ mRtx.moveToParent();
+ }
+
+ if (pNode.hasFirstChild()) {
+ mFirst = false;
+ mInsert = EInsertPos.ASFIRSTCHILD;
+ mRtx.moveToFirstChild();
+ mDepth++;
+ mRtx.getNode().acceptVisitor(this);
+ } else if (!mFirst && pNode.hasRightSibling()) {
+ mInsert = EInsertPos.ASRIGHTSIBLING;
+ mRtx.moveToRightSibling();
+ mRtx.getNode().acceptVisitor(this);
+ } else if (!mFirst) {
+ insertNextNode();
+ }
+ } catch (final AbsTTException e) {
+ throw new IllegalStateException(e);
+ }
+ return EVisitResult.CONTINUE;
+ }
+
+ @Override
+ public EVisitResult visit(final TextNode pNode) {
+ mRtx.moveTo(pNode.getNodeKey());
+ try {
+ mInsert.insertNode(mWtx, mRtx);
+
+ if (!mFirst && mRtx.getStructuralNode().hasRightSibling()) {
+ mRtx.moveToRightSibling();
+ mInsert = EInsertPos.ASRIGHTSIBLING;
+ mRtx.getNode().acceptVisitor(this);
+ } else if (!mFirst) {
+ insertNextNode();
+ }
+ } catch (final AbsTTException e) {
+ throw new IllegalStateException(e);
+ }
+ return EVisitResult.CONTINUE;
+ }
+
+ /** Insert next node in document order/preorder. */
+ private void insertNextNode() {
+ while (!mRtx.getStructuralNode().hasRightSibling() && mDepth > 0) {
+ mRtx.moveToParent();
+ mWtx.moveToParent();
+ mDepth--;
+ }
+
+ if (mDepth > 0) {
+ mInsert = EInsertPos.ASRIGHTSIBLING;
+ if (mRtx.getStructuralNode().hasRightSibling()) {
+ mRtx.moveToRightSibling();
+ mRtx.getNode().acceptVisitor(this);
+ }
+ }
+ }
+}
View
283 bundles/sirix-core/src/main/java/org/treetank/access/LockManager.java
@@ -0,0 +1,283 @@
+/**
+ * Copyright (c) 2011, University of Konstanz, Distributed Systems Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the University of Konstanz nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.treetank.access;
+
+/**
+ * <h1>LockManager</h1>
+ *
+ * <h2>Description</h2>
+ *
+ * <p>
+ * Each <code>Session</code> owns a <code>LockManager</code> which keeps track of all
+ * <code>WriteTransaction</code> and their respective transaction root nodes. The <code>LockManager</code>
+ * checks for a new <code>WriteTransaction</code> if the requested subtree is currently free for use.
+ *
+ */
+
+public class LockManager {
+
+ // // Locked nodes and transactionRootNodes of a LockManager
+ // private final HashMap<Long, Integer> lockedNodes;
+ // private final HashMap<SynchWriteTransaction, Set<Long>> transactionRootNodes;
+ // private static LockManager lock;
+ //
+ // /**
+ // * The LockManager with HashMaps of locked nodes and used transaction root
+ // * nodes
+ // */
+ // private LockManager() {
+ // this.lockedNodes = new HashMap<Long, Integer>(128);
+ // this.transactionRootNodes = new HashMap<SynchWriteTransaction, Set<Long>>(128);
+ // }
+ //
+ // public static LockManager getLockManager() {
+ // if (lock == null) {
+ // lock = new LockManager();
+ // }
+ //
+ // return lock;
+ // }
+ //
+ // /**
+ // *
+ // * @param nodekey
+ // * ID of nodekey that is to be locked
+ // * @param swtx
+ // * The corresponing SynchWriteTransaction
+ // */
+ // public synchronized void getWritePermission(long nodekey, SynchWriteTransaction swtx) {
+ // // lock parent node
+ // if (swtx.moveToParent()) {
+ // long current = nodekey;
+ // nodekey = swtx.getCurrentNode().getKey();
+ // swtx.moveTo(current);
+ // }
+ //
+ // // first write operation or after intermediate commit, there may be no
+ // // registered trn
+ // if (!this.transactionRootNodes.containsKey(swtx)) {
+ // // try to conquer the node - will throw exception if unsuccessfull
+ // conquer(swtx, nodekey);
+ // } else { // there is a registered trn for this session,
+ // // but are we within our conquered part of the tree?
+ // if (isInTransactionSubtree(swtx, nodekey)) {
+ // return;
+ // } else { // obviously we are not in the subtree
+ // conquer(swtx, nodekey);
+ // }
+ // }
+ // }
+ //
+ // /**
+ // *
+ // * @param swtx
+ // * The locks of the Trn(s) of this SynchWriteTransaction will be
+ // * released
+ // */
+ // public synchronized void releaseWritePermission(SynchWriteTransaction swtx) {
+ // Set<Long> hset = transactionRootNodes.get(swtx);
+ // if (hset == null || hset.isEmpty()) {
+ // return;
+ // }
+ // Long[] trns = null;
+ // trns = hset.toArray(new Long[0]);
+ // for (Long trn : trns) {
+ // unlockAncestors(swtx, trn);
+ // }
+ // transactionRootNodes.remove(swtx);
+ // }
+ //
+ // private void conquer(SynchWriteTransaction swtx, long nodeToConquer) {
+ //
+ // if (!isConquerable(swtx, nodeToConquer)) {
+ // throw new IllegalStateException();
+ // }
+ //
+ // lockAncestors(swtx, nodeToConquer);
+ // registerTransactionRootNodeKey(swtx, nodeToConquer);
+ //
+ // }
+ //
+ // /**
+ // * isConquerable determines whether a node can be captured
+ // *
+ // * @param NodeToConquer
+ // * @return common ancestor nodekey if available, throws exception if not
+ // */
+ // private boolean isConquerable(SynchWriteTransaction swtx, long NodeToConquer) {
+ // /*
+ // * (1)Node locked? (2) Yes:Do locks originate only from own swtx? (3)
+ // * Yes:Unlock corresponding trns and lock nodeToConquer -> TRUE (4) No:
+ // * Locking not possible: FALSE (5) No: Is there an ancestor of trn
+ // * registered as trn? (6) Yes: Locking not possible: FALSE (7) No: Lock
+ // * nodeToConquer TRUE
+ // */
+ //
+ // if (lockedNodes.containsKey(NodeToConquer)) { // (1)
+ // Set<Long> hset = transactionRootNodes.get(swtx); // own trns
+ //
+ // if (hset == null || hset.isEmpty()) {
+ // return false;
+ // }
+ //
+ // // Check if locks originate from own swtx (2)
+ // int ownLockCount = 0;
+ //
+ // Long[] trns = null;
+ // trns = hset.toArray(new Long[1]);
+ //
+ // for (Long trn : trns) {
+ // swtx.moveTo(trn);
+ // if (swtx.getCurrentNode().getKey() == NodeToConquer) {
+ // ownLockCount++;
+ // }
+ // while (swtx.moveTo(swtx.getCurrentNode().getParentKey())) {
+ // if (swtx.getCurrentNode().getKey() == NodeToConquer) {
+ // ownLockCount++;
+ // }
+ // }
+ // }
+ // if (ownLockCount == lockedNodes.get(NodeToConquer)) { // (3)
+ // return true;
+ // } else { // (4)
+ // return false;
+ // }
+ // }
+ //
+ // // (5)
+ // swtx.moveTo(NodeToConquer);
+ // Set<SynchWriteTransaction> keyset = transactionRootNodes.keySet(); // get
+ // // all
+ // // swtx
+ // while (swtx.moveToParent()) {
+ // Iterator iterate = keyset.iterator();
+ // long currentNodekey = swtx.getCurrentNode().getKey();
+ // while (iterate.hasNext()) {
+ // Set valueset = transactionRootNodes.get(iterate.next());
+ // if (valueset.contains(currentNodekey)) {
+ // return false; // (6)
+ // }
+ // }
+ // }
+ //
+ // return true; // (7)
+ // }
+ //
+ // /*
+ // * Increments the lock count of the nodekey <code>key</code> by 1. Creates
+ // * new entry in HashMap if the key is not present yet.
+ // *
+ // * @param key The key of the node to lock
+ // *
+ // * @return
+ // */
+ // private void lockKey(long key) {
+ // if (lockedNodes.containsKey(key)) {
+ // lockedNodes.put(key, lockedNodes.get(key) + 1);
+ // } else {
+ // lockedNodes.put(key, 1);
+ // }
+ // }
+ //
+ // /*
+ // * Decrements the lock count of the nodekey <code>key</code> by 1. Removes
+ // * the entry in HashMap if the lock count would become 0.
+ // *
+ // * @param key The key of the node to unlock
+ // */
+ // private void unlockKey(long key) {
+ // if (lockedNodes.containsKey(key)) {
+ // if (lockedNodes.get(key) > 1) {
+ // lockedNodes.put(key, lockedNodes.get(key) - 1);
+ // return;
+ // } else if (lockedNodes.get(key) == 1) {
+ // lockedNodes.remove(key);
+ // return;
+ // }
+ // }
+ // throw new IllegalStateException("Key not in hashmap: " + key);
+ // }
+ //
+ // /*
+ // * Adds a nodekey to the list of transation root nodes
+ // *
+ // * @param key Nodekey to add to the list
+ // */
+ // private void registerTransactionRootNodeKey(SynchWriteTransaction swtx, long key) {
+ // if (!this.transactionRootNodes.containsKey(swtx)) {
+ // this.transactionRootNodes.put(swtx, new HashSet<Long>());
+ // }
+ // this.transactionRootNodes.get(swtx).add(key);
+ // }
+ //
+ // /*
+ // * checks if a node is within a subtree of the same wtx
+ // */
+ // private boolean isInTransactionSubtree(SynchWriteTransaction swtx, long nodeKey) {
+ // long current = swtx.getCurrentNode().getKey();
+ // if (transactionRootNodes.get(swtx).contains(nodeKey)) { // node is a trn
+ // return true;
+ // }
+ // while (swtx.moveTo(swtx.getCurrentNode().getParentKey())) { // check
+ // // ancestors
+ // if (transactionRootNodes.get(swtx).contains(swtx.getCurrentNode().getKey())) {
+ // swtx.moveTo(current);
+ // return true;
+ // }
+ // }
+ // swtx.moveTo(current); // not in subtree
+ // return false;
+ // }
+ //
+ // /*
+ // * Locks nodeToLock and all its ancestors for the given session
+ // */
+ // private void lockAncestors(SynchWriteTransaction swtx, long nodeToLock) {
+ // long current = swtx.getCurrentNode().getKey();
+ // swtx.moveTo(nodeToLock);
+ // // lock trk and all its parents
+ // lockKey(nodeToLock);
+ // if (swtx.moveTo(swtx.getCurrentNode().getParentKey())) {
+ // lockKey(swtx.getCurrentNode().getKey());
+ // }
+ // swtx.moveTo(current);
+ // }
+ //
+ // /*
+ // * Unlocks nodeToUnlock and all its ancestors
+ // */
+ // private void unlockAncestors(SynchWriteTransaction swtx, long nodeToUnlock) {
+ // long current = swtx.getCurrentNode().getKey();
+ // swtx.moveTo(nodeToUnlock);
+ // unlockKey(swtx.getCurrentNode().getKey());
+ // while (swtx.moveTo(swtx.getCurrentNode().getParentKey())) {
+ // unlockKey(swtx.getCurrentNode().getKey());
+ // }
+ // swtx.moveTo(current);
+ // }
+}
View
465 bundles/sirix-core/src/main/java/org/treetank/access/NodeReadTrx.java
@@ -0,0 +1,465 @@
+/**
+ * Copyright (c) 2011, University of Konstanz, Distributed Systems Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the University of Konstanz nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.treetank.access;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Optional;
+
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.xml.namespace.QName;
+
+import org.treetank.api.IItemList;
+import org.treetank.api.INodeReadTrx;
+import org.treetank.api.IPageReadTrx;
+import org.treetank.api.ISession;
+import org.treetank.exception.AbsTTException;
+import org.treetank.exception.TTIOException;
+import org.treetank.node.ENode;
+import org.treetank.node.ElementNode;
+import org.treetank.node.NamespaceNode;
+import org.treetank.node.NullNode;
+import org.treetank.node.interfaces.INameNode;
+import org.treetank.node.interfaces.INode;
+import org.treetank.node.interfaces.IStructNode;
+import org.treetank.node.interfaces.IValNode;
+import org.treetank.service.xml.xpath.ItemList;
+import org.treetank.settings.EFixed;
+import org.treetank.utils.NamePageHash;
+
+/**
+ * <h1>ReadTransaction</h1>
+ *
+ * <p>
+ * Read-only transaction with single-threaded cursor semantics. Each read-only transaction works on a given
+ * revision key.
+ * </p>
+ */
+public final class NodeReadTrx implements INodeReadTrx {
+
+ /** ID of transaction. */
+ private final long mId;
+
+ /** Session state this write transaction is bound to. */
+ protected final Session mSession;
+
+ /** State of transaction including all cached stuff. */
+ private IPageReadTrx mPageReadTransaction;
+
+ /** Strong reference to currently selected node. */
+ private INode mCurrentNode;
+
+ /** Tracks whether the transaction is closed. */
+ private boolean mClosed;
+
+ /** Read-transaction-exclusive item list. */
+ private final ItemList<INode> mItemList;
+
+ /**
+ * Constructor.
+ *
+ * @param pSession
+ * the current {@link ISession} the transaction is bound to
+ * @param pTransactionID
+ * ID of transaction
+ * @param pPageReadTransaction
+ * {@link IPageReadTrx} to interact with the page layer
+ * @throws TTIOException
+ * if an I/O error occurs
+ */
+ NodeReadTrx(@Nonnull final Session pSession, @Nonnegative final long pTransactionID,
+ @Nonnull final IPageReadTrx pPageReadTransaction) throws TTIOException {
+ mSession = checkNotNull(pSession);
+ checkArgument(pTransactionID >= 0);
+ mId = pTransactionID;
+ mPageReadTransaction = checkNotNull(pPageReadTransaction);
+ final Optional<INode> node = getPageTransaction().getNode(EFixed.ROOT_NODE_KEY.getStandardProperty());
+ if (node.isPresent()) {
+ mCurrentNode = node.get();
+ } else {
+ throw new IllegalStateException("Node couldn't be fetched from persistent storage!");
+ }
+ mClosed = false;
+ mItemList = new ItemList<>();
+ }
+
+ @Override
+ public final long getTransactionID() {
+ assertNotClosed();
+ return mId;
+ }
+
+ @Override
+ public final long getRevisionNumber() throws TTIOException {
+ assertNotClosed();
+ return mPageReadTransaction.getActualRevisionRootPage().getRevision();
+ }
+
+ @Override
+ public final long getRevisionTimestamp() throws TTIOException {
+ assertNotClosed();
+ return mPageReadTransaction.getActualRevisionRootPage().getRevisionTimestamp();
+ }
+
+ @Override
+ public final boolean moveTo(final long pNodeKey) {
+ assertNotClosed();
+ if (pNodeKey == EFixed.NULL_NODE_KEY.getStandardProperty()) {
+ return false;
+ } else {
+ // Remember old node and fetch new one.
+ final INode oldNode = mCurrentNode;
+ Optional<? extends INode> newNode;
+ try {
+ // Immediately return node from item list if node key negative.
+ if (pNodeKey < 0) {
+ if (mItemList.size() > 0) {
+ newNode = mItemList.getItem(pNodeKey);
+ } else {
+ newNode = Optional.absent();
+ }
+ } else {
+ newNode = mPageReadTransaction.getNode(pNodeKey);
+ }
+ } catch (final TTIOException e) {
+ newNode = Optional.absent();
+ }
+
+ if (newNode.isPresent()) {
+ mCurrentNode = newNode.get();
+ return true;
+ } else {
+ mCurrentNode = oldNode;
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public final boolean moveToDocumentRoot() {
+ assertNotClosed();
+ return moveTo(EFixed.ROOT_NODE_KEY.getStandardProperty());
+ }
+
+ @Override
+ public final boolean moveToParent() {
+ assertNotClosed();
+ return moveTo(mCurrentNode.getParentKey());
+ }
+
+ @Override
+ public final boolean moveToFirstChild() {
+ assertNotClosed();
+ final IStructNode node = getStructuralNode();
+ if (!node.hasFirstChild()) {
+ return false;
+ }
+ return moveTo(node.getFirstChildKey());
+ }
+
+ @Override
+ public final boolean moveToLeftSibling() {
+ assertNotClosed();
+ final IStructNode node = getStructuralNode();
+ if (!node.hasLeftSibling()) {
+ return false;
+ }
+ return moveTo(node.getLeftSiblingKey());
+ }
+
+ @Override
+ public final boolean moveToRightSibling() {
+ assertNotClosed();
+ final IStructNode node = getStructuralNode();
+ if (!node.hasRightSibling()) {
+ return false;
+ }
+ return moveTo(node.getRightSiblingKey());
+ }
+
+ @Override
+ public final boolean moveToAttribute(final int pIndex) {
+ assertNotClosed();
+ if (mCurrentNode.getKind() == ENode.ELEMENT_KIND) {
+ final ElementNode element = ((ElementNode)mCurrentNode);
+ if (element.getAttributeCount() > pIndex) {
+ return moveTo(element.getAttributeKey(pIndex));
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public final boolean moveToNamespace(final int pIndex) {
+ assertNotClosed();
+ if (mCurrentNode.getKind() == ENode.ELEMENT_KIND) {
+ final ElementNode element = ((ElementNode)mCurrentNode);
+ if (element.getNamespaceCount() > pIndex) {
+ return moveTo(element.getNamespaceKey(pIndex));
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public final String getValueOfCurrentNode() {
+ assertNotClosed();
+ String returnVal;
+ if (mCurrentNode instanceof IValNode) {
+ returnVal = new String(((IValNode)mCurrentNode).getRawValue());
+ } else if (mCurrentNode.getKind() == ENode.NAMESPACE_KIND) {
+ returnVal =
+ mPageReadTransaction.getName(((NamespaceNode)mCurrentNode).getURIKey(), ENode.NAMESPACE_KIND);
+ } else {
+ returnVal = "";
+ }
+ return returnVal;
+ }
+
+ @Override
+ public final QName getQNameOfCurrentNode() {
+ assertNotClosed();
+ String name = "";
+ String uri = "";
+ if (mCurrentNode instanceof INameNode) {
+ name = mPageReadTransaction.getName(((INameNode)mCurrentNode).getNameKey(), mCurrentNode.getKind());
+ uri = mPageReadTransaction.getName(((INameNode)mCurrentNode).getURIKey(), ENode.NAMESPACE_KIND);
+ return buildQName(uri, name);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public final String getTypeOfCurrentNode() {
+ assertNotClosed();
+ return mPageReadTransaction.getName(mCurrentNode.getTypeKey(), getNode().getKind());
+ }
+
+ @Override
+ public final int keyForName(final String pName) {
+ assertNotClosed();
+ return NamePageHash.generateHashForString(pName);
+ }
+
+ @Override
+ public final String nameForKey(final int pKey) {
+ assertNotClosed();
+ return mPageReadTransaction.getName(pKey, getNode().getKind());
+ }
+
+ @Override
+ public final byte[] rawNameForKey(final int pKey) {
+ assertNotClosed();
+ return mPageReadTransaction.getRawName(pKey, getNode().getKind());
+ }
+
+ @Override
+ public final IItemList<INode> getItemList() {
+ assertNotClosed();
+ return mItemList;
+ }
+
+ @Override
+ public void close() throws AbsTTException {
+ if (!mClosed) {
+ // Close own state.
+ mPageReadTransaction.close();
+
+ // Callback on session to make sure everything is cleaned up.
+ mSession.closeReadTransaction(mId);
+
+ // Immediately release all references.
+ mPageReadTransaction = null;
+ mCurrentNode = null;
+
+ mClosed = true;
+ }
+ }
+
+ @Override
+ public final String toString() {
+ ToStringHelper helper = Objects.toStringHelper(this);
+ try {
+ helper.add("Revision number", getRevisionNumber());
+ } catch (final TTIOException e) {
+ }
+
+ if (getNode().getKind() == ENode.ATTRIBUTE_KIND || getNode().getKind() == ENode.ELEMENT_KIND) {
+ helper.add("Name of Node", getQNameOfCurrentNode().toString());
+ }
+
+ if (getNode().getKind() == ENode.ATTRIBUTE_KIND || getNode().getKind() == ENode.TEXT_KIND) {
+ helper.add("Value of Node", getValueOfCurrentNode());
+ }
+
+ if (getNode().getKind() == ENode.ROOT_KIND) {
+ helper.addValue("Node is DocumentRoot");
+ }
+ helper.add("node", getNode().toString());
+
+ return helper.toString();
+ }
+
+ /**
+ * Set state to closed.
+ */
+ final void setClosed() {
+ mClosed = true;
+ }
+
+ /**
+ * Is the transaction closed?
+ *
+ * @return {@code true} if the transaction was closed, {@code false} otherwise
+ */
+ @Override
+ public final boolean isClosed() {
+ return mClosed;
+ }
+
+ /**
+ * Make sure that the session is not yet closed when calling this method.
+ */
+ final void assertNotClosed() {
+ if (mClosed) {
+ throw new IllegalStateException("Transaction is already closed.");
+ }
+ }
+
+ /**
+ * Get the {@link IPageReadTrx}.
+ *
+ * @return current {@link IPageReadTrx}
+ */
+ public IPageReadTrx getPageTransaction() {
+ assertNotClosed();