[Mulgara-svn] r105 - branches/xafix/src/jar/resolver/java/org/mulgara/resolver

andrae at mulgara.org andrae at mulgara.org
Tue Oct 17 12:10:50 UTC 2006


Author: andrae
Date: 2006-10-17 07:10:50 -0500 (Tue, 17 Oct 2006)
New Revision: 105

Added:
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/ModelExistsOperation.java
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/OperationContextXAResource.java
Modified:
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/CacheResolver.java
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
   branches/xafix/src/jar/resolver/java/org/mulgara/resolver/SubqueryAnswer.java
Log:
This commit answers the OperationContext lifecycle, and Database Bootstrap
issues.

It also contains a critical refactoring migrating the last of the resolution
functionality from DatabaseSession to OperationContext.

The sole remaining question is:  JRDF.



Modified: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/CacheResolver.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/CacheResolver.java	2006-10-16 07:27:31 UTC (rev 104)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/CacheResolver.java	2006-10-17 12:10:50 UTC (rev 105)
@@ -185,6 +185,7 @@
   private Resolver getTemporaryResolver(LocalNode modelLocalNode) throws
       LocalizeException, QueryException, ResolverException,
       ResolverFactoryException, TuplesException {
+
     Resolver temporaryResolver = temporaryResolverFactory.newResolver(
         true, resolverSession, systemResolver
         );

Modified: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java	2006-10-16 07:27:31 UTC (rev 104)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java	2006-10-17 12:10:50 UTC (rev 105)
@@ -66,6 +66,7 @@
 import org.mulgara.resolver.spi.SymbolicTransformationContext;
 import org.mulgara.resolver.spi.SystemResolver;
 import org.mulgara.resolver.view.ViewMarker;
+import org.mulgara.resolver.view.SessionView;
 import org.mulgara.store.nodepool.NodePool;
 
 // !!FIXME: We need to consider how we partition OperationContext to seperate out the functions required
@@ -84,7 +85,7 @@
  *   Technology, Inc</a>
  * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
  */
-class DatabaseOperationContext implements OperationContext, SymbolicTransformationContext
+class DatabaseOperationContext implements OperationContext, SymbolicTransformationContext, SessionView
 {
   /**
    * Logger.
@@ -95,6 +96,11 @@
     Logger.getLogger("DatabaseOperationContext.class,getName()");
 
   /**
+   * Is this a write, or read-only operation.
+   */
+  private boolean isWriteOperation;
+
+  /**
    * The models from external resolvers which have been cached as temporary
    * models.
    *
@@ -121,9 +127,26 @@
    */
   private final Map systemModelCacheMap = new WeakHashMap();
 
+  /**
+   * The models from external resolvers which have been cached as temporary
+   * models and modified.
+   *
+   * Every model in this set can be manipulated by resolvers from the
+   * {@link #temporaryResolverFactory}.
+   */
+  private final Set changedCachedModelSet = new HashSet();
+
+  /**
+   * The models from external resolvers which have been cached as temporary
+   * models.
+   *
+   * Every model in this set can be manipulated by resolvers from the
+   * {@link #temporaryResolverFactory}.
+   */
+  private final Set cachedModelSet = new HashSet();
+
   // Immutable properties of the containing DatabaseSession
   private final Set                cachedResolverFactorySet;
-  private final DatabaseSession    databaseSession;
   private final Map                enlistedResolverMap;
   private final Map                externalResolverFactoryMap;
   private final Map                internalResolverFactoryMap;
@@ -133,6 +156,9 @@
   private final ResolverFactory    temporaryResolverFactory;
   private final MulgaraTransactionManager transactionManager;
 
+  /** The systemResolver that effectively defines the context this object represents. */
+  private SystemResolver systemResolver;
+
   //
   // Constructor
   //
@@ -140,10 +166,9 @@
   /**
    * Sole constructor.
    */
-  DatabaseOperationContext(Set                cachedModelSet,
+  DatabaseOperationContext(boolean            isWriteOperation,
+                           SystemResolverFactory systemResolverFactory,
                            Set                cachedResolverFactorySet,
-                           Set                changedCachedModelSet,
-                           DatabaseSession    databaseSession,
                            Map                externalResolverFactoryMap,
                            Map                internalResolverFactoryMap,
                            DatabaseMetadata   metadata,
@@ -152,10 +177,7 @@
                            ResolverFactory    temporaryResolverFactory,
                            MulgaraTransactionManager transactionManager)
   {
-    assert cachedModelSet             != null;
     assert cachedResolverFactorySet   != null;
-    assert changedCachedModelSet      != null;
-    assert databaseSession            != null;
     assert enlistedResolverMap        != null;
     assert externalResolverFactoryMap != null;
     assert internalResolverFactoryMap != null;
@@ -166,10 +188,10 @@
     assert transactionManager         != null;
 
     // Initialize fields
-    this.cachedModelSet             = cachedModelSet;
+    this.isWriteOperation           = isWriteOperation;
+    this.cachedModelSet             = new HashSet();
     this.cachedResolverFactorySet   = cachedResolverFactorySet;
-    this.changedCachedModelSet      = changedCachedModelSet;
-    this.databaseSession            = databaseSession;
+    this.changedCachedModelSet      = new HashSet();
     this.enlistedResolverMap        = new HashMap(); // This will need to be fixed.
     this.externalResolverFactoryMap = externalResolverFactoryMap;
     this.internalResolverFactoryMap = internalResolverFactoryMap;
@@ -178,6 +200,12 @@
     this.temporaryModelTypeURI      = temporaryModelTypeURI;
     this.temporaryResolverFactory   = temporaryResolverFactory;
     this.transactionManager         = transactionManager;
+
+    // Set to SystemResolver while we are within a transaction
+    // Set to null outside of a transaction;
+    this.systemResolver             = null;
+    systemResolverFactory.newResolver(isWriteOpreation);
+    enlistResolver(this.systemResolver);
   }
 
   //
@@ -210,7 +238,7 @@
       else {
         // This might be an external model or an aliased internal model.
         // get the model URI
-        Node modelNode = databaseSession.getSystemResolver().globalize(model);
+        Node modelNode = systemResolver.globalize(model);
         if (!(modelNode instanceof URIReference)) {
           throw new QueryException(modelNode.toString() + " is not a valid Model");
         }
@@ -219,7 +247,7 @@
         // check if this is really a reference to a local model, using a different server name
         Node aliasedNode = getCanonicalAlias(modelURI);
         if (aliasedNode != null) {
-          long aliasedModel = databaseSession.getSystemResolver().localize(aliasedNode);
+          long aliasedModel = systemResolver.localize(aliasedNode);
           return findModelResolverFactory(aliasedModel);
         }
 
@@ -308,8 +336,7 @@
     return securityAdapterList;
   }
 
-  public Resolver obtainResolver(ResolverFactory resolverFactory,
-                                 SystemResolver  systemResolver)
+  public Resolver obtainResolver(ResolverFactory resolverFactory)
     throws QueryException
   {
     ResolverSession session;
@@ -321,7 +348,7 @@
     }
 
     try {
-      resolver = resolverFactory.newResolver(databaseSession.isWriting(),
+      resolver = resolverFactory.newResolver(isWriteOperation,
                                              systemResolver,
                                              systemResolver);
 
@@ -331,7 +358,7 @@
       //        (specifically intervals), and distributed queries
       //        (specificially appended joins).
       if (resolver instanceof ViewMarker) {
-        ((ViewMarker) resolver).setSession(databaseSession);
+        ((ViewMarker) resolver).setSession(this);
       }
     }
     catch (ResolverFactoryException e) {
@@ -354,7 +381,7 @@
   public long getCanonicalModel(long model) {
     // globalize to a URI
     try {
-      Node modelNode = databaseSession.getSystemResolver().globalize(model);
+      Node modelNode = systemResolver.globalize(model);
       if (!(modelNode instanceof URIReference)) {
         logger.warn(modelNode.toString() + " is not a valid Model");
         return model;
@@ -364,7 +391,7 @@
       // check if this is really a reference to a local model, using a different server name
       Node aliasedNode = getCanonicalAlias(modelURI);
       if (aliasedNode != null) {
-        return databaseSession.getSystemResolver().localize(aliasedNode);
+        return systemResolver.localize(aliasedNode);
       }
     } catch (Exception e) {
       // unable to get a canonical form, so leave this model alone
@@ -382,7 +409,7 @@
       if (logger.isDebugEnabled()) {
         logger.debug("Finding modelTypeURI for " + modelURI);
       }
-      long rawModel = databaseSession.getSystemResolver().localize(new URIReferenceImpl(modelURI));
+      long rawModel = systemResolver.localize(new URIReferenceImpl(modelURI));
       long canModel = getCanonicalModel(rawModel);
 
       URI modelTypeURI = findModelTypeURI(canModel);
@@ -472,7 +499,7 @@
                          new LocalNode(metadata.getRdfTypeNode()),
                          modelTypeVariable,
                          new LocalNode(metadata.getSystemModelNode()));
-    Resolution resolution = databaseSession.getSystemResolver().resolve(modelConstraint);
+    Resolution resolution = systemResolver.resolve(modelConstraint);
     assert resolution != null;
 
     // Check the solution and extract the model type (if any) from it
@@ -486,7 +513,7 @@
           throw new QueryException("Model " + model +
               " has more than one type!");
         }
-        Node modelNode = databaseSession.getSystemResolver().globalize(modelType);
+        Node modelNode = systemResolver.globalize(modelType);
         assert modelNode instanceof URIReferenceImpl;
         modelTypeURI = ((URIReferenceImpl) modelNode).getURI();
         systemModelCacheMap.put(modelLocalNode, modelTypeURI);
@@ -521,7 +548,7 @@
   {
     try {
       // Globalize the node
-      Node node = (Node) databaseSession.getSystemResolver().globalize(n);
+      Node node = (Node) systemResolver.globalize(n);
       if (!(node instanceof URIReference)) {
         throw new QueryException(node + " is not a URI reference");
       }
@@ -605,8 +632,7 @@
   // Local query methods
   //
 
-  protected void doModify(// The SystemResolver should be in the context already - it isn't, but it should be.  SystemResolver systemResolver, URI modelURI,
-      Statements statements, boolean insert) throws Throwable {
+  protected void doModify(URI modelURI, Statements statements, boolean insert) throws Throwable {
     long model = systemResolver.localize(new URIReferenceImpl(modelURI));
     model = getCanonicalModel(model);
 
@@ -640,10 +666,6 @@
     }
   }
 
-  public Answer innerQuery(Query query) throws QueryException {
-    return doQuery(systemResolver, query);
-  }
-
   Tuples innerCount(LocalQuery localQuery) throws QueryException {
     LocalQuery lq = (LocalQuery)localQuery.clone();
     transform(this, lq);
@@ -653,7 +675,7 @@
     return result;
   }
 
-  Answer doQuery(SystemResolver  systemResolver, Query query) throws Exception
+  Answer doQuery(Query query) throws Exception
   {
     LocalQuery localQuery = new LocalQuery(query, systemResolver, this);
 
@@ -851,5 +873,138 @@
     return tuples;
   }
 
+  /**
+   * Clear the cache of temporary models.
+   */
+  private void clearCache()
+  {
+    // Clear the temporary models
+    if (!cachedModelSet.isEmpty()) {
+      try {
+        Resolver temporaryResolver =
+          temporaryResolverFactory.newResolver(true,
+                                               systemResolver,
+                                               systemResolver);
+        for (Iterator i = cachedModelSet.iterator(); i.hasNext();) {
+          LocalNode modelLocalNode = (LocalNode) i.next();
+          long model = modelLocalNode.getValue();
 
+          if (changedCachedModelSet.contains(modelLocalNode)) {
+            // Write back the modifications to the original model
+            try {
+              Resolver resolver =
+                findResolverFactory(model).newResolver(true,
+                                                       systemResolver,
+                                                       systemResolver);
+              Variable s = new Variable("s"),
+                       p = new Variable("p"),
+                       o = new Variable("o");
+              resolver.modifyModel(
+                model,
+                new TuplesWrapperStatements(
+                  temporaryResolver.resolve(
+                    new ConstraintImpl(s, p, o, modelLocalNode)
+                  ),
+                  s, p, o
+                ),
+                true  // insert the content
+              );
+            }
+            catch (Exception e) {
+              logger.error("Failed to write back cached model " + model +
+                           " after transaction", e);
+            }
+            changedCachedModelSet.remove(modelLocalNode);
+          }
+
+          // Remove the cached model
+          try {
+            temporaryResolver.removeModel(model);
+          }
+          catch (Exception e) {
+            logger.error(
+              "Failed to clear cached model " + model + " after transaction",
+               e
+            );
+          }
+          i.remove();
+        }
+      }
+      catch (Exception e) {
+        logger.error("Failed to clear cached models after transaction", e);
+      }
+    }
+  }
+
+
+  /**
+   * Find a cached resolver factory for write back.
+   *
+   * @return a completely unwrapped resolver factory
+   */
+  // TODO: Common code with findModelResolverFactory should be consolidated.
+  private ResolverFactory findResolverFactory(long model) throws QueryException
+  {
+    if (logger.isDebugEnabled()) {
+      logger.debug("Finding raw resolver factory for model " + model);
+    }
+
+    try {
+      // get the model URI
+      Node modelNode = systemResolver.globalize(model);
+      if (!(modelNode instanceof URIReference)) {
+        throw new QueryException(modelNode.toString() + " is not a valid Model");
+      }
+      URI modelURI = ((URIReference)modelNode).getURI();
+
+      // test the model URI against the current server
+      try {
+        if (logger.isDebugEnabled()) {
+          logger.debug("Comparing " + metadata.getURI().toString() + " to " + (new URI(modelURI.getScheme(),
+                  modelURI.getSchemeSpecificPart(), null)).toString());
+        }
+        if (metadata.getURI().equals(new URI(modelURI.getScheme(), modelURI.getSchemeSpecificPart(), null))) {
+          // should be on the current server, but was not found here
+          throw new QueryException(modelNode.toString() + " is not a Model");
+        }
+      }
+      catch (URISyntaxException use) {
+        throw new QueryException("Internal error.  Model URI cannot be manipulated.");
+      }
+
+      // This is not a local model, get the protocol
+      String modelProtocol = findProtocol(model);
+      if (logger.isDebugEnabled()) {
+        logger.debug("Model " + model + " protocol is " + modelProtocol);
+      }
+
+      // find the factory for this protocol
+      ResolverFactory resolverFactory =
+          (ResolverFactory) externalResolverFactoryMap.get(modelProtocol);
+      if (resolverFactory == null) {
+        throw new QueryException(
+            "Unsupported protocol for destination model (" +
+            modelProtocol + ", " + model + " : '" + modelProtocol + "')");
+      }
+
+      return resolverFactory;
+    }
+    catch (GlobalizeException eg) {
+      throw new QueryException("Unable to globalize modeltype", eg);
+    }
+  }
+
+
+  protected SystemResolver getSystemResolver() {
+    return systemResolver;
+  }
+
+  protected void initiate(MulgaraTransaction transaction) {
+    systemResolver = systemResolverFactory.newResolver(isWriteOpreation);
+    enlistResolver(systemResolver);
+  }
+
+  protected XAResource getXAResource() {
+    return new OperationContentXAResource(this);
+  }
 }

Modified: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2006-10-16 07:27:31 UTC (rev 104)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2006-10-17 12:10:50 UTC (rev 105)
@@ -54,7 +54,6 @@
 import org.mulgara.query.*;
 import org.mulgara.query.rdf.*;
 import org.mulgara.resolver.spi.*;
-import org.mulgara.resolver.view.SessionView;
 import org.mulgara.rules.*;
 import org.mulgara.server.Session;
 import org.mulgara.store.nodepool.NodePool;
@@ -79,7 +78,7 @@
  *
  * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
  */
-class DatabaseSession implements Session, LocalSession, SessionView, AnswerDatabaseSession {
+class DatabaseSession implements Session, LocalSession, AnswerDatabaseSession {
   public static final boolean ASSERT_STATEMENTS = true;
   public static final boolean DENY_STATEMENTS = false;
 
@@ -92,15 +91,6 @@
     Logger.getLogger(DatabaseSession.class.getName() + "#symbolic");
 
   /**
-   * The models from external resolvers which have been cached as temporary
-   * models.
-   *
-   * Every model in this set can be manipulated by resolvers from the
-   * {@link #temporaryResolverFactory}.
-   */
-  private final Set cachedModelSet = new HashSet();
-
-  /**
    * Resolver factories that should be have access to their models cached.
    *
    * This field is read-only.
@@ -108,15 +98,6 @@
   private final Set cachedResolverFactorySet;
 
   /**
-   * The models from external resolvers which have been cached as temporary
-   * models and modified.
-   *
-   * Every model in this set can be manipulated by resolvers from the
-   * {@link #temporaryResolverFactory}.
-   */
-  private final Set changedCachedModelSet = new HashSet();
-
-  /**
    * The list of all registered {@link ResolverFactory} instances.
    */
   private final List resolverFactoryList;
@@ -147,9 +128,6 @@
   /** Factory used to obtain the SystemResolver */
   private final SystemResolverFactory systemResolverFactory;
 
-  /** Resolver used for accessing the system model (<code>#</code>).  */
-  protected SystemResolver systemResolver;
-
   /** Factory used to obtain the SystemResolver */
   private final ResolverFactory temporaryResolverFactory;
 
@@ -165,9 +143,14 @@
   private ContentHandlerManager contentHandlers;
 
   /**
+   * The current operationContext when autoCommit is off.
+   */
+  private OperationContext operationContext;
+
+  /**
    * The transcation manager for this database.
    */
-  MulgaraTransactionManager transactionManager;
+  private MulgaraTransactionManager transactionManager;
 
   //
   // Constructor
@@ -298,15 +281,15 @@
 
   long bootstrapSystemModel(DatabaseMetadataImpl metadata) throws
       QueryException {
-    logger.info("Bootstrapping System Model");
-    // Validate parameters
     if (metadata == null) {
       throw new IllegalArgumentException("metadata null");
     }
 
-    // Create the model
-    systemResolver = beginTransactionalBlock(true);
     try {
+      MulgaraTransaction transaction = transactionManager.getTransaction(this, operation.isWriteOperation());
+      SystemResolver systemResolver = systemResolverFactory.newResolver(true);
+      transaction.enlistResolver(systemResolver);
+
       // Find the local node identifying the model
       long model = systemResolver.localizePersistent(
           new URIReferenceImpl(metadata.getSystemModelURI()));
@@ -351,6 +334,7 @@
 
       systemResolverFactory.setDatabaseMetadata(metadata);
 
+      // we need to commit here.
       return model;
     } catch (Throwable e) {
       rollbackTransactionalBlock(e);
@@ -383,9 +367,6 @@
         temporaryModelTypeURI, "");
   }
 
-  public ResolverSession getResolverSession() {
-    return systemResolver;
-  }
 
   /**
    * Preallocate a local node number for an RDF {@link Node}.
@@ -591,50 +572,9 @@
   }
 
   public boolean modelExists(URI modelURI) throws QueryException {
-
-    // Attempt to create a read only transaction
-    try {
-      startTransactionalOperation(false);
-    }
-    catch (IllegalArgumentException iae) {
-
-      // If we're in a transaction then try to do it anyway.
-      try {
-        long model = systemResolver.lookupPersistent(new URIReferenceImpl(
-            modelURI));
-
-        return systemResolver.modelExists(model);
-      }
-      catch (ResolverException re) {
-        throw new QueryException("Failed to resolve URI: " + modelURI, re);
-      }
-      catch (LocalizeException le) {
-        // Return false - we failed to find the node.
-        return false;
-      }
-    }
-
-    // If we created a new transaction perform the same operation with
-    // try/catches for correct handling of exceptions.
-    try {
-      long model;
-
-      try {
-        model = systemResolver.lookupPersistent(new URIReferenceImpl(
-            modelURI));
-      }
-      catch (LocalizeException le) {
-        // Return false - we failed to find the node.
-        return false;
-      }
-      return systemResolver.modelExists(model);
-
-    } catch (Throwable e) {
-      rollbackTransactionalBlock(e);
-    } finally {
-      finishTransactionalOperation("Could not find model " + modelURI);
-    }
-    throw new QueryException("Illegal transactional state in session");
+    ModelExistsOperation operation = new ModelExistsOperation(modelURI);
+    execute(operation, "Failed to determine model existence");
+    return operation.getResult();
   }
 
   /**
@@ -676,6 +616,7 @@
   }
 
   public void setAutoCommit(boolean autoCommit) throws QueryException {
+    // !!FIXME: Need to setup an operationContext here.
     try {
       transactionManager.setAutoCommit(this);
     } catch (MulgaraTransactionException em) {
@@ -757,165 +698,29 @@
     throws QueryException
   {
     try {
-      OperationContext operationContext = new DatabaseOperationContext(
-          cachedModelSet,
-          cachedResolverFactorySet,
-          changedCachedModelSet,
-          this,
-          externalResolverFactoryMap,
-          internalResolverFactoryMap,
-          metadata,
-          securityAdapterList,
-          temporaryModelTypeURI,
-          temporaryResolverFactory,
-          transactionManager,
-          symbolicTransformationList);
       MulgaraTransaction transaction = transactionManager.getTransaction(this, operation.isWriteOperation());
-      transaction.execute(operation, operationContext, systemResolver, resolverSessionFactory, metadata);
+      transaction.execute(operation, resolverSessionFactory, metadata);
     } catch (MulgaraTransactionException em) {
       throw new QueryException(failureMessage, em);
     }
-
   }
 
-  /**
-   * Clear the cache of temporary models.
-   */
-  private void clearCache()
-  {
-    // Clear the temporary models
-    if (!cachedModelSet.isEmpty()) {
-      try {
-        Resolver temporaryResolver =
-          temporaryResolverFactory.newResolver(true,
-                                               systemResolver,
-                                               systemResolver);
-        for (Iterator i = cachedModelSet.iterator(); i.hasNext();) {
-          LocalNode modelLocalNode = (LocalNode) i.next();
-          long model = modelLocalNode.getValue();
-
-          if (changedCachedModelSet.contains(modelLocalNode)) {
-            // Write back the modifications to the original model
-            try {
-              Resolver resolver =
-                findResolverFactory(model).newResolver(true,
-                                                       systemResolver,
-                                                       systemResolver);
-              Variable s = new Variable("s"),
-                       p = new Variable("p"),
-                       o = new Variable("o");
-              resolver.modifyModel(
-                model,
-                new TuplesWrapperStatements(
-                  temporaryResolver.resolve(
-                    new ConstraintImpl(s, p, o, modelLocalNode)
-                  ),
-                  s, p, o
-                ),
-                true  // insert the content
-              );
-            }
-            catch (Exception e) {
-              logger.error("Failed to write back cached model " + model +
-                           " after transaction", e);
-            }
-            changedCachedModelSet.remove(modelLocalNode);
-          }
-
-          // Remove the cached model
-          try {
-            temporaryResolver.removeModel(model);
-          }
-          catch (Exception e) {
-            logger.error(
-              "Failed to clear cached model " + model + " after transaction",
-               e
-            );
-          }
-          i.remove();
-        }
-      }
-      catch (Exception e) {
-        logger.error("Failed to clear cached models after transaction", e);
-      }
-    }
-  }
-
-  /**
-   * Find a cached resolver factory for write back.
-   *
-   * @return a completely unwrapped resolver factory
-   */
-  // TODO: Common code with DatabaseOperationContent.findModelResolverFactory
-  //       should be consolidated.
-  private ResolverFactory findResolverFactory(long model) throws QueryException
-  {
-    if (logger.isDebugEnabled()) {
-      logger.debug("Finding raw resolver factory for model " + model);
-    }
-
-    try {
-      // get the model URI
-      Node modelNode = systemResolver.globalize(model);
-      if (!(modelNode instanceof URIReference)) {
-        throw new QueryException(modelNode.toString() + " is not a valid Model");
-      }
-      URI modelURI = ((URIReference)modelNode).getURI();
-
-      // test the model URI against the current server
-      try {
-        if (logger.isDebugEnabled()) {
-          logger.debug("Comparing " + metadata.getURI().toString() + " to " + (new URI(modelURI.getScheme(),
-                  modelURI.getSchemeSpecificPart(), null)).toString());
-        }
-        if (metadata.getURI().equals(new URI(modelURI.getScheme(), modelURI.getSchemeSpecificPart(), null))) {
-          // should be on the current server, but was not found here
-          throw new QueryException(modelNode.toString() + " is not a Model");
-        }
-      }
-      catch (URISyntaxException use) {
-        throw new QueryException("Internal error.  Model URI cannot be manipulated.");
-      }
-
-      // This is not a local model, get the protocol
-      String modelProtocol = operationContext.findProtocol(model);
-      if (logger.isDebugEnabled()) {
-        logger.debug("Model " + model + " protocol is " + modelProtocol);
-      }
-
-      // find the factory for this protocol
-      ResolverFactory resolverFactory =
-          (ResolverFactory) externalResolverFactoryMap.get(modelProtocol);
-      if (resolverFactory == null) {
-        throw new QueryException(
-            "Unsupported protocol for destination model (" +
-            modelProtocol + ", " + model + " : '" + modelProtocol + "')");
-      }
-
-      return resolverFactory;
-    }
-    catch (GlobalizeException eg) {
-      throw new QueryException("Unable to globalize modeltype", eg);
-    }
-  }
-
   public boolean isLocal() {
     return true;
   }
 
-  //
-  // Private accessors intended only for DatabaseOperationContext
-  //
-
-  SystemResolver getSystemResolver() {
-    return systemResolver;
+  OperationContext newOperationContext(boolean isWriteOperation) {
+    return new DatabaseOperationContext(
+        isWriteOperation,
+        systemResolverFactory,
+        cachedResolverFactorySet,
+        externalResolverFactoryMap,
+        internalResolverFactoryMap,
+        metadata,
+        securityAdapterList,
+        temporaryModelTypeURI,
+        temporaryResolverFactory,
+        transactionManager,
+        symbolicTransformationList);
   }
-
-  Transaction getTransaction() {
-    return transaction;
-  }
-
-  boolean isWriting() {
-    return writing;
-  }
 }

Added: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/ModelExistsOperation.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/ModelExistsOperation.java	2006-10-16 07:27:31 UTC (rev 104)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/ModelExistsOperation.java	2006-10-17 12:10:50 UTC (rev 105)
@@ -0,0 +1,85 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is the Kowari Metadata Store.
+ *
+ * The Initial Developer of the Original Code is Plugged In Software Pty
+ * Ltd (http://www.pisoftware.com, mailto:info at pisoftware.com). Portions
+ * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002
+ * Plugged In Software Pty Ltd. All Rights Reserved.
+ *
+ * Contributor(s): This file, excluding the two lines of the execute method 
+ *   is an original work developed by Netymon Pty Ltd.  Excluding these to
+ *   lines this file is:
+ *   Copyright (c) 2006 Netymon Pty Ltd.
+ *   All Rights Reserved.
+ *
+ * [NOTE: The text of this Exhibit A may differ slightly from the text
+ * of the notices in the Source Code files of the Original Code. You
+ * should use the text of this Exhibit A rather than the text found in the
+ * Original Code Source Code for Your Modifications.]
+ *
+ */
+
+package org.mulgara.resolver;
+
+// Java 2 standard packages
+import java.net.URI;
+
+// Third party packages
+import org.apache.log4j.Logger;
+
+// Local packages
+import org.mulgara.query.*;
+import org.mulgara.resolver.spi.*;
+import org.mulgara.server.Session;
+
+class ModelExistsOperation implements Operation
+{
+  /**
+   * Logger.
+   */
+  private static final Logger logger =
+    Logger.getLogger(ModelExistsOperation.class.getName());
+
+  private URI modelURI = null;
+
+  private boolean result;
+
+
+  QueryOperation(URI modelURI) {
+    this.modelURI = modelURI;
+  }
+
+  //
+  // Methods implementing Operation
+  //
+
+  public void execute(OperationContext       operationContext,
+                      SystemResolver         systemResolver,
+                      ResolverSessionFactory resolverSessionFactory,
+                      DatabaseMetadata       metadata) throws Exception
+  {
+    long model = systemResolver.lookupPersistent(new URIReferenceImpl(
+        modelURI));
+
+    result = systemResolver.modelExists(model);
+  }
+
+  public boolean isWriteOperation() {
+    return false;
+  }
+
+  
+  boolean getResult() {
+    return result;
+  }
+}

Modified: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java	2006-10-16 07:27:31 UTC (rev 104)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransaction.java	2006-10-17 12:10:50 UTC (rev 105)
@@ -43,7 +43,8 @@
  * @licence Open Software License v3.0</a>
  */
 public class MulgaraTransaction {
-  private MulgaraTransactionManager mulagaraManager;
+  private MulgaraTransactionManager manager;
+  private OperationContext context;
 
   private Transaction transaction;
   private Thread currentThread;
@@ -58,8 +59,9 @@
   private int rollback;
   private Throwable rollbackCause;
 
-  public MulgaraTransaction(MulgaraTransactionManager manager) {
+  public MulgaraTransaction(MulgaraTransactionManager manager, OperationContext context) {
     this.manager = manager;
+    this.context = context;
 
     this.transaction = manager.transactionStart();
     inuse = 1; // Note: This implies implict activation as a part of construction.
@@ -67,6 +69,9 @@
 
     rollback = NO_ROLLBACK;
     rollbackCause = null;
+
+    context.initiate();
+    this.transaction.enlistResource(context.getXAResource());
   }
 
   // FIXME: Not yet certain I have the error handling right here.
@@ -132,14 +137,13 @@
     }
   }
 
-  void execute(OperationContext operation,
-               SystemResolver systemResolver,
-               ResolverSessionFactory resolverSessionFactory, // FIXME: We shouldn't need this.
+  void execute(Operation operation,
+               ResolverSessionFactory resolverSessionFactory, // FIXME: We shouldn't need this. - only used for backup and restore operations.
                DatabaseMetadata databaseMetatdata) {
     activate();
     try {
-      operation.execute(operationContext,
-                        systemResolver,
+      operation.execute(context,
+                        context.getSystemResolver(),
                         resolverSessionFactory,
                         metadata);
     } catch (Throwable th) {
@@ -191,8 +195,6 @@
     try {
       transaction.commit();
     } finally {
-      session.clearCache();
-      operationContext.clearSystemModelCache();
       transactionManager.transactionComplete(this);
     }
   }

Modified: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2006-10-16 07:27:31 UTC (rev 104)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/MulgaraTransactionManager.java	2006-10-17 12:10:50 UTC (rev 105)
@@ -49,7 +49,7 @@
 public class MulgaraTransactionManager {
   // Write lock is associated with a session.
   private Session currentWritingSession;
-  private MulgaraTransaction writeTransaction;
+  private MulgaraTransaction userTransaction;
 
   /** Map from session to transaction for all 'write' transactions that have been rolledback. */
   private Map failedSessions;
@@ -61,7 +61,7 @@
 
   public MulgaraTransactionManager(TransactionManager transactionManager) {
     this.currentWritingSession = null;
-    this.writeTransaction = null;
+    this.userTransaction = null;
 
     this.failedSessions = new HashMap();
 
@@ -78,15 +78,16 @@
    *     obtain the write-lock, create a new transaction object and return it.</li>
    * </ul>
    */
-  public synchronized MulgaraTransaction getTransaction(Session session, boolean write) throws MulgaraTransactionException {
+  public synchronized MulgaraTransaction getTransaction(DatabaseSession session, boolean write) throws MulgaraTransactionException {
     if (session == currentWritingSession) {
-      return writeTransaction;
+      return userTransaction;
     } 
 
     if (write) {
       obtainWriteLock(session);
     }
-    writeTransaction = new MulgaraTransaction(this, transactionManager);
+
+    return new MulgaraTransaction(this, session.getOperationContext());
   }
 
 
@@ -108,7 +109,7 @@
 
   private synchronized void releaseWriteLock() {
     currentWritingSession = null;
-    writeTransaction = null;
+    userTransaction = null;
     writeLockMutex.notify();
   }
 
@@ -127,11 +128,11 @@
   public synchronized void rollback(Session session) {
     if (session == currentWritingSession) {
       try {
-        writeTransaction.explicitRollback();
+        userTransaction.explicitRollback();
         finalizeTransaction();
       } finally {
-        failedSessions.put(currentWritingSession, writeTransaction);
-        writeTransaction = null;
+        failedSessions.put(currentWritingSession, userTransaction);
+        userTransaction = null;
         currentWritingSession = null;
         releaseWriteLock();
       }
@@ -140,7 +141,7 @@
     }
   }
 
-  public synchronized void setAutocommit(Session session, boolean autoCommit) {
+  public synchronized void setAutocommit(DatabaseSession session, boolean autoCommit) {
     if (session == currentWritingSession && failedSessions.containsKey(session)) {
       // CRITICAL ERROR - transaction failed, but we did not finalise it.
     }
@@ -165,7 +166,10 @@
       if (autoCommit) {
         // AutoCommit on -> on === no-op.  Log info.
       } else {
-        // AutoCommit on -> off ==
+        // AutoCommit on -> off == Start new transaction.
+        obtainWriteLock(session);
+        userTransaction = new MulgaraTransaction(this, session.newOperationContext(true));
+        currentWritingSession = session;
       }
     }
   }
@@ -200,7 +204,7 @@
 
   public synchronized void transactionComplete(MulgaraTransaction transaction) {
     transactionManager.commit(transaction);
-    if (transaction == writeTransaction) {
+    if (transaction == userTransaction) {
       releaseWriteLock();
     }
     activeTransactions.remove(Thread.currentThread());

Added: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/OperationContextXAResource.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/OperationContextXAResource.java	2006-10-16 07:27:31 UTC (rev 104)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/OperationContextXAResource.java	2006-10-17 12:10:50 UTC (rev 105)
@@ -0,0 +1,87 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.rosenlaw.com/OSL3.0.htm
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * This file is an original work developed by Netymon Pty Ltd
+ * (http://www.netymon.com, mailto:mail at netymon.com). Portions created
+ * by Netymon Pty Ltd are Copyright (c) 2006 Netymon Pty Ltd.
+ * All Rights Reserved.
+ */
+package org.mulgara.resolver;
+
+// Java 2 standard packages
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+// Third party packages
+import org.apache.log4j.Logger;
+
+/**
+ * Responsible for ensuring that the transaction scoped, but non-transactional, resources in 
+ * the OperationContext are released at the end of the transaction.
+ *
+ * @created 2006-10-17
+ *
+ * @author <a href="mailto:andrae at netymon.com">Andrae Muys</a>
+ *
+ * @version $Revision: $
+ *
+ * @modified $Date: $
+ *
+ * @maintenanceAuthor $Author: $
+ *
+ * @company <A href="mailto:mail at netymon.com">Netymon Pty Ltd</A>
+ *
+ * @copyright &copy;2006 <a href="http://www.netymon.com/">Netymon Pty Ltd</a>
+ *
+ * @licence Open Software License v3.0</a>
+ */
+public class OperationContextXAResource implements XAResource
+{
+  /** Logger.  */
+  private static final Logger logger =
+    Logger.getLogger(OperationContextXAResource.class.getName());
+
+  public OperationContextXAResource(DatabaseOperationContext context)
+  {
+    this.context = context;
+  }
+
+  //
+  // Methods implementing XAResource
+  //
+
+  public void start(Xid xid, int flags) throws XAException { }
+
+  public int prepare(Xid xid) throws XAException { }
+
+  public void commit(Xid xid, boolean onePhase) throws XAException { }
+
+  public void end(Xid xid, int flags) throws XAException { }
+
+  public void forget(Xid xid) throws XAException {
+    context.clearCache();
+    context.clearSystemModelCache();
+  }
+
+  public int getTransactionTimeout() throws XAException { }
+
+  public boolean isSameRM(XAResource xaResource) throws XAException
+  {
+    return xaResource == this;
+  }
+
+  public Xid[] recover(int flag) throws XAException { }
+
+  public void rollback(Xid xid) throws XAException { }
+
+  public boolean setTransactionTimeout(int transactionTimeout) throws XAException { }
+}

Modified: branches/xafix/src/jar/resolver/java/org/mulgara/resolver/SubqueryAnswer.java
===================================================================
--- branches/xafix/src/jar/resolver/java/org/mulgara/resolver/SubqueryAnswer.java	2006-10-16 07:27:31 UTC (rev 104)
+++ branches/xafix/src/jar/resolver/java/org/mulgara/resolver/SubqueryAnswer.java	2006-10-17 12:10:50 UTC (rev 105)
@@ -305,7 +305,7 @@
         logger.debug("Generated subquery: " + query);
       }
 
-      return operationContext.innerQuery(query);
+      return operationContext.doQuery(query);
     }
     catch (Exception e) {
       throw new QueryException("Failed to resolve subquery", e);




More information about the Mulgara-svn mailing list