Package org.apache.excalibur.source.impl

Source Code of org.apache.excalibur.source.impl.AbstractSourceResolver

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.excalibur.source.impl;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
import org.apache.excalibur.source.SourceFactory;
import org.apache.excalibur.source.SourceResolver;
import org.apache.excalibur.source.SourceUtil;
import org.apache.excalibur.source.URIAbsolutizer;

/**
* This is an abstract implementation of a {@link SourceResolver}.
*
* The source resolving is done relative to a base directory/URI (if
* the given location is relative). The base directory/URI has to be set
* using {@link #setBaseURL(URL)}.
*
* A subclass should implement {@link #getSourceFactory(String)} and
* {@link #releaseSourceFactory(SourceFactory)} if required.
*
* To support various logging frameworks, the subclass should implement the
* {@link #isDebugEnabled()} and the {@link #debug(String)} method.
*
* @see org.apache.excalibur.source.SourceResolver
*
* @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
* @version $Id: AbstractSourceResolver.java 522060 2007-03-24 17:27:56Z cziegeler $
*/
public abstract class AbstractSourceResolver
    implements SourceResolver
{

    /**
     * The base URL
     */
    protected URL m_baseURL;

    /** Set the base url. */
    public void setBaseURL(URL baseurl)
    {
        m_baseURL = baseurl;
    }

    protected boolean isDebugEnabled()
    {
        return false;
    }

    protected void debug(String text)
    {
        // we do not log
    }

    protected abstract SourceFactory getSourceFactory(String protocol);

    protected void releaseSourceFactory(SourceFactory factory)
    {
        // nothing to do by default
    }

    /**
     * Get a <code>Source</code> object.
     * @throws org.apache.excalibur.source.SourceNotFoundException if the source cannot be found
     */
    public Source resolveURI( String location )
        throws MalformedURLException, IOException, SourceException
    {
        return this.resolveURI( location, null, null );
    }

    /**
     * Get a <code>Source</code> object.
     * @throws org.apache.excalibur.source.SourceNotFoundException if the source cannot be found
     */
    public Source resolveURI( String location,
                              String baseURI,
                              Map parameters )
        throws MalformedURLException, IOException, SourceException
    {
        if( this.isDebugEnabled() )
        {
            this.debug( "Resolving '" + location + "' with base '" + baseURI + "' in context '" + m_baseURL + "'" );
        }
        if( location == null ) throw new MalformedURLException( "Invalid System ID" );
        if( null != baseURI && SourceUtil.indexOfSchemeColon(baseURI) == -1 )
        {
            throw new MalformedURLException( "BaseURI is not valid, it must contain a protocol: " + baseURI );
        }

        if( baseURI == null ) baseURI = m_baseURL.toExternalForm();

        String systemID = location;
        // special handling for windows file paths
        if( location.length() > 1 && location.charAt( 1 ) == ':' )
            systemID = "file:/" + location;
        else if( location.length() > 2 && location.charAt(0) == '/' && location.charAt(2) == ':' )
            systemID = "file:" + location;

        // determine protocol (scheme): first try to get the one of the systemID, if that fails, take the one of the baseURI
        String protocol;
        int protocolPos = SourceUtil.indexOfSchemeColon(systemID);
        if( protocolPos != -1 )
        {
            protocol = systemID.substring( 0, protocolPos );
        }
        else
        {
            protocolPos = SourceUtil.indexOfSchemeColon(baseURI);
            if( protocolPos != -1 )
                protocol = baseURI.substring( 0, protocolPos );
            else
                protocol = "*";
        }

        Source source = null;
        // search for a SourceFactory implementing the protocol
        SourceFactory factory = null;
        try
        {
            factory = this.getSourceFactory( protocol );
            if ( factory != null )
            {
                systemID = absolutize( factory, baseURI, systemID );
                if( this.isDebugEnabled() )
                    this.debug( "Resolved to systemID : " + systemID );
                source = factory.getSource( systemID, parameters );
            }
        }
        finally
        {
            this.releaseSourceFactory( factory );
        }

        if( null == source )
        {
            try
            {
                factory = this.getSourceFactory("*");
                if ( factory == null )
                {
                    throw new SourceException( "Unable to select source factory for '" + systemID + "'. No default factory found.");
                }
                systemID = absolutize( factory, baseURI, systemID );
                if( this.isDebugEnabled() )
                    this.debug( "Resolved to systemID : " + systemID );
                source = factory.getSource( systemID, parameters );
            }
            finally
            {
                this.releaseSourceFactory(factory);
            }
        }

        return source;
    }

    /**
     * Makes an absolute URI based on a baseURI and a relative URI.
     */
    private String absolutize( SourceFactory factory, String baseURI, String systemID )
    {
        if( factory instanceof URIAbsolutizer )
            systemID = ((URIAbsolutizer)factory).absolutize(baseURI, systemID);
        else
            systemID = SourceUtil.absolutize(baseURI, systemID);
        return systemID;
    }

    /**
     * Releases a resolved resource
     * @param source the source to release
     */
    public void release( final Source source )
    {
        if( source == null ) return;

        // search for a SourceFactory implementing the protocol
        final String scheme = source.getScheme();
        SourceFactory factory = null;

        try
        {
            factory = this.getSourceFactory(scheme);
            if ( factory == null )
            {
                factory = this.getSourceFactory("*");
                if ( factory == null )
                {
                    throw new RuntimeException( "Unable to select source factory for '" + source.getURI() + "'.");
                }
            }
            factory.release(source);
        }
        finally
        {
            this.releaseSourceFactory( factory );
        }
    }
}
TOP

Related Classes of org.apache.excalibur.source.impl.AbstractSourceResolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.