1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,564 @@ 1.4 +/* 1.5 + * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Sun designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Sun in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.26 + * have any questions. 1.27 + */ 1.28 +package com.sun.corba.se.spi.orb ; 1.29 + 1.30 +import java.util.StringTokenizer ; 1.31 + 1.32 +import java.lang.reflect.Array ; 1.33 + 1.34 +import java.net.URL ; 1.35 +import java.net.MalformedURLException ; 1.36 + 1.37 +import com.sun.corba.se.spi.logging.CORBALogDomains ; 1.38 + 1.39 +import com.sun.corba.se.impl.logging.ORBUtilSystemException ; 1.40 +import com.sun.corba.se.impl.orbutil.ORBClassLoader ; 1.41 +import com.sun.corba.se.impl.orbutil.ObjectUtility ; 1.42 + 1.43 +/** This is a static factory class for commonly used operations 1.44 +* for property parsing. The following operations are supported: 1.45 +* <ul> 1.46 +* <li>maskErrorAction( Operation op ) executes op and returns the result. If op throws an 1.47 +* exception, the result is null. 1.48 +* <li>indexAction( int arg ) returns the [arg] element of value, which must be an Object[]</li> 1.49 +* <li>identityAction() return the value</li> 1.50 +* <li>booleanAction() return a Boolean representing true or false values of the String value</li> 1.51 +* <li>integerAction() returns an Integer for the String value, which must be a decimal integer</li> 1.52 +* <li>stringAction() returns the String value</li> 1.53 +* <li>classAction() returns a class for the String value, as loaded by the ORB classloader</li> 1.54 +* <li>setFlagAction() always return Boolean.TRUE</li> 1.55 +* <li>URLAction() returns a java.net.URL for the String value, which must be a valid URL</li> 1.56 +* <li>integerRangeAction( int min, int max ) returns an Integer for the String value, which must be a 1.57 +* decimal integer in the range min to max inclusive</li> 1.58 +* <li>listAction( String sep, Operation ) tokenizes the String value with sep as separator, then 1.59 +* applies the Operation to each token, and returns an array of the result</li> 1.60 +* <li>sequenceAction( String, Operation[] ) tokenizes the String value with sep as separator, then 1.61 +* applies each Operation in the Operation array to successive tokens, and returns an array of the results</li> 1.62 +* <li>compose( Operation op1, Operation op2 ) is the operation that applies op2 to the result of applying 1.63 +* op1 to the value</li> 1.64 +* <li>mapAction( Operation ) applies the Operation to each element of an array of objects, and returns 1.65 +* an array of the results</li> 1.66 +* <li>mapSequenceAction( Operation[] ) applies the corresponding element of the Operation array to an 1.67 +* element of the Object[] value, and returns an array of the results</li> 1.68 +* <li>convertIntegerToShort coerces an Integer into a Short.</li> 1.69 +* </ul> 1.70 +* Other operations can be directly defined, and combined using these basic operations. 1.71 +*/ 1.72 +public abstract class OperationFactory { 1.73 + private OperationFactory() {} 1.74 + 1.75 + private static String getString( Object obj ) 1.76 + { 1.77 + if (obj instanceof String) 1.78 + return (String)obj ; 1.79 + else 1.80 + throw new Error( "String expected" ) ; 1.81 + } 1.82 + 1.83 + private static Object[] getObjectArray( Object obj ) 1.84 + { 1.85 + if (obj instanceof Object[]) 1.86 + return (Object[])obj ; 1.87 + else 1.88 + throw new Error( "Object[] expected" ) ; 1.89 + } 1.90 + 1.91 + private static StringPair getStringPair( Object obj ) 1.92 + { 1.93 + if (obj instanceof StringPair) 1.94 + return (StringPair)obj ; 1.95 + else 1.96 + throw new Error( "StringPair expected" ) ; 1.97 + } 1.98 + 1.99 + private static abstract class OperationBase implements Operation{ 1.100 + public boolean equals( Object obj ) 1.101 + { 1.102 + if (this==obj) 1.103 + return true ; 1.104 + 1.105 + if (!(obj instanceof OperationBase)) 1.106 + return false ; 1.107 + 1.108 + OperationBase other = (OperationBase)obj ; 1.109 + 1.110 + return toString().equals( other.toString() ) ; 1.111 + } 1.112 + 1.113 + public int hashCode() 1.114 + { 1.115 + return toString().hashCode() ; 1.116 + } 1.117 + } 1.118 + 1.119 + private static class MaskErrorAction extends OperationBase 1.120 + { 1.121 + private Operation op ; 1.122 + 1.123 + public MaskErrorAction( Operation op ) 1.124 + { 1.125 + this.op = op ; 1.126 + } 1.127 + 1.128 + public Object operate( Object arg ) 1.129 + { 1.130 + try { 1.131 + return op.operate( arg ) ; 1.132 + } catch (java.lang.Exception exc) { 1.133 + return null ; 1.134 + } 1.135 + } 1.136 + 1.137 + public String toString() 1.138 + { 1.139 + return "maskErrorAction(" + op + ")" ; 1.140 + } 1.141 + } 1.142 + 1.143 + public static Operation maskErrorAction( Operation op ) 1.144 + { 1.145 + return new MaskErrorAction( op ) ; 1.146 + } 1.147 + 1.148 + private static class IndexAction extends OperationBase 1.149 + { 1.150 + private int index ; 1.151 + 1.152 + public IndexAction( int index ) 1.153 + { 1.154 + this.index = index ; 1.155 + } 1.156 + 1.157 + public Object operate( Object value ) 1.158 + { 1.159 + return getObjectArray( value )[ index ] ; 1.160 + } 1.161 + 1.162 + public String toString() 1.163 + { 1.164 + return "indexAction(" + index + ")" ; 1.165 + } 1.166 + } 1.167 + 1.168 + public static Operation indexAction( int index ) 1.169 + { 1.170 + return new IndexAction( index ) ; 1.171 + } 1.172 + 1.173 + private static class SuffixAction extends OperationBase 1.174 + { 1.175 + public Object operate( Object value ) 1.176 + { 1.177 + return getStringPair( value ).getFirst() ; 1.178 + } 1.179 + 1.180 + public String toString() { return "suffixAction" ; } 1.181 + } 1.182 + 1.183 + private static Operation suffixActionImpl = new SuffixAction() ; 1.184 + 1.185 + private static class ValueAction extends OperationBase 1.186 + { 1.187 + public Object operate( Object value ) 1.188 + { 1.189 + return getStringPair( value ).getSecond() ; 1.190 + } 1.191 + 1.192 + public String toString() { return "valueAction" ; } 1.193 + } 1.194 + 1.195 + private static Operation valueActionImpl = new ValueAction() ; 1.196 + 1.197 + private static class IdentityAction extends OperationBase 1.198 + { 1.199 + public Object operate( Object value ) 1.200 + { 1.201 + return value ; 1.202 + } 1.203 + 1.204 + public String toString() { return "identityAction" ; } 1.205 + } 1.206 + 1.207 + private static Operation identityActionImpl = new IdentityAction() ; 1.208 + 1.209 + private static class BooleanAction extends OperationBase 1.210 + { 1.211 + public Object operate( Object value ) 1.212 + { 1.213 + return new Boolean( getString( value ) ) ; 1.214 + } 1.215 + 1.216 + public String toString() { return "booleanAction" ; } 1.217 + } 1.218 + 1.219 + private static Operation booleanActionImpl = new BooleanAction() ; 1.220 + 1.221 + private static class IntegerAction extends OperationBase 1.222 + { 1.223 + public Object operate( Object value ) 1.224 + { 1.225 + return new Integer( getString( value ) ) ; 1.226 + } 1.227 + 1.228 + public String toString() { return "integerAction" ; } 1.229 + } 1.230 + 1.231 + private static Operation integerActionImpl = new IntegerAction() ; 1.232 + 1.233 + private static class StringAction extends OperationBase 1.234 + { 1.235 + public Object operate( Object value ) 1.236 + { 1.237 + return value ; 1.238 + } 1.239 + 1.240 + public String toString() { return "stringAction" ; } 1.241 + } 1.242 + 1.243 + private static Operation stringActionImpl = new StringAction() ; 1.244 + 1.245 + private static class ClassAction extends OperationBase 1.246 + { 1.247 + public Object operate( Object value ) 1.248 + { 1.249 + String className = getString( value ) ; 1.250 + 1.251 + try { 1.252 + Class result = ORBClassLoader.loadClass( className ) ; 1.253 + return result ; 1.254 + } catch (Exception exc) { 1.255 + ORBUtilSystemException wrapper = ORBUtilSystemException.get( 1.256 + CORBALogDomains.ORB_LIFECYCLE ) ; 1.257 + throw wrapper.couldNotLoadClass( exc, className ) ; 1.258 + } 1.259 + } 1.260 + 1.261 + public String toString() { return "classAction" ; } 1.262 + } 1.263 + 1.264 + private static Operation classActionImpl = new ClassAction() ; 1.265 + 1.266 + private static class SetFlagAction extends OperationBase 1.267 + { 1.268 + public Object operate( Object value ) 1.269 + { 1.270 + return Boolean.TRUE ; 1.271 + } 1.272 + 1.273 + public String toString() { return "setFlagAction" ; } 1.274 + } 1.275 + 1.276 + private static Operation setFlagActionImpl = new SetFlagAction() ; 1.277 + 1.278 + private static class URLAction extends OperationBase 1.279 + { 1.280 + public Object operate( Object value ) 1.281 + { 1.282 + String val = (String)value ; 1.283 + try { 1.284 + return new URL( val ) ; 1.285 + } catch (MalformedURLException exc) { 1.286 + ORBUtilSystemException wrapper = ORBUtilSystemException.get( 1.287 + CORBALogDomains.ORB_LIFECYCLE ) ; 1.288 + throw wrapper.badUrl( exc, val ) ; 1.289 + } 1.290 + } 1.291 + 1.292 + public String toString() { return "URLAction" ; } 1.293 + } 1.294 + 1.295 + private static Operation URLActionImpl = new URLAction() ; 1.296 + 1.297 + public static Operation identityAction() 1.298 + { 1.299 + return identityActionImpl ; 1.300 + } 1.301 + 1.302 + public static Operation suffixAction() 1.303 + { 1.304 + return suffixActionImpl ; 1.305 + } 1.306 + 1.307 + public static Operation valueAction() 1.308 + { 1.309 + return valueActionImpl ; 1.310 + } 1.311 + 1.312 + public static Operation booleanAction() 1.313 + { 1.314 + return booleanActionImpl ; 1.315 + } 1.316 + 1.317 + public static Operation integerAction() 1.318 + { 1.319 + return integerActionImpl ; 1.320 + } 1.321 + 1.322 + public static Operation stringAction() 1.323 + { 1.324 + return stringActionImpl ; 1.325 + } 1.326 + 1.327 + public static Operation classAction() 1.328 + { 1.329 + return classActionImpl ; 1.330 + } 1.331 + 1.332 + public static Operation setFlagAction() 1.333 + { 1.334 + return setFlagActionImpl ; 1.335 + } 1.336 + 1.337 + public static Operation URLAction() 1.338 + { 1.339 + return URLActionImpl ; 1.340 + } 1.341 + 1.342 + private static class IntegerRangeAction extends OperationBase 1.343 + { 1.344 + private int min ; 1.345 + private int max ; 1.346 + 1.347 + IntegerRangeAction( int min, int max ) 1.348 + { 1.349 + this.min = min ; 1.350 + this.max = max ; 1.351 + } 1.352 + 1.353 + public Object operate( Object value ) 1.354 + { 1.355 + int result = Integer.parseInt( getString( value ) ) ; 1.356 + if ((result >= min) && (result <= max)) 1.357 + return new Integer( result ) ; 1.358 + else 1.359 + throw new IllegalArgumentException( 1.360 + "Property value " + result + " is not in the range " + 1.361 + min + " to " + max ) ; 1.362 + } 1.363 + 1.364 + public String toString() { 1.365 + return "integerRangeAction(" + min + "," + max + ")" ; 1.366 + } 1.367 + } 1.368 + 1.369 + public static Operation integerRangeAction( int min, int max ) 1.370 + { 1.371 + return new IntegerRangeAction( min, max ) ; 1.372 + } 1.373 + 1.374 + private static class ListAction extends OperationBase { 1.375 + private String sep ; 1.376 + private Operation act ; 1.377 + 1.378 + ListAction( String sep, Operation act ) 1.379 + { 1.380 + this.sep = sep ; 1.381 + this.act = act ; 1.382 + } 1.383 + 1.384 + // Note that this method carefully constructs an array of the type 1.385 + // of the first result, rather than just using Object[], which is 1.386 + // not convertible into the correct type. Also note that no tokens 1.387 + // results in a null result. 1.388 + public Object operate( Object value ) 1.389 + { 1.390 + StringTokenizer st = new StringTokenizer( getString( value ), 1.391 + sep ) ; 1.392 + int length = st.countTokens() ; 1.393 + Object result = null ; 1.394 + int ctr = 0 ; 1.395 + while (st.hasMoreTokens()) { 1.396 + String next = st.nextToken() ; 1.397 + Object val = act.operate( next ) ; 1.398 + if (result == null) 1.399 + result = Array.newInstance( val.getClass(), length ) ; 1.400 + Array.set( result, ctr++, val ) ; 1.401 + } 1.402 + 1.403 + return result ; 1.404 + } 1.405 + 1.406 + public String toString() { 1.407 + return "listAction(separator=\"" + sep + 1.408 + "\",action=" + act + ")" ; 1.409 + } 1.410 + } 1.411 + 1.412 + public static Operation listAction( String sep, Operation act ) 1.413 + { 1.414 + return new ListAction( sep, act ) ; 1.415 + } 1.416 + 1.417 + private static class SequenceAction extends OperationBase 1.418 + { 1.419 + private String sep ; 1.420 + private Operation[] actions ; 1.421 + 1.422 + SequenceAction( String sep, Operation[] actions ) 1.423 + { 1.424 + this.sep = sep ; 1.425 + this.actions = actions ; 1.426 + } 1.427 + 1.428 + public Object operate( Object value ) 1.429 + { 1.430 + StringTokenizer st = new StringTokenizer( getString( value ), 1.431 + sep ) ; 1.432 + 1.433 + int numTokens = st.countTokens() ; 1.434 + if (numTokens != actions.length) 1.435 + throw new Error( 1.436 + "Number of tokens and number of actions do not match" ) ; 1.437 + 1.438 + int ctr = 0 ; 1.439 + Object[] result = new Object[ numTokens ] ; 1.440 + while (st.hasMoreTokens()) { 1.441 + Operation act = actions[ctr] ; 1.442 + String next = st.nextToken() ; 1.443 + result[ctr++] = act.operate( next ) ; 1.444 + } 1.445 + 1.446 + return result ; 1.447 + } 1.448 + 1.449 + public String toString() { 1.450 + return "sequenceAction(separator=\"" + sep + 1.451 + "\",actions=" + 1.452 + ObjectUtility.compactObjectToString(actions) + ")" ; 1.453 + } 1.454 + } 1.455 + 1.456 + public static Operation sequenceAction( String sep, 1.457 + Operation[] actions ) 1.458 + { 1.459 + return new SequenceAction( sep, actions ) ; 1.460 + } 1.461 + 1.462 + private static class ComposeAction extends OperationBase 1.463 + { 1.464 + private Operation op1 ; 1.465 + private Operation op2 ; 1.466 + 1.467 + ComposeAction( Operation op1, Operation op2 ) 1.468 + { 1.469 + this.op1 = op1 ; 1.470 + this.op2 = op2 ; 1.471 + } 1.472 + 1.473 + public Object operate( Object value ) 1.474 + { 1.475 + return op2.operate( op1.operate( value ) ) ; 1.476 + } 1.477 + 1.478 + public String toString() { 1.479 + return "composition(" + op1 + "," + op2 + ")" ; 1.480 + } 1.481 + } 1.482 + 1.483 + public static Operation compose( Operation op1, Operation op2 ) 1.484 + { 1.485 + return new ComposeAction( op1, op2 ) ; 1.486 + } 1.487 + 1.488 + private static class MapAction extends OperationBase 1.489 + { 1.490 + Operation op ; 1.491 + 1.492 + MapAction( Operation op ) 1.493 + { 1.494 + this.op = op ; 1.495 + } 1.496 + 1.497 + public Object operate( Object value ) 1.498 + { 1.499 + Object[] values = (Object[])value ; 1.500 + Object[] result = new Object[ values.length ] ; 1.501 + for (int ctr=0; ctr<values.length; ctr++ ) 1.502 + result[ctr] = op.operate( values[ctr] ) ; 1.503 + return result ; 1.504 + } 1.505 + 1.506 + public String toString() { 1.507 + return "mapAction(" + op + ")" ; 1.508 + } 1.509 + } 1.510 + 1.511 + public static Operation mapAction( Operation op ) 1.512 + { 1.513 + return new MapAction( op ) ; 1.514 + } 1.515 + 1.516 + private static class MapSequenceAction extends OperationBase 1.517 + { 1.518 + private Operation[] op ; 1.519 + 1.520 + public MapSequenceAction( Operation[] op ) 1.521 + { 1.522 + this.op = op ; 1.523 + } 1.524 + 1.525 + // XXX Does this correctly handle array types? It seems 1.526 + // that hetereogeneous arrays work this way, while 1.527 + // homogeneous arrays need to use Array.newInstance tricks. 1.528 + public Object operate( Object value ) 1.529 + { 1.530 + Object[] values = (Object[])value ; 1.531 + Object[] result = new Object[ values.length ] ; 1.532 + for (int ctr=0; ctr<values.length; ctr++ ) 1.533 + result[ctr] = op[ctr].operate( values[ctr] ) ; 1.534 + return result ; 1.535 + } 1.536 + 1.537 + public String toString() { 1.538 + return "mapSequenceAction(" + 1.539 + ObjectUtility.compactObjectToString(op) + ")" ; 1.540 + } 1.541 + } 1.542 + 1.543 + public static Operation mapSequenceAction( Operation[] op ) 1.544 + { 1.545 + return new MapSequenceAction( op ) ; 1.546 + } 1.547 + 1.548 + private static class ConvertIntegerToShort extends OperationBase 1.549 + { 1.550 + public Object operate( Object value ) 1.551 + { 1.552 + Integer val = (Integer)value ; 1.553 + return new Short( val.shortValue() ) ; 1.554 + } 1.555 + 1.556 + public String toString() { 1.557 + return "ConvertIntegerToShort" ; 1.558 + } 1.559 + } 1.560 + 1.561 + private static Operation convertIntegerToShortImpl = new ConvertIntegerToShort() ; 1.562 + 1.563 + public static Operation convertIntegerToShort() 1.564 + { 1.565 + return convertIntegerToShortImpl ; 1.566 + } 1.567 +}