001: //
002: // This file is part of the prose package.
003: //
004: // The contents of this file are subject to the Mozilla Public License
005: // Version 1.1 (the "License"); you may not use this file except in
006: // compliance with the License. You may obtain a copy of the License at
007: // http://www.mozilla.org/MPL/
008: //
009: // Software distributed under the License is distributed on an "AS IS" basis,
010: // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011: // for the specific language governing rights and limitations under the
012: // License.
013: //
014: // The Original Code is prose.
015: //
016: // The Initial Developer of the Original Code is Andrei Popovici. Portions
017: // created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
018: // All Rights Reserved.
019: //
020: // Contributor(s):
021: package ch.ethz.prose.crosscut;
022:
023: import java.lang.IllegalArgumentException;
024: import java.lang.NullPointerException;
025: import java.lang.Class;
026: import java.lang.Error;
027: import java.lang.IndexOutOfBoundsException;
028: import java.lang.IllegalAccessException;
029: import java.util.Arrays;
030: import ch.ethz.jvmai.JoinPoint;
031: import java.lang.InstantiationException;
032: import java.lang.reflect.Method;
033: import java.lang.Object;
034: import java.lang.System;
035: import java.lang.reflect.InvocationTargetException;
036:
037: /** The execution of an advice method of aribitrary signature.
038: */
039: class DefaultMcutAdvice extends McutAdvice {
040: private static final long serialVersionUID = 3256720663157880374L;
041: private final MethodCut methodCut;
042:
043: DefaultMcutAdvice(MethodCut methodCut, JoinPoint m,
044: MethodCutSignaturePattern a) {
045: super (methodCut, m, a);
046: this .methodCut = methodCut;
047: }
048:
049: protected void execute() throws IllegalAccessException,
050: InvocationTargetException {
051: Object actualParams[] = new Object[stackArgsLength];
052: System
053: .arraycopy(stackArgs, 0, actualParams, 0,
054: stackArgsLength);
055: localActionImpl(methodCut, advice.methodObj, stackArgs[0],
056: actualParams);
057: }
058:
059: // implement create local action
060: private void localActionImpl(Object adviceThis, Method advMethod,
061: Object localThis, Object[] localParam)
062: throws InvocationTargetException, IllegalAccessException {
063:
064: Object[] localPar = new Object[localParam.length - 1];
065: System.arraycopy(localParam, 1, localPar, 0,
066: localParam.length - 1);
067:
068: Class[] adviceSignature = advMethod.getParameterTypes();
069: Object[] actualParams = new Object[adviceSignature.length];
070: for (int i = 0; i < adviceSignature.length; i++) {
071:
072: Object crtLocParam = localThis;
073: if (i > 0) {
074: try {
075: crtLocParam = localPar[i - 1];
076: } catch (IndexOutOfBoundsException e) {
077: // we can actually ignore this case. It happens
078: // if the advice signature looks like (XXX,REST)
079: // but the joinpointed method has no parameters.
080: // then localParams(0) does not exist.
081: // formally, i set crtLocParam to zero
082: crtLocParam = null;
083: }
084: }
085: if (Wildcard.class.isAssignableFrom(adviceSignature[i])) {
086: Wildcard oscarWild;
087: try {
088: oscarWild = (Wildcard) adviceSignature[i]
089: .newInstance();
090: if (i < localPar.length + 1
091: && (crtLocParam == null || oscarWild
092: .isAssignableFrom(crtLocParam
093: .getClass())))
094: oscarWild.setObject(crtLocParam);
095: else {
096: Object rest = new Object[localPar.length - i
097: + 1];
098: System.arraycopy(localPar, i - 1, rest, 0,
099: localPar.length - i + 1);
100: oscarWild.setObject(rest);
101: }
102: }
103: // the Wilcard specification states that wildcard classes
104: // should have an emtpy default constructor. If they
105: // don't have;it it is a RUNES IMPLEMENTATION ERROR
106: catch (IllegalAccessException noConstructor) {
107:
108: throw new Error(noConstructor.toString() + "/"
109: + adviceSignature[i]);
110: } catch (InstantiationException wrongConstructor) {
111: throw new Error(wrongConstructor.toString());
112: }
113:
114: actualParams[i] = oscarWild;
115: } else {
116: actualParams[i] = crtLocParam;
117: }
118: }
119:
120: // 3. create an action with the event stuff
121: try {
122: advMethod.invoke(adviceThis, actualParams);
123: } catch (IllegalArgumentException wrongArgs) {
124: throw new Error("MethodCut.joinPointAction: " + wrongArgs
125: + ". Actual arguments"
126: + Arrays.asList(actualParams)
127: + " Expected arguments: " + advMethod);
128: } catch (IllegalAccessException wrongMethod) {
129: throw new IllegalAccessException("Advice method ("
130: + advMethod + ") not visible");
131: } catch (NullPointerException noReceiver) {
132: throw new Error("MethodCut.joinPointAction:"
133: + noReceiver.toString());
134: }
135: }
136:
137: }
|