Author: reto
Date: Mon Jul  8 20:35:58 2013
New Revision: 1500935

URL: http://svn.apache.org/r1500935
Log:
CLEREZZA-468: routing implemented in TcManager. Changes to API to accept 
DefaultGraph as URI rather than TripleCollection

Modified:
    
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/QueryableTcProvider.java
    
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java
    
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java
    
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/sparql/SparqlPreParser.java
    
clerezza/trunk/rdf.jena.tdb.storage/src/main/java/org/apache/clerezza/rdf/jena/tdb/storage/BaseTdbTcProvider.java
    clerezza/trunk/site/src/main/scala/TitledContentRenderlet.scala

Modified: 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/QueryableTcProvider.java
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/QueryableTcProvider.java?rev=1500935&r1=1500934&r2=1500935&view=diff
==============================================================================
--- 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/QueryableTcProvider.java
 (original)
+++ 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/QueryableTcProvider.java
 Mon Jul  8 20:35:58 2013
@@ -19,6 +19,7 @@
 package org.apache.clerezza.rdf.core.access;
 
 import org.apache.clerezza.rdf.core.TripleCollection;
+import org.apache.clerezza.rdf.core.UriRef;
 import org.apache.clerezza.rdf.core.sparql.query.Query;
 
 /**
@@ -37,18 +38,6 @@ public interface QueryableTcProvider ext
      *            FROM clause is present
      * @return the resulting ResultSet, Graph or Boolean value
      */
-    public Object executeSparqlQuery(String query, TripleCollection 
defaultGraph);
+    public Object executeSparqlQuery(String query, UriRef defaultGraphUri);
 
-    /**
-     * Executes any sparql query. The type of the result object will vary
-     * depending on the type of the query.
-     * 
-     * @param query
-     *            the sparql query to execute
-     * @param defaultGraph
-     *            the default graph against which to execute the query if not
-     *            FROM clause is present
-     * @return the resulting ResultSet, Graph or Boolean value
-     */
-    public Object executeSparqlQuery(Query query, TripleCollection 
defaultGraph);
 }

Modified: 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java?rev=1500935&r1=1500934&r2=1500935&view=diff
==============================================================================
--- 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java
 (original)
+++ 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcManager.java
 Mon Jul  8 20:35:58 2013
@@ -38,8 +38,10 @@ import org.apache.clerezza.rdf.core.acce
 import org.apache.clerezza.rdf.core.impl.WriteBlockedMGraph;
 import org.apache.clerezza.rdf.core.impl.WriteBlockedTripleCollection;
 import org.apache.clerezza.rdf.core.sparql.NoQueryEngineException;
+import org.apache.clerezza.rdf.core.sparql.ParseException;
 import org.apache.clerezza.rdf.core.sparql.QueryEngine;
 import org.apache.clerezza.rdf.core.sparql.ResultSet;
+import org.apache.clerezza.rdf.core.sparql.SparqlPreParser;
 import org.apache.clerezza.rdf.core.sparql.query.AskQuery;
 import org.apache.clerezza.rdf.core.sparql.query.ConstructQuery;
 import org.apache.clerezza.rdf.core.sparql.query.DescribeQuery;
