[Mulgara-svn] r213 - in trunk/src/jar: . resolver-distributed resolver-distributed/java resolver-distributed/java/org resolver-distributed/java/org/mulgara resolver-distributed/java/org/mulgara/resolver resolver-distributed/java/org/mulgara/resolver/distributed

pag at mulgara.org pag at mulgara.org
Fri Mar 30 12:48:51 UTC 2007


Author: pag
Date: 2007-03-30 06:48:50 -0600 (Fri, 30 Mar 2007)
New Revision: 213

Added:
   trunk/src/jar/resolver-distributed/
   trunk/src/jar/resolver-distributed/build.xml
   trunk/src/jar/resolver-distributed/java/
   trunk/src/jar/resolver-distributed/java/org/
   trunk/src/jar/resolver-distributed/java/org/mulgara/
   trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/
   trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/
   trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/AnswerResolution.java
   trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/Delegator.java
   trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/DistributedResolver.java
   trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/DistributedResolverFactory.java
   trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java
   trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/package.html
   trunk/src/jar/resolver-distributed/resolver-distributed-build.properties
Log:
Initial commit.  Compiling, but not tested.  More needs to be done for keeping blank nodes distinct between different servers

Added: trunk/src/jar/resolver-distributed/build.xml
===================================================================
--- trunk/src/jar/resolver-distributed/build.xml	2007-03-28 08:52:38 UTC (rev 212)
+++ trunk/src/jar/resolver-distributed/build.xml	2007-03-30 12:48:50 UTC (rev 213)
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE project>
+
+<!-- =================================================================== -->
+<!--                       Project definition                            -->
+<!-- =================================================================== -->
+<project name="resolver-distributed" default="resolver-distributed.jar" basedir="../../..">
+
+  <!-- =================================================================== -->
+  <!--                          Path Definitions                           -->
+  <!-- =================================================================== -->
+  <path id="resolver-distributed-classpath">
+    <path refid="common-classpath"/>
+    <fileset file="${query.dist.dir}/${query.jar}"/>
+    <fileset file="${resolver-spi.dist.dir}/${resolver-spi.jar}"/>
+    <fileset file="${resolver.dist.dir}/${resolver.jar}"/>
+    <fileset file="${util.dist.dir}/${util.jar}"/>
+    <fileset file="${tuples.dist.dir}/${tuples.jar}"/>
+    <fileset file="${driver.dist.dir}/${driver.jar}"/>
+    <fileset file="${store-nodepool-memory.dist.dir}/${store-nodepool-memory.jar}"/>
+    <fileset file="${store-nodepool-xa.dist.dir}/${store-nodepool-xa.jar}"/>
+    <fileset file="${store-stringpool-memory.dist.dir}/${store-stringpool-memory.jar}"/>
+    <fileset file="${store-stringpool-xa.dist.dir}/${store-stringpool-xa.jar}"/>
+    <fileset file="${server.dist.dir}/${server.jar}"/>
+    <fileset file="${server-rmi.dist.dir}/${server-rmi.jar}"/>
+    <fileset file="${server-local.dist.dir}/${server-local.jar}"/>
+    <fileset file="${tuples-hybrid.dist.dir}/${tuples-hybrid.jar}"/>
+  </path>
+
+  <path id="resolver-distributed-test-classpath">
+    <path refid="resolver-distributed-classpath"/>
+    <fileset file="${resolver-distributed.dist.dir}/${resolver-distributed.jar}"/>
+  </path>
+
+  <target name="resolver-distributed-clean" description="Removes all compile generated files for the resolver-distributed">
+    <tstamp/>
+    <delete dir="${resolver-distributed.obj.dir}"/>
+    <delete dir="${resolver-distributed.test.dir}"/>
+    <delete dir="${resolver-distributed.dist.dir}"/>
+  </target>
+
+  <target name="-resolver-distributed-prepare"
+          description="Creates all directories associated with the resolver-distributed's
+                       compilation"
+          depends="-prepare-build">
+    <mkdir dir="${resolver-distributed.obj.dir}"/>
+    <mkdir dir="${resolver-distributed.test.dir}"/>
+    <mkdir dir="${resolver-distributed.dist.dir}"/>
+    <mkdir dir="${resolver-distributed.obj.dir}/classes"/>
+  </target>
+
+  <target name="resolver-distributed-compile"
+        depends="-resolver-distributed-prepare,
+                 query-jar,
+                 resolver-spi-jar,
+                 resolver-jar,
+                 util-jar,
+                 tuples-jar,
+                 driver-jar,
+                 server-rmi-jar, 
+                 server-local-jar, 
+                 tuples-hybrid-jar"
+          description="Compiles all resolver-distributed related files included generated source code">
+    <javac destdir="${resolver-distributed.obj.dir}/classes" debug="on" deprecation="on" source="1.5">
+      <classpath refid="resolver-distributed-classpath"/>
+      <src path="${resolver-distributed.src.dir}/java"/>
+    </javac>
+  </target>
+
+  <target name="resolver-distributed-jar"
+        depends="resolver-distributed-compile, -resolver-distributed-jar-uptodate"
+        unless="resolver-distributed.jar.uptodate"
+        description="Builds the distributed Resolver JAR">
+    <jar jarfile="${resolver-distributed.dist.dir}/${resolver-distributed.jar}">
+      <fileset dir="${resolver-distributed.obj.dir}/classes"/>
+    </jar>
+  </target>
+
+  <target name="-resolver-distributed-jar-uptodate">
+    <uptodate property="resolver-distributed.jar.uptodate"
+              targetfile="${resolver-distributed.dist.dir}/${resolver-distributed.jar}">
+      <srcfiles dir="${resolver-distributed.obj.dir}/classes" includes="**/*"/>
+    </uptodate>
+  </target>
+
+  <target name="resolver-distributed-dist"
+          depends="resolver-distributed-jar"
+          unless="resolver-distributed.uptodate"
+          description="Performs all tasks related to finalising this resolver-distributed and readying it for distribution">
+
+    <!-- All that's involved in the final version of the resolver-distributed library
+         is the jar so we don't need to do anything because the dependencies
+         take care of the work. -->
+  </target>
+
+  <target name="resolver-distributed-test"
+          depends="resolver-distributed-jar, resolver-file-jar, resolver-http-jar"
+          description="Carries out unit testing for this resolver-distributed">
+    <antcall target="component-test">
+      <param name="classpath.id" value="resolver-distributed-test-classpath"/>
+      <param name="dir" value="${resolver-distributed.src.dir}"/>
+      <param name="jar" value="${resolver-distributed.jar}"/>
+    </antcall>
+  </target>
+
+  <target name="resolver-distributed-javadoc"
+          depends="resolver-distributed-jar"
+          description="Creates the javadoc for this resolver-distributed">
+    <antcall target="javadoc">
+      <param name="javadoc.package" value="org.mulgara.resolver.distributed.*"/>
+      <param name="javadoc.classpath" value="resolver-distributed-classpath"/>
+      <param name="javadoc.sourcepath" value="${resolver-distributed.src.dir}/java"/>
+    </antcall>
+  </target>
+
+  <target name="resolver-distributed-help"
+          description="Displays the help information for this resolver-distributed">
+
+    <!-- This is similar to the main project's help except the information
+         is specific to this resolver-distributed -->
+
+    <echo message="Welcome to the build script for ${resolver-distributed.name}."/>
+    <echo message=""/>
+    <echo message="These targets can be invoked as follows:"/>
+    <echo message="  ./build.sh &lt;target&gt;"/>
+    <echo message=""/>
+
+    <java fork="false" classname="org.apache.tools.ant.Main" newenvironment="false">
+      <jvmarg value="${arch.bits}"/>
+      <arg line="-buildfile ${resolver-distributed.src.dir}/build.xml -projecthelp"/>
+    </java>
+  </target>
+
+</project>


