| 264 | | final NakedObjectActionPeer[] actionPeers1 = findActionMethodPeers(MethodScope.OBJECT, true); |
| 265 | | final NakedObjectActionPeer[] actionPeers2 = findActionMethodPeers(MethodScope.OBJECT, false); |
| 266 | | final NakedObjectActionPeer[] actionPeers = new NakedObjectActionPeer[actionPeers1.length + actionPeers2.length]; |
| 267 | | System.arraycopy(actionPeers1, 0, actionPeers, 0, actionPeers1.length); |
| 268 | | System.arraycopy(actionPeers2, 0, actionPeers, actionPeers1.length, actionPeers2.length); |
| | 264 | MethodScope methodScope = MethodScope.OBJECT; |
| | 265 | final NakedObjectActionPeer[] actionPeers = findActionMethodsPeers(methodScope); |
| 286 | | final NakedObjectActionPeer[] findClassActionMethods1 = findActionMethodPeers(MethodScope.CLASS, true); |
| 287 | | final NakedObjectActionPeer[] findClassActionMethods2 = findActionMethodPeers(MethodScope.CLASS, false); |
| 288 | | final NakedObjectActionPeer[] findClassActionMethods = new NakedObjectActionPeer[findClassActionMethods1.length + findClassActionMethods2.length]; |
| 289 | | System.arraycopy(findClassActionMethods1, 0, findClassActionMethods, 0, findClassActionMethods1.length); |
| 290 | | System.arraycopy(findClassActionMethods2, 0, findClassActionMethods, findClassActionMethods1.length, findClassActionMethods2.length); |
| | 283 | MethodScope methodsScope2 = MethodScope.CLASS; |
| | 284 | final NakedObjectActionPeer[] findClassActionMethods = findActionMethodsPeers(methodsScope2); |
| | 410 | private NakedObjectActionPeer[] findActionMethodsPeers( |
| | 411 | MethodScope methodScope) { |
| | 412 | final NakedObjectActionPeer[] actionPeers1 = findActionMethodPeers(methodScope, true); |
| | 413 | final NakedObjectActionPeer[] actionPeers2 = findActionMethodPeers(methodScope, false); |
| | 414 | final NakedObjectActionPeer[] actionPeers = new NakedObjectActionPeer[actionPeers1.length + actionPeers2.length]; |
| | 415 | System.arraycopy(actionPeers1, 0, actionPeers, 0, actionPeers1.length); |
| | 416 | System.arraycopy(actionPeers2, 0, actionPeers, actionPeers1.length, actionPeers2.length); |
| | 417 | return actionPeers; |
| | 418 | } |
| | 419 | |
| | 420 | |
| 428 | | final Method actionMethod = methods[i]; |
| 429 | | if (!MethodFinderUtils.inScope(methodScope, actionMethod)) { |
| 430 | | continue; |
| 431 | | } |
| 432 | | |
| 433 | | List<Class<?>> typesToLoad = new ArrayList<Class<?>>(); |
| 434 | | getSpecificationTraverser().traverseTypes(actionMethod, typesToLoad); |
| 435 | | |
| 436 | | boolean anyLoadedAsNull = reflector.loadSpecifications(typesToLoad); |
| 437 | | if (anyLoadedAsNull) { |
| 438 | | continue; |
| 439 | | } |
| 440 | | |
| 441 | | |
| 442 | | // build/validate action parameters |
| 443 | | // as for return type, if the reflector's class strategy says to skip any of the |
| 444 | | // action's parameter types, then just ignore this action altogether. |
| 445 | | final Class<?>[] parameterTypes = actionMethod.getParameterTypes(); |
| 446 | | |
| 447 | | // previously we wrapped primitives. However, this prevents the lookup of |
| 448 | | // actions during remote authorization calls (using Identifier class). |
| 449 | | // ... should we remove ... ? |
| 450 | | // final Class<?>[] parameterClasses = WrapperUtils.wrapAsNecessary(parameterTypes); |
| 451 | | |
| 452 | | final Class<?>[] parameterClasses = parameterTypes; |
| 453 | | |
| 454 | | final int numParameters = parameterClasses.length; |
| 455 | | final JavaNakedObjectActionParamPeer[] actionParams = new JavaNakedObjectActionParamPeer[numParameters]; |
| 456 | | |
| 457 | | for (int j = 0; j < numParameters; j++) { |
| 458 | | NakedObjectSpecification paramSpec = getSpecificationLoader().loadSpecification(parameterClasses[j]); |
| 459 | | if (paramSpec == null) { |
| 460 | | continue eachMethod; |
| 461 | | } |
| 462 | | actionParams[j] = new JavaNakedObjectActionParamPeer(paramSpec); |
| 463 | | } |
| 464 | | |
| 465 | | |
| 466 | | if (getFacetProcessor().recognizes(actionMethod)) { |
| 467 | | if (actionMethod.getName().startsWith("set")) { |
| 468 | | continue; |
| 469 | | } |
| 470 | | if (skipRecognisedHelperMethod) { |
| 471 | | LOG.info(" skipping possible helper method " + actionMethod); |
| 472 | | continue; |
| 473 | | } |
| 474 | | } |
| 475 | | |
| 476 | | if (LOG.isDebugEnabled()) { |
| 477 | | LOG.debug(" identified action " + actionMethod); |
| 478 | | } |
| 479 | | methods[i] = null; |
| 480 | | |
| 481 | | |
| 482 | | // build action |
| 483 | | final String fullMethodName = actionMethod.getName(); |
| 484 | | final Identifier identifier = Identifier.actionIdentifier(className, fullMethodName, parameterTypes); |
| 485 | | final JavaNakedObjectActionPeer action = new JavaNakedObjectActionPeer(identifier, actionParams); |
| 486 | | |
| 487 | | // process facets on the action & parameters |
| 488 | | getFacetProcessor() |
| 489 | | .process(type, actionMethod, new JavaIntrospectorMethodRemover(), action, NakedObjectFeatureType.ACTION); |
| 490 | | for (int j = 0; j < actionParams.length; j++) { |
| 491 | | getFacetProcessor().processParams(actionMethod, j, actionParams[j]); |
| 492 | | } |
| 493 | | |
| 494 | | actionPeers.add(action); |
| | 432 | NakedObjectActionPeer actionPeer = findActionMethodPeer(methodScope, skipRecognisedHelperMethod, methods[i]); |
| | 433 | if (actionPeer != null) { |
| | 434 | methods[i] = null; |
| | 435 | actionPeers.add(actionPeer); |
| | 436 | } |
| | 442 | private NakedObjectActionPeer findActionMethodPeer(final MethodScope methodScope, boolean skipRecognisedHelperMethod, final Method actionMethod) { |
| | 443 | |
| | 444 | if (!representsAction(methodScope, skipRecognisedHelperMethod, actionMethod)) { |
| | 445 | return null; |
| | 446 | } |
| | 447 | |
| | 448 | // build action |
| | 449 | return createAction(actionMethod); |
| | 450 | } |
| | 451 | |
| | 452 | private NakedObjectActionPeer createAction(final Method actionMethod) { |
| | 453 | final Class<?>[] parameterTypes = getParameterTypesFor(actionMethod); |
| | 454 | final int numParameters = parameterTypes.length; |
| | 455 | |
| | 456 | final JavaNakedObjectActionParamPeer[] actionParams = new JavaNakedObjectActionParamPeer[numParameters]; |
| | 457 | for (int j = 0; j < numParameters; j++) { |
| | 458 | NakedObjectSpecification paramSpec = getSpecificationLoader().loadSpecification(parameterTypes[j]); |
| | 459 | if (paramSpec == null) { |
| | 460 | return null; |
| | 461 | } |
| | 462 | actionParams[j] = new JavaNakedObjectActionParamPeer(paramSpec); |
| | 463 | } |
| | 464 | |
| | 465 | |
| | 466 | final String fullMethodName = actionMethod.getName(); |
| | 467 | final Identifier identifier = Identifier.actionIdentifier(className, fullMethodName, parameterTypes); |
| | 468 | final JavaNakedObjectActionPeer action = new JavaNakedObjectActionPeer(identifier, actionParams); |
| | 469 | |
| | 470 | // process facets on the action & parameters |
| | 471 | getFacetProcessor() |
| | 472 | .process(type, actionMethod, new JavaIntrospectorMethodRemover(), action, NakedObjectFeatureType.ACTION); |
| | 473 | for (int j = 0; j < actionParams.length; j++) { |
| | 474 | getFacetProcessor().processParams(actionMethod, j, actionParams[j]); |
| | 475 | } |
| | 476 | |
| | 477 | return action; |
| | 478 | } |
| | 479 | |
| | 480 | private boolean representsAction(final MethodScope methodScope, boolean skipRecognisedHelperMethod, final Method actionMethod) { |
| | 481 | |
| | 482 | if (!MethodFinderUtils.inScope(methodScope, actionMethod)) { |
| | 483 | return false; |
| | 484 | } |
| | 485 | |
| | 486 | List<Class<?>> typesToLoad = new ArrayList<Class<?>>(); |
| | 487 | getSpecificationTraverser().traverseTypes(actionMethod, typesToLoad); |
| | 488 | |
| | 489 | boolean anyLoadedAsNull = reflector.loadSpecifications(typesToLoad); |
| | 490 | if (anyLoadedAsNull) { |
| | 491 | return false; |
| | 492 | } |
| | 493 | |
| | 494 | if (!loadParamSpecs(actionMethod)) { |
| | 495 | return false; |
| | 496 | } |
| | 497 | |
| | 498 | if (getFacetProcessor().recognizes(actionMethod)) { |
| | 499 | if (actionMethod.getName().startsWith("set")) { |
| | 500 | return false; |
| | 501 | } |
| | 502 | if (skipRecognisedHelperMethod) { |
| | 503 | LOG.info(" skipping possible helper method " + actionMethod); |
| | 504 | return false; |
| | 505 | } |
| | 506 | } |
| | 507 | |
| | 508 | if (LOG.isDebugEnabled()) { |
| | 509 | LOG.debug(" identified action " + actionMethod); |
| | 510 | } |
| | 511 | |
| | 512 | return true; |
| | 513 | } |
| | 514 | |
| | 515 | private boolean loadParamSpecs(final Method actionMethod) { |
| | 516 | final Class<?>[] parameterTypes = getParameterTypesFor(actionMethod); |
| | 517 | return loadParamSpecs(parameterTypes); |
| | 518 | } |
| | 519 | |
| | 520 | private Class<?>[] getParameterTypesFor(final Method actionMethod) { |
| | 521 | |
| | 522 | // build/validate action parameters |
| | 523 | // as for return type, if the reflector's class strategy says to skip any of the |
| | 524 | // action's parameter types, then just ignore this action altogether. |
| | 525 | final Class<?>[] parameterTypes = actionMethod.getParameterTypes(); |
| | 526 | |
| | 527 | |
| | 528 | // previously we wrapped primitives. However, this prevents the lookup of |
| | 529 | // actions during remote authorization calls (using Identifier class). |
| | 530 | // ... should we remove ... ? |
| | 531 | // final Class<?>[] parameterClasses = WrapperUtils.wrapAsNecessary(parameterTypes); |
| | 532 | return parameterTypes; |
| | 533 | } |
| | 534 | |
| | 535 | private boolean loadParamSpecs(final Class<?>[] parameterTypes) { |
| | 536 | final int numParameters = parameterTypes.length; |
| | 537 | for (int j = 0; j < numParameters; j++) { |
| | 538 | NakedObjectSpecification paramSpec = getSpecificationLoader().loadSpecification(parameterTypes[j]); |
| | 539 | if (paramSpec == null) { |
| | 540 | return false; |
| | 541 | } |
| | 542 | } |
| | 543 | return true; |
| | 544 | } |
| | 545 | |