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: // $Id: Aspect.java,v 1.1.1.1 2003/07/02 15:30:50 apopovic Exp $
022: // =====================================================================
023: //
024: // (history at end)
025: //
026:
027: package ch.ethz.prose;
028:
029: import java.io.Serializable;
030: import java.util.List;
031:
032: import ch.ethz.prose.crosscut.Crosscut;
033:
034: /** Class aspect is the
035: *
036: */
037: public abstract class Aspect implements Insertable, Serializable {
038:
039: /** This method is called <em>before and after</em> this
040: * aspect is inserted into an <code>AspectManager</code>.
041: * By overriding the default (which is a no-op), one can
042: * define setup actions. If this method throws an exception,
043: * the aspect insertion fails.
044: */
045: public void insertionAction(boolean isBefore) {
046: }
047:
048: /** this method is called before and after the withdrawal of an aspect.
049: */
050: public void withdrawalAction(boolean isBefore) {
051: }
052:
053: /** Aspects are associated to objects. This method generates a 'random'
054: * object.
055: */
056: public static Object generateUniqueAssociation() {
057: return "" + System.currentTimeMillis() + birthDayCount++;
058: }
059:
060: protected static long birthDayCount = 0;
061: private List ownedCrosscutList = null;
062: protected Object aspectID = null;
063: private boolean aspectIDisSet = false;
064: protected int priority = 0;
065:
066: /** Associate aspect with a given object. Note that
067: * the associated has in PROSE the same role as the 'perObject', 'perVM',
068: * etc. role in other languages and frameworks. For one given object,
069: * just ONE aspect instance may be inserted in PROSE at a given time.
070: * With this, if you specify the name "foo" as an associated object, any insertion
071: * of a second aspect associated to "foo" results in an exception.
072: * In other words, a unique name means a 'per VM' aspect. However,
073: * you may associate aspects to the elements o1..oN of a vector
074: * of your choice. In this case, it will be a 'per Object' aspect.
075: * An aspect not explicitely associated to an id is associated to a random
076: * object.
077: */
078: public synchronized void associateTo(Object id) {
079: if (aspectIDisSet)
080: throw new IllegalStateException(
081: "reset of IDs not allowed in aspects");
082:
083: if (id == null)
084: throw new IllegalArgumentException(
085: "null ids not accepted as arguments");
086:
087: this .aspectIDisSet = true;
088: this .aspectID = id;
089: }
090:
091: /** Create an aspect with an automatically generated association. Note that
092: * the aspects associations have in PROSE the same role as the 'perObject', 'perVM',
093: * etc. role in other languages and frameworks.
094: */
095: public Aspect() {
096: aspectID = generateUniqueAssociation();
097: }
098:
099: /** Return a list of crosscuts owned by this Aspect. Note that this
100: * method returns the same list of objects during
101: * the existence of asspect. This list is initialized using the
102: * <code>crosscuts</code> template method.
103: *
104: */
105: public List getCrosscuts() {
106: if (ownedCrosscutList != null)
107: return ownedCrosscutList;
108:
109: Crosscut[] ownedCrosscuts = crosscuts();
110: ownedCrosscutList = new java.util.Vector();
111:
112: for (int i = 0; i < ownedCrosscuts.length; i++) {
113: ownedCrosscuts[i].setOwner(this );
114: ownedCrosscutList.add(ownedCrosscuts[i]);
115: }
116:
117: return ownedCrosscutList;
118: }
119:
120: /** Get the priority of this aspect. Advices (indireclty) belonging
121: * to this aspect are executed from low priority values to
122: * high prioirity values. The default priority is 0.
123: *
124: */
125: public int getPriority() {
126: return priority;
127: }
128:
129: /** Set the priority of this aspect. Advices (indireclty) belonging
130: * to this aspect are executed from low priority values to
131: * high prioirity values. The default priority is 0.
132: */
133: public void setPriority(int prio) {
134: this .priority = prio;
135: }
136:
137: /** Return the object associated to this aspect */
138: public Object getAssociatedObject() {
139: return aspectID;
140: }
141:
142: /** This is a template meethod. Users must define
143: * this method to return a list of crosscut objects
144: * that belong to this aspect
145: */
146: protected abstract Crosscut[] crosscuts();
147:
148: /**
149: * Indicates whether some other object is "equal to" this one. The
150: * result is <code>true</code> if and only if <code>obj</code> is
151: * not <code>null</code> and is a instance of
152: * <code>DefaultAspect</code> and has equal contents as this
153: * object.
154: * @param obj other object with which to compare
155: * @return <code>true</code> iff <code>obj</code> is equal to this
156: * <code>DefaultAspect</code>
157: */
158: public boolean equals(Object obj) {
159: return obj instanceof Aspect
160: && aspectID.equals(((Aspect) obj).aspectID);
161: }
162:
163: /**
164: * Returns a hashcode for this object.
165: * @return hashcode value
166: */
167: public int hashCode() {
168: return (int) aspectID.hashCode();
169: }
170:
171: public String toString() {
172: return "Aspect [" + aspectID + "]";
173: }
174:
175: }
176:
177: //======================================================================
178: //
179: // $Log: Aspect.java,v $
180: // Revision 1.1.1.1 2003/07/02 15:30:50 apopovic
181: // Imported from ETH Zurich
182: //
183: // Revision 1.6 2003/06/07 15:33:54 popovici
184: // Compile bug fix: getCrosscuts couldnt have been final
185: //
186: // Revision 1.5 2003/05/26 13:28:48 popovici
187: // Documentation Improvements
188: //
189: // Revision 1.4 2003/05/25 11:44:20 popovici
190: // default association now over the new method 'generateUniqueAssociation'
191: //
192: // Revision 1.3 2003/05/20 16:05:01 popovici
193: //
194: // New QueryManager replaces functionality in AspectManager (better Soc)
195: // New 'Surrogate' classes for usage in the QueryManager
196: // The 'RemoteAspectManager' and tools modified to use the Surrogates and the QueryManager
197: //
198: // Revision 1.2 2003/05/06 15:13:34 popovici
199: // aspectId renamed to 'associated object'
200: //
201: // Revision 1.1 2003/05/05 13:58:29 popovici
202: // renaming from runes to prose
203: //
204: // Revision 1.4 2003/04/29 12:41:03 popovici
205: // Feature added:
206: // - the 'setPriority' in class insertable allows now Aspects and Crosscuts to have a priority.
207: // Notitification is done from low int priorities to high int priorities.
208: // - the 'setAspectID' introduced to replace constuctor; used to be cumberstone for subclasses
209: //
210: // Revision 1.3 2003/04/27 13:21:32 popovici
211: // Aspects now have identities. Equality is based
212: // either on an ad-hoc identity, or on a specific
213: // name given by the user
214: //
215: // Revision 1.2 2003/04/17 15:43:45 popovici
216: // crosscuts renamed to 'getCrosscuts'
217: // createCrosscuts renamed to 'crosscuts'
218: //
219: // Revision 1.1 2003/04/17 15:15:09 popovici
220: // Extension->Aspect renaming
221: //
222: // Revision 1.6 2003/04/17 12:49:41 popovici
223: // Refactoring of the crosscut package
224: // ExceptionCut renamed to ThrowCut
225: // McutSignature is now SignaturePattern
226: //
227: // Revision 1.5 2003/04/17 08:47:12 popovici
228: // Important functionality additions
229: // - Cflow specializers
230: // - Restructuring of the MethodCut, SetCut, ThrowCut, and GetCut (they are much smaller)
231: // - Transactional capabilities
232: // - Total refactoring of Specializer evaluation, which permits fine-grained distinction
233: // between static and dynamic specializers.
234: // - Functionality pulled up in abstract classes
235: // - Uniformization of advice methods patterns and names
236: //
237: // Revision 1.4 2003/03/04 18:36:36 popovici
238: // Organization of imprts
239: //
240: // Revision 1.3 2002/03/28 13:48:33 popovici
241: // Mozilla-ified
242: //
243: // Revision 1.2 2002/02/21 12:36:47 popovici
244: // Interface 'Insertable' added. Extensions and crosscuts
245: // are now insertable objects.
246: //
247: // Revision 1.1.1.1 2001/11/29 18:13:15 popovici
248: // Sources from runes
249: //
250: // Revision 1.1.2.3 2001/02/07 11:47:01 popovici
251: // Abstract methods 'insertionAction' and 'withdrawalAction' added.
252: //
253: // Revision 1.1.2.2 2001/02/05 13:27:21 mrmuller
254: // needs to implement Serializable, so that Extensions can be passed by value
255: //
256: // Revision 1.1.2.1 2000/10/24 17:44:51 popovici
257: // Documentation added.
258: //
259: // Revision 1.1 2000/10/16 11:53:24 popovici
260: // Initial Revision
261: //
|