/**************************************************************************** | |
* | |
* 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; | |
} | |
} |