All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.mx.util.ObjectNameConverter Maven / Gradle / Ivy

There is a newer version: 6.0.0.M1
Show newest version
/*
* 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(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy