AspectOriented Programming Seyyed Jamaleddin Pishvayi pishvayice sharif edu

  • Slides: 56
Download presentation
Aspect-Oriented Programming Seyyed Jamaleddin Pishvayi pishvayi@ce. sharif. edu Graduate Student Department of Electronics and

Aspect-Oriented Programming Seyyed Jamaleddin Pishvayi pishvayi@ce. sharif. edu Graduate Student Department of Electronics and Computer Engineering University of Tehran Mehr 1383, Sharif Univ. 9/12/2021

What is AOP • • • Aspect Oriented Programming Not an OO replacement Technique

What is AOP • • • Aspect Oriented Programming Not an OO replacement Technique for handling ‘Crosscutting concerns’ Tries to eliminate code scattering and tangling Examples: log all exceptions, capture all SQL statements, authenticate users before access Mehr 1383, Sharif Univ. 9/12/2021 2

Programming Evolution Overview Mehr 1383, Sharif Univ. 9/12/2021 3

Programming Evolution Overview Mehr 1383, Sharif Univ. 9/12/2021 3

Monolithic programs Mehr 1383, Sharif Univ. 9/12/2021 4

Monolithic programs Mehr 1383, Sharif Univ. 9/12/2021 4

What is software? • Software expresses solutions to problems • Humans decompose complex problems

What is software? • Software expresses solutions to problems • Humans decompose complex problems into simpler problems • Humans express solutions to problems using a programming language • Programming language imposes constraints on how the problem is decomposed Mehr 1383, Sharif Univ. 9/12/2021 5

Tackling the software problem • Programming in the small – Decompose problem into programming

Tackling the software problem • Programming in the small – Decompose problem into programming language statements • Programming in the medium – Decompose problem into modules / classes / objects • Programming in the large – Decompose problem into components Mehr 1383, Sharif Univ. 9/12/2021 6

Unstructured code 10 20 30 40 50 60 let i = 1 if i

Unstructured code 10 20 30 40 50 60 let i = 1 if i > 4 then goto 60 print i i = i + 1 goto 20 print "done" Mehr 1383, Sharif Univ. 9/12/2021 • Code paths are tangled – Goto's cross each other 7

Elegant unstructured code 10 20 30 40 50 let i = 1 print i

Elegant unstructured code 10 20 30 40 50 let i = 1 print i i = i + 1 if i < 4 then goto 20 print "done" Mehr 1383, Sharif Univ. 9/12/2021 • Code paths not tangled • Code is compact • Code is idiomatic – Put test at end 8

Why does elegance matter? • Computer does not care! • Programs always change –

Why does elegance matter? • Computer does not care! • Programs always change – ~10 X maintenance vs. original development • Programs become resistant to change over time – Must be readable by others – Must have obvious extensibility points – Must have well designed unit tests to encourage extensibility Mehr 1383, Sharif Univ. 9/12/2021 9