@@ -56,67 +58,71 @@ import org.osgi.framework.ServiceRegistr
 import org.osgi.service.component.ComponentContext;
 
 /**
- * This class implements <code>TcManager</code>, delegating the actual
- * provision and creation of Graphs or MGraphs to registered 
<code>TcProvider</code>s. The class
- * attempts to satisfy the request using the register 
<code>WeightedTcProvider</code>
- * in decreasing order of weight. If multiple providers have the same weight 
the
- * lexicographical order of the fully qualified class name determines which one
- * is used, namely the one that occurs earlier. If a call to a registered 
provider
- * causes an <code>IllegalArgumentException</code>, 
<code>NoSuchEntityException</code>
- * or <code>UnsupportedOperationException</code> then the call is delegated to 
the
+ * This class implements
+ * <code>TcManager</code>, delegating the actual provision and creation of
+ * Graphs or MGraphs to registered
+ * <code>TcProvider</code>s. The class attempts to satisfy the request using 
the
+ * register
+ * <code>WeightedTcProvider</code> in decreasing order of weight. If multiple
+ * providers have the same weight the lexicographical order of the fully
+ * qualified class name determines which one is used, namely the one that 
occurs
+ * earlier. If a call to a registered provider causes an
+ * <code>IllegalArgumentException</code>,
+ * <code>NoSuchEntityException</code> or
+ * <code>UnsupportedOperationException</code> then the call is delegated to the
  * next provider.
  *
  * Only one instance of this class should exist in a system, the public no
- * argument constructor is meant for initialization by dependency injection 
systems
- * such as OSGi-DS. Applications should use the static 
<code>getInstance()</code>
- * method if they aren't using a framework that injects them the instance.
+ * argument constructor is meant for initialization by dependency injection
+ * systems such as OSGi-DS. Applications should use the static
+ * <code>getInstance()</code> method if they aren't using a framework that
+ * injects them the instance.
  *
- * This class returns <code>LockableMGraph</code>s a subtype of 
<code>MGraph</code>
- * that allows read/write locks.
- * 
- * This class also registers all TripleCollections as services with the 
property 
+ * This class returns
+ * <code>LockableMGraph</code>s a subtype of
+ * <code>MGraph</code> that allows read/write locks.
+ *
+ * This class also registers all TripleCollections as services with the 
property
  * 'name' indicating there name.
- * 
- * Security checks are done when a TripleCollection is retrieved. The returned 
- * TripleCollection will do no further security checks. Because of this it 
should 
- * not be passed to a context where different access control applies. If an 
MGraph
- * is retrieved without having write permission the returned mGraph will be 
read-only.
- * 
- * If a TripleCollections needs to passed around across different security 
contexts
- * the one retrieved from the OSGi service whiteboard should be used as this 
- * performs access control on every access.
+ *
+ * Security checks are done when a TripleCollection is retrieved. The returned
+ * TripleCollection will do no further security checks. Because of this it
+ * should not be passed to a context where different access control applies. If
+ * an MGraph is retrieved without having write permission the returned mGraph
+ * will be read-only.
+ *
+ * If a TripleCollections needs to passed around across different security
+ * contexts the one retrieved from the OSGi service whiteboard should be used 
as
+ * this performs access control on every access.
  *
  * @author reto, mir, hasan
- * 
+ *
  */
 @Component
 @Service(TcManager.class)
