[Yanel-commits] rev 27403 - in public/yanel/trunk/src: core/java/org/wyona/yanel/core/source core/java/org/wyona/yanel/core/transformation impl/java/org/wyona/yanel/impl/resources

simon at wyona.com simon at wyona.com
Tue Sep 18 11:33:04 CEST 2007


Author: simon
Date: 2007-09-18 11:33:04 +0200 (Tue, 18 Sep 2007)
New Revision: 27403

Added:
   public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/YanelRepositoryResolver.java
Modified:
   public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/ResourceResolver.java
   public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/SourceException.java
   public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/SourceResolver.java
   public/yanel/trunk/src/core/java/org/wyona/yanel/core/transformation/XIncludeTransformer.java
   public/yanel/trunk/src/impl/java/org/wyona/yanel/impl/resources/BasicXMLResource.java
Log:
added yanelrepo protocol. see bug#5555

Modified: public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/ResourceResolver.java
===================================================================
--- public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/ResourceResolver.java	2007-09-18 08:28:44 UTC (rev 27402)
+++ public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/ResourceResolver.java	2007-09-18 09:33:04 UTC (rev 27403)
@@ -11,20 +11,24 @@
 import org.wyona.yanel.core.api.attributes.ViewableV2;
 import org.wyona.yanel.core.attributes.viewable.View;
 import org.wyona.yanel.core.util.ResourceAttributeHelper;
-import org.xml.sax.InputSource;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
 
+
 /**
  * Source resolver for yanel resources.
- * It returns an InputSource made from the view of the resource with
+ * It returns an Source made from the view of the resource with
  * the given uri. It will look for the resource in the realm of the resource
  * which is passed to the constructor of this ResourceResolver.
  * 
  * It uses the following URI syntax:
  * yanelresource:/path/to/resource
  * 
+ * TODO: support access to other realms, e.g. yanelresource:realmid:path/to/resource
  * TODO: support relative uris?
  */