Property changes on: trunk/src/jar/resolver-distributed/build.xml
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/AnswerResolution.java
===================================================================
--- trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/AnswerResolution.java	2007-03-28 08:52:38 UTC (rev 212)
+++ trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/AnswerResolution.java	2007-03-30 12:48:50 UTC (rev 213)
@@ -0,0 +1,79 @@
+/*
+ * 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.opensource.org/licenses/osl-3.0.txt
+ *
+ * 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.
+ */
+
+package org.mulgara.resolver.distributed;
+
+import org.apache.log4j.Logger;  // Apache Log4J
+
+import org.mulgara.query.Answer;
+import org.mulgara.query.Constraint;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.resolver.spi.GlobalizeException;
+import org.mulgara.resolver.spi.LocalizedTuples;
+import org.mulgara.resolver.spi.ResolverSession;
+import org.mulgara.resolver.spi.Resolution;
+
+import org.mulgara.store.tuples.Annotation;
+import org.mulgara.store.tuples.RowComparator;
+import org.mulgara.store.tuples.Tuples;
+
+/**
+ * A {@link Resolution} which extends a LocalizedTuples, which in turn wraps an Answer.
+ *
+ * @created 2007-03-23
+ * @author Paul Gearon
+ * @version $Revision: $
+ * @modified $Date: $ @maintenanceAuthor $Author: $
+ * @copyright &copy; 2007 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+class AnswerResolution extends LocalizedTuples implements Resolution {
+
+  /** Logger.  */
+  private static final Logger logger = Logger.getLogger(AnswerResolution.class.getName());
+
+  /** The constraint. */
+  private final Constraint constraint;
+
+
+  /**
+   * Construct an AnswerResolution, passing most of the work off to the LocalizedTuples.
+   * @param session The current session.
+   * @param answer The answer to be wrapped by the parent class.
+   * @param constraint the constraint.
+   * @throws IllegalArgumentException if <var>constraint<var> is <code>null</code>
+   */
+  AnswerResolution(ResolverSession session, Answer answer, Constraint constraint) {
+    super(session, answer);
+    if (constraint == null) throw new IllegalArgumentException("Null constraint parameter");
+    this.constraint = constraint;
+  }
+
+
+  /**
+   * Get the constraint leading to this resolution.
+   * @return The constraint for the resolution.
+   */
+  public Constraint getConstraint() {
+    return constraint;
+  }
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isComplete() {
+    return true;
+  }
+
+}

