@Nonnull
  public static IReadableResource getResolvedResource (@Nullable final String sSystemId,
                                                       @Nullable final String sBaseURI,
                                                       @Nullable final ClassLoader aClassLoader)
  {
    if (StringHelper.hasNoText (sSystemId) && StringHelper.hasNoText (sBaseURI))
      throw new IllegalArgumentException ("Both systemID and baseURI are null!");

    // Retrieve only once
    final boolean bDebugResolve = isDebugResolve ();

    if (LOGGER.isDebugEnabled ())
      LOGGER.debug ("Trying to resolve resource " +
                    sSystemId +
                    " from base " +
                    sBaseURI +
                    (aClassLoader == null ? "" : " with ClassLoader " + aClassLoader));

    if (bDebugResolve)
      if (LOGGER.isInfoEnabled ())
        LOGGER.info ("doStandardResourceResolving ('" + sSystemId + "', '" + sBaseURI + "', " + aClassLoader + ")");

    // It happens quite often that some resolution does not work here
    final URL aSystemURL = URLHelper.getAsURL (sSystemId, false);

    // Was an absolute URL requested?
    if (aSystemURL != null)
    {
      // File URL are handled separately, as they might be relative (as in
      // 'file:../dir/include.xml')!
      if (!aSystemURL.getProtocol ().equals (URLHelper.PROTOCOL_FILE))
      {
        final URLResource ret = new URLResource (aSystemURL);
        if (bDebugResolve)
          if (LOGGER.isInfoEnabled ())
            LOGGER.info ("  resolved system URL to " + ret);
        return ret;
      }
    }

    if (ClassPathResource.isExplicitClassPathResource (sBaseURI))
      return _resolveClassPathResource (sSystemId, sBaseURI, aClassLoader);

    // jar:file or wsjar:file or zip:file???
    if (isExplicitJarFileResource (sBaseURI))
      try
      {
        return _resolveJarFileResource (sSystemId, sBaseURI);
      }
      catch (final MalformedURLException ex)
      {
        throw new UncheckedIOException (ex);
      }

    // Try whether the base is a URI
    final URL aBaseURL = URLHelper.getAsURL (sBaseURI);

    // Handle "file" protocol separately
    if (aBaseURL != null && !aBaseURL.getProtocol ().equals (URLHelper.PROTOCOL_FILE))
      try
      {
        return _resolveURLResource (sSystemId, aBaseURL);
      }
      catch (final MalformedURLException ex)
      {
        throw new UncheckedIOException (ex);
      }

    // Base is not a URL or a file based URL
    File aBaseFile;
    if (aBaseURL != null)
      aBaseFile = URLHelper.getAsFile (aBaseURL);
    else
      if (sBaseURI != null)
        aBaseFile = new File (sBaseURI);
      else
        aBaseFile = null;

    if (StringHelper.hasNoText (sSystemId))
    {
      // Nothing to resolve
      // Note: BaseFile should always be set here!
      final FileSystemResource ret = new FileSystemResource (aBaseFile);
      if (bDebugResolve)
        if (LOGGER.isInfoEnabled ())
          LOGGER.info ("  resolved base URL to " + ret);
      return ret;
    }

    // Get the system ID file
    File aSystemFile;
    if (aSystemURL != null)
      aSystemFile = URLHelper.getAsFile (aSystemURL);
    else
      aSystemFile = new File (sSystemId);

    // If the provided file is an absolute file, take it
    if (aSystemFile.isAbsolute ())
    {
      final FileSystemResource aAbsFile = new FileSystemResource (aSystemFile);
      if (!aAbsFile.exists ())
      {
        // Sometimes paths starting with "/" are passed in - as they are
        // considered absolute when running on Linux, try if a combined file
        // eventually exists
        final FileSystemResource aMerged = _getChildResource (aBaseFile, aSystemFile);
        if (aMerged.exists ())
        {
          if (bDebugResolve)
            if (LOGGER.isInfoEnabled ())
              LOGGER.info ("  resolved base + system URL to " + aMerged);
          return aMerged;
        }
      }

      // If the absolute version exists, or if both the absolute and the merged
      // version do NOT exist, return the absolute version anyway.
      if (bDebugResolve)
        if (LOGGER.isInfoEnabled ())
          LOGGER.info ("  resolved system URL to " + aAbsFile);
      return aAbsFile;
    }

    final FileSystemResource ret = _getChildResource (aBaseFile, aSystemFile);
    if (bDebugResolve)
      if (LOGGER.isInfoEnabled ())
        LOGGER.info ("  resolved base + system URL to " + ret);
    return ret;
  }
