Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jboss.mx.util.ObjectNameConverter Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.mx.util;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
/**
* Converts forbidden characters in the key and value of an object name
* to valid characters and back.
*
* Character Conversion Table: (based on RFC 1738 style escapes
* '%' => '%25'
* '*' => '%2a'
* ',' => '%2c'
* ':' => '%3a'
* '?' => '%3f'
* '=' => '%3d'
* '\'' => '%27'
* '\"' => '%22'
* Thanx to William Hoyle for mention this
* Attention: When you have a comma in one of your property
* value then you have to use a Hashtable to provide the properties
* otherwise the property parsing will fail.
*
* @author Andreas Schaefer
* @author William Hoyle
* @version $Revision: 61306 $
*/
public class ObjectNameConverter
{
/**
* Parses the given Object Name String representation and
* replaces any invalid characters in property keays and values with
* valid characters.
* Attention: Do not use this method when a property
* key or value contain a comma because then the parsing will fail.
* Please use the {@link #convert( java.lang.String, java.util.Hashtable )
* convert( String, Hashtable )} instead because the properties
* are already parsed (by you).
*
* @param pObjectName String representing an Object Name which must
* not contain a comman inside a property value
*
* @return Created Object Name with the converted keys and values
* of the given Object Name
*
* @throws javax.management.MalformedObjectNameException If the given Object Name
* is not correct
**/
public static ObjectName convert( String pObjectName )
throws MalformedObjectNameException
{
if( pObjectName == null ) {
throw new MalformedObjectNameException( "null name" );
}
// REVIEW, is the following a hack?: It is in the spec for patterns
if( pObjectName.length() == 0 ) {
pObjectName = "*:*";
}
int lIndex = pObjectName.indexOf( ":" );
if( lIndex < 0 ) {
throw new MalformedObjectNameException( "missing domain" );
}
String lDomain = pObjectName.substring( 0, lIndex );
if( ( lIndex + 1 ) < pObjectName.length() ) {
return createObjectName(lDomain, pObjectName.substring( lIndex + 1 ));
} else {
throw new MalformedObjectNameException( "properties missing" );
}
}
/**
* Check the keys and values of the properties and convert invalid characters
*
* @param pDomainName Name of the Domain
* @param pProperites Hashtable containing the properties of the Object Name
*
* @return Created Object Name with the converted keays and values
*
* @throws javax.management.MalformedObjectNameException If the given Object Name
* is not correct
**/
public static ObjectName convert( String pDomainName, Hashtable pProperties )
throws MalformedObjectNameException
{
if( pDomainName == null ) {
throw new MalformedObjectNameException( "missing domain" );
}
if( pProperties == null || pProperties.size() == 0 ) {
throw new MalformedObjectNameException(" null or empty properties" );
}
return createObjectName(pDomainName, pProperties, false);
}
/**
* Takes the properties from the given Object Name and convert
* special characters back
*
* @param pObjectName Given Object Name
*
* @return Hashtable with the back converted properties in it
* and will contain a "*" as key if the given object
* name is a property pattern for queries.
**/
public static Hashtable getProperties( ObjectName pObjectName )
{
Hashtable lReturn = reverseProperties( pObjectName.getKeyPropertyList() );
if( pObjectName.isPropertyPattern() ) {
lReturn.put( "*", "*" );
}
return lReturn;
}
/**
* Takes the properties from the given Object Name and convert
* special characters back
*
* @param pObjectName Given Object Name
*
* @return String with the original Object Name String representation and
* when a property pattern Object Name for queries it contains a ",*"
* at the end.
**/
public static String getString( ObjectName pObjectName )
{
String lReturn = pObjectName.getDomain() + ":" + reverseString( pObjectName.getKeyPropertyList() );
if( pObjectName.isPropertyPattern() ) {
lReturn = lReturn + ",*";
}
return lReturn;
}
/**
* Encrypt or decrypt the forbidden characters in an Object Name value property
*
* @param pValue Property Value of the Object Name's property list to be en- or decrypted
* @param pEncrypt True if the value must be encrypted otherwise decrypted
*
* @return A en- or decrypted String according to the conversion table above
**/
public static String convertCharacters( String pValue, boolean pEncrypt ) {
String lReturn = pValue;
if( pEncrypt ) {
int lIndex = lReturn.indexOf( "%" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"%25" +
( ( lIndex + 1 ) < lReturn.length() ? lReturn.substring( lIndex + 1 ) : "" );
lIndex = lReturn.indexOf( "%", lIndex + 2 );
}
lIndex = lReturn.indexOf( "*" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"%2a" +
( ( lIndex + 1 ) < lReturn.length() ? lReturn.substring( lIndex + 1 ) : "" );
lIndex = lReturn.indexOf( "*" );
}
lIndex = lReturn.indexOf( ":" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"%3a" +
( ( lIndex + 1 ) < lReturn.length() ? lReturn.substring( lIndex + 1 ) : "" );
lIndex = lReturn.indexOf( ":" );
}
lIndex = lReturn.indexOf( "?" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"%3f" +
( ( lIndex + 1 ) < lReturn.length() ? lReturn.substring( lIndex + 1 ) : "" );
lIndex = lReturn.indexOf( "?" );
}
lIndex = lReturn.indexOf( "=" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"%3d" +
( ( lIndex + 1 ) < lReturn.length() ? lReturn.substring( lIndex + 1 ) : "" );
lIndex = lReturn.indexOf( "=" );
}
lIndex = lReturn.indexOf( "," );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"%2c" +
( ( lIndex + 1 ) < lReturn.length() ? lReturn.substring( lIndex + 1 ) : "" );
lIndex = lReturn.indexOf( "," );
}
lIndex = lReturn.indexOf( "'" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"%27" +
( ( lIndex + 1 ) < lReturn.length() ? lReturn.substring( lIndex + 1 ) : "" );
lIndex = lReturn.indexOf( "'" );
}
lIndex = lReturn.indexOf( "\"" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"%22" +
( ( lIndex + 1 ) < lReturn.length() ? lReturn.substring( lIndex + 1 ) : "" );
lIndex = lReturn.indexOf( "\"" );
}
} else {
int lIndex = lReturn.indexOf( "%2a" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"*" +
( ( lIndex + 3 ) < lReturn.length() ? lReturn.substring( lIndex + 3 ) : "" );
lIndex = lReturn.indexOf( "%2a" );
}
lIndex = lReturn.indexOf( "%3a" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
":" +
( ( lIndex + 3 ) < lReturn.length() ? lReturn.substring( lIndex + 3 ) : "" );
lIndex = lReturn.indexOf( "%3a" );
}
lIndex = lReturn.indexOf( "%3f" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"?" +
( ( lIndex + 3 ) < lReturn.length() ? lReturn.substring( lIndex + 3 ) : "" );
lIndex = lReturn.indexOf( "%3f" );
}
lIndex = lReturn.indexOf( "%3d" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"=" +
( ( lIndex + 3 ) < lReturn.length() ? lReturn.substring( lIndex + 3 ) : "" );
lIndex = lReturn.indexOf( "%3d" );
}
lIndex = lReturn.indexOf( "%2c" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"," +
( ( lIndex + 3 ) < lReturn.length() ? lReturn.substring( lIndex + 3 ) : "" );
lIndex = lReturn.indexOf( "%2c" );
}
lIndex = lReturn.indexOf( "%25" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"%" +
( ( lIndex + 3 ) < lReturn.length() ? lReturn.substring( lIndex + 3 ) : "" );
lIndex = lReturn.indexOf( "%25" );
}
lIndex = lReturn.indexOf( "%27" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"'" +
( ( lIndex + 3 ) < lReturn.length() ? lReturn.substring( lIndex + 3 ) : "" );
lIndex = lReturn.indexOf( "%27" );
}
lIndex = lReturn.indexOf( "%22" );
while( lIndex >= 0 ) {
lReturn = ( lIndex > 0 ? lReturn.substring( 0, lIndex ) : "" ) +
"\"" +
( ( lIndex + 3 ) < lReturn.length() ? lReturn.substring( lIndex + 3 ) : "" );
lIndex = lReturn.indexOf( "%22" );
}
}
return lReturn;
}
/**
* takes the properties string and breaks it up into key/value pairs for
* insertion into a newly created hashtable.
*
* minimal validation is performed so that it doesn't blow up when
* constructing the kvp strings.
*
* checks for duplicate keys
*
* detects property patterns
*
*/
private static ObjectName createObjectName(String domain, String properties) throws MalformedObjectNameException
{
if (null == properties || properties.length() < 1)
{
throw new MalformedObjectNameException("null or empty properties");
}
// The StringTokenizer below hides malformations such as ',,' in the
// properties string or ',' as the first or last character.
// Rather than asking for tokens and building a state machine I'll
// just manually check for those 3 scenarios.
if (properties.startsWith(",") || properties.endsWith(",") || properties.indexOf(",,") != -1)
{
throw new MalformedObjectNameException("empty key/value pair in properties string");
}
Hashtable ptable = new Hashtable();
StringTokenizer tokenizer = new StringTokenizer(properties, ",");
boolean lPattern = false;
while (tokenizer.hasMoreTokens())
{
String chunk = tokenizer.nextToken();
if (chunk.equals("*"))
{
lPattern = true;
continue;
}
int keylen = chunk.length();
int eqpos = chunk.indexOf('=');
// test below: as in '=value' or 'key=' so that our substrings don't blow up
if (eqpos < 1 || (keylen == eqpos + 1))
{
throw new MalformedObjectNameException("malformed key/value pair: " + chunk);
}
String key = chunk.substring(0, eqpos);
if (ptable.containsKey(key))
{
throw new MalformedObjectNameException("duplicate key: " + key);
}
ptable.put(key, chunk.substring(eqpos + 1, keylen));
}
return createObjectName(domain, ptable, lPattern);
}
/**
* validates incoming properties hashtable
*
* builds canonical string
*
* precomputes the hashcode
*/
private static ObjectName createObjectName(String domain, Hashtable properties, boolean pPattern) throws MalformedObjectNameException
{
if (null == properties || (!pPattern && properties.size() < 1))
{
throw new MalformedObjectNameException("null or empty properties");
}
Iterator it = properties.keySet().iterator();
Hashtable lReturn = new Hashtable( properties.size() );
while (it.hasNext())
{
String key = null;
try
{
key = (String) it.next();
}
catch (ClassCastException e)
{
throw new MalformedObjectNameException("key is not a string");
}
String val = null;
try
{
val = (String) properties.get(key);
}
catch (ClassCastException e)
{
throw new MalformedObjectNameException("value is not a string");
}
// Search for invalid characters and replace them
String lKey = convertCharacters( key, true );
String lValue = convertCharacters( val, true );
lReturn.put( lKey, lValue );
}
ObjectName result = new ObjectName(domain, lReturn);
if (pPattern)
return new ObjectName(result.getCanonicalName() + ",*");
return result;
}
private static Hashtable reverseProperties( Hashtable pProperties ) {
Hashtable lReturn = new Hashtable( pProperties.size() );
Iterator i = pProperties.keySet().iterator();
while( i.hasNext() ) {
String lKey = (String) i.next();
String lValue = (String) pProperties.get( lKey );
lKey = convertCharacters( lKey, false );
lValue = convertCharacters( lValue, false );
lReturn.put( lKey, lValue );
}
return lReturn;
}
private static String reverseString( Hashtable pProperties ) {
StringBuffer lReturn = new StringBuffer();
Iterator i = pProperties.keySet().iterator();
while( i.hasNext() ) {
String lKey = (String) i.next();
String lValue = (String) pProperties.get( lKey );
lKey = convertCharacters( lKey, false );
lValue = convertCharacters( lValue, false );
if( lReturn.length() > 0 ) {
lReturn.append( "," );
}
lReturn.append( lKey );
lReturn.append( "=" );
lReturn.append( lValue );
}
return lReturn.toString();
}
}