Added: trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/Delegator.java
===================================================================
--- trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/Delegator.java	2007-03-28 08:52:38 UTC (rev 212)
+++ trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/Delegator.java	2007-03-30 12:48:50 UTC (rev 213)
@@ -0,0 +1,41 @@
+/*
+ * 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.opensource.org/licenses/osl-3.0.txt
+ *
+ * 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.
+ */
+
+package org.mulgara.resolver.distributed;
+
+import org.mulgara.query.Constraint;
+import org.mulgara.query.LocalNode;
+import org.mulgara.resolver.spi.Resolution;
+import org.mulgara.query.QueryException;
+
+
+/**
+ * Inteface for an object capable of resolving a constraint
+ *
+ * @created 2007-03-20
+ * @author <a href="mailto:gearon at users.sourceforge.net">Paul Gearon</a>
+ * @version $Revision: $
+ * @modified $Date: $
+ * @maintenanceAuthor $Author: $
+ * @copyright &copy; 2007 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public interface Delegator {
+
+  /**
+   * Resolve a given constraint down to the appropriate resolution.
+   * @param constraint The constraint to resolve.
+   * @param model The LocalNode containing the model
+   * @throws QueryException A delegator specific problem occurred resolving the constraint.
+   */
+  public Resolution resolve(Constraint constraint, LocalNode model) throws QueryException;
+}