-public class ResourceResolver implements SourceResolver {
+public class ResourceResolver implements URIResolver {
 
     private static Category log = Category.getInstance(ResourceResolver.class);
     
@@ -37,12 +41,8 @@
     }
     
     /**
-     * @see org.wyona.yanel.core.source.SourceResolver#resolve(java.lang.String)
      */
-    public InputSource resolve(String uri) throws SourceException {
-        if (log.isDebugEnabled()) {
-            log.debug("resolving: " + uri);
-        }
+    public Source resolve(String uri, String base) throws SourceException {
         String prefix = SCHEME + ":";
         if (!uri.startsWith(prefix)) {
             log.error("unknown scheme: " + uri);
@@ -64,10 +64,10 @@
                     log.debug("including document: " + viewV1path);
                 }
                 View view = ((ViewableV1) targetResource).getView(new Path(viewV1path), null);
-                return new InputSource(view.getInputStream());
+                return new StreamSource(view.getInputStream());
             } else if (ResourceAttributeHelper.hasAttributeImplemented(targetResource, "Viewable", "2")) {
                 View view = ((ViewableV2) targetResource).getView(null);
-                return new InputSource(view.getInputStream());
+                return new StreamSource(view.getInputStream());
             } else {
                 log.warn("Resource is not viewable: " + uri);
                 return null;

Modified: public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/SourceException.java
===================================================================
--- public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/SourceException.java	2007-09-18 08:28:44 UTC (rev 27402)
+++ public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/SourceException.java	2007-09-18 09:33:04 UTC (rev 27403)
@@ -1,16 +1,18 @@
 package org.wyona.yanel.core.source;
 
+import javax.xml.transform.TransformerException;
+
 /**
  * 
  */
-public class SourceException extends Exception {
+public class SourceException extends TransformerException {
 
     /**
      *
      */
-    public SourceException() {
-        super();
-    }
+    //public SourceException() {
+        //super();
+    //}
 
     /**
      *

Modified: public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/SourceResolver.java
===================================================================
--- public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/SourceResolver.java	2007-09-18 08:28:44 UTC (rev 27402)
+++ public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/SourceResolver.java	2007-09-18 09:33:04 UTC (rev 27403)
@@ -1,13 +1,68 @@
 package org.wyona.yanel.core.source;
 
-import org.xml.sax.InputSource;
+import java.util.HashMap;
 
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+
+import org.apache.log4j.Category;
+import org.wyona.yanel.core.Resource;
+
 /**
- * Resolves a URI to a InputSource.
- * TODO: make this more generic, i.e. return a more generic source object.
+ * Resolves a URI to a Source.
+ * This class just checks the scheme and delegates to the scheme-specific resolver.
+ * 
+ * TODO: allow to configure schemes in a config file
  */
-public interface SourceResolver {
+public class SourceResolver implements URIResolver {
 
-    InputSource resolve(String uri) throws SourceException;
+    private static Category log = Category.getInstance(SourceResolver.class);
     
+    private HashMap resolvers;
+    private Resource resource;
+    
+    public SourceResolver(Resource resource) {
+        this.resource = resource;
+        this.resolvers = new HashMap();
+    }
+    
+    public Source resolve(String uri, String base) throws SourceException {
+        if (log.isDebugEnabled()) {
+            log.debug("resolving: " + uri);
+        }
+        int colonIndex = uri.indexOf(":");
+        if (colonIndex <= 0) {
+            throw new SourceException("invalid url syntax (missing scheme): " + uri);
+        }
+        String scheme = uri.substring(0, colonIndex);
+        URIResolver resolver = getResolver(scheme);
+        if (resolver != null) {
+            try {
+                return resolver.resolve(uri, base);
+            } catch (TransformerException e) {
+                throw new SourceException(e.getMessage(), e);
+            }
+        } else {
+            throw new SourceException("unknown scheme: " + scheme);
+        }
+    }
+    
+    private URIResolver getResolver(String scheme) {
+        URIResolver resolver = null;
+        if (this.resolvers.containsKey(scheme)) {
+            resolver = (URIResolver)this.resolvers.get(scheme);
+        } else {
+            if (scheme.equals("yanelresource")) {
+                resolver = new ResourceResolver(this.resource);
+                this.resolvers.put(scheme, resolver);
+            } else if (scheme.equals("yanelrepo")) {
+                resolver = new YanelRepositoryResolver(this.resource);
+                this.resolvers.put(scheme, resolver);
+                //resolver = new RepositoryResolver(this.resource);
+            }
+        }
+        return resolver;
+    }
+    
 }

Added: public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/YanelRepositoryResolver.java
===================================================================
--- public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/YanelRepositoryResolver.java	                        (rev 0)
+++ public/yanel/trunk/src/core/java/org/wyona/yanel/core/source/YanelRepositoryResolver.java	2007-09-18 09:33:04 UTC (rev 27403)
@@ -0,0 +1,93 @@
+package org.wyona.yanel.core.source;
+
+import java.io.InputStream;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.log4j.Category;
+import org.wyona.yanel.core.Resource;
+import org.wyona.yanel.core.Yanel;
+import org.wyona.yanel.core.map.Realm;
+import org.wyona.yarep.core.Repository;
+
+
+/**
+ * Resolves URIs which point to a node in a repository of a yanel realm.
+ * 
+ * Syntax:
+ * yanelrepo:{realmID}:{repoID}:{path}
+ * yanelrepo:{realmID}:{path}
+ * yanelrepo:{path}
+ * 
+ * e.g.
+ * yanelrepo:myrealm:myrepo:/foo/bar.xml
+ * yanelrepo:myrealm:/foo/bar.xml
+ * yanelrepo:/foo/bar.xml
+ * 
+ */
+public class YanelRepositoryResolver implements URIResolver {
+
+    private static Category log = Category.getInstance(YanelRepositoryResolver.class);
+
+    private static final String SCHEME = "yanelrepo";
+    
+    private Resource resource;
+    
+    public YanelRepositoryResolver(Resource resource) {
+        this.resource = resource;
+    }
+
+    public Source resolve(String href, String base) throws SourceException {
+        String prefix = SCHEME + ":";
+        
+        // only accept 'yanelrepo:' URIs
+        if (href == null || !href.startsWith(prefix)){
+            return null;
+        }
+
+        String[] tokens = href.split(":");
+        String realmID = null;
+        String repoID = null;
+        String path = null;
+        if (tokens.length == 2) {
+            path = tokens[1];
+        } else if (tokens.length == 3) {
+            realmID = tokens[1];
+            path = tokens[2];
+        } else if (tokens.length == 4) {
+            realmID = tokens[1];
+            repoID = tokens[2];
+            path = tokens[3];
+        } else {
+            throw new SourceException("invalid url syntax: " + href);
+        }
+        
+        // we can't resolve to a Collection (indicated by a trailing '/')
+        if (path.endsWith("/")){
+            return null;
+        }
+
+        try {
+            Realm realm;
+            if (realmID != null) {
+                realm = Yanel.getInstance().getRealmConfiguration().getRealm(realmID);
+            } else {
+                realm = resource.getRealm();
+            }
+            Repository repo;
+            if (repoID != null) {
+                repo = realm.getRepository(repoID);
+            } else {
+                repo = realm.getRepository();
+            }
+            InputStream in = repo.getNode(path).getInputStream();
+            return new StreamSource(in);
+        } catch (Exception e) {
+            String errorMsg = "Could not resolve URI: " + href + ": " + e.toString();
+            log.error(errorMsg, e);
+            throw new SourceException(errorMsg, e);
+        }
+    }
+}

Modified: public/yanel/trunk/src/core/java/org/wyona/yanel/core/transformation/XIncludeTransformer.java
===================================================================
--- public/yanel/trunk/src/core/java/org/wyona/yanel/core/transformation/XIncludeTransformer.java	2007-09-18 08:28:44 UTC (rev 27402)
+++ public/yanel/trunk/src/core/java/org/wyona/yanel/core/transformation/XIncludeTransformer.java	2007-09-18 09:33:04 UTC (rev 27403)
@@ -1,5 +1,8 @@
 package org.wyona.yanel.core.transformation;
 
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.sax.SAXSource;
+
 import org.apache.log4j.Category;
 import org.apache.xml.resolver.tools.CatalogResolver;
 import org.wyona.yanel.core.source.SourceResolver;
@@ -21,7 +24,7 @@
 
     public static final String NS_URI = "http://www.w3.org/2001/XInclude";
     
-    private SourceResolver resolver;
+    private URIResolver resolver;
     private boolean ignoreDocumentEvent;
     private boolean insideIncludeElement;
     
@@ -30,7 +33,7 @@
         this.insideIncludeElement = false;
     }
 
-    public void setResolver(SourceResolver resolver) {
+    public void setResolver(URIResolver resolver) {
         this.resolver = resolver;
     }
 
@@ -58,7 +61,7 @@
             
             this.ignoreDocumentEvent = true;
             try {
-                xmlReader.parse(resolver.resolve(href));
+                xmlReader.parse(SAXSource.sourceToInputSource(resolver.resolve(href, null)));
             } catch (Exception e) {
                 log.error("XInclude error for href: " + href + ":  " + e, e);
                 throw new SAXException(e);

Modified: public/yanel/trunk/src/impl/java/org/wyona/yanel/impl/resources/BasicXMLResource.java
===================================================================
--- public/yanel/trunk/src/impl/java/org/wyona/yanel/impl/resources/BasicXMLResource.java	2007-09-18 08:28:44 UTC (rev 27402)
+++ public/yanel/trunk/src/impl/java/org/wyona/yanel/impl/resources/BasicXMLResource.java	2007-09-18 09:33:04 UTC (rev 27403)
@@ -36,7 +36,7 @@
 import org.wyona.yanel.core.attributes.viewable.View;
 import org.wyona.yanel.core.attributes.viewable.ViewDescriptor;
 import org.wyona.yanel.core.serialization.SerializerFactory;
-import org.wyona.yanel.core.source.ResourceResolver;
+import org.wyona.yanel.core.source.SourceResolver;
 import org.wyona.yanel.core.transformation.I18nTransformer2;
 import org.wyona.yanel.core.transformation.XIncludeTransformer;
 import org.wyona.yanel.core.util.PathUtil;
@@ -134,7 +134,7 @@
            
             // create xinclude transformer:
             XIncludeTransformer xIncludeTransformer = new XIncludeTransformer();
-            ResourceResolver resolver = new ResourceResolver(this);
+            SourceResolver resolver = new SourceResolver(this);
             xIncludeTransformer.setResolver(resolver);
            
             // create serializer:



More information about the Yanel-commits mailing list