src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java

Mon, 08 Apr 2013 23:12:03 +0100

author
coffeys
date
Mon, 08 Apr 2013 23:12:03 +0100
changeset 475
39d15bbb5741
parent 205
b2fff4b7e8cd
child 748
6845b95cba6b
permissions
-rw-r--r--

8001032: Restrict object access
Summary: Restrict object access; fix reviewed also by Alexander Fomin
Reviewed-by: alanb, ahgross

duke@1 1 /*
coffeys@475 2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
ohair@158 7 * published by the Free Software Foundation. Oracle designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
ohair@158 9 * by Oracle in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
ohair@158 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@158 22 * or visit www.oracle.com if you need additional information or have any
ohair@158 23 * questions.
duke@1 24 */
duke@1 25 package com.sun.corba.se.spi.orb ;
duke@1 26
duke@1 27 import java.util.StringTokenizer ;
skoppar@205 28 import java.util.Arrays ;
duke@1 29
duke@1 30 import java.lang.reflect.Array ;
duke@1 31
duke@1 32 import java.net.URL ;
duke@1 33 import java.net.MalformedURLException ;
duke@1 34
duke@1 35 import com.sun.corba.se.spi.logging.CORBALogDomains ;
duke@1 36
duke@1 37 import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
duke@1 38 import com.sun.corba.se.impl.orbutil.ObjectUtility ;
duke@1 39
coffeys@475 40 import sun.corba.SharedSecrets;
coffeys@475 41
duke@1 42 /** This is a static factory class for commonly used operations
duke@1 43 * for property parsing. The following operations are supported:
duke@1 44 * <ul>
duke@1 45 * <li>maskErrorAction( Operation op ) executes op and returns the result. If op throws an
duke@1 46 * exception, the result is null.
duke@1 47 * <li>indexAction( int arg ) returns the [arg] element of value, which must be an Object[]</li>
duke@1 48 * <li>identityAction() return the value</li>
duke@1 49 * <li>booleanAction() return a Boolean representing true or false values of the String value</li>
duke@1 50 * <li>integerAction() returns an Integer for the String value, which must be a decimal integer</li>
duke@1 51 * <li>stringAction() returns the String value</li>
duke@1 52 * <li>classAction() returns a class for the String value, as loaded by the ORB classloader</li>
duke@1 53 * <li>setFlagAction() always return Boolean.TRUE</li>
duke@1 54 * <li>URLAction() returns a java.net.URL for the String value, which must be a valid URL</li>
duke@1 55 * <li>integerRangeAction( int min, int max ) returns an Integer for the String value, which must be a
duke@1 56 * decimal integer in the range min to max inclusive</li>
duke@1 57 * <li>listAction( String sep, Operation ) tokenizes the String value with sep as separator, then
duke@1 58 * applies the Operation to each token, and returns an array of the result</li>
duke@1 59 * <li>sequenceAction( String, Operation[] ) tokenizes the String value with sep as separator, then
duke@1 60 * applies each Operation in the Operation array to successive tokens, and returns an array of the results</li>
duke@1 61 * <li>compose( Operation op1, Operation op2 ) is the operation that applies op2 to the result of applying
duke@1 62 * op1 to the value</li>
duke@1 63 * <li>mapAction( Operation ) applies the Operation to each element of an array of objects, and returns
duke@1 64 * an array of the results</li>
duke@1 65 * <li>mapSequenceAction( Operation[] ) applies the corresponding element of the Operation array to an
duke@1 66 * element of the Object[] value, and returns an array of the results</li>
duke@1 67 * <li>convertIntegerToShort coerces an Integer into a Short.</li>
duke@1 68 * </ul>
duke@1 69 * Other operations can be directly defined, and combined using these basic operations.
duke@1 70 */
duke@1 71 public abstract class OperationFactory {
duke@1 72 private OperationFactory() {}
duke@1 73
duke@1 74 private static String getString( Object obj )
duke@1 75 {
duke@1 76 if (obj instanceof String)
duke@1 77 return (String)obj ;
duke@1 78 else
duke@1 79 throw new Error( "String expected" ) ;
duke@1 80 }
duke@1 81
duke@1 82 private static Object[] getObjectArray( Object obj )
duke@1 83 {
duke@1 84 if (obj instanceof Object[])
duke@1 85 return (Object[])obj ;
duke@1 86 else
duke@1 87 throw new Error( "Object[] expected" ) ;
duke@1 88 }
duke@1 89
duke@1 90 private static StringPair getStringPair( Object obj )
duke@1 91 {
duke@1 92 if (obj instanceof StringPair)
duke@1 93 return (StringPair)obj ;
duke@1 94 else
duke@1 95 throw new Error( "StringPair expected" ) ;
duke@1 96 }
duke@1 97
duke@1 98 private static abstract class OperationBase implements Operation{
duke@1 99 public boolean equals( Object obj )
duke@1 100 {
duke@1 101 if (this==obj)
duke@1 102 return true ;
duke@1 103
duke@1 104 if (!(obj instanceof OperationBase))
duke@1 105 return false ;
duke@1 106
duke@1 107 OperationBase other = (OperationBase)obj ;
duke@1 108
duke@1 109 return toString().equals( other.toString() ) ;
duke@1 110 }
duke@1 111
duke@1 112 public int hashCode()
duke@1 113 {
duke@1 114 return toString().hashCode() ;
duke@1 115 }
duke@1 116 }
duke@1 117
duke@1 118 private static class MaskErrorAction extends OperationBase
duke@1 119 {
duke@1 120 private Operation op ;
duke@1 121
duke@1 122 public MaskErrorAction( Operation op )
duke@1 123 {
duke@1 124 this.op = op ;
duke@1 125 }
duke@1 126
duke@1 127 public Object operate( Object arg )
duke@1 128 {
duke@1 129 try {
duke@1 130 return op.operate( arg ) ;
duke@1 131 } catch (java.lang.Exception exc) {
duke@1 132 return null ;
duke@1 133 }
duke@1 134 }
duke@1 135
duke@1 136 public String toString()
duke@1 137 {
duke@1 138 return "maskErrorAction(" + op + ")" ;
duke@1 139 }
duke@1 140 }
duke@1 141
duke@1 142 public static Operation maskErrorAction( Operation op )
duke@1 143 {
duke@1 144 return new MaskErrorAction( op ) ;
duke@1 145 }
duke@1 146
duke@1 147 private static class IndexAction extends OperationBase
duke@1 148 {
duke@1 149 private int index ;
duke@1 150
duke@1 151 public IndexAction( int index )
duke@1 152 {
duke@1 153 this.index = index ;
duke@1 154 }
duke@1 155
duke@1 156 public Object operate( Object value )
duke@1 157 {
duke@1 158 return getObjectArray( value )[ index ] ;
duke@1 159 }
duke@1 160
duke@1 161 public String toString()
duke@1 162 {
duke@1 163 return "indexAction(" + index + ")" ;
duke@1 164 }
duke@1 165 }
duke@1 166
duke@1 167 public static Operation indexAction( int index )
duke@1 168 {
duke@1 169 return new IndexAction( index ) ;
duke@1 170 }
duke@1 171
duke@1 172 private static class SuffixAction extends OperationBase
duke@1 173 {
duke@1 174 public Object operate( Object value )
duke@1 175 {
duke@1 176 return getStringPair( value ).getFirst() ;
duke@1 177 }
duke@1 178
duke@1 179 public String toString() { return "suffixAction" ; }
duke@1 180 }
duke@1 181
duke@1 182 private static Operation suffixActionImpl = new SuffixAction() ;
duke@1 183
duke@1 184 private static class ValueAction extends OperationBase
duke@1 185 {
duke@1 186 public Object operate( Object value )
duke@1 187 {
duke@1 188 return getStringPair( value ).getSecond() ;
duke@1 189 }
duke@1 190
duke@1 191 public String toString() { return "valueAction" ; }
duke@1 192 }
duke@1 193
duke@1 194 private static Operation valueActionImpl = new ValueAction() ;
duke@1 195
duke@1 196 private static class IdentityAction extends OperationBase
duke@1 197 {
duke@1 198 public Object operate( Object value )
duke@1 199 {
duke@1 200 return value ;
duke@1 201 }
duke@1 202
duke@1 203 public String toString() { return "identityAction" ; }
duke@1 204 }
duke@1 205
duke@1 206 private static Operation identityActionImpl = new IdentityAction() ;
duke@1 207
duke@1 208 private static class BooleanAction extends OperationBase
duke@1 209 {
duke@1 210 public Object operate( Object value )
duke@1 211 {
duke@1 212 return new Boolean( getString( value ) ) ;
duke@1 213 }
duke@1 214
duke@1 215 public String toString() { return "booleanAction" ; }
duke@1 216 }
duke@1 217
duke@1 218 private static Operation booleanActionImpl = new BooleanAction() ;
duke@1 219
duke@1 220 private static class IntegerAction extends OperationBase
duke@1 221 {
duke@1 222 public Object operate( Object value )
duke@1 223 {
duke@1 224 return new Integer( getString( value ) ) ;
duke@1 225 }
duke@1 226
duke@1 227 public String toString() { return "integerAction" ; }
duke@1 228 }
duke@1 229
duke@1 230 private static Operation integerActionImpl = new IntegerAction() ;
duke@1 231
duke@1 232 private static class StringAction extends OperationBase
duke@1 233 {
duke@1 234 public Object operate( Object value )
duke@1 235 {
duke@1 236 return value ;
duke@1 237 }
duke@1 238
duke@1 239 public String toString() { return "stringAction" ; }
duke@1 240 }
duke@1 241
duke@1 242 private static Operation stringActionImpl = new StringAction() ;
duke@1 243
duke@1 244 private static class ClassAction extends OperationBase
duke@1 245 {
duke@1 246 public Object operate( Object value )
duke@1 247 {
duke@1 248 String className = getString( value ) ;
duke@1 249
duke@1 250 try {
coffeys@475 251 Class<?> result =
coffeys@475 252 SharedSecrets.getJavaCorbaAccess().loadClass( className ) ;
duke@1 253 return result ;
duke@1 254 } catch (Exception exc) {
duke@1 255 ORBUtilSystemException wrapper = ORBUtilSystemException.get(
duke@1 256 CORBALogDomains.ORB_LIFECYCLE ) ;
duke@1 257 throw wrapper.couldNotLoadClass( exc, className ) ;
duke@1 258 }
duke@1 259 }
duke@1 260
duke@1 261 public String toString() { return "classAction" ; }
duke@1 262 }
duke@1 263
duke@1 264 private static Operation classActionImpl = new ClassAction() ;
duke@1 265
duke@1 266 private static class SetFlagAction extends OperationBase
duke@1 267 {
duke@1 268 public Object operate( Object value )
duke@1 269 {
duke@1 270 return Boolean.TRUE ;
duke@1 271 }
duke@1 272
duke@1 273 public String toString() { return "setFlagAction" ; }
duke@1 274 }
duke@1 275
duke@1 276 private static Operation setFlagActionImpl = new SetFlagAction() ;
duke@1 277
duke@1 278 private static class URLAction extends OperationBase
duke@1 279 {
duke@1 280 public Object operate( Object value )
duke@1 281 {
duke@1 282 String val = (String)value ;
duke@1 283 try {
duke@1 284 return new URL( val ) ;
duke@1 285 } catch (MalformedURLException exc) {
duke@1 286 ORBUtilSystemException wrapper = ORBUtilSystemException.get(
duke@1 287 CORBALogDomains.ORB_LIFECYCLE ) ;
duke@1 288 throw wrapper.badUrl( exc, val ) ;
duke@1 289 }
duke@1 290 }
duke@1 291
duke@1 292 public String toString() { return "URLAction" ; }
duke@1 293 }
duke@1 294
duke@1 295 private static Operation URLActionImpl = new URLAction() ;
duke@1 296
duke@1 297 public static Operation identityAction()
duke@1 298 {
duke@1 299 return identityActionImpl ;
duke@1 300 }
duke@1 301
duke@1 302 public static Operation suffixAction()
duke@1 303 {
duke@1 304 return suffixActionImpl ;
duke@1 305 }
duke@1 306
duke@1 307 public static Operation valueAction()
duke@1 308 {
duke@1 309 return valueActionImpl ;
duke@1 310 }
duke@1 311
duke@1 312 public static Operation booleanAction()
duke@1 313 {
duke@1 314 return booleanActionImpl ;
duke@1 315 }
duke@1 316
duke@1 317 public static Operation integerAction()
duke@1 318 {
duke@1 319 return integerActionImpl ;
duke@1 320 }
duke@1 321
duke@1 322 public static Operation stringAction()
duke@1 323 {
duke@1 324 return stringActionImpl ;
duke@1 325 }
duke@1 326
duke@1 327 public static Operation classAction()
duke@1 328 {
duke@1 329 return classActionImpl ;
duke@1 330 }
duke@1 331
duke@1 332 public static Operation setFlagAction()
duke@1 333 {
duke@1 334 return setFlagActionImpl ;
duke@1 335 }
duke@1 336
duke@1 337 public static Operation URLAction()
duke@1 338 {
duke@1 339 return URLActionImpl ;
duke@1 340 }
duke@1 341
duke@1 342 private static class IntegerRangeAction extends OperationBase
duke@1 343 {
duke@1 344 private int min ;
duke@1 345 private int max ;
duke@1 346
duke@1 347 IntegerRangeAction( int min, int max )
duke@1 348 {
duke@1 349 this.min = min ;
duke@1 350 this.max = max ;
duke@1 351 }
duke@1 352
duke@1 353 public Object operate( Object value )
duke@1 354 {
duke@1 355 int result = Integer.parseInt( getString( value ) ) ;
duke@1 356 if ((result >= min) && (result <= max))
duke@1 357 return new Integer( result ) ;
duke@1 358 else
duke@1 359 throw new IllegalArgumentException(
duke@1 360 "Property value " + result + " is not in the range " +
duke@1 361 min + " to " + max ) ;
duke@1 362 }
duke@1 363
duke@1 364 public String toString() {
duke@1 365 return "integerRangeAction(" + min + "," + max + ")" ;
duke@1 366 }
duke@1 367 }
duke@1 368
duke@1 369 public static Operation integerRangeAction( int min, int max )
duke@1 370 {
duke@1 371 return new IntegerRangeAction( min, max ) ;
duke@1 372 }
duke@1 373
duke@1 374 private static class ListAction extends OperationBase {
duke@1 375 private String sep ;
duke@1 376 private Operation act ;
duke@1 377
duke@1 378 ListAction( String sep, Operation act )
duke@1 379 {
duke@1 380 this.sep = sep ;
duke@1 381 this.act = act ;
duke@1 382 }
duke@1 383
duke@1 384 // Note that this method carefully constructs an array of the type
duke@1 385 // of the first result, rather than just using Object[], which is
duke@1 386 // not convertible into the correct type. Also note that no tokens
duke@1 387 // results in a null result.
duke@1 388 public Object operate( Object value )
duke@1 389 {
duke@1 390 StringTokenizer st = new StringTokenizer( getString( value ),
duke@1 391 sep ) ;
duke@1 392 int length = st.countTokens() ;
duke@1 393 Object result = null ;
duke@1 394 int ctr = 0 ;
duke@1 395 while (st.hasMoreTokens()) {
duke@1 396 String next = st.nextToken() ;
duke@1 397 Object val = act.operate( next ) ;
duke@1 398 if (result == null)
duke@1 399 result = Array.newInstance( val.getClass(), length ) ;
duke@1 400 Array.set( result, ctr++, val ) ;
duke@1 401 }
duke@1 402
duke@1 403 return result ;
duke@1 404 }
duke@1 405
duke@1 406 public String toString() {
duke@1 407 return "listAction(separator=\"" + sep +
duke@1 408 "\",action=" + act + ")" ;
duke@1 409 }
duke@1 410 }
duke@1 411
duke@1 412 public static Operation listAction( String sep, Operation act )
duke@1 413 {
duke@1 414 return new ListAction( sep, act ) ;
duke@1 415 }
duke@1 416
duke@1 417 private static class SequenceAction extends OperationBase
duke@1 418 {
duke@1 419 private String sep ;
duke@1 420 private Operation[] actions ;
duke@1 421
duke@1 422 SequenceAction( String sep, Operation[] actions )
duke@1 423 {
duke@1 424 this.sep = sep ;
duke@1 425 this.actions = actions ;
duke@1 426 }
duke@1 427
duke@1 428 public Object operate( Object value )
duke@1 429 {
duke@1 430 StringTokenizer st = new StringTokenizer( getString( value ),
duke@1 431 sep ) ;
duke@1 432
duke@1 433 int numTokens = st.countTokens() ;
duke@1 434 if (numTokens != actions.length)
duke@1 435 throw new Error(
duke@1 436 "Number of tokens and number of actions do not match" ) ;
duke@1 437
duke@1 438 int ctr = 0 ;
duke@1 439 Object[] result = new Object[ numTokens ] ;
duke@1 440 while (st.hasMoreTokens()) {
duke@1 441 Operation act = actions[ctr] ;
duke@1 442 String next = st.nextToken() ;
duke@1 443 result[ctr++] = act.operate( next ) ;
duke@1 444 }
duke@1 445
duke@1 446 return result ;
duke@1 447 }
duke@1 448
duke@1 449 public String toString() {
duke@1 450 return "sequenceAction(separator=\"" + sep +
duke@1 451 "\",actions=" +
skoppar@205 452 Arrays.toString(actions) + ")" ;
duke@1 453 }
duke@1 454 }
duke@1 455
duke@1 456 public static Operation sequenceAction( String sep,
duke@1 457 Operation[] actions )
duke@1 458 {
duke@1 459 return new SequenceAction( sep, actions ) ;
duke@1 460 }
duke@1 461
duke@1 462 private static class ComposeAction extends OperationBase
duke@1 463 {
duke@1 464 private Operation op1 ;
duke@1 465 private Operation op2 ;
duke@1 466
duke@1 467 ComposeAction( Operation op1, Operation op2 )
duke@1 468 {
duke@1 469 this.op1 = op1 ;
duke@1 470 this.op2 = op2 ;
duke@1 471 }
duke@1 472
duke@1 473 public Object operate( Object value )
duke@1 474 {
duke@1 475 return op2.operate( op1.operate( value ) ) ;
duke@1 476 }
duke@1 477
duke@1 478 public String toString() {
duke@1 479 return "composition(" + op1 + "," + op2 + ")" ;
duke@1 480 }
duke@1 481 }
duke@1 482
duke@1 483 public static Operation compose( Operation op1, Operation op2 )
duke@1 484 {
duke@1 485 return new ComposeAction( op1, op2 ) ;
duke@1 486 }
duke@1 487
duke@1 488 private static class MapAction extends OperationBase
duke@1 489 {
duke@1 490 Operation op ;
duke@1 491
duke@1 492 MapAction( Operation op )
duke@1 493 {
duke@1 494 this.op = op ;
duke@1 495 }
duke@1 496
duke@1 497 public Object operate( Object value )
duke@1 498 {
duke@1 499 Object[] values = (Object[])value ;
duke@1 500 Object[] result = new Object[ values.length ] ;
duke@1 501 for (int ctr=0; ctr<values.length; ctr++ )
duke@1 502 result[ctr] = op.operate( values[ctr] ) ;
duke@1 503 return result ;
duke@1 504 }
duke@1 505
duke@1 506 public String toString() {
duke@1 507 return "mapAction(" + op + ")" ;
duke@1 508 }
duke@1 509 }
duke@1 510
duke@1 511 public static Operation mapAction( Operation op )
duke@1 512 {
duke@1 513 return new MapAction( op ) ;
duke@1 514 }
duke@1 515
duke@1 516 private static class MapSequenceAction extends OperationBase
duke@1 517 {
duke@1 518 private Operation[] op ;
duke@1 519
duke@1 520 public MapSequenceAction( Operation[] op )
duke@1 521 {
duke@1 522 this.op = op ;
duke@1 523 }
duke@1 524
duke@1 525 // XXX Does this correctly handle array types? It seems
duke@1 526 // that hetereogeneous arrays work this way, while
duke@1 527 // homogeneous arrays need to use Array.newInstance tricks.
duke@1 528 public Object operate( Object value )
duke@1 529 {
duke@1 530 Object[] values = (Object[])value ;
duke@1 531 Object[] result = new Object[ values.length ] ;
duke@1 532 for (int ctr=0; ctr<values.length; ctr++ )
duke@1 533 result[ctr] = op[ctr].operate( values[ctr] ) ;
duke@1 534 return result ;
duke@1 535 }
duke@1 536
duke@1 537 public String toString() {
duke@1 538 return "mapSequenceAction(" +
skoppar@205 539 Arrays.toString(op) + ")" ;
duke@1 540 }
duke@1 541 }
duke@1 542
duke@1 543 public static Operation mapSequenceAction( Operation[] op )
duke@1 544 {
duke@1 545 return new MapSequenceAction( op ) ;
duke@1 546 }
duke@1 547
duke@1 548 private static class ConvertIntegerToShort extends OperationBase
duke@1 549 {
duke@1 550 public Object operate( Object value )
duke@1 551 {
duke@1 552 Integer val = (Integer)value ;
duke@1 553 return new Short( val.shortValue() ) ;
duke@1 554 }
duke@1 555
duke@1 556 public String toString() {
duke@1 557 return "ConvertIntegerToShort" ;
duke@1 558 }
duke@1 559 }
duke@1 560
duke@1 561 private static Operation convertIntegerToShortImpl = new ConvertIntegerToShort() ;
duke@1 562
duke@1 563 public static Operation convertIntegerToShort()
duke@1 564 {
duke@1 565 return convertIntegerToShortImpl ;
duke@1 566 }
duke@1 567 }

mercurial