Added: trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/DistributedResolver.java
===================================================================
--- trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/DistributedResolver.java	2007-03-28 08:52:38 UTC (rev 212)
+++ trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/DistributedResolver.java	2007-03-30 12:48:50 UTC (rev 213)
@@ -0,0 +1,177 @@
+/*
+ * 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.opensource.org/licenses/osl-3.0.txt
+ *
+ * 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.
+ */
+
+package org.mulgara.resolver.distributed;
+
+// Java 2 standard packages
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import javax.transaction.xa.XAResource;
+
+// Third party packages
+import org.apache.log4j.Logger;
+
+// Locally written packages
+import org.mulgara.query.Constraint;
+import org.mulgara.query.ConstraintElement;
+import org.mulgara.query.LocalNode;
+import org.mulgara.query.QueryException;
+import org.mulgara.resolver.spi.DummyXAResource;
+import org.mulgara.resolver.spi.Resolution;
+import org.mulgara.resolver.spi.Resolver;
+import org.mulgara.resolver.spi.ResolverException;
+import org.mulgara.resolver.spi.ResolverFactoryException;
+import org.mulgara.resolver.spi.ResolverSession;
+import org.mulgara.resolver.spi.Statements;
+import org.mulgara.server.Session;
+import org.mulgara.server.SessionFactory;
+
+/**
+ * Resolves constraints accessible through a session.
+ *
+ * @created 2007-03-20
+ * @author <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @version $Revision: $
+ * @modified $Date: $
+ * @maintenanceAuthor $Author: $
+ * @copyright &copy; 2007 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class DistributedResolver implements Resolver
+{
+  /** Logger.  */
+  private static Logger logger = Logger.getLogger(DistributedResolver.class.getName());
+
+  /** The delegator that resolves the constraint on another server.  */
+  private final Delegator delegator;
+
+  /** A map of servers to sessions.  This acts as a cache, and also so we may close the sessions.  */
+  private Map<URI,Session> serverToSession = new HashMap<URI,Session>();
+
+  /** A collections of session factories.  This is so we may close these factories.  */
+  private Collection<SessionFactory> sessionFactories = new HashSet<SessionFactory>();
+
+
+
+  /**
+   * Construct a Distributed Resolver.
+   * @param resolverSession the session this resolver is associated with.
+   * @throws IllegalArgumentException if <var>resolverSession</var> is <code>null</code>
+   * @throws ResolverFactoryException if the superclass is unable to handle its arguments
+   */
+  DistributedResolver(ResolverSession resolverSession) throws ResolverFactoryException {
+
+    if (logger.isDebugEnabled()) logger.debug("Instantiating a distributed resolver");
+
+    // Validate "resolverSession" parameter
+    if (resolverSession == null) throw new IllegalArgumentException( "Null \"resolverSession\" parameter");
+
+    delegator = new NetworkDelegator(resolverSession);
+  }
+
+
+  /**
+   * Model creation method.  Not supported in this resolver.
+   * @throws ResolverException The server should not ask this resolver to create a model.
+   */
+  public void createModel(long model, URI modelType) throws ResolverException {
+    throw new ResolverException("Requesting model creation from a distributed resolver.");
+  }
+
+
+  /**
+   * Expose a callback object for enlistment by a transaction manager.
+   * Uses a dumy xa resource for the moment, but may need to create a fully
+   * functional xa resource which is mapped to a session.
+   *
+   * @return an {@link XAResource} that can be used by a transaction manager to
+   *   coordinate this resolver's participation in a distributed transaction.
+   *   For now this is a {@link DummyXAResource} with a 10 second transaction timeout
+   * @see javax.resource.spi.ManagedConnection#getXAResource
+   */
+  public XAResource getXAResource() {
+    return new DummyXAResource(
+      10  // seconds before transaction timeout
+    );
+  }
+
+
+  /**
+   * Insert or delete RDF statements in an existing model.
+   * This is illegal for this model type.
+   *
+   * @param model  the local node identifying an existing model
+   * @param statements  the {@link Statements} to insert into the
+   *   <var>model</var>
+   * @param occurs  whether to assert the <var>statements</var>, or (if
+   *   <code>false</code>) to deny it
+   * @throws ResolverException The server should not ask this resolver to modify data.
+   */
+  public void modifyModel(long model, Statements statements, boolean occurs) throws ResolverException {
+    throw new ResolverException("Distributed models are read only");
+  }
+
+
+  /**
+   * Remove the cached model containing the contents of a URL.
+   * @throws ResolverException The server should not ask this resolver to modify data.
+   */
+  public void removeModel(long model) throws ResolverException {
+    throw new ResolverException("Distributed models cannot be removed");
+  }
+
+
+  /**
+   * Resolve a constraint against an RDF/XML document.
+   * @param constraint The constraint pattern to be resolved.
+   * @return A resolution for the constraint against a model.
+   * @throws IllegalArgumentException The constraint is <code>null</code>, or not set to a non-local model.
+   * @throws QueryException There was a problem resolving the constraint.
+   */
+  public Resolution resolve(Constraint constraint) throws QueryException {
+    if (logger.isDebugEnabled()) logger.debug("Resolve " + constraint);
+
+    // validate the parameter
+    if (constraint == null) throw new IllegalArgumentException();
+    ConstraintElement modelElement = constraint.getElement(3);
+    if (!(modelElement instanceof LocalNode)) throw new QueryException("Constraint not set to a distributed model.");
+    
+    return delegator.resolve(constraint, (LocalNode)modelElement);
+  }
+
+
+  /**
+   * Close all sessions and factories used by this resolver.
+   */
+  public void close() {
+    for (Session s: serverToSession.values()) {
+      try {
+        s.close();
+      } catch (QueryException qe) {
+        logger.error("Exception while closing session", qe);
+      }
+    }
+    for (SessionFactory sf: sessionFactories) {
+      try {
+        sf.close();
+      } catch (QueryException qe) {
+        logger.error("Exception while closing session", qe);
+      }
+    }
+  }
+
+
+  public void abort() {
+    // no-op
+  }
+}

Added: trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/DistributedResolverFactory.java
===================================================================
--- trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/DistributedResolverFactory.java	2007-03-28 08:52:38 UTC (rev 212)
+++ trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/DistributedResolverFactory.java	2007-03-30 12:48:50 UTC (rev 213)
@@ -0,0 +1,135 @@
+/*
+ * 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.opensource.org/licenses/osl-3.0.txt
+ *
+ * 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.
+ *
+ */
+
+package org.mulgara.resolver.distributed;
+
+// Java 2 standard packages
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+// Third party packages
+import org.apache.log4j.Logger;
+
+// Locally written packages
+import org.mulgara.resolver.spi.Resolver;
+import org.mulgara.resolver.spi.ResolverFactory;
+import org.mulgara.resolver.spi.ResolverFactoryException;
+import org.mulgara.resolver.spi.ResolverFactoryInitializer;
+import org.mulgara.resolver.spi.ResolverSession;
+import org.mulgara.resolver.spi.InitializerException;
+
+/**
+ * Factory for a resolver that delegates resolution to another server.
+ *
+ * @created 2007-03-20
+ * @author <a href="mailto:gearon at users.sourceforge.net">Paul Gearon</a>
+ * @version $Revision: $
+ * @modified $Date: $
+ * @maintenanceAuthor $Author: $
+ * @copyright &copy; 2007 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class DistributedResolverFactory implements ResolverFactory
+{
+  /** Logger. */
+  private static Logger logger = Logger.getLogger(DistributedResolverFactory.class.getName());
+
+  /** Collection of constructed resolvers. */
+  private Collection<DistributedResolver> openResolvers = new HashSet<DistributedResolver>();
+
+  /** Protocols which are handled by the served resolver. */
+  private static final String[] protocols = new String[] { "rmi" };
+
+  /** Set of the handled protocols. */
+  private static Set<String> protocolSet = new HashSet<String>();
+
+  // initialize the set to contain the elements of the array
+  static {
+    for (String p: protocols) protocolSet.add(p);
+  }
+
+  /**
+   * Instantiate a {@link DistributedResolverFactory}.
+   * @param initializer The system initializer to be registered with.
+   * @throws InitializerException An error occurred while registering this resolver type.
+   */
+  private DistributedResolverFactory(ResolverFactoryInitializer initializer) throws InitializerException {
+    // Validate "resolverFactoryInitializer" parameter
+    if (initializer == null) {
+      throw new IllegalArgumentException("Null \"resolverFactoryInitializer\" parameter");
+    }
+
+    // Claim the protocols supported by the resolver, and initialize the local protocol set
+    for (String p: protocols) {
+      initializer.addProtocol(p, this);
+      protocolSet.add(p);
+    }
+  }
+
+  /**
+   * {@inheritDoc ResolverFactory}
+   */
+  public void close() {
+    for (DistributedResolver r: openResolvers) r.close();
+  }
+
+  /**
+   * {@inheritDoc ResolverFactory}
+   */
+  public void delete() {
+    // null implementation
+  }
+
+
+  /**
+   * Register this resolver upon database startup.
+   *
+   * @param initializer the database within which to find or create
+   *        the various XML Schema resources
+   * @throws InitializerException if the XML Schema resources can't be found or created
+   */
+  public static ResolverFactory newInstance(ResolverFactoryInitializer initializer) throws InitializerException {
+    return new DistributedResolverFactory(initializer);
+  }
+
+
+  /**
+   * Obtain a distributed resolver.
+   *
+   * @param resolverSession the session which this query is local to
+   * @param canWrite {@inheritDoc}; ignored, as these models are read only
+   * @throws IllegalArgumentException if <var>resolverSession</var> is
+   *         <code>null</code> or canWrite is <code>true</code>
+   * @throws ResolverFactoryException {@inheritDoc}
+   */
+  public Resolver newResolver(
+      boolean canWrite, ResolverSession resolverSession, Resolver systemResolver
+  ) throws ResolverFactoryException {
+
+    if (resolverSession == null) throw new IllegalArgumentException("No session provided for the resolver!");
+    if (canWrite) throw new IllegalArgumentException("Cannot write to a remote model!");
+    DistributedResolver r = new DistributedResolver(resolverSession);
+    openResolvers.add(r);
+    return r;
+  }
+
+
+  /**
+   * Gets the protocols recognized by this resolver.
+   * @return A set of the recognized protocols.
+   */
+  public static Set<String> getProtocols() {
+    return protocolSet;
+  }
+}

