KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > instrument > WrapperTransformer


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.aop.instrument;
23
24 import javassist.CtMember;
25
26 /**
27  * This class is responsible for wrapping joinpoints.
28  * In this context, wrapping means just changing a joinpoint status according
29  * to it's wrapping state.
30  * A joinpoint is identified by a class member and a transformation text, because
31  * there may be more than one joinpoint associated with a classe member, and
32  * whe have to differentiate them (pick, for exemple, the field read and field write
33  * joinpoints; in this case we have two joinponts associated with a single field).
34  * When more than a joinpont is associated with a class member, we say that there is
35  * more than one transformation type available to be applied to this class member.
36  * The transformation types available to a member are identified by a <code>String</code>
37  * array passed to <code>WrapperTransformer</code> constructor.
38  * There must be a <code>WrapperTransformer</code> instance for each transformer. That
39  * means that when we talk about transformation types available to a class member, we mean
40  * the member associated with the transformer (for exemple, in the case of <code>
41  * ConstructorExecutionTransformer</code>, the member is a constructor).
42  * @author Flavia Rainone
43  */

44 public class WrapperTransformer
45 {
46
47    private static final byte UNWRAPPED = (byte) 0;
48
49    private static final byte WRAPPED = (byte) 1;
50
51    private static final byte NOT_PREPARED = (byte) 2;
52
53    private static final String JavaDoc WRAPPER_STATUS_ATTRIBUTE =
54       "aop$wrapperStatus$aop";
55
56    /**
57     * May be used as the <code>transformations</code> array in the constructor, if a class
58     * member will be affected by only one type of transformation. In this case, a joinpoint
59     * can be identified only by a class member.
60     */

61    protected static final String JavaDoc[] SINGLE_TRANSFORMATION = new String JavaDoc[] {WRAPPER_STATUS_ATTRIBUTE};
62    /**
63     * Index that identifies the single transformation contained in <code>SINGLE_TRANSFORMATION</code>.
64     * If <code>SINGLE_TRANSFORMATION</code> was passed as the <code>transformations</code>
65     * argument to the constructor, this variable has to be used as the transformation index value
66     * in the <code>WrapperTransformer</code> methods calls.
67     */

68    protected static final int SINGLE_TRANSFORMATION_INDEX = 0;
69    
70    private String JavaDoc[] transformationsStatus;
71    
72    /**
73     * Creates a wrapper transformer.
74     * @param transformations list of all transformations that may be applied
75     * to a joinpoint. It may be <code>SINGLE_TRANSFORMATION</code> if
76     * a class member will be affected by only one type of transformation (i. e. if
77     * a joinpont can be identified only by the class member).
78     */

79    public WrapperTransformer(String JavaDoc[] transformations)
80    {
81       if (transformations == SINGLE_TRANSFORMATION)
82       {
83          this.transformationsStatus = transformations;
84       }
85       else
86       {
87          this.transformationsStatus = new String JavaDoc[transformations.length];
88          for (int i = 0; i < transformations.length; i++)
89          {
90             transformationsStatus[i] = WRAPPER_STATUS_ATTRIBUTE + "$" + transformations[i];
91          }
92       }
93    }
94    
95    /**
96     * Prepares the joinpoint for wrapping.
97     * @param member the member associated with the joinpoint.
98     * @param transformationIndex index of the transformation text which, along with
99     * <code>member</code>, identifies the joinpoint to be prepared.
100     */

101    public void prepareForWrapping(final CtMember member, final int transformationIndex) {
102       if (getWrapperStatusAttribute(member, transformationIndex) != NOT_PREPARED)
103       {
104          throw new RuntimeException JavaDoc("Member already prepared:" + member);
105       }
106       this.setWrapperStatusAttribute(member, transformationIndex, UNWRAPPED);
107    }
108
109    /**
110     * Wraps the joinpoint.
111     * @param member the member associated with the joinpoint.
112     * @param transformationIndex index of the transformation text which, along with
113     * <code>member</code>, identifies the joinpoint to be wrapped.
114     */

115    public void wrap(CtMember member, int transformationIndex) {
116       byte wrapperStatus = getWrapperStatusAttribute(member, transformationIndex);
117       if (wrapperStatus != UNWRAPPED)
118       {
119          String JavaDoc errorMessage = "Member not unwrapped: " + member.getName() + "." +
120          member.getDeclaringClass().getName();
121          errorMessage += "\nMember status: ";
122          errorMessage += (wrapperStatus == NOT_PREPARED)? "NOT_PREPARED" : "WRAPPED";
123          
124          throw new RuntimeException JavaDoc(errorMessage);
125       }
126       setWrapperStatusAttribute(member, transformationIndex, WRAPPED);
127    }
128    
129    /**
130     * Unwraps the joinpoint.
131     * @param member the member associated with the joinpoint.
132     * @param transformationIndex index of the transformation text which, along with
133     * <code>member</code>, identifies the joinpoint to be unwrapped.
134     */

135    public void unwrap(CtMember member, int transformationIndex) {
136       byte wrapperStatus = getWrapperStatusAttribute(member, transformationIndex);
137       if (wrapperStatus != WRAPPED)
138       {
139          String JavaDoc errorMessage = "Member not wrapped: " + member.getName() + "." +
140          member.getDeclaringClass().getName();
141          errorMessage += "\nMember status: ";
142          errorMessage += (wrapperStatus == NOT_PREPARED)? "NOT_PREPARED" : "UNWRAPPED";
143          throw new RuntimeException JavaDoc(errorMessage);
144       }
145       setWrapperStatusAttribute(member, transformationIndex, UNWRAPPED);
146    }
147    
148    /**
149     * Checks if the joinpoint is not prepared.
150     * @param member the member associated with the joinpoint.
151     * @param transformationIndex index of the transformation text which, along with
152     * <code>member</code>, identifies the joinpoint whose status will be checked.
153     */

154    public boolean isNotPrepared(CtMember member, int transformationIndex)
155    {
156       byte wrapperStatus = getWrapperStatusAttribute(member, transformationIndex);
157       return wrapperStatus == NOT_PREPARED;
158    }
159
160    /**
161     * Checks if the joinpoint is wrapped.
162     * @param member the member associated with the joinpoint.
163     * @param transformationIndex index of the transformation text which, along with
164     * <code>member</code>, identifies the joinpoint whose status will be checked.
165     */

166    public boolean isWrapped(CtMember member, int transformationIndex)
167    {
168       byte wrapperStatus = getWrapperStatusAttribute(member, transformationIndex);
169       return wrapperStatus == WRAPPED;
170    }
171    
172    /**
173     * Returns the joinpoint wrapper status, which may be <code>WRAPPED
174     * </code>,<code>UNWRAPPED</code> or <code>NOT_PREPARED</code>.
175     * @param member the member associated with the joinpoint.
176     * @param transformationIndex index of the transformation text which, along with
177     * <code>member</code>, identifies the joinpoint whose status will be returned.
178     * @return the joinpoint wrapper status.
179     */

180    private byte getWrapperStatusAttribute(CtMember member, int transformationIndex)
181    {
182       byte[] attributeValue = member.getAttribute(transformationsStatus[transformationIndex]);
183       if (attributeValue == null)
184       {
185          return NOT_PREPARED;
186       }
187       return attributeValue[0];
188    }
189
190    /**
191     * Sets the joinpoint wrapper status.
192     * @param member the member associated with the joinpoint.
193     * @param transformationIndex index of the transformation text which, along with
194     * <code>member</code>, identifies the joinpoint whose status will be changed.
195     * @param status the new joinpoint wrapper status, which may be <code>WRAPPED
196     * </code>, <code>UNWRAPPED</code> or <code>NOT_PREPARED</code>.
197     */

198    private void setWrapperStatusAttribute(CtMember member, int transformationIndex, byte status)
199    {
200       member.setAttribute(transformationsStatus[transformationIndex], new byte[] {status});
201    }
202 }
Popular Tags