-@Reference(name="weightedTcProvider", policy=ReferencePolicy.DYNAMIC,
-        referenceInterface=WeightedTcProvider.class,
-        cardinality=ReferenceCardinality.MANDATORY_MULTIPLE)
+@Reference(name = "weightedTcProvider", policy = ReferencePolicy.DYNAMIC,
+        referenceInterface = WeightedTcProvider.class,
+        cardinality = ReferenceCardinality.MANDATORY_MULTIPLE)
 public class TcManager extends TcProviderMultiplexer {
 
     private static volatile TcManager instance;
-
     private TcAccessController tcAccessController = new 
TcAccessController(this);
-
     private Map<UriRef, ServiceRegistration> serviceRegistrations = Collections
             .synchronizedMap(new HashMap<UriRef, ServiceRegistration>());
-
-
-    @Reference(policy=ReferencePolicy.DYNAMIC,
-            cardinality=ReferenceCardinality.MANDATORY_UNARY)
+    @Reference(policy = ReferencePolicy.DYNAMIC,
+            cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected QueryEngine queryEngine;
-
+    @Reference
+    protected SparqlPreParser sparqlPreParser;
     private ComponentContext componentContext;
     private Collection<UriRef> mGraphsToRegisterOnActivation = new 
HashSet<UriRef>();
     private Collection<UriRef> graphsToRegisterOnActivation = new 
HashSet<UriRef>();
 
-
     /**
      * the constructor sets the singleton instance to allow instantiation by
      * OSGi-DS. This constructor should not be called except by OSGi-DS,
-     * otherwise the static <code>getInstance</code> method should be used.
+     * otherwise the static
+     * <code>getInstance</code> method should be used.
      */
     public TcManager() {
         TcManager.instance = this;
@@ -127,14 +133,14 @@ public class TcManager extends TcProvide
      * created (e.g. by OSGi declarative services) this instance is returned,
      * otherwise a new instance is created and providers are injected using the
      * service provider interface (META-INF/services/)
-     * 
+     *
      * @return the singleton instance
      */
     public static TcManager getInstance() {
         if (instance == null) {
             synchronized (TcManager.class) {
                 if (instance == null) {
-                    new TcManager();
+                    instance = new TcManager();
                     Iterator<WeightedTcProvider> weightedProviders = 
ServiceLoader
                             .load(WeightedTcProvider.class).iterator();
                     while (weightedProviders.hasNext()) {
@@ -151,6 +157,7 @@ public class TcManager extends TcProvide
                         System.out.println("QE: "
                                 + instance.queryEngine.getClass());
                     }
+                    instance.sparqlPreParser = new SparqlPreParser(instance);
                 }
             }
         }
@@ -204,8 +211,6 @@ public class TcManager extends TcProvide
         return super.getTriples(name);
     }
 
-    
-
     @Override
     public LockableMGraph createMGraph(UriRef name)
             throws UnsupportedOperationException {
@@ -267,16 +272,24 @@ public class TcManager extends TcProvide
 
     /**
      * Executes any sparql query. The type of the result object will vary
-     * depending on the type of the query.
-     * 
-     * @param query
-     *            the sparql query to execute
-     * @param defaultGraph
-     *            the default graph against which to execute the query if not
-     *            FROM clause is present
+     * depending on the type of the query. If the defaultGraph is available
+     * in this TcManages executeSparqlQuery(String, UriRef) should be used 
instead.
+     *
+     * @param query the sparql query to execute
+     * @param defaultGraph the default graph against which to execute the query
+     * if no FROM clause is present
      * @return the resulting ResultSet, Graph or Boolean value
      */
-    public Object executeSparqlQuery(String query, TripleCollection 
defaultGraph) {
+    public Object executeSparqlQuery(String query, TripleCollection 
defaultGraph) throws ParseException {
+        final UriRef defaultGraphName = new 
UriRef("urn:x-temp:/kjsfadfhfasdffds");
+        final Set<UriRef> referencedGraphs = 
sparqlPreParser.getReferredGraphs(query, defaultGraphName);
+        TcProvider singleTargetTcProvider = null;
+        if ((referencedGraphs != null) && 
(!referencedGraphs.contains(defaultGraphName))) {
+            singleTargetTcProvider = 
getSingleTargetTcProvider(referencedGraphs);
+        }
+        if ((singleTargetTcProvider != null) && (singleTargetTcProvider 
instanceof QueryableTcProvider)) {
+            return 
((QueryableTcProvider)singleTargetTcProvider).executeSparqlQuery(query, null);
+        }
         final QueryEngine queryEngine = this.queryEngine;
         if (queryEngine != null) {
             return queryEngine.execute(this, defaultGraph, query);
@@ -284,18 +297,33 @@ public class TcManager extends TcProvide
             throw new NoQueryEngineException();
         }
     }
+    
+    public Object executeSparqlQuery(String query, UriRef defaultGraphName) 
throws ParseException {
+        final Set<UriRef> referencedGraphs = 
sparqlPreParser.getReferredGraphs(query, defaultGraphName);
+        TcProvider singleTargetTcProvider = null;
+        if ((referencedGraphs != null)) {
+            singleTargetTcProvider = 
getSingleTargetTcProvider(referencedGraphs);
+        }
+        if ((singleTargetTcProvider != null) && (singleTargetTcProvider 
instanceof QueryableTcProvider)) {
+            return 
((QueryableTcProvider)singleTargetTcProvider).executeSparqlQuery(query, 
defaultGraphName);
+        }
+        final QueryEngine queryEngine = this.queryEngine;
+        if (queryEngine != null) {
+            return queryEngine.execute(this, 
this.getTriples(defaultGraphName), query);
+        } else {
+            throw new NoQueryEngineException();
+        }
+    }
 
     /**
      * Executes any sparql query. The type of the result object will vary
      * depending on the type of the query.
-     * 
-     * @param query
-     *            the sparql query to execute
-     * @param defaultGraph
-     *            the default graph against which to execute the query if not
-     *            FROM clause is present
+     *
+     * @param query the sparql query to execute
+     * @param defaultGraph the default graph against which to execute the query
+     * if no FROM clause is present
      * @return the resulting ResultSet, Graph or Boolean value
-     * 
+     *
      * @deprecated Query is discontinued
      */
     @Deprecated
@@ -310,70 +338,62 @@ public class TcManager extends TcProvide
 
     /**
      * Executes a sparql SELECT query.
-     * 
-     * @param query
-     *            the sparql SELECT query to execute
-     * @param defaultGraph
-     *            the default graph against which to execute the query if not
-     *            FROM clause is present
+     *
+     * @param query the sparql SELECT query to execute
+     * @param defaultGraph the default graph against which to execute the query
+     * if not FROM clause is present
      * @return the resulting ResultSet
      * @deprecated Query is discontinued
      */
     @Deprecated
     public ResultSet executeSparqlQuery(SelectQuery query,
             TripleCollection defaultGraph) {
-        return (ResultSet) executeSparqlQuery((Query)query, defaultGraph);
+        return (ResultSet) executeSparqlQuery((Query) query, defaultGraph);
     }
 
     /**
      * Executes a sparql ASK query.
-     * 
-     * @param query
-     *            the sparql ASK query to execute
-     * @param defaultGraph
-     *            the default graph against which to execute the query if not
-     *            FROM clause is present
+     *
+     * @param query the sparql ASK query to execute
+     * @param defaultGraph the default graph against which to execute the query
+     * if not FROM clause is present
      * @return the boolean value this query evaluates to
      * @deprecated Query is discontinued
      */
     @Deprecated
     public boolean executeSparqlQuery(AskQuery query,
             TripleCollection defaultGraph) {
-        return (Boolean) executeSparqlQuery((Query)query, defaultGraph);
+        return (Boolean) executeSparqlQuery((Query) query, defaultGraph);
     }
 
     /**
      * Executes a sparql DESCRIBE query.
-     * 
-     * @param query
-     *            the sparql DESCRIBE query to execute
-     * @param defaultGraph
-     *            the default graph against which to execute the query if not
-     *            FROM clause is present
+     *
+     * @param query the sparql DESCRIBE query to execute
+     * @param defaultGraph the default graph against which to execute the query
+     * if not FROM clause is present
      * @return the resulting Graph
      * @deprecated Query is discontinued
      */
     @Deprecated
     public Graph executeSparqlQuery(DescribeQuery query,
             TripleCollection defaultGraph) {
-        return (Graph) executeSparqlQuery((Query)query, defaultGraph);
+        return (Graph) executeSparqlQuery((Query) query, defaultGraph);
     }
 
     /**
      * Executes a sparql CONSTRUCT query.
-     * 
-     * @param query
-     *            the sparql CONSTRUCT query to execute
-     * @param defaultGraph
-     *            the default graph against which to execute the query if not
-     *            FROM clause is present
+     *
+     * @param query the sparql CONSTRUCT query to execute
+     * @param defaultGraph the default graph against which to execute the query
+     * if not FROM clause is present
      * @return the resulting Graph
      * @deprecated Query is discontinued
      */
     @Deprecated
     public Graph executeSparqlQuery(ConstructQuery query,
             TripleCollection defaultGraph) {
-        return (Graph) executeSparqlQuery((Query)query, defaultGraph);
+        return (Graph) executeSparqlQuery((Query) query, defaultGraph);
     }
 
     /**
@@ -387,8 +407,7 @@ public class TcManager extends TcProvide
     /**
      * Registers a provider
      *
-     * @param provider
-     *            the provider to be registered
+     * @param provider the provider to be registered
      */
     protected void bindWeightedTcProvider(WeightedTcProvider provider) {
         addWeightedTcProvider(provider);
@@ -397,8 +416,7 @@ public class TcManager extends TcProvide
     /**
      * Unregister a provider
      *
-     * @param provider
-     *            the provider to be deregistered
+     * @param provider the provider to be deregistered
      */
     protected void unbindWeightedTcProvider(
             WeightedTcProvider provider) {
@@ -429,13 +447,13 @@ public class TcManager extends TcProvide
         String[] interfaceNames;
         Object service;
         if (isMGraph) {
-            interfaceNames = new String[] {
+            interfaceNames = new String[]{
                 MGraph.class.getName(),
                 LockableMGraph.class.getName()
             };
             service = new MGraphServiceFactory(this, name, tcAccessController);
         } else {
-            interfaceNames = new String[] {Graph.class.getName()};
+            interfaceNames = new String[]{Graph.class.getName()};
             service = new GraphServiceFactory(this, name, tcAccessController);
         }
         final int bundleState = 
componentContext.getBundleContext().getBundle().getState();
@@ -456,4 +474,21 @@ public class TcManager extends TcProvide
             serviceRegistrations.remove(name);
         }
     }
+
+    private TcProvider getSingleTargetTcProvider(final Set<UriRef> 
referencedGraphs) {
+        TcProvider singleTargetTcProvider = null;
+        for (WeightedTcProvider provider : providerList) {
+            final Set<UriRef> providerTripleCollections = 
provider.listTripleCollections();
+            if (providerTripleCollections.containsAll(referencedGraphs)) {
+               singleTargetTcProvider = provider;
+               break; //success
+            }
+            for (UriRef graphName : referencedGraphs) {
+                if (providerTripleCollections.contains(graphName)) {
+                    break; //failure
+                }
+            }      
+        }
+        return singleTargetTcProvider;
+    }
 }

Modified: 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java?rev=1500935&r1=1500934&r2=1500935&view=diff
==============================================================================
--- 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java
 (original)
+++ 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/access/TcProviderMultiplexer.java
 Mon Jul  8 20:35:58 2013
@@ -44,7 +44,7 @@ import org.apache.clerezza.rdf.core.spar
  */
 public class TcProviderMultiplexer implements TcProvider {
 
-    private SortedSet<WeightedTcProvider> providerList = new 
TreeSet<WeightedTcProvider>(
+    protected SortedSet<WeightedTcProvider> providerList = new 
TreeSet<WeightedTcProvider>(
             new WeightedProviderComparator());
     /**
      * Mapping to LockableMGraph's and ServiceRegistration using their URI's 
as key.

Modified: 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/sparql/SparqlPreParser.java
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/sparql/SparqlPreParser.java?rev=1500935&r1=1500934&r2=1500935&view=diff
==============================================================================
--- 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/sparql/SparqlPreParser.java
 (original)
+++ 
clerezza/trunk/rdf.core/src/main/java/org/apache/clerezza/rdf/core/sparql/SparqlPreParser.java
 Mon Jul  8 20:35:58 2013
@@ -51,6 +51,19 @@ public class SparqlPreParser {
         this.tcManager = tcManager;
     }
 
+    /**
+     * This returns the graphs targeted by the queryString. This are the the 
+     * triple collections explicitely refreded in FROM and FROM NAMED clauses, 
+     * and if the queryString contains no FROM clause the defaultGraph.
+     * 
+     * For queries that are not limited to specified set of graphs null is 
returned.
+     * 
+     * 
+     * @param queryString
+     * @param defaultGraph
+     * @return 
+     * @throws ParseException 
+     */
     public Set<UriRef> getReferredGraphs(String queryString, UriRef 
defaultGraph) throws ParseException {
         Set<UriRef> referredGraphs;
         JavaCCGeneratedSparqlPreParser parser = new 
JavaCCGeneratedSparqlPreParser(new StringReader(queryString));

Modified: 
clerezza/trunk/rdf.jena.tdb.storage/src/main/java/org/apache/clerezza/rdf/jena/tdb/storage/BaseTdbTcProvider.java
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/rdf.jena.tdb.storage/src/main/java/org/apache/clerezza/rdf/jena/tdb/storage/BaseTdbTcProvider.java?rev=1500935&r1=1500934&r2=1500935&view=diff
==============================================================================
--- 
clerezza/trunk/rdf.jena.tdb.storage/src/main/java/org/apache/clerezza/rdf/jena/tdb/storage/BaseTdbTcProvider.java
 (original)
+++ 
clerezza/trunk/rdf.jena.tdb.storage/src/main/java/org/apache/clerezza/rdf/jena/tdb/storage/BaseTdbTcProvider.java
 Mon Jul  8 20:35:58 2013
@@ -14,6 +14,7 @@ import com.hp.hpl.jena.query.QueryExecEx
 import com.hp.hpl.jena.query.QueryExecution;
 import com.hp.hpl.jena.query.QueryExecutionFactory;
 import com.hp.hpl.jena.query.QueryFactory;
+import org.apache.clerezza.rdf.core.UriRef;
 
 abstract class BaseTdbTcProvider implements QueryableTcProvider{
 
@@ -28,13 +29,14 @@ abstract class BaseTdbTcProvider impleme
        // 
------------------------------------------------------------------------
 
     @Override
-    public Object executeSparqlQuery(final String query, TripleCollection 
defaultGraph) {
+    public Object executeSparqlQuery(final String query, UriRef defaultGraph) {
                // Missing permission (java.lang.RuntimePermission 
getClassLoader)
                // when calling QueryFactory.create causes 
ExceptionInInitializerError
                // to be thrown.
                // QueryExecutionFactory.create requires
                // (java.io.FilePermission [etc/]location-mapping.* read)
                // Thus, they are placed within doPrivileged
+        getDataset().setDefaultModel(null);
                QueryExecution qexec = AccessController
                                .doPrivileged(new 
PrivilegedAction<QueryExecution>() {
 
@@ -67,10 +69,6 @@ abstract class BaseTdbTcProvider impleme
                }
     }
     
-    @Override
-    public Object executeSparqlQuery(Query query, TripleCollection 
defaultGraph) {
-       return executeSparqlQuery(query.toString(), defaultGraph);
-    }
 
        // 
------------------------------------------------------------------------
        // Getters / Setters

Modified: clerezza/trunk/site/src/main/scala/TitledContentRenderlet.scala
URL: 
http://svn.apache.org/viewvc/clerezza/trunk/site/src/main/scala/TitledContentRenderlet.scala?rev=1500935&r1=1500934&r2=1500935&view=diff
==============================================================================
--- clerezza/trunk/site/src/main/scala/TitledContentRenderlet.scala (original)
+++ clerezza/trunk/site/src/main/scala/TitledContentRenderlet.scala Mon Jul  8 
20:35:58 2013
@@ -53,7 +53,7 @@ class TitledContentRenderlet extends SRe
                                                                        <ul 
class="nav-entries">
                                                                                
<li>{menuLink("/getting-started/","Getting Started")}</li>
                                                                                
<li>{menuLink("/architecture/","The Apache Clerezza Stack")}</li>
-                                                                               
<li><a href="http://clerezza.apache.org/apidoc"; target="_blank">API 
docs</a></li>
+                                                                               
<li><a href="http://clerezza.apache.org/apidocs/"; target="_blank">API 
docs</a></li>
                                                                                
<li>{menuLink("/faq/","FAQ")}</li>
                                                                        </ul>
                                                                </li>
@@ -96,7 +96,7 @@ class TitledContentRenderlet extends SRe
 
                                                                                
                <li><a href="/getting-started/">Getting Started</a></li>
                                                                                
                <li><a href="/architecture/">The Apache Clerezza Stack</a></li>
-                                                                               
                <li><a href="http://clerezza,apache.org/apidoc"; 
target="_blank">API docs</a></li>
+                                                                               
                <li><a href="http://clerezza,apache.org/apidocs/"; 
target="_blank">API docs</a></li>
                                                                                
                <li><a href="/faq/">FAQ</a></li>
                                                                                
        </ul>
 


Reply via email to