package org.wyona.yanel.core.source;

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 Source.
 * This class just checks the scheme and delegates to the scheme-specific resolver.
 * 
 * TODO: allow to configure schemes in a config file
 */
public class SourceResolver implements URIResolver {

    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);
            } else if (scheme.equals("http")) {
                resolver = new HttpResolver(this.resource);
                this.resolvers.put(scheme, resolver);
            } else if (scheme.equals("rthtdocs")) {
                resolver = new RTHtdocsResolver(this.resource);
                this.resolvers.put(scheme, resolver);
            } else if (scheme.equals("rtyanelhtdocs")) {
                resolver = new RTYanelHtdocsResolver(this.resource);
                this.resolvers.put(scheme, resolver);
            }
        }
        return resolver;
    }
    
}

@@ -254,16 +254,54 @@
 esource;
+%0Aimport org.wyona.commons.io.PathUtil;
 %0A%0A/**%0A *
@@ -806,24 +806,47 @@
 %0A    %7D%0A    %0A
+    /**%0A     *%0A     */%0A
     public S
@@ -972,17 +972,26 @@
 ug(%22
+URI to be 
 resolv
-ing
+ed
 : %22 
@@ -990,32 +990,71 @@
 lved: %22 + uri);%0A
+            log.debug(%22Base: %22+ base);%0A
         %7D%0A      
@@ -1039,32 +1039,33 @@
 ase);%0A        %7D%0A
+%0A
         int colo
@@ -1087,16 +1087,17 @@
 dexOf(%22:
+/
 %22);%0A    
@@ -1104,180 +1104,1203 @@
     
-if (colonIndex %3C= 0) %7B%0A            throw new SourceException(%22invalid url syntax (missing scheme): %22 + uri);%0A        %7D%0A        String scheme = uri.substring(0, colonIndex);
+String uriScheme = %22%22;%0A        if (colonIndex %3C= 0) %7B//Check for scheme in URI, if true, then URI has no scheme%0A            //log.error(%22DEBUG: URI has no scheme: %22 + uri);%0A            if (base != null) %7B%0A                int colBaseIndex = base.indexOf(%22:/%22);%0A                if(colBaseIndex %3C=0 )%7B//Check for scheme in Base%0A                    throw new SourceException(%22invalid url syntax (missing scheme): %22 + uri);//no scheme found in uri and base%0A                %7Delse%7B//base contains scheme. Use base scheme for uri scheme%0A                    uriScheme = base.substring(0, colBaseIndex);%0A                    uri = PathUtil.concat(base,uri);                %0A                    //log.error(%22DEBUG: Use scheme of base: %22 + uriScheme + %22, %22 + uri);%0A                %7D%0A            %7D else %7B%0A                log.error(%22Neither scheme for URI nor base specified for URI: %22 + uri);%0A                throw new SourceException(%22invalid url syntax (missing scheme): %22 + uri);//no scheme found in uri and base%0A            %7D%0A        %7D else %7B//uri contains scheme%0A            uriScheme = uri.substring(0, colonIndex);%0A            //log.error(%22DEBUG: URI has scheme: %22 + uriScheme + %22, %22 + uri);%0A        %7D%0A
 %0A   
@@ -2339,17 +2339,20 @@
 esolver(
-s
+uriS
 cheme);%0A
@@ -2421,42 +2421,162 @@
     
-return resolver.resolve(uri, base)
+// TODO: What shall be used as base?!%0A                Source s = resolver.resolve(uri, base);%0A                s.setSystemId(uri);%0A                return s
 ;%0A  
@@ -2756,15 +2756,39 @@
 on(%22
-unknown
+No resolver could be loaded for
  sch
@@ -2796,17 +2796,20 @@
 me: %22 + 
-s
+uriS
 cheme);%0A
@@ -2825,24 +2825,47 @@
 %0A    %7D%0A    %0A
+    /**%0A     *%0A     */%0A
     private 

check for scheme of base and try to resolve accordingly