/******************************************************************************
* Copyright (c) 2008-2013, Linagora
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Linagora - initial API and implementation
*******************************************************************************/
package com.ebmwebsourcing.petals.common.internal.provisional.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.namespace.QName;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.ebmwebsourcing.petals.common.internal.provisional.sse.StructuredModelHelper;
/**
* A set of utility methods to format names.
* @author Vincent Zurczak - EBM WebSourcing
*/
public final class NamespaceUtils {
/**
* Private constructor for utility class.
*/
private NamespaceUtils() {
// nothing
}
/**
* Verifies if a string is not null and is a shorten namespace.
* <p>
* <code>{http://petals.ow2.org}value</code> is an example of shorten namespace.
* </p>
*
* @param s a string
* @return
*/
public static boolean isShortenNamespace( String s ) {
return s != null && s.matches( "\\{[^}]+\\}[^{}]+" );
}
/**
* Remove the name space elements from a string.
* Name space elements are name space URLs between curly brackets or name space prefixes.
* If the string is null, it returns the empty string.
*
* @param name the name whose name space elements should be removed.
* @return the substring without name space URL and prefix.
*/
public static String removeNamespaceElements( String name ) {
if( name == null )
return "";
// Remove name space (written between '{' and '}').
Pattern namespacePattern = Pattern.compile( "\\{.+\\}" );
Matcher m = namespacePattern.matcher( name );
if( name.contains( "{" ) && ! m.find())
return "";
int namespaceEndPosition = name.lastIndexOf( '}' );
if( namespaceEndPosition > 0 )
name = name.substring( namespaceEndPosition + 1 );
// Remove name space prefix.
String[] splits = name.split( ":" );
if( splits.length == 1 )
return name.trim();
// In any other case, return the string in last position.
return splits[ splits.length - 1 ].trim();
}
/**
* Builds a QName object from a serialized QName.
* <p>
* Notice that this method does not check the validity of the parameter.
* If no name space URI was found, then only the local part will be used.
* </p>
*
* @param qname something like {http://namespace/uri}localPart
* @return a QName
*/
public static QName buildQName( String qname ) {
String nsUri = extractNamespaceUri( qname );
String local = removeNamespaceElements( qname );
return new QName( nsUri, local );
}
/**
* Gets the QName associated with an attribute.
* <p>
* <code><... interface-name="toto:itfName" xmlns:toto="http://lol.fr" ...></code>
* will return {http://lol.fr}itfName when this method is called with the attribute
* "interface-name".
* </p>
*
* @param attribute the attribute
* @return the associated QName, or null if the attribute value does not have a valid syntax
*/
public static QName getQNameAttribute( Attr attribute ) {
QName result = null;
String value = attribute.getNodeValue().trim();
String[] splits = value.split( ":" );
if( splits.length == 1 ) {
result = new QName( value );
}
else if( splits.length == 2 ) {
String prefix = splits[ 0 ];
String decl = splits[ 1 ];
String url = DomUtils.lookupNamespaceURI( prefix, attribute.getOwnerElement());
result = new QName( url, decl, prefix );
}
return result;
}
/**
* Gets the QName associated with an element.
* <p>
* <code><petalsCDK:operation xmlns:op="http://toto.fr">op:value<></code>
* will return {http://toto.fr}value.
* </p>
*
* @param element the element
* @return the associated QName, or null if the attribute value does not have a valid syntax
*/
public static QName getQNameElement( Element element ) {
QName result = null;
String value = StructuredModelHelper.getElementSimpleValue( element );
String[] splits = value.split( ":" );
if( splits.length == 1 ) {
result = new QName( value );
}
else if( splits.length == 2 ) {
String prefix = splits[ 0 ];
String decl = splits[ 1 ];
String url = DomUtils.lookupNamespaceURI( prefix, element );
result = new QName( url, decl, prefix );
}
return result;
}
/**
* Get the name space URI from a QName value.
* <p>
* "{http://petals.ow2.org}value" will return "http://petals.ow2.org"<br />
* "petals:value", where the name space URI for the prefix "petals" is defined
* in or before the node using this value, will return the associated name space URI,
* or null if the name space declaration was not found.
* </p>
* <p>
* If qNameValue is null, then null is returned.
* </p>
*
* @param qNameValue
* @param node
* @return
*/
public static String getNamespaceUri( String qNameValue, Node node ) {
if( qNameValue == null )
return null;
String uri = extractNamespaceUri( qNameValue );
if( uri.length() == 0 ) {
int index = qNameValue.indexOf( ':' );
if( index > 0 ) {
String prefix = qNameValue.substring( 0, index );
uri = DomUtils.lookupNamespaceURI( prefix, node );
}
else
uri = null;
}
return uri;
}
/**
* Extract the name space URI from a name space given as a string.
* Example: <b>{http://namespace.uri}toto</b> will return <b>http://namespace.uri</b>
* @param namespace
* @return the name space URI, or the empty string if no URI was found
*/
public static String extractNamespaceUri( String namespace ) {
if( namespace == null )
return "";
String namespaceCopy = namespace;
Pattern namespacePattern = Pattern.compile("\\{.+\\}"); //$NON-NLS-1$
Matcher m = namespacePattern.matcher( namespaceCopy );
if( ! m.find())
return "";
namespaceCopy = namespaceCopy.substring( m.start(), m.end());
if( namespaceCopy.startsWith( "{" )) //$NON-NLS-1$
namespaceCopy = namespaceCopy.substring( 1 );
if( namespaceCopy.endsWith( "}" )) //$NON-NLS-1$
namespaceCopy = namespaceCopy.substring( 0, namespaceCopy.length() - 1 );
return namespaceCopy.trim();
}
/**
*
* @param nsDeclaration
* @return
*/
public static String getNsPrefixFromNsDeclaration( String nsDeclaration ) {
NsDeclarationElements decl = extractNsDeclarationElements( nsDeclaration );
return decl != null ? decl.getPrefix() : null;
}
/**
*
* @param nsDeclaration
* @return
*/
public static String getNsUrlFromNsDeclaration( String nsDeclaration ) {
NsDeclarationElements decl = extractNsDeclarationElements( nsDeclaration );
return decl != null ? decl.getUrl() : null;
}
/**
* @return a bean containing elements relative to a name space declaration, or
* null if the argument does not match with the regular expression describing a
* name space declaration.
*
* The regular expression describing a name space declaration
* is "xmlns(\\:[-_\\w]+)?\\=\"[-.:/_\\w]+\"".
*/
private static NsDeclarationElements extractNsDeclarationElements( String nsDeclaration ) {
if( nsDeclaration == null )
return null;
Pattern nsDeclarationPattern =
Pattern.compile( "xmlns(\\:[-_\\w]+)?\\=\"[-.:/_\\w]+\"" ); //$NON-NLS-1$
Matcher m = nsDeclarationPattern.matcher( nsDeclaration );
if( !m.find())
return null;
NsDeclarationElements result = new NsDeclarationElements();
String[] parts = nsDeclaration.split( "=" );
result.url = parts[ 1 ].replace( "\"", "" );
result.prefix = parts[ 0 ].replace( "xmlns", "" ).replace( ":", "" );
return result;
}
/**
* A simple bean to store elements from a name space declaration.
*/
private static class NsDeclarationElements {
private String prefix;
private String url;
/**
* @return the prefix
*/
public String getPrefix() {
return this.prefix;
}
/**
* @return the url
*/
public String getUrl() {
return this.url;
}
}
}