/*******************************************************************************
 * Copyright (c) 1998, 2008 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/
package org.eclipse.persistence.sdo.helper;

import java.net.URI;
import java.net.URL;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.xml.sax.InputSource;

/**
 * <p><b>Purpose</b>: Default implementation of the org.eclipse.persistence.sdo.helper.SchemaResolver interface
 * <p><b>Responsibilities</b>:<ul>
 * <li> Given the source schema and namespace and schemaLocation values from an import or include return the referenced Schema
 * <li> If a baseSchemaLocation is set it will be prepended to all schemaLocations passed into the resovleSchema methods
 * <li> This implementation will try to open an Inputstream to a URL created from the schemaLocation and return a StreamSource based on that inputstream
 * </ul>
 *
 * @see org.eclipse.persistence.sdo.helper.SchemaResolver
 */
public class DefaultSchemaResolver implements SchemaResolver {
    private String baseSchemaLocation;

    public DefaultSchemaResolver() {
    }

    /**
     * Given the source schema and namespace and schemaLocation values from an import
     * or include return the referenced Schema.
     * 
     * @param sourceXSD The Source object of the source schema
     * @param namespace The namespace portion of the import/include
     * @param schemaLocation The schemaLocation portion of the import/include
     * @return Source for the referenced Schema or null if processing the referenced
     * schema should be skipped
     */
    public Source resolveSchema(Source sourceXSD, String namespace, String schemaLocation) {
        try {
            URL schemaUrl = null;
            if (getBaseSchemaLocation() != null) {
                // Attempt to resolve the schema location against the base location
                schemaUrl = new URI(getBaseSchemaLocation()).resolve(schemaLocation).toURL();
            } else {
                schemaUrl = new URL(schemaLocation);
            }
            return new StreamSource(schemaUrl.toExternalForm());
        } catch (Exception e) {
            AbstractSessionLog.getLog().log(AbstractSessionLog.WARNING, "sdo_error_processing_referenced_schema", new Object[] { e.getClass().getName(), namespace, schemaLocation });
            AbstractSessionLog.getLog().logThrowable(AbstractSessionLog.FINEST, e);
        }
        return null;
    }

    /**
     * Satisfy EntityResolver interface implementation.
     * Allow resolution of external entities.
     * 
     * @param publicId
     * @param systemId
     * @return null
     */
    public InputSource resolveEntity(String publicId, String systemId) {
        return null;
    }

    /**
    * Optional baseSchemaLocation can be specified
    * If set, all schemaLocations passed into the resolveSchema methods will be resolved
    * against this base location according to the java.net.URI API
    * 
    * @param baseSchemaLocation optional baseSchemaLocation
    */
    public void setBaseSchemaLocation(String baseSchemaLocation) {
        this.baseSchemaLocation = baseSchemaLocation;
    }

    public String getBaseSchemaLocation() {
        return baseSchemaLocation;
    }
}
@@ -2426,12 +2426,25 @@
     
-if (
+String baseLoc = 
 getB
@@ -2466,21 +2466,519 @@
 on()
- != null) %7B%0D%0A
+;%0D%0A            if (baseLoc == null) %7B%0D%0A                // No base location, use schema location%0D%0A                schemaUrl = new URI(schemaLocation).toURL();%0D%0A            %7D else %7B%0D%0A                // May need to resolve against the base location%0D%0A                URI schemaUri = new URI(schemaLocation);%0D%0A                // If the schema location is absolute, ignore base location%0D%0A                if (schemaUri.isAbsolute()) %7B%0D%0A                    schemaUrl = schemaUri.toURL();%0D%0A                %7D else %7B%0D%0A    
     
@@ -3070,33 +3070,39 @@
             
-schemaUrl
+    URI baseUri
  = new URI(g
@@ -3104,41 +3104,485 @@
 URI(
-getBaseSchemaLocation()).resolve(
+baseLoc);%0D%0A                    // Handle 'jar:' case - we will need to try and create the schema URL manually%0D%0A                    if (baseUri.isOpaque() && baseUri.getScheme().equals(%22jar%22)) %7B%0D%0A                        // Example - jar:file:/C:/schema.jar!/my.xsd%0D%0A                        // Strip off anything after the last '/' character (base location could represent a file)%0D%0A                        schemaUrl = new URI(baseLoc.substring(0, baseLoc.lastIndexOf(%22/%22) + 1) + 
 sche
@@ -3607,32 +3607,40 @@
 );%0D%0A            
+        
 %7D else %7B%0D%0A      
@@ -3625,32 +3625,40 @@
       %7D else %7B%0D%0A
+        
                 
@@ -3679,26 +3679,104 @@
 w UR
-L(schemaLocation);
+I(baseLoc).resolve(schemaUri).toURL();%0D%0A                    %7D%0D%0A                %7D                
 %0D%0A  

Fix for bug# 240718 (SDO 2.1.1 TCK - Need to be able to resolve schema location against base location containing jar file)