Added: trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java
===================================================================
--- trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java	2007-03-28 08:52:38 UTC (rev 212)
+++ trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java	2007-03-30 12:48:50 UTC (rev 213)
@@ -0,0 +1,234 @@
+/*
+ * 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.opensource.org/licenses/osl-3.0.txt
+ *
+ * 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.
+ *
+ */
+
+package org.mulgara.resolver.distributed;
+
+import org.mulgara.query.Answer;
+import org.mulgara.query.Constraint;
+import org.mulgara.query.ConstraintElement;
+import org.mulgara.query.ConstraintImpl;
+import org.mulgara.query.LocalNode;
+import org.mulgara.query.ModelResource;
+import org.mulgara.query.Query;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.UnconstrainedAnswer;
+import org.mulgara.query.Variable;
+import org.mulgara.query.rdf.URIReferenceImpl;
+import org.mulgara.server.Session;
+import org.mulgara.server.SessionFactory;
+import org.mulgara.server.ServerInfo;
+import org.mulgara.server.NonRemoteSessionException;
+import org.mulgara.server.driver.SessionFactoryFinder;
+import org.mulgara.server.driver.SessionFactoryFinderException;
+import org.mulgara.resolver.spi.GlobalizeException;
+import org.mulgara.resolver.spi.Resolution;
+import org.mulgara.resolver.spi.ResolverException;
+import org.mulgara.resolver.spi.ResolverSession;
+
+import org.jrdf.graph.Node;
+import org.jrdf.graph.URIReference;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+
+/**
+ * Resolve a constraint across a socket.
+ *
+ * @created 2007-03-20
+ * @author <a href="mailto:gearon at users.sourceforge.net">Paul Gearon</a>
+ * @version $Revision: $
+ * @modified $Date: $
+ * @maintenanceAuthor $Author: $
+ * @copyright &copy; 2007 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class NetworkDelegator implements Delegator {
+
+  /** The session to delegate resolutions through. */
+  private ResolverSession session;
+
+  /** A cache of distributed sessions. */
+  private Map<URI,Session> sessionCache = new HashMap<URI,Session>();
+
+  /**
+   * A cache of distributed session factories.
+   * Each entry matches an entry in sessionCache, but a separate set for cleaner code.
+   */
+  private List<SessionFactory> factoryCache = new ArrayList<SessionFactory>();
+
+
+  /**
+   * Constructs a delegator, using a given session.
+   * @param session The session to delegate resolution through.
+   */
+  public NetworkDelegator(ResolverSession session) {
+    this.session = session;
+  }
+
+
+  /**
+   * Resolve a given constraint down to the appropriate resolution.
+   * @param localConstraint The constraint to resolve in local form.
+   * @param localModel The LocalNode containing the model.
+   * @throws QueryException A error occurred resolving the constraint.
+   */
+  public Resolution resolve(Constraint localConstraint, LocalNode localModel) throws QueryException {
+    // globalize the model
+    Node modelNode = globalizeNode(localModel);
+    if (!(modelNode instanceof URIReference)) throw new QueryException("Unexpected model type in constraint: (" + modelNode.getClass() + ")" + modelNode.toString());
+    // convert the node to a URIReferenceImpl, which includes the Value interface
+    URIReferenceImpl model = makeRefImpl((URIReference)modelNode);
+
+    // check if this model is really on a remote server
+    URI modelUri = model.getURI();
+    testForLocality(modelUri);
+
+    Answer ans = getModelSession(modelUri).query(globalizedQuery(localConstraint, model));
+    return new AnswerResolution(session, ans, localConstraint);
+  }
+
+
+  /**
+   * Create a query for a single constraint.
+   * @param constraint The local constraint to query for.
+   * @return The globalized query, looking for the single constraint.
+   */
+  protected Query globalizedQuery(Constraint localConstraint, URIReferenceImpl model) throws QueryException {
+    // convert the constraint to network compatible form
+    Constraint globalConstraint = new ConstraintImpl(
+            globalizeConstraintElement(localConstraint.getElement(0)),
+            globalizeConstraintElement(localConstraint.getElement(1)),
+            globalizeConstraintElement(localConstraint.getElement(2)),
+            model
+    );
+
+    // convert the variable set to a variable list
+    List<Variable> variables = new ArrayList<Variable>((Set<Variable>)globalConstraint.getVariables());
+    // build the new query
+    return new Query(variables, new ModelResource(model.getURI()), globalConstraint, null, Collections.EMPTY_LIST, null, 0, new UnconstrainedAnswer());
+  }
+
+
+  /**
+   * Convert a local node to a global value.
+   * @param localNode The node to globalize.
+   * @return The globalized node, either a BlankNode, a URIReference, or a Literal.
+   * @throws QueryException An error occurred while globalizing
+   */
+  protected Node globalizeNode(LocalNode localNode) throws QueryException {
+    try {
+      return session.globalize(localNode.getValue());
+    } catch (GlobalizeException ge) {
+      throw new QueryException("Error globalizing node: " + localNode, ge);
+    }
+  }
+
+
+  /**
+   * Converts a constraint element from local form into global form.
+   * @param localElement The constraint element in local form.
+   * @throws QueryException The constraint element could not be globalized.
+   */
+  protected ConstraintElement globalizeConstraintElement(ConstraintElement localElement) throws QueryException {
+    // return the element if it does not need to be converted
+    if (!(localElement instanceof LocalNode) || (localElement instanceof URIReferenceImpl)) return localElement;
+
+    // try {
+      // convert the reference to a Value
+      return makeRefImpl((URIReference)globalizeNode((LocalNode)localElement));
+    // } catch (ResolverException re) {
+      // throw new QueryException("Unable to globalize constraint element: " + localElement, re);
+    // }
+  }
+
+
+  /**
+   * Guarantee that a URIReference is a URIReferenceImpl, wrapping in a new URIReferenceImpl if needed.
+   * This method is required since URIReferenceImpl meets the Value interface when URIReference does not.
+   * @param ref The reference to convert if needed.
+   * @return A URIReferenceImpl matching ref.
+   */
+  protected URIReferenceImpl makeRefImpl(URIReference ref) {
+    return (ref instanceof URIReferenceImpl) ? (URIReferenceImpl)ref : new URIReferenceImpl(ref.getURI());
+  }
+
+
+  /**
+   * Tests if a model is really on a different server.  If the model is local then throw an exception.
+   * @param modelUri The URI of the model to test.
+   * @throws QueryException Thrown when the model is on the current system.
+   */
+  protected void testForLocality(URI modelUri) throws QueryException {
+    String protocol = modelUri.getScheme();
+    if (!DistributedResolverFactory.getProtocols().contains(protocol)) {
+      throw new IllegalStateException("Bad Protocol sent to distributed resolver.");
+    }
+    String host = modelUri.getHost();
+    if (ServerInfo.getHostnameAliases().contains(host)) {
+      throw new QueryException("Attempt to resolve a local model through the distributed resolver.");
+    }
+  }
+
+
+  /**
+   * Gets a remote session on a server specified by a given model URI.
+   * @param modelUri The URI of the model to get a session for.
+   * @return a remote session on the host found in the model.
+   * @throws QueryException Thrown when the model is a bad URI, or the session cannot be created.
+   */
+  protected Session getModelSession(URI modelUri) throws QueryException {
+    try {
+      // use the URI without the model fragment
+      return getServerSession(new URI(modelUri.getScheme(), modelUri.getSchemeSpecificPart(), ""));
+    } catch (URISyntaxException use) {
+      throw new AssertionError(use);
+    }
+  }
+
+
+  /**
+   * Retrieves a session for a given server URI, using a cached value if possible.
+   * @param serverUri The URI of the server to get a session for.
+   * @return a remote session on the host specified in serverUri.
+   * @throws QueryException Thrown when the session cannot be created.
+   */
+  protected Session getServerSession(URI serverUri) throws QueryException {
+    Session session = sessionCache.get(serverUri);
+    return (session != null) ? session : newSession(serverUri);
+  }
+
+
+  /**
+   * Get a new session and save in the cache.
+   * @param serverUri The URI of the server to create a session for.
+   * @return A new remote session.
+   * @throws QueryException There was a problem creating the session.
+   */
+  protected Session newSession(URI serverUri) throws QueryException {
+    try {
+      // The factory won't be in the cache, as a corresponding session would have already been created.
+      SessionFactory sessionFactory = SessionFactoryFinder.newSessionFactory(serverUri, true);
+      factoryCache.add(sessionFactory);
+      // now create the session
+      Session session = sessionFactory.newSession();
+      sessionCache.put(serverUri, session);
+      return session;
+    } catch (NonRemoteSessionException nrse) {
+      throw new QueryException("State Error: non-local URI was mapped to a local session", nrse);
+    } catch (SessionFactoryFinderException sffe) {
+      throw new QueryException("Unable to get a session to the server", sffe);
+    }
+  }
+
+}