Language support for elegance int i = 1; while( i < 4 ) {

Language support for elegance int i = 1; while( i < 4 ) { print( i ); } Mehr 1383, Sharif Univ. 9/12/2021 • Language support encourages (enforces? ) best practices – Discourages goto 10

Is elegance enough? • • • Suitable for programming in the small Suitable for

Is elegance enough? • • • Suitable for programming in the small Suitable for enhancing localized understanding of code Unsuitable for sharing secrets Unsuitable for building larger abstractions Unsuitable for understanding larger abstractions Mehr 1383, Sharif Univ. 9/12/2021 11

Modular programming Mehr 1383, Sharif Univ. 9/12/2021 12

Modular programming Mehr 1383, Sharif Univ. 9/12/2021 12

Modularization • Decompose problem into independent modules • Each module exposes a public interface

Modularization • Decompose problem into independent modules • Each module exposes a public interface • Each module hides implementation from caller Mehr 1383, Sharif Univ. 9/12/2021 13

Modularization: Windows • Windows operating system code is highly modularized – – – –

Modularization: Windows • Windows operating system code is highly modularized – – – – kernel 32. dll user 32. dll gdi 32. dll dbghelp. dll ole 32. dll comctl 32. dll ws 2_32. dll mscoree. dll Mehr 1383, Sharif Univ. 9/12/2021 14

Modularization and Abstraction • Modularization == separation of concerns – Based on common functionality

Modularization and Abstraction • Modularization == separation of concerns – Based on common functionality – Based on shared secrets • Modularization encourages abstraction – Interact with module only using its interface – Lets us look at overall system structure – Lets us zoom in on one part of system at a time Mehr 1383, Sharif Univ. 9/12/2021 15

Is modularization enough? • Modules are too coarse grained – Public interface is too

Is modularization enough? • Modules are too coarse grained – Public interface is too wide (kernel 32. dll exports 928 methods!) – Hierarchical organization impossible – Secrets go hand in hand with certain methods • We need to raise the abstraction bar – Think in terms of smaller "bundles" of code and data – Helps us deal with increasing complexity Mehr 1383, Sharif Univ. 9/12/2021 16

Object-oriented programming Mehr 1383, Sharif Univ. 9/12/2021 17

Object-oriented programming Mehr 1383, Sharif Univ. 9/12/2021 17

Object-oriented programming • • • Decompose problem into independent classes Each class exposes a

Object-oriented programming • • • Decompose problem into independent classes Each class exposes a public interface Each class exposes a protected interface Each class hides implementation from caller … Mehr 1383, Sharif Univ. 9/12/2021 18

Is OOP enough? • Some code must cut across class hierarchies • Interface based

Is OOP enough? • Some code must cut across class hierarchies • Interface based programming helps on definition – Consider Cloneable, Serializable in Java API – Offers no assistance on the implementation • What happens if you need to retrofit cross cutting code against existing client applications? – Can't do it without modifying those apps! Mehr 1383, Sharif Univ. 9/12/2021 19

Good Modularity with OOP: URL Pattern Matching • URL pattern matching in org. apache.

Good Modularity with OOP: URL Pattern Matching • URL pattern matching in org. apache. tomcat – red shows relevant lines of code – nicely fits in two boxes (using inheritance) Mehr 1383, Sharif Univ. 9/12/2021 20

But … Logging Is not Modularized • logging in org. apache. tomcat – red

But … Logging Is not Modularized • logging in org. apache. tomcat – red shows lines of code that handle logging – not in just one place – not even in a small number of places Mehr 1383, Sharif Univ. 9/12/2021 21

Another Example: Session Expiration Is not Modularized Application. Session /* * ================================== * *

Another Example: Session Expiration Is not Modularized Application. Session /* * ================================== * * The Apache Software License, Version 1. 1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement : * "This product includes software developed by the * Apache Software Foundation (http: //www. apache. org/). " * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache. org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http: //www. apache. org/>. * * [Additional notices, if required by prior licensing conditions] * */ public void invalidate() { server. Session. remove. Application. Session(context Standard. Session package org. apache. tomcat. session; Enumeration enum = values. keys(); while ( enum. has. More. Elements ()) { String name = ( String)enum. next. Element (); remove. Value(name ); } valid = false; } public boolean is. New () { if (! valid) { String msg = sm. get. String("application. Session. session. ise throw new "); import import import import if ( this. Access. Time == creation. Time ) { return true; } else { return false; } } /** * @deprecated */ public void put. Value(String name, Object value) { set. Attribute(name , value); } public void set. Attribute(String name, Object value) { if (! valid) { String msg = sm. get. String("application. Session. session. ise "); Illegal. State. Exception(msg ); if (name == null) { String msg = sm. get. String("application. Session. value. iae throw new (( Http. Session. Binding. Listener)value). value. Bound(e ); } "); Illegal. State. Exception(msg ); if (name == null) { String msg = sm. get. String("application. Session. value. iae "); Illegal. Argument. Exception(msg ); return values. get(name); /** * The collection of user data attributes associated with this Session. */ private Hashtable attributes = new Hashtable (); /** * The session identifier of this Session. */ private String id = null; /** * @deprecated */ public String[] get. Value. Names () { Enumeration e = get. Attribute. Names (); Vector names = new Vector(); /** * Descriptive information describing this Session implementation. */ private static final String info = "Standard. Session/1. 0"; while ( e. has. More. Elements ()) { names. add. Element(e. next. Element ()); } value. Names = new String[names. size()]; } != -1) { *= 60; public Enumeration get. Attribute. Names () { if (! valid) { String msg = sm. get. String("application. Session. session. ise throw new "); Illegal. State. Exception(msg ); } /** * The Manager with which this Session is associated. */ private Manager manager = null; /** * Called by context when request comes in so that accesses and * inactivities can be dealt with accordingly. */ /** * The maximum time interval, in seconds, between client requests before * the servlet container may invalidate this session. A negative time * indicates that the session should never time out. */ private int max. Inactive. Interval = -1; return ( Enumeration)values. Clone. keys (); } void accessed() { // set last accessed to this. Access. Time as it will be left over // from the previous access last. Accessed = this. Access. Time ; this. Access. Time = System. current. Time. Millis (); /** * @deprecated */ public void remove. Value(String remove. Attribute(name ); } validate(); name) { /** * Flag indicating whether this session is new or } public void remove. Attribute(String name) { if (! valid) { String msg = sm. get. String("application. Session. session. ise void validate() { // if we have an inactive interval, check to see if we've exceeded it if ( inactive. Interval != -1) { int this. Interval = ( int)(System. current. Time. Millis () - last. Accessed ) / 1000; throw new if (name == null) { String msg = sm. get. String("application. Session. value. iae } // ------------------------ Session Package Methods /** * Return the <code> is. Valid </code> flag for this session. */ boolean is. Valid () { } throw new } */ private boolean Illegal. Argument. Exception(msg ); /** * The string manager for this package. */ private String. Manager sm = String. Manager. get. Manager("org. apache. tomcat. se Object o = values. get(name); if (o instanceof Http. Session. Binding. Listener ) { Http. Session. Binding. Event e = new Http. Session. Binding. Event(this, name ); "); (( Http. Session. Binding. Listener)o). value. Unbound(e ssion "); /** * The HTTP session context associated with this session. */ private static Http. Session. Context session. Context = null; values. remove(name); } } public long get. Creation. Time () { if (valid) { return creation. Time ; } else { String msg = sm. get. String("application. Session. session. ise public void set. Max. Inactive. Interval(int interval) { if (! valid) { String msg = sm. get. String("application. Session. session. ise "); throw new "); /** * The current accessed time for this session. */ private long this. Accessed. Time = creation. Time ; Illegal. State. Exception(msg ); } inactive. Interval = interval; } } /** * * @deprecated */ public int get. Max. Inactive. Interval () { if (! valid) { String msg = sm. get. String("application. Session. session. ise throw new public Http. Session. Context get. Session. Context () { return new Session. Context. Impl (); // ------------------------Http. Session Properties "); return inactive. Interval ; } if ( session. Context == null) session. Context = new Standard. Session. Context (); return ( session. Context ); } //-----------------------------------"); this. creation. Time = time; this. last. Accessed. Time = time; this. Accessed. Time = time; Illegal. State. Exception(msg ); } } Server. Sess on } /** * Return the session identifier for this session. */ public String get. Id () { // -----------------------Http. Session Public Methods return (attributes. get(name)); } if ((this. id != null) && (manager instanceof Manager. Base )) (( Manager. Base ) manager). remove(this); return (attributes. keys()); } /** * Return descriptive information about this Session implementation and * the corresponding version number, in the format * <code>& lt; description> /< version&gt ; </code>. */ public String get. Info () { return (this. info); } /** * Return the object bound with the specified name in this session, or * <code>null</code> if no object is bound with that name. * * @ param name Name of the value to be returned * * @exception Illegal. State. Exception if this method is called on an * invalidated session * * @deprecated As of Version 2. 2, this method is replaced by * <code> get. Attribute ()</code> */ public Object get. Value(String name) { return ( get. Attribute(name )); return ( this. last. Accessed. Time ); } return (this. manager); this. manager = manager; } /** * Return the maximum time interval, in seconds, between client requests * before the servlet container will invalidate the session. A negative * time indicates that the session should never time out. * * @exception Illegal. State. Exception if this method is called on * an invalidated session */ public int get. Max. Inactive. Interval () { return ( this. max. Inactive. Interval ); } /** * Set the maximum time interval, in seconds, between client requests * before the servlet container will invalidate the session. A negative * time indicates that the session should never time out. * * @ param interval The new maximum interval */ public void set. Max. Inactive. Interval(int interval) { this. max. Inactive. Interval // XXX // sync'd for safty -- no other thread should be getting something // from this while we are reaping. This isn't the most optimal // solution for this, but we'll determine something else later. package org. apache. tomcat. session; import org. apache. tomcat. util. *; import org. apache. tomcat. core. *; import java. io. *; import java. net. *; import java. util. *; import javax. servlet. http. *; while ( enum. has. More. Elements ()) { Object key = enum. next. Element (); Server. Session session = ( Server. Session)sessions. get(key ); session. reap(); session. validate(); } synchronized void remove. Session(Server. Session String id = session. get. Id (); return * @author Craig R. Mc. Clanahan ctx) { manager. create. Session(). get. Session (); } */ Standard. Session. Manager * Remove all sessions because our associated Context is being shut down. implements Session. Manager { * * @ param ctx The context that is being shut down */ // -----------------------------Constructors public void remove. Sessions(Context ctx) { // contexts, we just want to remove the sessions of Session. Manager that adapts to the corresponding // connection open if (manager */ instanceof Lifecycle) { try { public Standard. Session. Manager () { ((Lifecycle) manager). stop(); manager = new if (manager } catch ( Lifecycle. Exception Standard. Manager (); throw new instanceof Lifecycle) { Illegal. State. Exception ("" + e); } try { } ((Lifecycle) manager). configure(null); ((Lifecycle) manager). start(); } catch ( Lifecycle. Exception throw new } e) { Illegal. State. Exception ("" + e); /** } } * Used by context to configure the session manager's inactivity timeout. * } * The Session. Manager may have some default session time out, the * Context on the other hand has it's timeout set by the deployment * descriptor ( web. xml ). This method lets the Context { // Validate and update our current component state if (!started) throw new Lifecycle. Exception ( sm. get. String("standard. Manager. not. Started ")); started = false; * @ param minutes The session inactivity timeout in minutes. */ public void * The Manager implementation we are actually using. set. Session. Time. Out(int minutes) { if(-1 != minutes) { */ // The manager works with seconds. . . private Manager manager = null; manager. set. Max. Inactive. Interval(minutes } } } // Expire all active sessions Session sessions[] = find. Sessions (); for ( int i = 0; i < sessions. length; i++) { Standard. Session session = ( Standard. Session ) sessions[i]; if (! session. is. Valid ()) continue; session. expire(); } } = check. Interval ; // ---------------------------- Private Methods /** * Return descriptive information about this Manager implementation and * the corresponding version number, in the format * <code>& lt; description> /< version&gt ; </code>. */ public String get. Info () { /** * Invalidate all sessions that have expired. */ private void process. Expires () { long time. Now = System. current. Time. Millis (); Session sessions[] = find. Sessions (); return (this. info); session) { remove. Sessions(Context context) { for ( int i = 0; i < sessions. length; i++) { Standard. Session session = ( Standard. Session ) sessions[i]; if (! session. is. Valid ()) continue; int max. Inactive. Interval = session. get. Max. Inactive. Interval (); if ( max. Inactive. Interval < 0) continue; int time. Idle = // Truncate, do not round up ( int) (( time. Now - session. get. Last. Accessed. Time ()) / 1000 L); if ( time. Idle >= max. Inactive. Interval ) session. expire(); } /** * Return the maximum number of active Sessions allowed, or -1 for * no limit. */ public int get. Max. Active. Sessions () { get. Manager () { } } /** * Set the maximum number of actives Sessions allowed, or -1 for * no limit. * * @ param max The new maximum number of sessions */ public void set. Max. Active. Sessions(int max) { private Hashtable sessions = new Hashtable (); private Reaper reaper; private Server. Session. Manager () { reaper = Reaper. get. Reaper (); reaper. set. Server. Session. Manager(this ); reaper. start(); } this. max. Active. Sessions Server. Session serv. S =ap. S. get. Server. Session (); serv. S. accessed (); ap. S. accessed (); // cache it - no need to compute it again req. set. Session ( ap. S ); } public Http. Session create. Session(Context ctx) { String session. Id = Session. Id. Generator. generate. Id (); Server. Session session = new Server. Session(session. Id ); sessions. put(session. Id , session); if(-1 != inactive. Interval ) { session. set. Max. Inactive. Interval(inactive. Interval /** * Sleep for the duration specified by the <code> * property. */ private void thread. Sleep () { check. Interval </code> try { Thread. sleep(check. Interval * 1000 L); } catch ( Interrupted. Exception e) { ; } = max; } // ----------------------------- Public Methods } /** * Construct and return a new session object, based on the default * settings specified by this Manager's properties. The session * id will be assigned by this method, and available via the get. Id () * method of the returned session. If a new session cannot be created * for any reason, return <code>null</code>. * * @exception Illegal. State. Exception if a new session cannot be * instantiated for any reason */ public Session create. Session () { /** * Start the background thread that will periodically check for * session timeouts. */ private void thread. Start () { if (thread != null) return; thread. Done = false; thread = new Thread(this, thread. set. Daemon(true ); thread. start(); ); if (( max. Active. Sessions >= 0) && (sessions. size() >= max. Active. Sessions )) throw new Illegal. State. Exception ( sm. get. String("standard. Manager. create. Session. ise } return session. get. Application. Session ( ctx, true ); } public Http. Session find. Session(Context ctx, String id) { Server. Session s. Session =(Server. Session)sessions. get(id ); if(s. Session ==null) return null; thread. Name ); } ")); /** * Stop the background thread that is periodically checking for * session timeouts. */ private void thread. Stop () { return ( super. create. Session ()); } return s. Session. get. Application. Session(ctx , false); } if (thread == null) return; return (null); thread. Done = true; thread. interrupt(); try { thread. join(); } catch ( Interrupted. Exception ; } } } e) { thread = null; } // --------------------------- Background Thread /** * The background thread that checks for session timeouts and shutdown. */ public void run() { return ( this. New ); } // Loop until the termination semaphore is set while (! thread. Done ) { thread. Sleep (); process. Expires (); } = interval; } } } conforgure the * session manager according to this value. * /** // Stop the background reaper thread. Stop (); /** * Set the check interval (in seconds) for this Manager. * * @ param check. Interval The new check interval */ public void set. Check. Interval(int check. Interval ) { ctx! // The manager will still run after that ( i. e. keep database * implementation. // --------------------------- Instance Variables return ( this. max. Active. Sessions ); public static Server. Session. Manager return manager; } Mehr 1383, Sharif Univ. 9/12/2021 * public final class // Start the background reaper thread. Start (); } public void Enumera public void accessed( Context ctx, Request req, String id ) { Application. Session ap. S=(Application. Session)find. Session ( ctx, id); if( ap. S==null) return; } /** * Return <code>true</code> if the client does not yet know about the * session, or if the client chooses not to join the session. For * example, if the server used only cookie-based sessions, and the client * has disabled the use of cookies, then a session would be new on each * request. * * @exception Illegal. State. Exception if this method is called on an * invalidated session */ public boolean is. New () { return (null); public Http. Session create. Session(Context ())); /** * Gracefully terminate the active use of the public methods of this * component. This method should be the last one called on a given * instance of this component. * * @exception Illegal. State. Exception if this component has not been started * @exception Illegal. State. Exception if this component has already * been stopped * @exception Lifecycle. Exception if this component detects a fatal error * that needs to be reported */ public void stop() throws Lifecycle. Exception { session. invalidate(); sessions. remove(id); = -1; Server. Session. Manager (); final class Standard. Session. Context // Cause this session to expire(); } } * should be. ())); session. get. Session (); } catch ( IOException e) { Session. Manager interface) * a Context to tell the Manager that we create what the default session * timeout for this web application (specified in the deployment descriptor) // Validate and update our current component state if (!configured) throw new Lifecycle. Exception ( sm. get. String("standard. Manager. not. Configured ")); if (started) throw new Lifecycle. Exception ( sm. get. String("standard. Manager. already. Started ")); started = true; } } /** * Return the <code> Http. Session </code> associated with the * specified session identifier. * * @ param id Session identifier for which to look up a session * * @deprecated As of Java Servlet API 2. 1 with no replacement. * This method must return null and will be removed in a * future version of the API. */ public Http. Session get. Session(String id) { return * XXX - At present, there is no way (via the for manager. find. Session(id ); if(session!=null) * <p> ())); "); return ( this. check. Interval ); this. check. Interval } implements Session. Manager { private String. Manager sm = String. Manager. get. Manager("org. apache. tomcat. session "); private static Server. Session. Manager manager; // = new Server. Session. Manager (); /** * This class is a dummy implementation of the <code> Http. Session. Context </code> * interface, to conform to the requirement that such an object be returned * when <code> Http. Session. get. Session. Context ()</code> is called. * * @author Craig R. Mc. Clanahan * * @deprecated As of Java Servlet API 2. 1 with no replacement. The * interface will be removed in a future version of this API. */ return (dummy. elements()); Session session = * collection class, and has minimal knowledge of the detailed request } /** * * @author James Duncan Davidson [ duncan@eng. sun. com ] * @author Jason Hunter [ jch@eng. sun. com ] * @author James Todd [gonzo@eng. sun. com] */ static { manager = new } try { // XXX a manager may be shared by multiple /** * Return the check interval (in seconds) for this Manager. */ public int get. Check. Interval () { synchronized void reap() { Enumeration enum = sessions. keys(); } /** * Invalidates this session and unbinds any objects bound to it. * * @exception Illegal. State. Exception if this method is called on * an invalidated session */ public void invalidate() { public Http. Session find. Session ( Context ctx, String id ) { /** * The background thread. */ private Thread thread = null; protected int inactive. Interval private Vector dummy = new Vector(); // XXX should we throw exception or just return null ? ? * processing semantics of handling sessions. * Create a new Manager /** * Has this component been started yet? */ private boolean started = false; public class Server. Session. Manager } /** * Return the session identifiers of all sessions defined * within this context. * * @deprecated As of Java Servlet API 2. 1 with no replacement. * This method must return an empty <code>Enumeration</code> * and will be removed in a future version of the API. */ public Enumeration get. Ids () { Http. Session - avoid another find req. set. Session ( session ); } Once we commit to the new Manager/Session The Tomcat. Next "Manager" interface acts more like a } s): s & ( int get. Max. Inactive. Interval () | long get. Creation. Time () | Object get. Attribute(String ) | Enumeration get. Attribute. Names () | String[] get. Value. Names () | void invalidate() | boolean is. New () | void remove. Attribute(String ) | void set. Attribute(String , Object)); implements Http. Session. Context // cache the * <b>IMPLEMENTATION NOTE</b>: * paradigm, I would suggest moving the logic implemented here back into * the core level. * Prepare for the beginning of active use of the public methods of this * component. This method should be called after <code>configure()</code>, * and before any of the public methods of the component are utilized. * * @exception Illegal. State. Exception if this component has not yet been * configured (if required for this component) * @exception Illegal. State. Exception if this component has already been * started * @exception Lifecycle. Exception if this component detects a fatal error * that prevents this component from being used */ public void start() throws Lifecycle. Exception { // ------------------------------- Properties static advice(Standard. Session s): invalidate(s) { before { if (! s. is. Valid ()) throw new Illegal. State. Exception ( s. sm. get. String("standard. Session. " + this. Join. Point. method. Name + ". ise")); } } Vector results = new Vector(); Enumeration attrs = get. Attribute. Names (); while ( attrs. has. More. Elements ()) { String attr = (String) attrs. next. Element (); results. add. Element(attr ); } String names[] = new String[results. size()]; for ( int i = 0; i < names. length; i++) names[i] = (String) results. element. At(i ); return (names); } /** * Set the Manager within which this Session is valid. * * @ param manager The new Manager */ public void set. Manager(Manager manager) { /** * The string manager for this package. */ private String. Manager sm = String. Manager. get. Manager("org. apache. tomcat. session Server. Session. Manager // ------------------------------- Private Class /** * Return the Manager within which this Session is valid. */ public Manager get. Manager () { ((Session) session). access(); org. apache. tomcat. core. Session. Manager * and lifecycle configuration is not supported. } } /** * Return the set of names of objects bound to this session. If there * are no such objects, a zero-length array is returned. * * @exception Illegal. State. Exception if this method is called on an * invalidated session * * @deprecated As of Version 2. 2, this method is replaced by * <code> get. Attribute. Names ()</code> */ public String[] get. Value. Names () { instanceof Session) * <p> /** * Name to register for the background thread. */ private String thread. Name = "Standard. Manager "; } /** * Return the last time the client sent a request associated with this * session, as the number of milliseconds since midnight, January 1, 1970 * GMT. Actions that your application takes, such as getting or setting * a value associated with the session, do not affect the access time. */ public long get. Last. Accessed. Time () { ctx, Request req, String id) { Http. Session session= find. Session(ctx , id); if( session == null) return; if (session /** /** * The maximum number of active Sessions allowed, or -1 for no limit. */ protected int max. Active. Sessions = -1; } crosscut invalidate(Standard. Session this. id = id; if ((manager != null) && (manager instanceof Manager. Base )) (( Manager. Base ) manager). add(this); * @ param session The session to be marked public void accessed(Context * <p> node = attributes. get. Named. Item("max. Inactive. Interval "); if (node != null) { try { set. Max. Inactive. Interval(Integer. parse. Int(node. get. Node. Value } catch ( Throwable t) { ; // XXX - Throw exception? } } /** * The background thread completion semaphore. */ private boolean thread. Done = false; // Serialize the attribute count and the attribute values stream. write. Object(new Integer(results. size())); Enumeration names = results. elements(); while ( names. has. More. Elements ()) { String name = (String) names. next. Element (); stream. write. Object(name ); stream. write. Object(attributes. get(name )); } /** * Return an <code>Enumeration</code> of <code>String</code> objects * containing the names of the objects bound to this session. * * @exception Illegal. State. Exception if this method is called on an * invalidated session */ public Enumeration get. Attribute. Names () { This should be Request. Interceptor. * */ import org. apache. tomcat. core. Session. Manager ; import org. apache. tomcat. util. Session. Util ; } // Accumulate the names of serializable attributes Vector results = new Vector(); Enumeration attrs = get. Attribute. Names (); while ( attrs. has. More. Elements ()) { String attr = (String) attrs. next. Element (); Object value = attributes. get(attr ); if (value instanceof Serializable ) results. add. Element(attr ); } return (this. id); * Mark the specified session's last accessed time. * called for each request by a import org. apache. tomcat. core. Request; import org. apache. tomcat. core. Response; * XXX - At present, use of <code> Standard. Manager </code> is hard coded, node = attributes. get. Named. Item("max. Active. Sessions "); if (node != null) { try { set. Max. Active. Sessions(Integer. parse. Int(node. get. Node. Value } catch ( Throwable t) { ; // XXX - Throw exception? } } /** * The descriptive information about this implementation. */ private static final String info = "Standard. Manager/1. 0"; } /** * Set the session identifier for this session. * * @ param id The new session identifier */ public void set. Id(String id) { /** import org. apache. tomcat. catalina. *; import org. apache. tomcat. core. Context; * Specialized implementation of node = attributes. get. Named. Item("check. Interval "); if (node != null) { try { set. Check. Interval(Integer. parse. Int(node. get. Node. Value } catch ( Throwable t) { ; // XXX - Throw exception? } } /** * Has this component been configured yet? */ private boolean configured = false; // Write the scalar instance variables (except Manager) stream. write. Object(new Long(creation. Time )); stream. write. Object(id ); stream. write. Object(new Long(last. Accessed. Time )); stream. write. Object(new Integer(max. Inactive. Interval )); stream. write. Object(new Boolean(is. New )); stream. write. Object(new Boolean(is. Valid )); /** * Return the object bound with the specified name in this session, or * <code>null</code> if no object is bound with that name. * * @ param name Name of the attribute to be returned * * @exception Illegal. State. Exception if this method is called on an * invalidated session */ public Object get. Attribute(String name) { import javax. servlet. http. Cookie ; import javax. servlet. http. Http. Session ; * that adapts to the new component-based Manager implementation. ")); // Parse and process our configuration parameters if (!(" Manager". equals(parameters. get. Node. Name ()))) return; Named. Node. Map attributes = parameters. get. Attributes (); Node node = null; /** * The interval (in seconds) between checks for expired sessions. */ private int check. Interval = 60; /** * Write a serialized version of this session object to the specified * object output stream. * <p> * <b>IMPLEMENTATION NOTE</b>: The owning Manager will not be stored * in the serialized representation of this Session. After calling * <code> read. Object ()</code>, you must set the associated Manager * explicitly. * <p> * <b>IMPLEMENTATION NOTE</b>: Any attribute that is not Serializable * will be silently ignored. If you do not want any such attributes, * be sure the <code>distributable</code> property of our associated * Manager is set to <code>true</code>. * * @ param stream The output stream to write to * * @exception IOException if an input/output error occurs */ private void write. Object(Object. Output. Stream stream) throws IOException { } // Validate and update our current component state if (configured) throw new Lifecycle. Exception ( sm. get. String("standard. Manager. already. Configured configured = true; if (parameters == null) return; // --------------------------- Instance Variables } /** * Return the session context with which this session is associated. * * @deprecated As of Version 2. 1, this method is deprecated and has no * replacement. It will be removed in a future version of the * Java Servlet API. */ public Http. Session. Context get. Session. Context () { import java. io. IOException ; /** * Configure this component, based on the specified configuration * parameters. This method should be called immediately after the * component instance is created, and before <code>start()</code> * is called. * * @ parameters Configuration parameters for this component * (<B>FIXME: What object type should this really be? ) * * @exception Illegal. State. Exception if this component has already been * configured and/or started * @exception Lifecycle. Exception if this component detects a fatal error * in the configuration parameters it was given */ public void configure(Node parameters) throws Lifecycle. Exception { public final class Standard. Manager extends Manager. Base implements Lifecycle, Runnable { // Deserialize the attribute count and attribute values int n = ((Integer) stream. read. Object()). int. Value (); for ( int i = 0; i < n; i++) { String name = (String) stream. read. Object (); Object value = (Object) stream. read. Object (); attributes. put(name, value); } return ( this. creation. Time ); } // -------------------------- Session Properties /** * Set the creation time for this session. This method is called by the * Manager when an existing Session instance is reused. * * @ param time The new creation time */ public void set. Creation. Time(long time) { Http. Session Private Methods // Deserialize the scalar instance variables (except Manager) creation. Time = ((Long) stream. read. Object()). long. Value (); id = (String) stream. read. Object (); last. Accessed. Time = ((Long) stream. read. Object()). long. Value (); max. Inactive. Interval = ((Integer) stream. read. Object()). int. Value (); is. New = ((Boolean) stream. read. Object()). boolean. Value (); is. Valid = ((Boolean) stream. read. Object()). boolean. Value (); /** * Return the time when this session was created, in milliseconds since * midnight, January 1, 1970 GMT. * * @exception Illegal. State. Exception if this method is called on an * invalidated session */ public long get. Creation. Time () { Illegal. State. Exception(msg ); } } // ---------------------- /** * Read a serialized version of this session object from the specified * object input stream. * <p> * <b>IMPLEMENTATION NOTE</b>: The reference to the owning Manager * is not restored by this method, and must be set explicitly. * * @ param stream The input stream to read from * * @exception Class. Not. Found. Exception if an unknown class is specified * @exception IOException if an input/output error occurs */ private void read. Object(Object. Input. Stream stream) throws Class. Not. Found. Exception , IOException { ); } Illegal. State. Exception(msg ); } } // HTTP SESSION IMPLEMENTATION METHODS } this. New = is. New ; /** * Set the <code> is. Valid </code> flag for this session. * * @ param is. Valid The new value for the <code> is. Valid </code> flag */ void set. Valid(boolean is. Valid ) { // ----------------------------- Public Methods package org. apache. tomcat. session; java. io. IOException ; java. util. Enumeration; java. util. Hashtable ; java. util. Vector; org. apache. tomcat. catalina. *; javax. servlet. http. Cookie ; javax. servlet. http. Http. Session ; org. apache. tomcat. util. String. Manager ; org. w 3 c. dom. Named. Node. Map; org. w 3 c. dom. Node; /** * Standard implementation of the <b>Manager</b> interface that provides * no session persistence or distributable capabilities, but does support * an optional, configurable, maximum number of active sessions allowed. * <p> * Lifecycle configuration of this component assumes an XML node * in the following format: * <code> * & lt; Manager class. Name ="org. apache. tomcat. session. Standard. Manager " * check. Interval ="60" max. Active. Sessions ="-1" * max. Inactive. Interval ="-1" /> * </code> * where you can adjust the following parameters, with default values * in square brackets: * <ul> * <li><b>check. Interval </b> - The interval (in seconds) between background * thread checks for expired sessions. [60] * <li><b>max. Active. Sessions </b> - The maximum number of sessions allowed to * be active at once, or -1 for no limit. [-1] * <li><b>max. Inactive. Interval </b> - The default maximum number of seconds of * inactivity before which the servlet container is allowed to time out * a session, or -1 for no limit. This value should be overridden from * the default session timeout specified in the web application deployment * descriptor, if any. [-1] * </ ul> * * @author Craig R. Mc. Clanahan * @version $Revision: 1. 1 $ $Date: 2000/05/02 21: 28: 30 $ */ synchronized (attributes) { remove. Attribute(name ); attributes. put(name, value); if (value instanceof Http. Session. Binding. Listener ) (( Http. Session. Binding. Listener ) value). value. Bound (new Http. Session. Binding. Event((Http. Session ) this, name)); } /** * Set the <code> is. New </code> flag for this session. * * @ param is. New The new value for the <code> is. New </code> this. Valid = is. Valid ; is. New = true; /** * Flag indicating whether this session is valid or not. */ private boolean is. Valid = false; Standard. Session. Manager // --------------------------- Lifecycle Methods import import import if ((manager != null) && manager. get. Distributable () && !(value instanceof Serializable )) throw new Illegal. Argument. Exception ( sm. get. String("standard. Session. set. Attribute. iae ")); return ( this. Valid ); } flag not. "); Standard. Manager package org. apache. tomcat. session; /** * Bind an object to this session, using the specified name. If an object * of the same name is already bound to this session, the object is * replaced. * <p> * After this method executes, and if the object implements * <code> Http. Session. Binding. Listener </code>, the container calls * <code> value. Bound ()</code> on the object. * * @ param name Name to which the object is bound, cannot be null * @ param value Object to be bound, cannot be null * * @exception Illegal. Argument. Exception if an attempt is made to add a * non- serializable object in an environment marked distributable. * @exception Illegal. State. Exception if this method is called on an * invalidated session */ public void set. Attribute(String name, Object value) { Illegal. State. Exception(msg ); } if ( this. Interval > inactive. Interval ) { invalidate(); } Sess on n ercep or remove. Attribute(name ); } // Tell our Manager that this Session has been recycled if ((manager != null) && (manager instanceof Manager. Base )) (( Manager. Base ) manager). recycle(this); */ void set. New(boolean is. New ) { Hashtable values. Clone = ( Hashtable)values. clone (); throw new attributes. clear(); creation. Time = 0 L; id = null; last. Accessed. Time = 0 L; manager = null; max. Inactive. Interval = -1; is. New = true; is. Valid = false; /** * The last accessed time for this Session. */ private long last. Accessed. Time = creation. Time ; return value. Names ; = context. get. Session. Time. Out (); Server. Session get. Server. Session () { return server. Session ; } public long get. Last. Accessed. Time () { if (valid) { return last. Accessed ; } else { String msg = sm. get. String("application. Session. session. ise // Reset the instance variables associated with this Session names. copy. Into(value. Names ); } /** * Remove the object bound with the specified name from this session. If * the session does not have an object bound with this name, this method * does nothing. * <p> * After this method executes, and if the object implements * <code> Http. Session. Binding. Listener </code>, the container calls * <code> value. Unbound ()</code> on the object. * * @ param name Name of the object to remove from this session. * * @exception Illegal. State. Exception if this method is called on an * invalidated session * * @deprecated As of Version 2. 2, this method is replaced by * <code> remove. Attribute ()</code> */ public void remove. Value(String name) { /** * Release all object references, and initialize instance variables, in * preparation for reuse of this object. */ public void recycle() { /** * The time this session was created, in milliseconds since midnight, * January 1, 1970 GMT. */ private long creation. Time = 0 L; } String[] } // Mark this session as invalid set. Valid(false ); // -------------------------- Instance Variables } Application. Session(String id, Server. Session server. Session , Context context) { this. server. Session = server. Session ; this. context = context; this. id = id; synchronized (attributes) { Object object = attributes. get(name); if (object == null) return; attributes. remove(name); // System. out. println ( "Removing attribute " + name ); if (object instanceof Http. Session. Binding. Listener ) { (( Http. Session. Binding. Listener ) object). value. Unbound (new Http. Session. Binding. Event((Http. Session ) this, name)); } } // Unbind any objects associated with this session Vector results = new Vector(); Enumeration attrs = get. Attribute. Names (); while ( attrs. has. More. Elements ()) { String attr = (String) attrs. next. Element (); results. add. Element(attr ); } Enumeration names = results. elements(); while ( names. has. More. Elements ()) { String name = (String) names. next. Element (); remove. Attribute(name ); } } implements Http. Session { private String. Manager sm = String. Manager. get. Manager("org. apache. tomcat. session "); private Hashtable values = new Hashtable (); private String id; private Server. Session server. Session ; private Context context; private long creation. Time = System. current. Time. Millis (); ; private long this. Access. Time = creation. Time ; private long last. Accessed = creation. Time ; private int inactive. Interval = -1; private boolean valid = true; throw new // Remove this session from our manager's active if ((manager != null) && (manager instanceof Manager. Base )) (( Manager. Base ) manager). remove(this); } public Object get. Attribute(String name) { if (! valid) { String msg = sm. get. String("application. Session. session. ise throw new /** * Remove the object bound with the specified name from this session. If * the session does not have an object bound with this name, this method * does nothing. * <p> * After this method executes, and if the object implements * <code> Http. Session. Binding. Listener </code>, the container calls * <code> value. Unbound ()</code> on the object. * * @ param name Name of the object to remove from this session. * * @exception Illegal. State. Exception if this method is called on an * invalidated session */ public void remove. Attribute(String name) { sessions /** * Construct a new Session associated with the specified Manager. * * @ param manager The manager with which this Session is associated */ public Standard. Session(Manager manager) { super(); this. manager = manager; throw new set. Attribute(name , value); } = this. Accessed. Time ; = System. current. Time. Millis (); /** * Perform the internal processing required to invalidate this session, * without triggering an exception if the session has already expired. */ public void expire() { values. put(name, value); } throw new this. last. Accessed. Time this. New =false; } // ----------------------------- Constructors if (value != null && value instanceof Http. Session. Binding. Listener ) { Http. Session. Binding. Event e = new Http. Session. Binding. Event(this , name); /** * Core implementation of an application level session * * @author James Duncan Davidson [ duncan@eng. sun. com ] * @author Jason Hunter [ jch@eng. sun. com ] * @author James Todd [gonzo@eng. sun. com] */ public String get. Id () { if (valid) { return id; } else { String msg = sm. get. String("application. Session. session. ise /** * Update the accessed time information for this session. This method * should be called by the context when a request comes in for a particular * session, even if the application does not reference it. */ public void access() { // remove any existing binding /** * @deprecated */ public Object get. Value(String name) { return get. Attribute(name ); } import org. apache. tomcat. core. *; import org. apache. tomcat. util. String. Manager ; import java. io. *; import java. net. *; import java. util. *; import javax. servlet. http. *; this. inactive. Interval // ------------------------Session Public Methods "); Illegal. Argument. Exception(msg ); } if ( this. inactive. Interval } ; /** * Standard implementation of the <b>Session</b> interface. This object is * serializable , so that it can be stored in persistent storage or transferred * to a different JVM for distributable session support. * <p> * <b>IMPLEMENTATION NOTE</b>: An instance of this class represents both the * internal (Session) and application level (Http. Session ) view of the session. * However, because the class itself is not declared public, Java logic outside * of the <code>org. apache. tomcat. session</code> package cannot cast an * Http. Session view of this instance back to a Session view. * * @author Craig R. Mc. Clanahan * @version $Revision: 1. 2 $ $Date: 2000/05/15 17: 54: 10 $ */ final class Standard. Session implements Http. Session , Session { } remove. Value(name ); * Bind an object to this session, using the specified name. If an object * of the same name is already bound to this session, the object is * replaced. * <p> * After this method executes, and if the object implements * <code> Http. Session. Binding. Listener </code>, the container calls * <code> value. Bound ()</code> on the object. * * @ param name Name to which the object is bound, cannot be null * @ param value Object to be bound, cannot be null * * @exception Illegal. State. Exception if this method is called on an * invalidated session * * @deprecated As of Version 2. 2, this method is replaced by * <code> set. Attribute ()</code> */ public void put. Value(String name, Object value) { return (( Http. Session ) this); } } package org. apache. tomcat. session; public class Application. Session java. io. IOException ; java. io. Object. Input. Stream ; java. io. Object. Output. Stream ; java. io. Serializable ; java. util. Enumeration; java. util. Hashtable ; java. util. Vector; javax. servlet. Servlet. Exception ; javax. servlet. http. Http. Session. Binding. Event ; javax. servlet. http. Http. Session. Binding. Listener javax. servlet. http. Http. Session. Context ; org. apache. tomcat. catalina. *; org. apache. tomcat. util. String. Manager ; Illegal. State. Exception(msg ); } throw new /** * Return the <code> Http. Session </code> for which this object * is the facade. */ public Http. Session get. Session () { ); // remove everything in the session 22 * 60);

AOP: Identifying cross-cuts Mehr 1383, Sharif Univ. 9/12/2021 23

AOP: Identifying cross-cuts Mehr 1383, Sharif Univ. 9/12/2021 23

AOP: Defining aspects Mehr 1383, Sharif Univ. 9/12/2021 24

AOP: Defining aspects Mehr 1383, Sharif Univ. 9/12/2021 24

AOP: Weaving aspects Mehr 1383, Sharif Univ. 9/12/2021 25

AOP: Weaving aspects Mehr 1383, Sharif Univ. 9/12/2021 25

Cross Cutting Bank. Acct Product get. Balance() get. SKU() get. Owner() get. Qty() set.

Cross Cutting Bank. Acct Product get. Balance() get. SKU() get. Owner() get. Qty() set. Owner() set. SKU() set. Balance() set. Qty() to. XML() store() Mehr 1383, Sharif Univ. 9/12/2021 Serializable to XML Persistable 26

Aspect-Oriented Programming • Identify concerns that cut across class / object boundaries • Write

Aspect-Oriented Programming • Identify concerns that cut across class / object boundaries • Write code (an aspect) that encapsulates that concern • Define a weave that specifies how the aspect will be weaved into existing code Mehr 1383, Sharif Univ. 9/12/2021 27

AOP Constructs • Cross Cutting Concern – Even though most classes in an OO

AOP Constructs • Cross Cutting Concern – Even though most classes in an OO model will perform a single, specific function, they often share common, secondary requirements with other classes. For example, we may want to add logging to all classes whenever a thread enters or exits a method. Even though the primary functionality of each class is very different, the code needed to perform the secondary functionality is often identical. • Point Cut – This is the term given to the point of execution in the application at which cross cutting concern needs to be applied. In our example, a point cut is reached when the thread enters a method, and another point cut is reached when the thread exits the method Mehr 1383, Sharif Univ. 9/12/2021 28

AOP Constructs (Cont. ) • Advice – This is the additional code that you

AOP Constructs (Cont. ) • Advice – This is the additional code that you want to apply to your existing model. In our example, this is the logging code that we want to apply whenever the thread enters or exits a method • Aspect – The combination of the point cut and the advice is termed an aspect. In the example below, we add a logging aspect to our application by defining a point cut and giving the correct advice • Joint Part – Well defined locations in the execution of a program, typically, these include method invocations, field accesses, exception handlers, etc… – Each join point is a possible place at which an aspect may specify behaviour Mehr 1383, Sharif Univ. 9/12/2021 29

An Example: Policies and software • Method implements three policies in addition to its

An Example: Policies and software • Method implements three policies in addition to its code! – Tracing policy: all public methods must be traceable – Security policy: employee salary only readable by managers – Exception policy: all Fatal. Exceptions must be logged • Should not mix policies and code – Developers need to know to put policy code in there – Policies obscure the method's implementation Mehr 1383, Sharif Univ. 9/12/2021 30

Aspects can implement policies Public Function Read. Employee. Salary( id as Integer ) as

Aspects can implement policies Public Function Read. Employee. Salary( id as Integer ) as Single 1 Trace. Write. Line( String. Format( "Reading employee # {0}'s salary", id ) ) 2 If System. Threading. Thread. Current. Principal. Is. In. Role( "manager" ) Then Try ' Code that reads employee's salary 3 Catch e as Fatal. Exception Logging. Log. Fatal. Exception( e, "Read. Employee. Salary" ) End Try End If End Sub Mehr 1383, Sharif Univ. 9/12/2021 31

Aspects can implement policies 1 2 3 public class Tracing. Policy { public void

Aspects can implement policies 1 2 3 public class Tracing. Policy { public void Before( Call. Context c ) { Trace. Write. Line( String. Format( "Called: {0}", c. Method. Name ) ); } } public class Security. Policy { public bool Access. Check() { return System. Threading. Thread. Current. Principal. Is. In. Role( "manager" ); } } public class Exception. Policy { public void Thrown( Fatal. Exception e ) { Logger. Log. Fatal. Exception( e ); } } Mehr 1383, Sharif Univ. 9/12/2021 32

Weaving aspects before methods public class Tracing. Policy { public void Before( Call. Context

Weaving aspects before methods public class Tracing. Policy { public void Before( Call. Context c ) { Trace. Write. Line( String. Format( "Called: {0}", c. Method. Name ) ); } } <weave> <aspect target="public *. *: : *( * )" type="Before" method="Tracing. Policy. Before( Call. Context )"/> </weave> Mehr 1383, Sharif Univ. 9/12/2021 33

Weaving aspects around methods public class Security. Policy { public bool Access. Check() {

Weaving aspects around methods public class Security. Policy { public bool Access. Check() { return System. Threading. Thread. Current. Principal. Is. In. Role( "manager" ); } } <weave> <aspect target="[ interface: Manager. Only == true ] public *. *: : *( * )" type="Around" method="Security. Policy. Access. Check()"/> </weave> [ Manager. Only ] public interface ISensitive. Employee. Data { float Read. Employee. Salary( int id ); . . . } Mehr 1383, Sharif Univ. 9/12/2021 34

Weaving aspects around methods public class Exception. Policy { public void Thrown( Fatal. Exception

Weaving aspects around methods public class Exception. Policy { public void Thrown( Fatal. Exception e ) { Logger. Log. Fatal. Exception( e ); } } <weave> <aspect target="public *. *: : *( * )" type="Thrown( Fatal. Exception )" method="Exception. Policy. Thrown( Fatal. Exception )"/> </weave> Mehr 1383, Sharif Univ. 9/12/2021 35

What is Aspect. J? • • • An open source language 100% Java compatible

What is Aspect. J? • • • An open source language 100% Java compatible An AOP implementation Extension to Java, new syntax Started at Xerox, now Eclipse project Mehr 1383, Sharif Univ. 9/12/2021 36

Getting and installing • • Download from eclipse. org/aspectj Run executable JAR Use aspectjrt.

Getting and installing • • Download from eclipse. org/aspectj Run executable JAR Use aspectjrt. jar on classpath Includes structure browser, debugger Mehr 1383, Sharif Univ. 9/12/2021 37

Writing an aspect • • Write the class Write the aspect (. java or.

Writing an aspect • • Write the class Write the aspect (. java or. aj) Weave with ‘ajc’ compiler Must have aspectjrt. jar for compile and runtime • Simply use AJDT (Aspect. J Development Tool ) as IDE Mehr 1383, Sharif Univ. 9/12/2021 38

Definitions • • Join point Pointcut Advice Introduction (Inter type declaration) Mehr 1383, Sharif

Definitions • • Join point Pointcut Advice Introduction (Inter type declaration) Mehr 1383, Sharif Univ. 9/12/2021 39

Join points • Points in a programs execution – Method call( public void set.

Join points • Points in a programs execution – Method call( public void set. Owner(String) ) – Method call execution – Constructor call initialization (Bank. Account. new() ) – Constructor call execution – Field get – Field set – Exception handler execution – Constructor Call – Initializer Execution – Static Initializer Execution – Object Pre Initialization – Object Initialization – No finer join points in Aspect. J (loops, if checks) Mehr 1383, Sharif Univ. 9/12/2021 40

Join point patterns • Names can be matched with * • call ( *

Join point patterns • Names can be matched with * • call ( * * Bank. Account. *(*)) – Matches all calls on Bank. Account, regardless of visibility or return type, with one argument • call ( * *. (*)) – Matches all method calls with 1 parameter • call ( * *. (. . )) – Matches all method calls Mehr 1383, Sharif Univ. 9/12/2021 41

Join Point Patterns Cont • Subtypes can be matched with a + – call

Join Point Patterns Cont • Subtypes can be matched with a + – call (public void Bank. Account+(. . )) • Can also match on throws patterns – call (public void Bank. Account+(. . ) throws Exception+) • Watch out for infinite recursion! – Aspects match aspects too – Use ! within() Mehr 1383, Sharif Univ. 9/12/2021 42

Pointcuts • Structure for selecting join points in a program and collecting context (args,

Pointcuts • Structure for selecting join points in a program and collecting context (args, target, source) • Declaring a named pointcut – pointcut change. Balance() : call (public void Bank. Account. set. Balance(java. math. Big. Decimal)); • Can be combined with logical operators, &&, ||, and ! Mehr 1383, Sharif Univ. 9/12/2021 43

Pointcuts (cont. ) • Valid on interfaces and classes • Syntax – – pointcut

Pointcuts (cont. ) • Valid on interfaces and classes • Syntax – – pointcut name ([parameters]) : designator (ajoinpoint); Name will be used to handle actions ajoinpoint is a signature match Designator decides when this join point will match like call , execution , … Mehr 1383, Sharif Univ. 9/12/2021 44

Aspect. J Point-Cuts • • • call)Signature( execution(Signature( get(Signature( set(Signature( handler(Type. Pattern( initialization(Signature( staticinitialization(Signature(

Aspect. J Point-Cuts • • • call)Signature( execution(Signature( get(Signature( set(Signature( handler(Type. Pattern( initialization(Signature( staticinitialization(Signature( within(Type. Pattern( withincode(Type. Pattern( cflow(Pointcut( cflowbelow(Pointcut( Mehr 1383, Sharif Univ. 9/12/2021 • • • this)Type. Pattern | Id( target(Type. Pattern | Id( args(Type. Pattern | Id( … , Pointcut. Id(Type. Pattern | Id( if (Boolean. Expression( Pointcut 1 && Pointcut 2 Pointcut 1 || Pointcut 2 !Pointcut )Pointcut( 45

Aspect. J Advisers • Advice defines crosscutting behavior. • It is defined in terms

Aspect. J Advisers • Advice defines crosscutting behavior. • It is defined in terms of pointcuts. • The code of a piece of advice runs at every join point picked out by its pointcut. • The code runs before, after, or around the join point Mehr 1383, Sharif Univ. 9/12/2021 46

Advice Type • before – excellent for preconditions – argument checking, setup code, lazy

Advice Type • before – excellent for preconditions – argument checking, setup code, lazy init • after – can be qualified with: after returning, or after throwing – Cleanup of resources – checking/manipulating the return value • around – the most powerful advice – can replace invocation, or just surround – use proceed() to call method Mehr 1383, Sharif Univ. 9/12/2021 47

Inter-type Declarations • Aspect. J can be used to change the structure of existing

Inter-type Declarations • Aspect. J can be used to change the structure of existing code – – – add members (id fields, dirty flag) add methods (to. XML, store. To. JDBC) add types that extend existing types or implement interfaces declare custom compilation errors or warnings convert checked exceptions to unchecked • Can use from aspects, or regular code • Write normal variable and methods in your aspect, but prefix them with your class name Mehr 1383, Sharif Univ. 9/12/2021 48

Inter-type declarations cont. • Very powerful • Can do wacky things – – Add

Inter-type declarations cont. • Very powerful • Can do wacky things – – Add concrete fields & methods to interfaces (no constructors) Modify aspects Make an existing class dynamically implement an interface Make an existing class extend another Mehr 1383, Sharif Univ. 9/12/2021 49

Aspect. J: Simple Example public class Person { private String name; private String address;

Aspect. J: Simple Example public class Person { private String name; private String address; private int age; public static void main)String[] args ({ Person person =new Person")Mahdi Minoochehr; (" person. set. Address("Tehran, P 15; (" person. set. Age(15; ( } public Person)String name}(this. name=name{; public String get. Address (){ return address; } public int get. Age (){ return age; } public String get. Name (){ return name; } public void set. Address)String address ({ this. address public void set. Age)int age ({ this. age =age; } =address; } } Mehr 1383, Sharif Univ. 9/12/2021 50

Aspect. J: Simple Example (cont. ) public aspect Logger { pointcut traced. Call :

Aspect. J: Simple Example (cont. ) public aspect Logger { pointcut traced. Call : ()call)void Person; ((. . )*. before : ()traced. Call (){ System. out. println("Entering: " + this. Join. Point. Static. Part. get. Signature; (() } after : ()traced. Call (){ System. out. println("Exiting+ " : this. Join. Point. Static. Part. get. Signature; (() } } Mehr 1383, Sharif Univ. 9/12/2021 51

The Risk: Aspect side-effects • Several aspects may be stacked at a join point

The Risk: Aspect side-effects • Several aspects may be stacked at a join point • Several unintended interactions are possible: – Aspect 1 is unaware of the side effects of Aspect 2 – Code at the join point is unaware of side effects of any aspect Mehr 1383, Sharif Univ. 9/12/2021 52

Who can use aspects? • There will be different groups of users – –

Who can use aspects? • There will be different groups of users – – – Developers Testers Operations Library developers Systems administrators Systems engineers / consultants Mehr 1383, Sharif Univ. 9/12/2021 53

How can it be used? • Development – Check contracts, Logging – Ensure good

How can it be used? • Development – Check contracts, Logging – Ensure good coding practices – Tracing, Testing • Optional runtime components – Debugging • Detecting incorrect usage (e. g. leaked DB connections) • Detecting abusive usage (e. g. holding DB connections too long) – Profiling • Implement core system features – Caching, Security Mehr 1383, Sharif Univ. 9/12/2021 54

Types of aspect weavers • Source code aspect weavers – Aspect. J (V 1.

Types of aspect weavers • Source code aspect weavers – Aspect. J (V 1. 0+) • Link time aspect weavers – Hyper/J (IBM Alphaworks) • Run time aspect weavers – CLAW (prototype) Mehr 1383, Sharif Univ. 9/12/2021 55

Where to go for more information • An Introduction to Aspect-Oriented Programming & Aspect.

Where to go for more information • An Introduction to Aspect-Oriented Programming & Aspect. J – http: //www. sable. mcgill. ca/~cs 763/Fall 2002/slides/aspect oriented programming overview. pdf • Aspect Oriented Programming – http: //www. aosd. net – http: //www. aspectj. org • CLAW – http: //www. iunknown. com • AOP without Buzzwords – http: //jroller. com/page/colyer/20040531#the_ted_neward_challenge_aop • On. Java – http: //www. onjava. com/pub/a/onjava/2004/01/14/aop. html Mehr 1383, Sharif Univ. 9/12/2021 56