duke@1: /*
ohair@158: * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1: *
duke@1: * This code is free software; you can redistribute it and/or modify it
duke@1: * under the terms of the GNU General Public License version 2 only, as
ohair@158: * published by the Free Software Foundation. Oracle designates this
duke@1: * particular file as subject to the "Classpath" exception as provided
ohair@158: * by Oracle in the LICENSE file that accompanied this code.
duke@1: *
duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1: * version 2 for more details (a copy is included in the LICENSE file that
duke@1: * accompanied this code).
duke@1: *
duke@1: * You should have received a copy of the GNU General Public License version
duke@1: * 2 along with this work; if not, write to the Free Software Foundation,
duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1: *
ohair@158: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@158: * or visit www.oracle.com if you need additional information or have any
ohair@158: * questions.
duke@1: */
duke@1: package com.sun.corba.se.spi.orb ;
duke@1:
duke@1: import java.util.StringTokenizer ;
duke@1:
duke@1: import java.lang.reflect.Array ;
duke@1:
duke@1: import java.net.URL ;
duke@1: import java.net.MalformedURLException ;
duke@1:
duke@1: import com.sun.corba.se.spi.logging.CORBALogDomains ;
duke@1:
duke@1: import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
duke@1: import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
duke@1: import com.sun.corba.se.impl.orbutil.ObjectUtility ;
duke@1:
duke@1: /** This is a static factory class for commonly used operations
duke@1: * for property parsing. The following operations are supported:
duke@1: *
duke@1: * - maskErrorAction( Operation op ) executes op and returns the result. If op throws an
duke@1: * exception, the result is null.
duke@1: *
- indexAction( int arg ) returns the [arg] element of value, which must be an Object[]
duke@1: * - identityAction() return the value
duke@1: * - booleanAction() return a Boolean representing true or false values of the String value
duke@1: * - integerAction() returns an Integer for the String value, which must be a decimal integer
duke@1: * - stringAction() returns the String value
duke@1: * - classAction() returns a class for the String value, as loaded by the ORB classloader
duke@1: * - setFlagAction() always return Boolean.TRUE
duke@1: * - URLAction() returns a java.net.URL for the String value, which must be a valid URL
duke@1: * - integerRangeAction( int min, int max ) returns an Integer for the String value, which must be a
duke@1: * decimal integer in the range min to max inclusive
duke@1: * - listAction( String sep, Operation ) tokenizes the String value with sep as separator, then
duke@1: * applies the Operation to each token, and returns an array of the result
duke@1: * - sequenceAction( String, Operation[] ) tokenizes the String value with sep as separator, then
duke@1: * applies each Operation in the Operation array to successive tokens, and returns an array of the results
duke@1: * - compose( Operation op1, Operation op2 ) is the operation that applies op2 to the result of applying
duke@1: * op1 to the value
duke@1: * - mapAction( Operation ) applies the Operation to each element of an array of objects, and returns
duke@1: * an array of the results
duke@1: * - mapSequenceAction( Operation[] ) applies the corresponding element of the Operation array to an
duke@1: * element of the Object[] value, and returns an array of the results
duke@1: * - convertIntegerToShort coerces an Integer into a Short.
duke@1: *
duke@1: * Other operations can be directly defined, and combined using these basic operations.
duke@1: */
duke@1: public abstract class OperationFactory {
duke@1: private OperationFactory() {}
duke@1:
duke@1: private static String getString( Object obj )
duke@1: {
duke@1: if (obj instanceof String)
duke@1: return (String)obj ;
duke@1: else
duke@1: throw new Error( "String expected" ) ;
duke@1: }
duke@1:
duke@1: private static Object[] getObjectArray( Object obj )
duke@1: {
duke@1: if (obj instanceof Object[])
duke@1: return (Object[])obj ;
duke@1: else
duke@1: throw new Error( "Object[] expected" ) ;
duke@1: }
duke@1:
duke@1: private static StringPair getStringPair( Object obj )
duke@1: {
duke@1: if (obj instanceof StringPair)
duke@1: return (StringPair)obj ;
duke@1: else
duke@1: throw new Error( "StringPair expected" ) ;
duke@1: }
duke@1:
duke@1: private static abstract class OperationBase implements Operation{
duke@1: public boolean equals( Object obj )
duke@1: {
duke@1: if (this==obj)
duke@1: return true ;
duke@1:
duke@1: if (!(obj instanceof OperationBase))
duke@1: return false ;
duke@1:
duke@1: OperationBase other = (OperationBase)obj ;
duke@1:
duke@1: return toString().equals( other.toString() ) ;
duke@1: }
duke@1:
duke@1: public int hashCode()
duke@1: {
duke@1: return toString().hashCode() ;
duke@1: }
duke@1: }
duke@1:
duke@1: private static class MaskErrorAction extends OperationBase
duke@1: {
duke@1: private Operation op ;
duke@1:
duke@1: public MaskErrorAction( Operation op )
duke@1: {
duke@1: this.op = op ;
duke@1: }
duke@1:
duke@1: public Object operate( Object arg )
duke@1: {
duke@1: try {
duke@1: return op.operate( arg ) ;
duke@1: } catch (java.lang.Exception exc) {
duke@1: return null ;
duke@1: }
duke@1: }
duke@1:
duke@1: public String toString()
duke@1: {
duke@1: return "maskErrorAction(" + op + ")" ;
duke@1: }
duke@1: }
duke@1:
duke@1: public static Operation maskErrorAction( Operation op )
duke@1: {
duke@1: return new MaskErrorAction( op ) ;
duke@1: }
duke@1:
duke@1: private static class IndexAction extends OperationBase
duke@1: {
duke@1: private int index ;
duke@1:
duke@1: public IndexAction( int index )
duke@1: {
duke@1: this.index = index ;
duke@1: }
duke@1:
duke@1: public Object operate( Object value )
duke@1: {
duke@1: return getObjectArray( value )[ index ] ;
duke@1: }
duke@1:
duke@1: public String toString()
duke@1: {
duke@1: return "indexAction(" + index + ")" ;
duke@1: }
duke@1: }
duke@1:
duke@1: public static Operation indexAction( int index )
duke@1: {
duke@1: return new IndexAction( index ) ;
duke@1: }
duke@1:
duke@1: private static class SuffixAction extends OperationBase
duke@1: {
duke@1: public Object operate( Object value )
duke@1: {
duke@1: return getStringPair( value ).getFirst() ;
duke@1: }
duke@1:
duke@1: public String toString() { return "suffixAction" ; }
duke@1: }
duke@1:
duke@1: private static Operation suffixActionImpl = new SuffixAction() ;
duke@1:
duke@1: private static class ValueAction extends OperationBase
duke@1: {
duke@1: public Object operate( Object value )
duke@1: {
duke@1: return getStringPair( value ).getSecond() ;
duke@1: }
duke@1:
duke@1: public String toString() { return "valueAction" ; }
duke@1: }
duke@1:
duke@1: private static Operation valueActionImpl = new ValueAction() ;
duke@1:
duke@1: private static class IdentityAction extends OperationBase
duke@1: {
duke@1: public Object operate( Object value )
duke@1: {
duke@1: return value ;
duke@1: }
duke@1:
duke@1: public String toString() { return "identityAction" ; }
duke@1: }
duke@1:
duke@1: private static Operation identityActionImpl = new IdentityAction() ;
duke@1:
duke@1: private static class BooleanAction extends OperationBase
duke@1: {
duke@1: public Object operate( Object value )
duke@1: {
duke@1: return new Boolean( getString( value ) ) ;
duke@1: }
duke@1:
duke@1: public String toString() { return "booleanAction" ; }
duke@1: }
duke@1:
duke@1: private static Operation booleanActionImpl = new BooleanAction() ;
duke@1:
duke@1: private static class IntegerAction extends OperationBase
duke@1: {
duke@1: public Object operate( Object value )
duke@1: {
duke@1: return new Integer( getString( value ) ) ;
duke@1: }
duke@1:
duke@1: public String toString() { return "integerAction" ; }
duke@1: }
duke@1:
duke@1: private static Operation integerActionImpl = new IntegerAction() ;
duke@1:
duke@1: private static class StringAction extends OperationBase
duke@1: {
duke@1: public Object operate( Object value )
duke@1: {
duke@1: return value ;
duke@1: }
duke@1:
duke@1: public String toString() { return "stringAction" ; }
duke@1: }
duke@1:
duke@1: private static Operation stringActionImpl = new StringAction() ;
duke@1:
duke@1: private static class ClassAction extends OperationBase
duke@1: {
duke@1: public Object operate( Object value )
duke@1: {
duke@1: String className = getString( value ) ;
duke@1:
duke@1: try {
duke@1: Class result = ORBClassLoader.loadClass( className ) ;
duke@1: return result ;
duke@1: } catch (Exception exc) {
duke@1: ORBUtilSystemException wrapper = ORBUtilSystemException.get(
duke@1: CORBALogDomains.ORB_LIFECYCLE ) ;
duke@1: throw wrapper.couldNotLoadClass( exc, className ) ;
duke@1: }
duke@1: }
duke@1:
duke@1: public String toString() { return "classAction" ; }
duke@1: }
duke@1:
duke@1: private static Operation classActionImpl = new ClassAction() ;
duke@1:
duke@1: private static class SetFlagAction extends OperationBase
duke@1: {
duke@1: public Object operate( Object value )
duke@1: {
duke@1: return Boolean.TRUE ;
duke@1: }
duke@1:
duke@1: public String toString() { return "setFlagAction" ; }
duke@1: }
duke@1:
duke@1: private static Operation setFlagActionImpl = new SetFlagAction() ;
duke@1:
duke@1: private static class URLAction extends OperationBase
duke@1: {
duke@1: public Object operate( Object value )
duke@1: {
duke@1: String val = (String)value ;
duke@1: try {
duke@1: return new URL( val ) ;
duke@1: } catch (MalformedURLException exc) {
duke@1: ORBUtilSystemException wrapper = ORBUtilSystemException.get(
duke@1: CORBALogDomains.ORB_LIFECYCLE ) ;
duke@1: throw wrapper.badUrl( exc, val ) ;
duke@1: }
duke@1: }
duke@1:
duke@1: public String toString() { return "URLAction" ; }
duke@1: }
duke@1:
duke@1: private static Operation URLActionImpl = new URLAction() ;
duke@1:
duke@1: public static Operation identityAction()
duke@1: {
duke@1: return identityActionImpl ;
duke@1: }
duke@1:
duke@1: public static Operation suffixAction()
duke@1: {
duke@1: return suffixActionImpl ;
duke@1: }
duke@1:
duke@1: public static Operation valueAction()
duke@1: {
duke@1: return valueActionImpl ;
duke@1: }
duke@1:
duke@1: public static Operation booleanAction()
duke@1: {
duke@1: return booleanActionImpl ;
duke@1: }
duke@1:
duke@1: public static Operation integerAction()
duke@1: {
duke@1: return integerActionImpl ;
duke@1: }
duke@1:
duke@1: public static Operation stringAction()
duke@1: {
duke@1: return stringActionImpl ;
duke@1: }
duke@1:
duke@1: public static Operation classAction()
duke@1: {
duke@1: return classActionImpl ;
duke@1: }
duke@1:
duke@1: public static Operation setFlagAction()
duke@1: {
duke@1: return setFlagActionImpl ;
duke@1: }
duke@1:
duke@1: public static Operation URLAction()
duke@1: {
duke@1: return URLActionImpl ;
duke@1: }
duke@1:
duke@1: private static class IntegerRangeAction extends OperationBase
duke@1: {
duke@1: private int min ;
duke@1: private int max ;
duke@1:
duke@1: IntegerRangeAction( int min, int max )
duke@1: {
duke@1: this.min = min ;
duke@1: this.max = max ;
duke@1: }
duke@1:
duke@1: public Object operate( Object value )
duke@1: {
duke@1: int result = Integer.parseInt( getString( value ) ) ;
duke@1: if ((result >= min) && (result <= max))
duke@1: return new Integer( result ) ;
duke@1: else
duke@1: throw new IllegalArgumentException(
duke@1: "Property value " + result + " is not in the range " +
duke@1: min + " to " + max ) ;
duke@1: }
duke@1:
duke@1: public String toString() {
duke@1: return "integerRangeAction(" + min + "," + max + ")" ;
duke@1: }
duke@1: }
duke@1:
duke@1: public static Operation integerRangeAction( int min, int max )
duke@1: {
duke@1: return new IntegerRangeAction( min, max ) ;
duke@1: }
duke@1:
duke@1: private static class ListAction extends OperationBase {
duke@1: private String sep ;
duke@1: private Operation act ;
duke@1:
duke@1: ListAction( String sep, Operation act )
duke@1: {
duke@1: this.sep = sep ;
duke@1: this.act = act ;
duke@1: }
duke@1:
duke@1: // Note that this method carefully constructs an array of the type
duke@1: // of the first result, rather than just using Object[], which is
duke@1: // not convertible into the correct type. Also note that no tokens
duke@1: // results in a null result.
duke@1: public Object operate( Object value )
duke@1: {
duke@1: StringTokenizer st = new StringTokenizer( getString( value ),
duke@1: sep ) ;
duke@1: int length = st.countTokens() ;
duke@1: Object result = null ;
duke@1: int ctr = 0 ;
duke@1: while (st.hasMoreTokens()) {
duke@1: String next = st.nextToken() ;
duke@1: Object val = act.operate( next ) ;
duke@1: if (result == null)
duke@1: result = Array.newInstance( val.getClass(), length ) ;
duke@1: Array.set( result, ctr++, val ) ;
duke@1: }
duke@1:
duke@1: return result ;
duke@1: }
duke@1:
duke@1: public String toString() {
duke@1: return "listAction(separator=\"" + sep +
duke@1: "\",action=" + act + ")" ;
duke@1: }
duke@1: }
duke@1:
duke@1: public static Operation listAction( String sep, Operation act )
duke@1: {
duke@1: return new ListAction( sep, act ) ;
duke@1: }
duke@1:
duke@1: private static class SequenceAction extends OperationBase
duke@1: {
duke@1: private String sep ;
duke@1: private Operation[] actions ;
duke@1:
duke@1: SequenceAction( String sep, Operation[] actions )
duke@1: {
duke@1: this.sep = sep ;
duke@1: this.actions = actions ;
duke@1: }
duke@1:
duke@1: public Object operate( Object value )
duke@1: {
duke@1: StringTokenizer st = new StringTokenizer( getString( value ),
duke@1: sep ) ;
duke@1:
duke@1: int numTokens = st.countTokens() ;
duke@1: if (numTokens != actions.length)
duke@1: throw new Error(
duke@1: "Number of tokens and number of actions do not match" ) ;
duke@1:
duke@1: int ctr = 0 ;
duke@1: Object[] result = new Object[ numTokens ] ;
duke@1: while (st.hasMoreTokens()) {
duke@1: Operation act = actions[ctr] ;
duke@1: String next = st.nextToken() ;
duke@1: result[ctr++] = act.operate( next ) ;
duke@1: }
duke@1:
duke@1: return result ;
duke@1: }
duke@1:
duke@1: public String toString() {
duke@1: return "sequenceAction(separator=\"" + sep +
duke@1: "\",actions=" +
duke@1: ObjectUtility.compactObjectToString(actions) + ")" ;
duke@1: }
duke@1: }
duke@1:
duke@1: public static Operation sequenceAction( String sep,
duke@1: Operation[] actions )
duke@1: {
duke@1: return new SequenceAction( sep, actions ) ;
duke@1: }
duke@1:
duke@1: private static class ComposeAction extends OperationBase
duke@1: {
duke@1: private Operation op1 ;
duke@1: private Operation op2 ;
duke@1:
duke@1: ComposeAction( Operation op1, Operation op2 )
duke@1: {
duke@1: this.op1 = op1 ;
duke@1: this.op2 = op2 ;
duke@1: }
duke@1:
duke@1: public Object operate( Object value )
duke@1: {
duke@1: return op2.operate( op1.operate( value ) ) ;
duke@1: }
duke@1:
duke@1: public String toString() {
duke@1: return "composition(" + op1 + "," + op2 + ")" ;
duke@1: }
duke@1: }
duke@1:
duke@1: public static Operation compose( Operation op1, Operation op2 )
duke@1: {
duke@1: return new ComposeAction( op1, op2 ) ;
duke@1: }
duke@1:
duke@1: private static class MapAction extends OperationBase
duke@1: {
duke@1: Operation op ;
duke@1:
duke@1: MapAction( Operation op )
duke@1: {
duke@1: this.op = op ;
duke@1: }
duke@1:
duke@1: public Object operate( Object value )
duke@1: {
duke@1: Object[] values = (Object[])value ;
duke@1: Object[] result = new Object[ values.length ] ;
duke@1: for (int ctr=0; ctr