Added: trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/package.html
===================================================================
--- trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/package.html	2007-03-28 08:52:38 UTC (rev 212)
+++ trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/package.html	2007-03-30 12:48:50 UTC (rev 213)
@@ -0,0 +1,13 @@
+<html>
+<head>
+<title>Distributed Resolver</title>
+</head>
+<body>
+<abstract>
+Distributed Resolver.
+</abstract>
+<p>
+This package is an internal resolver which delegates resolution to a remote Mulgara server.
+</p>
+</body>
+</html>

Added: trunk/src/jar/resolver-distributed/resolver-distributed-build.properties
===================================================================
--- trunk/src/jar/resolver-distributed/resolver-distributed-build.properties	2007-03-28 08:52:38 UTC (rev 212)
+++ trunk/src/jar/resolver-distributed/resolver-distributed-build.properties	2007-03-30 12:48:50 UTC (rev 213)
@@ -0,0 +1,15 @@
+#
+# Properties used by the Distributed Resolver module
+#
+
+# Module Name
+resolver-distributed.name          = Distributed Resolver
+
+# General module properties
+resolver-distributed.conf.dir      = ${resolver.conf.dir}/distributed
+resolver-distributed.src.dir       = ${jar.src.dir}/resolver-distributed
+resolver-distributed.obj.dir       = ${jar.obj.dir}/resolver-distributed
+resolver-distributed.dist.dir      = ${bin.dir}
+resolver-distributed.test.dir      = ${test.dir}/resolver-distributed
+resolver-distributed.jxtest.dir    = ${jxtest.dir}/resolver-distributed
+resolver-distributed.jar           = resolver-distributed-base-${mulgara-version}.jar


Property changes on: trunk/src/jar/resolver-distributed/resolver-distributed-build.properties
___________________________________________________________________
Name: svn:executable
   + *




More information about the Mulgara-svn mailing list