blob: 62da2d9d40452257a0ae934098690a1cfe4512d3 [file] [log] [blame]
/****************************************************************************
*
* Copyright (c) 2008-2011, EBM WebSourcing
*
* This source code is available under agreement available at
* http://www.petalslink.com/legal/licenses/petals-studio
*
* You should have received a copy of the agreement along with this program.
* If not, write to EBM WebSourcing (4, rue Amelie - 31200 Toulouse, France).
*
*****************************************************************************/
package org.eclipse.bpel.common.wsdl.helpers;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Date;
import org.eclipse.bpel.common.wsdl.SoaWsdlCommonPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
/**
* A set of helpers for URIs and URLs.
* @author Vincent Zurczak - EBM WebSourcing
*/
public class UriAndUrlHelper {
/**
* Builds an URI from an URL (with an handle for URLs not compliant with RFC 2396).
* @param url
* @return
*/
public static URI urlToUri( URL url ) {
URI uri;
try {
// Possible failing step.
uri = url.toURI();
} catch( Exception e ) {
// URL did not comply with RFC 2396 => illegal un-escaped characters.
try {
uri = new URI(
url.getProtocol(), url.getUserInfo(),
url.getHost(), url.getPort(),
url.getPath(), url.getQuery(), url.getRef());
} catch( Exception e1 ) {
// No automatic repair.
throw new IllegalArgumentException( "Broken URL: " + url );
}
}
uri = uri.normalize();
return uri;
}
/**
* Builds an URI from an URL string (with an handle for URLs not compliant with RFC 2396).
* @param urlAsString
* @return
*/
public static URI urlToUri( String urlAsString ) {
try {
URL url = new URL( urlAsString );
return urlToUri( url );
} catch( Exception e ) {
// e.printStackTrace();
}
throw new IllegalArgumentException( "Broken URL: " + urlAsString );
}
/**
* Extracts the file name from a URI or URL given as a string.
* <p>
* If the file name contains invalid characters, such as a question mark,
* this methods modifies the file name so that is is a valid file name.
* </p>
* @param uriAsString the URI or URL given as a string
* @return the file name (never null)
*/
public static String extractOrGenerateFileName( String uriAsString ) {
String fileName = uriAsString;
if( fileName.endsWith( "/" ))
fileName = fileName.substring( 0, fileName.length() - 1 );
int index = fileName.lastIndexOf( '/' );
if( index != -1 )
fileName = fileName.substring( ++ index );
// Handle cases like "jsp?value="
String lowered = fileName.toLowerCase();
if( lowered.endsWith( "?wsdl" ))
fileName = fileName.substring( 0, fileName.length() - 5 ) + ".wsdl";
else if( lowered.contains( "?wsdl=" ))
fileName = fileName.replace( "?wsdl=", "" ) + ".wsdl";
else if( lowered.endsWith( "?xsd" ))
fileName = fileName.substring( 0, fileName.length() - 5 ) + ".xsd";
else if( lowered.contains( "?xsd=" ))
fileName = fileName.replace( "?xsd=", "" ) + ".xsd";
else {
index = fileName.lastIndexOf( '?' );
if( index != -1 )
fileName = fileName.substring( ++ index );
}
// Handle empty values
if( fileName.trim().length() == 0 )
fileName = "importedFile__" + new Date().getTime();
// Replace invalid characters
index = fileName.lastIndexOf( '.' );
if( index != -1 ) {
String ext = fileName.substring( index );
String fwe = fileName.substring( 0, index );
fileName = fwe.replaceAll( "[^-0-9a-zA-Z_]", "-" ) + ext;
}
return fileName;
}
/**
* Builds an URI from an URI and a suffix.
*
* <p>
* This suffix can be an absolute URL, or a relative path
* with respect to the first URI. In this case, the suffix is resolved
* with respect to the URI.
* </p>
* <p>
* If the suffix is already an URL, its is returned.<br />
* If the suffix is a relative file path and cannot be resolved, an exception is thrown.
* </p>
* <p>
* The returned URI is normalized.
* </p>
*
* @param referenceUri the reference URI
* @param uriSuffix the URI suffix (not null)
* @return the new URI
* @throws URISyntaxException if the resolution failed
*/
public static URI buildNewURI( URI referenceUri, String uriSuffix ) throws URISyntaxException {
if( uriSuffix == null )
throw new NullPointerException( "The URI suffix cannot be null." );
uriSuffix = uriSuffix.replaceAll( "\\\\", "/" );
URI importUri = null;
try { // Absolute URL ?
importUri = urlToUri( new URL( uriSuffix ));
} catch( Exception e ) {
try { // Relative URL ?
importUri = referenceUri.resolve( new URI( null, uriSuffix, null ));
} catch( Exception e2 ) {
String msg =
"An URI could not be built from the URI " + referenceUri.toString()
+ " and the suffix " + uriSuffix + ".";
throw new URISyntaxException( msg, e2.getMessage());
}
}
return importUri.normalize();
}
/**
* Determines whether a string is an absolute URI.
* @param uriAsString the potential URI, as a string
* @return true if it is an absolute URI, false otherwise or if it is not a valid URI
*/
public static boolean isAbsoluteUri( String uriAsString ) {
boolean result;
try {
URI uri = urlToUri( uriAsString );
result = uri.isAbsolute();
} catch( Exception e ) {
result = false;
}
return result;
}
/**
* Returns the relative position of <code>uri</code> with respect to <code>originUri</code>.
*
* @param originUri the URI which acts as the <i>origin</i>.
* @param uri the URI whose relative path must be computed with respect to originUri.
* @return the relative path of <code>uri</code> with respect to originUri, if they
* are on the same host and have a same scheme, or <code>uri<code> otherwise.
*/
public static URI getRelativeLocationToUri( URI originUri, URI uri ) {
URI result = uri;
try {
originUri = UriAndUrlHelper.urlToUri( originUri.toURL());
uri = UriAndUrlHelper.urlToUri( uri.toURL());
URI relativeUri = originUri.relativize( uri ).normalize();
if( ! uri.equals( relativeUri )) {
result = relativeUri;
}
else {
// Do they have the same scheme?
String originScheme = originUri.getScheme();
String scheme = uri.getScheme();
boolean sameScheme = false;
if( originScheme != null )
sameScheme = originScheme.equals( scheme );
else
sameScheme = scheme == null;
// Do they have the same host?
String originHost = originUri.getHost();
String host = uri.getHost();
boolean sameHost = false;
if( originHost != null )
sameHost = originHost.equals( host );
else
sameHost = host == null;
// Make a special treatment for "file" scheme.
// Are they on the same disk partition?
// If no, then there is no relative path to compute.
boolean samePartition = true;
if( sameScheme && "file".equalsIgnoreCase( originScheme )) {
String originDevice = new Path( originUri.getPath()).getDevice();
String device = new Path( uri.getPath()).getDevice();
if( originDevice != null )
samePartition = originDevice.equals( device );
else
samePartition = device == null;
}
// If yes for both, we can define a relative location.
// The only reason why URI#relativize( ... ) could have failed previously,
// is because this method only works when "uri" is a child of "originUri".
// Otherwise, we have to insert ".." when required.
if( sameScheme && sameHost && samePartition ) {
String originPath = originUri.toString().replaceAll( "\\\\", "/" );
String path = uri.toString().replaceAll( "\\\\", "/" );
// Split the paths
String[] originParts = originPath.split( "/" );
String[] fileParts = path.split( "/" );
int matchSegmentsCpt = 0;
for( int i=0; i<originParts.length; i++ ) {
if( i >= fileParts.length )
break;
String otherSegment = fileParts[ i ];
String segment = originParts[ i ];
if( segment.equalsIgnoreCase( otherSegment ))
matchSegmentsCpt ++;
else
break;
}
// Build the relative location
StringBuffer relativePath = new StringBuffer();
if( matchSegmentsCpt > 0 ) {
for( int i=matchSegmentsCpt; i<originParts.length - 1; i++ )
relativePath.append( "../" );
for( int i=matchSegmentsCpt; i<fileParts.length - 1; i++ )
relativePath.append( fileParts[ i ] + "/" );
relativePath.append( fileParts[ fileParts.length - 1 ]);
// Remove extra ".." and "."
result = new URI( null, relativePath.toString(), null );
}
}
}
} catch( URISyntaxException e ) {
SoaWsdlCommonPlugin.log( e, IStatus.ERROR );
} catch( MalformedURLException e ) {
SoaWsdlCommonPlugin.log( e, IStatus.ERROR );
}
return result;
}
}