package org.cyclopsgroup.jmxterm; import java.io.IOException; import java.io.PrintStream; import java.util.regex.Pattern; import javax.management.remote.JMXServiceURL; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.io.output.NullOutputStream; import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.cyclopsgroup.jmxterm.utils.ValueFormat; /** * Utility class for syntax checking * * @author <a href="mailto:jiaqi.guo@gmail.com">Jiaqi Guo</a> */ public final class SyntaxUtils { /** * NULL string identifier */ public static final String NULL = ValueFormat.NULL; /** * Null print stream to redirect std streams */ public static final PrintStream NULL_PRINT_STREAM = new PrintStream( new NullOutputStream(), true ); private static final Pattern PATTERN_HOST_PORT = Pattern.compile( "^(\\w|\\.|\\-)+\\:\\d+$" ); /** * @param url String expression of MBean server URL or abbreviation like localhost:9991 * @param jpm Java process manager to get process URL * @return Parsed JMXServerURL * @throws IOException IO error */ public static JMXServiceURL getUrl( String url, JavaProcessManager jpm ) throws IOException { if ( StringUtils.isEmpty( url ) ) { throw new IllegalArgumentException( "Empty URL is not allowed" ); } else if ( NumberUtils.isDigits( url ) && jpm != null ) { Integer pid = Integer.parseInt( url ); JavaProcess p; // classworlds has some hard coded stdout printing. Therefore stdout needs to be redirected temporarily to // avoid meaningless console output PrintStream stdOut = System.out; System.setOut( NULL_PRINT_STREAM ); try { p = jpm.get( pid ); if ( p == null ) { throw new NullPointerException( "No such PID " + pid ); } if ( !p.isManageable() ) { p.startManagementAgent(); if ( !p.isManageable() ) { throw new IllegalStateException( "Managed agent for PID " + pid + " couldn't start. PID " + pid + " is not manageable" ); } } return new JMXServiceURL( p.toUrl() ); } finally { System.setOut( stdOut ); } } else if ( PATTERN_HOST_PORT.matcher( url ).find() ) { return new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://" + url + "/jmxrmi" ); } else { return new JMXServiceURL( url ); } } /** * Check if string value is <code>null</code> * * @param s String value * @return True if value is <code>null</code> */ public static boolean isNull( String s ) { return StringUtils.equalsIgnoreCase( NULL, s ) || StringUtils.equals( "*", s ); } /** * Parse given string expression to expected type of value * * @param expression String expression * @param type Target type * @return Object of value */ public static Object parse( String expression, String type ) { if ( expression == null || StringUtils.equalsIgnoreCase( NULL, expression ) ) { return null; } Class<?> c; try { c = ClassUtils.getClass( type ); } catch ( ClassNotFoundException e ) { throw new IllegalArgumentException( "Type " + type + " isn't valid", e ); } if ( c == String.class ) { return expression; } if ( StringUtils.isEmpty( expression ) ) { return null; } return ConvertUtils.convert( expression, c ); } private SyntaxUtils() { } }