@ Nonnull public static IReadableResource getResolvedResource ( @ Nullable final String sSystemId , @ Nullable final String sBaseURI , @ Nullable final ClassLoader aClassLoader ) { if ( StringHelper . hasNoText ( sSystemId ) && StringHelper . hasNoText ( sBaseURI ) ) throw new IllegalArgumentException ( "Both systemID and baseURI are null!" ) ; final boolean bDebugResolve = isDebugResolve ( ) ; if ( LOGGER . isDebugEnabled ( ) ) LOGGER . debug ( "Trying to resolve resource " + sSystemId + " from base " + sBaseURI + ( aClassLoader == null ? "" : " with ClassLoader " + aClassLoader ) ) ; if ( bDebugResolve ) if ( LOGGER . isInfoEnabled ( ) ) LOGGER . info ( "doStandardResourceResolving ('" + sSystemId + "', '" + sBaseURI + "', " + aClassLoader + ")" ) ; final URL aSystemURL = URLHelper . getAsURL ( sSystemId , false ) ; if ( aSystemURL != null ) { if ( ! aSystemURL . getProtocol ( ) . equals ( URLHelper . PROTOCOL_FILE ) ) { final URLResource ret = new URLResource ( aSystemURL ) ; if ( bDebugResolve ) if ( LOGGER . isInfoEnabled ( ) ) LOGGER . info ( "  resolved system URL to " + ret ) ; return ret ; } } if ( ClassPathResource . isExplicitClassPathResource ( sBaseURI ) ) return _resolveClassPathResource ( sSystemId , sBaseURI , aClassLoader ) ; if ( isExplicitJarFileResource ( sBaseURI ) ) try { return _resolveJarFileResource ( sSystemId , sBaseURI ) ; } catch ( final MalformedURLException ex ) { throw new UncheckedIOException ( ex ) ; } final URL aBaseURL = URLHelper . getAsURL ( sBaseURI ) ; if ( aBaseURL != null && ! aBaseURL . getProtocol ( ) . equals ( URLHelper . PROTOCOL_FILE ) ) try { return _resolveURLResource ( sSystemId , aBaseURL ) ; } catch ( final MalformedURLException ex ) { throw new UncheckedIOException ( ex ) ; } File aBaseFile ; if ( aBaseURL != null ) aBaseFile = URLHelper . getAsFile ( aBaseURL ) ; else if ( sBaseURI != null ) aBaseFile = new File ( sBaseURI ) ; else aBaseFile = null ; if ( StringHelper . hasNoText ( sSystemId ) ) { final FileSystemResource ret = new FileSystemResource ( aBaseFile ) ; if ( bDebugResolve ) if ( LOGGER . isInfoEnabled ( ) ) LOGGER . info ( "  resolved base URL to " + ret ) ; return ret ; } File aSystemFile ; if ( aSystemURL != null ) aSystemFile = URLHelper . getAsFile ( aSystemURL ) ; else aSystemFile = new File ( sSystemId ) ; if ( aSystemFile . isAbsolute ( ) ) { final FileSystemResource aAbsFile = new FileSystemResource ( aSystemFile ) ; if ( ! aAbsFile . exists ( ) ) { final FileSystemResource aMerged = _getChildResource ( aBaseFile , aSystemFile ) ; if ( aMerged . exists ( ) ) { if ( bDebugResolve ) if ( LOGGER . isInfoEnabled ( ) ) LOGGER . info ( "  resolved base + system URL to " + aMerged ) ; return aMerged ; } } if ( bDebugResolve ) if ( LOGGER . isInfoEnabled ( ) ) LOGGER . info ( "  resolved system URL to " + aAbsFile ) ; return aAbsFile ; } final FileSystemResource ret = _getChildResource ( aBaseFile , aSystemFile ) ; if ( bDebugResolve ) if ( LOGGER . isInfoEnabled ( ) ) LOGGER . info ( "  resolved base + system URL to " + ret ) ; return ret ; }
Do the standard resource resolving of sSystemId relative to sBaseURI

@param sSystemId
The resource to search. May be relative to the base URI or absolute.
May be <code>null</code> if base URI is set.
@param sBaseURI
The base URI from where the search is initiated. May be
<code>null</code> if sSystemId is set.
@param aClassLoader
The class loader to be used for {@link ClassPathResource} objects.
May be <code>null</code> in which case the default class loader is
used.
@return The non-<code>null</code> resource. May be non-existing!
@throws UncheckedIOException
In case the file resolution (to an absolute file) fails.