CS487_04_12_10

CS487_04_12_10 - CS487 Software Engineering I OMAR ALDAWUD © 2010 Illinois Institute of Technology Design Pattern – General DP • MVC – DP

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: CS487 Software Engineering I OMAR ALDAWUD 04/12/2010 © 2010 Illinois Institute of Technology Design Pattern – General DP • MVC – DP Summary CS585 1/ Benefits of Design Patterns Look for Recurring Patterns of classes and communicating objects. These patterns : – Solve a specific design problem – Provide an Elegant, Reusable, and Flexible solutions Each Design Pattern; – Names, Explains, and Evaluates an important and recurring design problem in OO systems AND – Provide an Elegant solution to the problem in its context. Benefits: – Reuse – Choose design alternatives – “get it right faster” CS585 2/ Christopher Alexander et al. Oxford Univ. Press 1977. A pattern Language: Towns Buildings, Constructions. “Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution for that problem, in such away that you can use this solution a million times over, without ever doing it the same way twice.” Christopher proposed 250 Patterns for Architectural Design Each pattern represents a generic reusable solution to a recurring problem – Short Passages Pattern • “…, long, sterile corridors set the scene for everything bad about modern architecture…” • Solution …. “ keep passages short. Make theme rooms as much like rooms as possible, with carpets or wood on the floor, …., beautiful windows, … the best are those with the whole wall is a window …” CS585 3/ Elements of a Design Pattern Pattern Name – A handle used to describe the design problem, its solution and consequences in one word Problem – When to apply the pattern – Explain the context Solution – What are the Elements that make up the design, their relationships, responsibilities and collaboration Consequences – Results and tradeoffs CS585 4/ Elements of a Design Pattern Design Patterns are “Descriptions of Communicating Objects that are customized to solve a general design problem in a particular context”. – The recurring aspects of designs are called design patterns. – A pattern is the outline of a reusable solution to a general problem encountered in a particular context – Many of them have been systematically documented for all software developers to use – A good pattern should – Be as general as possible – Contain a solution that has been proven to effectively solve the problem in the indicated context. CS585 5/ General Example MVC Pattern – Decouples views and models by establishing subscribe / notify protocol between them – Views represent the state of the model – Model contains data values – Controller mediates between views and model – See MVC Next Slide CS585 6/ MVC Example of Design Patterns View A B C C D 44 66 88 49 39 100 A B C C D 80 60 Ser i es1 40 20 0 A B C C D Model MVC Architecture A=50% B=30% C=55% – The model object holds the information – Views objects draw the visible parts of the view (or do something else) • Display number in tables • Display a bar chart – Each view has a controller which is an object that processes user interaction • Mouse or keyboard events CS585 7/ MVC – Oracle ADF Oracle Application Development Framework – The model layer represents the business information needed by the application, – The controller layer handles user input, interfaces with the model layer, and picks the presentation – The view layer presents the model data to the end-user. The model layer consists of one or more business services that expose application functionality and access to model data through a business service interface that is easy to test. These business services, in turn, rely on query components to retrieve that data and on business objects to validate and persist any new or modified data. Code implementing the business delegate design pattern abstracts the details of locating and using the business services. CS585 8/ MVC – Oracle ADF CS585 9/ Architectural patterns (architectural style) MVC Broker COM Common Object Request Broker Architecture (CORBA) multi-layer pipe and filter (transformational architectural pattern, transformational architecture) transaction-processing CS585 10/ multiplicity patterns many-to-many many-to-one one-to-many one-to-one CS585 11/ Describing Design Patterns Pattern Name Intent what does the DP do? Also known as Motivation scenario shows how the classes involoved solve the problem Applicability situations in which the DP can be applied Structure UML/ OMT Participants classes and/or objects and responsibilities Collaboration Consequences Implementations Sample code Know uses Related patterns CS585 12/ Software Design Patterns Published by Gamma et al. 23 commonly used design patterns – Creational Patterns • Object creation – Structural Patterns • Static composition of classes – Behavioral Patterns • Dynamic interaction among objects CS585 13/ Design Patterns Organization Criteria 1 Purpose reflects what a pattern does? – Creational Patterns, Deals with Object creation – Structural Patterns, deal with the composition of classes and or objects – Behavioral Patterns, show the interaction of objects and their responsibilities Criteria 2 Scope whether a pattern applies to objects or classes (Compile time vs. Run time) – Class Patterns • Deals with relationships between classes and their subclasses thru Inheritance thus Static or compile time structure – Object Patterns • Deals with object relationships at run time • Dynamic run time CS585 14/ Design Patterns Organization Purpose Structural Behavioral Adapter Interpretor Template Methos Composite Visitor Facade Chain Of Responsibility proxy Command Bridge Interpreter Adapter Memento Decorstor Observer Flyweight State Strategy Mediator Class Object Creational Factory Method singleton Abstract Factory Builder Prototype Scope CS585 15/ Design Patterns Summary Creational Structural Behavioral 16 CS585 Creational Design Patterns Address issues related to the creation of objects, such as: – Preventing the system from creating more than one object for a class (Singleton) – Delaying the creation of objects to run time – Abstract the instantiation process makes the system independent of how its objects are created, composed and represented • Class creational design pattern uses inheritance to vary the class that is instantiated • Object Creational Patterns will delegate instantiation to another object. CS585 17/ Creational Design Patterns Singleton 1. Add a static member to the class that refers to the first instantiation of this object (initially it is null). 2. Then, add a static method that instantiates this class if this member is null (and sets this member's value) and 3. Then returns the value of this member. – Encapsulates: That there is only one of these objects allowed. Abstract Factory – creatImage method determines at run time the type of object to create Builder Factory Prototype CS585 18/ Singleton –Solution: Data Singleton private static final Singleton theInstance; static getInstance() operation() getData() CS585 19/ Structural Design Patterns Describes common ways to organize classes and objects in a system. Adapter Composite Facade Proxy Bridge Flyweight Decorator CS585 20/ Structural Patterns How classes and objects are composed to form larger objects – Structural Class DP use inheritance to compose interfaces or implementations • Multiple inheritance as it mixes two or more classes into one • An Adaptor Pattern makes one interface conform to another – Structural Object Patterns describe ways to compose objects to realize new functionality • Composite describes how to build a class hierarchy made up of classes for 2 kinds of objects: primitive and composite • Proxy makes one object replaces another at run time • Flyweight lets many objects share functionality (efficiency) • Façade one object that represents one subsystem • Decorator lets decorate objects by adding functionality to it dynamically, for example adding scroll bars to an object window • Bridge decuples an abstraction form its implementation so that the two can vary independently CS585 21/ Structural Design Patterns PROXY makes one object (called proxy object ) replaces another at run time – Loading large images are replaced with gauge object to indicate the percentage of loaded images. Class javax.swing.JProgressBar ADAPTER – Adapt a class’s interface to match the interface a client expects COMPSITE – describes how to build a class hierarchy made up of classes for 2 kinds of objects: primitive and composite FLYWEIGHT lets many objects share functionality (efficiency) FACADE one object that represents one subsystem DECORATOR decorates objects by adding functionality to it dynamically, for example adding scroll bars to an object window CS585 22/ Behavioral Design Patterns How objects collaborate to achieve the final application – Observer Design Pattern • GUI components collaborate – Memento Design Pattern • Object saves its state (history information) – State Design Pattern • Object that report their state – Mediator Pattern Behavioral patterns are those which are concerned with interactions between the objects. The interactions between the objects should be such that they are talking to each other and still are loosely coupled. CS585 23/ Behavioral Design Patterns behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. – Algorithms – Assignment of responsibilities – Communication CS585 24/ Behavioral Patterns Encapsulate a Concept patterns usually define an abstract class that describes the encapsulating object with the concept that varies: – a Strategy object encapsulates an algorithm, – a State object encapsulates a state-dependent behavior – a Mediator object encapsulates the protocol between objects – an Iterator object encapsulates the way you access and traverse the components of an aggregate object CS585 25/ Behavioral Design Patterns Behavioral Class Design Patterns – Use inheritance to distribute behavior – Template Method – Interpreter Behavioral Object Design Patterns – Use object composition – Peer object knowledge of each and coupling – Mediator Pattern removes the need for each object to know about its peers • The Mediator object provides the indirection needed for loose coupling – Chain of Responsibility provide very loosely coupled objects • Clients send requests to a chain of responsible objects – Observer defines and maintains dependency between objects • MVC Model where the views of the model are changed whenever the model’s state changes CS585 26/ CS487 AOSD . 27 CS585 Aspect Oriented Programming Aspect Orientated Programming (AOP) is a programming paradigm that provides the user with the ability to modularize the representation of cross cutting concerns in A1 FC A2 order to maximize code reusability and solve the code-tangling problem. AOP provides mechanisms for decomposing a problem into functional components and the aspectual components called aspects. Aspects are concerns that cut across the functional components. AOP attempts to modularize Aspects, and uses weaving mechanism to combine aspects with the main functional components. Weaver Identifies components and aspects. Expresses each aspect in separate form, and then Combine aspects and components at implementation (weaving). CS585 28/ AOSD Aspects are concerns that cut across the functional components. – Synchronization, scheduling, logging, security, and fault tolerance are some examples of units of crosscutting functionality (aspects). – Usually the implementations of these aspects are scattered across multiple classes. – The scattering of the aspect code with the core class code reduces software quality, because of code-tangling problem. Aspect-Oriented programming modularizes aspects, and uses weaving mechanism to combine them with the main functionality of the system. CS585 29/ AOP… aspectj.org private long lastAccessed = creationTime; private int inactiveInterval = -1; ApplicationSession /* * ==================================================================== * * 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 [email protected] * * 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, INDIRECT, 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() { serverSession.removeApplicationSession(context); // remove everything in the session Enumeration enum = values.keys(); while (enum.hasMoreElements()) { String name = (String)enum.nextElement(); removeValue(name); } valid = false; } public boolean isNew() { if (! valid) { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } if (thisAccessTime == creationTime) { return true; } else { return false; } } /** * 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 (HttpSession) 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 * HttpSession view of this instance back to a Session view. * * @author Craig R. McClanahan * @version $Revision: 1.2 $ $Date: 2000/05/15 17:54:10 $ */ final class StandardSession implements HttpSession, Session { package org.apache.tomcat.session; import import import import import import import import import import import import import import java.io.IOException; java.io.ObjectInputStream; java.io.ObjectOutputStream; java.io.Serializable; java.util.Enumeration; java.util.Hashtable; java.util.Vector; javax.servlet.ServletException; javax.servlet.http.HttpSession; javax.servlet.http.HttpSessionBindingEvent; javax.servlet.http.HttpSessionBindingListener; javax.servlet.http.HttpSessionContext; org.apache.tomcat.catalina.*; org.apache.tomcat.util.StringManager; StandardSession /** /** * Return the <code>HttpSession</code> for which this object * is the facade. */ public HttpSession getSession() { return ((HttpSession) this); } * 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>HttpSessionBindingListener</code>, the container calls * <code>valueBound()</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 IllegalStateException if this method is called on an * invalidated session * * @deprecated As of Version 2.2, this method is replaced by * <code>setAttribute()</code> */ public void putValue(String name, Object value) { setAttribute(name, value); } void accessed() { // set last accessed to thisAccessTime as it will be left over // from the previous access lastAccessed = thisAccessTime; thisAccessTime = System.currentTimeMillis(); validate(); } void validate() { // if we have an inactive interval, check to see if we've exceeded it if (inactiveInterval != -1) { int thisInterval = (int)(System.currentTimeMill // ------------------------------------------------Session Public Methods /** * 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() { this.lastAccessedTime = this.thisAccessedTime; this.thisAccessedTime = System.currentTimeMillis(); this.isNew=false; } /** * @deprecated */ public void putValue(String name, Object value) { setAttribute(name, value); } public void setAttribute(String name, Object value) { if (! valid) { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } if (name == null) { String msg = sm.getString("applicationSession.value.iae"); throw new IllegalArgumentException(msg); } removeValue(name); // remove any existing binding /** * Perform the internal processing required to invalidate this session, * without triggering an exception if the session has already expired. */ public void expire() { // Remove this session from our manager's active sessions if ((manager != null) && (manager instanceof ManagerBase)) ((ManagerBase) manager).remove(this); // Unbind any objects associated with this session Vector results = new Vector(); Enumeration attrs = getAttributeNames(); while (attrs.hasMoreElements()) { String attr = (String) attrs.nextElement(); results.addElement(attr); } Enumeration names = results.elements(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); removeAttribute(name); } // Mark this session as invalid setValid(false); } /** * 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>HttpSessionBindingListener</code>, the container calls * <code>valueUnbound()</code> on the object. * * @param name Name of the object to remove from this session. * * @exception IllegalStateException if this method is called on an * invalidated session */ public void removeAttribute(String name) { synchronized (attributes) { Object object = attributes.get(name); if (object == null) return; attributes.remove(name); // System.out.println( "Removing attribute " + name ); if (object instanceof HttpSessionBindingListener) { ((HttpSessionBindingListener) object).valueUnbound (new HttpSessionBindingEvent((HttpSession) this, name)); } } } // ---------------------------------------------------------- Constructors if (value != null && value instanceof HttpSessionBindingListener) { HttpSessionBindingEvent e = new HttpSessionBindingEvent(this, name); ((HttpSessionBindingListener)value).valueBound(e); } values.put(name, value); } /** * @deprecated */ public Object getValue(String name) { return getAttribute(name); } public Object getAttribute(String name) { if (! valid) { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } if (name == null) { String msg = sm.getString("applicationSession.value.iae"); throw new IllegalArgumentException(msg); } /** * Construct a new Session associated with the specified Manager. * * @param manager The manager with which this Session is associated */ public StandardSession(Manager manager) { super(); this.manager = manager; } package org.apache.tomcat.session; import org.apache.tomcat.core.*; import org.apache.tomcat.util.StringManager; import java.io.*; import java.net.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; /** * Core implementation of an application level session * * @author James Duncan Davidson [[email protected]] * @author Jason Hunter [[email protected]] * @author James Todd [[email protected]] */ public class ApplicationSession implements HttpSession { // ---------------------------------------------------- Instance Variables /** * The collection of user data attributes associated with this Session. */ private Hashtable attributes = new Hashtable(); /** * Release all object references, and initialize instance variables, in * preparation for reuse of this object. */ public void recycle() { // Reset the instance variables associated with this Session attributes.clear(); creationTime = 0L; id = null; lastAccessedTime = 0L; manager = null; maxInactiveInterval = -1; isNew = true; isValid = false; // Tell our Manager that this Session has been recycled if ((manager != null) && (manager instanceof ManagerBase)) ((ManagerBase) manager).recycle(this); } /** * 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>HttpSessionBindingListener</code>, the container calls * <code>valueUnbound()</code> on the object. * * @param name Name of the object to remove from this session. * * @exception IllegalStateException if this method is called on an * invalidated session * * @deprecated As of Version 2.2, this method is replaced by * <code>removeAttribute()</code> */ public void removeValue(String name) { removeAttribute(name); } return values.get(name); private StringManager sm = StringManager.getManager("org.apache.tomcat.session"); private Hashtable values = new Hashtable(); private String id; private ServerSession serverSession; private Context context; private long creationTime = System.currentTimeMillis();; private long thisAccessTime = creationTime; private long lastAccessed = creationTime; private int inactiveInterval = -1; private boolean valid = true; ApplicationSession(String id, ServerSession serverSession, Context context) { this.serverSession = serverSession; this.context = context; this.id = id; this.inactiveInterval = context.getSessionTimeOut(); } if (this.inactiveInterval != -1) { this.inactiveInterval *= 60; } } ServerSession getServerSession() { return serverSession; } /** * Called by context when request comes in so that accesses and * inactivities can be dealt with accordingly. */ void accessed() { // set last accessed to thisAccessTime as it will be left over // from the previous access lastAccessed = thisAccessTime; thisAccessTime = System.currentTimeMillis(); validate(); } void validate() { // if we have an inactive interval, check to see if we've exceeded it if (inactiveInterval != -1) { int thisInterval = (int)(System.currentTimeMillis() - lastAccessed) / 1000; if (thisInterval > inactiveInterval) { invalidate(); } } } // HTTP SESSION IMPLEMENTATION METHODS public String getId() { if (valid) { return id; } else { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } } public long getCreationTime() { if (valid) { return creationTime; } else { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } } /** * * @deprecated */ public HttpSessionContext getSessionContext() { return new SessionContextImpl(); } } public long getLastAccessedTime() { if (valid) { return lastAccessed; } else { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } } } } public int getMaxInactiveInterval() { if (! valid) { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } return inactiveInterval; inactiveInterval = interval; } public void setMaxInactiveInterval(int interval) { if (! valid) { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } values.remove(name); } Object o = values.get(name); if (o instanceof HttpSessionBindingListener) { HttpSessionBindingEvent e = new HttpSessionBindingEvent(this,name); ((HttpSessionBindingListener)o).valueUnbound(e); } public void removeAttribute(String name) { if (! valid) { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } if (name == null) { String msg = sm.getString("applicationSession.value.iae"); throw new IllegalArgumentException(msg); public Enumeration getAttributeNames() { if (! valid) { String msg = sm.getString("applicationSession.session.ise"); throw new IllegalStateException(msg); } Hashtable valuesClone = (Hashtable)values.clone(); return (Enumeration)valuesClone.keys(); } } /** * @deprecated */ public String getValueNames() { Enumeration e = getAttributeNames(); Vector names = new Vector(); while (e.hasMoreElements()) { names.addElement(e.nextElement()); } String valueNames = new String[names.size()]; names.copyInto(valueNames); return valueNames; /** * The time this session was created, in milliseconds since midnight, * January 1, 1970 GMT. */ private long creationTime = 0L; /** * The session identifier of this Session. */ private String id = null; /** * Descriptive information describing this Session implementation. */ private static final String info = "StandardSession/1.0"; // ------------------------------------------------ Session Package Methods /** * Return the <code>isValid</code> flag for this session. */ boolean isValid() { return (this.isValid); } /** * 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>HttpSessionBindingListener</code>, the container calls * <code>valueBound()</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 IllegalArgumentException if an attempt is made to add a * non-serializable object in an environment marked distributable. * @exception IllegalStateException if this method is called on an * invalidated session */ public void setAttribute(String name, Object value) { if ((manager != null) && manager.getDistributable() && !(value instanceof Serializable)) throw new IllegalArgumentException (sm.getString("standardSession.setAttribute.iae")); synchronized (attributes) { removeAttribute(name); attributes.put(name, value); if (value instanceof HttpSessionBindingListener) ((HttpSessionBindingListener) value).valueBound (new HttpSessionBindingEvent((HttpSession) this, name)); } } SessionInterceptor package org.apache.tomcat.request; import org.apache.tomcat.core.*; import org.apache.tomcat.util.*; import java.io.*; import java.net.*; import java.util.*; import javax.servlet.http.*; /** * Will process the request and determine the session Id, and set it * in the Request. * It also marks the session as accessed. * * This implementation only handles Cookies sessions, please extend or * add new interceptors for other methods. * */ public class SessionInterceptor extends BaseInterceptor implements RequestInterceptor { // GS, separates the session id from the jvm route static final char SESSIONID_ROUTE_SEP = '.'; int debug=0; ContextManager cm; public SessionInterceptor() { } public void setDebug( int i ) { System.out.println("Set debug to " + i); debug=i; } public int beforeBody( Request rrequest, Response response ) { String reqSessionId = response.getSessionId(); if( debug>0 ) cm.log("Before Body " + reqSessionId ); if( reqSessionId==null) return 0; // GS, set the path attribute to the cookie. This way // multiple session cookies can be used, one for each // context. String sessionPath = rrequest.getContext().getPath(); if(sessionPath.length() == 0) { sessionPath = "/"; } // GS, piggyback the jvm route on the session id. if(!sessionPath.equals("/")) { String jvmRoute = rrequest.getJvmRoute(); if(null != jvmRoute) { reqSessionId = reqSessionId + SESSIONID_ROUTE_SEP + jvmRoute; } } Cookie cookie = new Cookie("JSESSIONID", reqSessionId); cookie.setMaxAge(-1); cookie.setPath(sessionPath); cookie.setVersion(1); response.addHeader( CookieTools.getCookieHeaderName(cookie), CookieTools.getCookieHeaderValue(cookie)); cookie.setVersion(0); response.addHeader( CookieTools.getCookieHeaderName(cookie), CookieTools.getCookieHeaderValue(cookie)); return 0; public int requestMap(Request request ) { String sessionId = null; Cookie cookies=request.getCookies(); // assert !=null for( int i=0; i<cookies.length; i++ ) { Cookie cookie = cookies[i]; if (cookie.getName().equals("JSESSIONID")) { sessionId = cookie.getValue(); sessionId=validateSessionId(request, sessionId); if (sessionId!=null){ request.setRequestedSessionIdFromCookie(true); } } } } StandardManager package org.apache.tomcat.session; // ------------------------------------------------------ Lifecycle Methods import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.apache.tomcat.catalina.*; import javax.servlet.http.Cookie; import javax.servlet.http.HttpSession; import org.apache.tomcat.util.StringManager; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; /** * 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. * * @param parameters Configuration parameters for this component * (<B>FIXME: What object type should this really be?) * * @exception IllegalStateException if this component has already been * configured and/or started * @exception LifecycleException if this component detects a fatal error * in the configuration parameters it was given */ public void configure(Node parameters) throws LifecycleException { // Validate and update our current component state if (configured) throw new LifecycleException (sm.getString("standardManager.alreadyConfigured")); configured = true; if (parameters == null) return; // Parse and process our configuration parameters if (!("Manager".equals(parameters.getNodeName()))) return; NamedNodeMap attributes = parameters.getAttributes(); Node node = null; node = attributes.getNamedItem("checkInterval"); if (node != null) { try { setCheckInterval(Integer.parseInt(node.getNodeValue())); } catch (Throwable t) { ; // XXX - Throw exception? } } node = attributes.getNamedItem("maxActiveSessions"); if (node != null) { try { setMaxActiveSessions(Integer.parseInt(node.getNodeValue())); } catch (Throwable t) { ; // XXX - Throw exception? } } node = attributes.getNamedItem("maxInactiveInterval"); if (node != null) { try { setMaxInactiveInterval(Integer.parseInt(node.getNodeValue())); } catch (Throwable t) { ; // XXX - Throw exception? } } } /** * The descriptive information about this implementation. */ private static final String info = "StandardManager/1.0"; StandardSessionManager package org.apache.tomcat.session; // --------------------------------------------------------- Public Methods import java.io.IOException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpSession; import org.apache.tomcat.catalina.*; import org.apache.tomcat.core.Context; import org.apache.tomcat.core.Request; import org.apache.tomcat.core.Response; import org.apache.tomcat.core.SessionManager; import org.apache.tomcat.util.SessionUtil; /** * Mark the specified session's last accessed time. * called for each request by a RequestInterceptor. * * @param session The session to be marked */ public void accessed(Context ctx, Request req, String id) { HttpSession session=findSession(ctx, id); if( session == null) return; /** * Specialized implementation of org.apache.tomcat.core.SessionManager * that adapts to the new component-based Manager implementation. * <p> * XXX - At present, use of <code>StandardManager</code> is hard coded, * and lifecycle configuration is not supported. * <p> * <b>IMPLEMENTATION NOTE</b>: Manager/Session Once we commit to the new // XXX should we throw exception or just return null ?? public HttpSession findSession( Context ctx, String id ) { try { Session session = manager.findSession(id); if(session!=null) return session.getSession(); } catch (IOException e) { } return (null); } // cache the HttpSession - avoid another find req.setSession( session ); if (session instanceof Session) ((Session) session).access(); This should be /** * The last accessed time for this Session. */ private long lastAccessedTime = creationTime; /** * The Manager with which this Session is associated. */ private Manager manager = null; /** * Set the <code>isNew</code> flag for this session. * * @param isNew The new value for the <code>isNew</code> flag */ void setNew(boolean isNew) { /** * @deprecated */ public void removeValue(String name) { removeAttribute(name); } /** * 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 maxInactiveInterval = -1; this.isNew = isNew; } // -------------------------------------------- HttpSession Private Methods public void setContextManager( ContextManager cm ) { this.cm=cm; } /** * Flag indicating whether this session is new or not. */ private boolean isNew = true; /** * Set the <code>isValid</code> flag for this session. * * @param isValid The new value for the <code>isValid</code> flag */ void setValid(boolean isValid) { this.isValid = isValid; } /** * Flag indicating whether this session is valid or not. */ private boolean isValid = false; // ------------------------------------------------HttpSession Properties /** * 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 ClassNotFoundException if an unknown class is specified * @exception IOException if an input/output error occurs */ private void readObject(ObjectInputStream stream) throws ClassNotFoundException, IOException { // Deserialize the scalar instance variables (except Manager) creationTime = ((Long) stream.readObject()).longValue(); id = (String) stream.readObject(); lastAccessedTime = ((Long) stream.readObject()).longValue(); maxInactiveInterval = ((Integer) stream.readObject()).intValue(); isNew = ((Boolean) stream.readObject()).booleanValue(); isValid = ((Boolean) stream.readObject()).booleanValue(); // Deserialize the attribute count and attribute values int n = ((Integer) stream.readObject()).intValue(); for (int i = 0; i < n; i++) { String name = (String) stream.readObject(); Object value = (Object) stream.readObject(); attributes.put(name, value); } } /** Notification of context shutdown */ public void contextShutdown( Context ctx ) throws TomcatException { if( ctx.getDebug() > 0 ) ctx.log("Removing sessions from " + ctx ); ctx.getSessionManager().removeSessions(ctx); } /** * 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 className="org.apache.tomcat.session.StandardManager" * checkInterval="60" maxActiveSessions="-1" * maxInactiveInterval="-1" /> * </code> * where you can adjust the following parameters, with default values * in square brackets: * <ul> * <li><b>checkInterval</b> - The interval (in seconds) between background * thread checks for expired sessions. [60] * <li><b>maxActiveSessions</b> - The maximum number of sessions allowed to * be active at once, or -1 for no limit. [-1] * <li><b>maxInactiveInterval</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. McClanahan * @version $Revision: 1.1.1.1 $ $Date: 2000/05/02 21:28:30 $ */ public final class StandardManager extends ManagerBase implements Lifecycle, Runnable { * paradigm, I would suggest moving the logic implemented here back into * the core level. The Tomcat.Next "Manager" interface acts more like a * collection class, and has minimal knowledge of the detailed request * processing semantics of handling sessions. * <p> * XXX - At present, there is no way (via the SessionManager interface) for * a Context to tell the Manager that we create what the default session } * timeout for this web application (specified in the deployment descriptor) * should be. * * @author Craig R. McClanahan */ /** public final class StandardSessionManager implements SessionManager { } } public HttpSession createSession(Context ctx) { return manager.createSession().getSession(); /** * The string manager for this package. */ private StringManager sm = StringManager.getManager("org.apache.tomcat.session") ; /** * Return the time when this session was created, in milliseconds since * midnight, January 1, 1970 GMT. * * @exception IllegalStateException if this method is called on an * invalidated session */ public long getCreationTime() { return (this.creationTime); // ----------------------------------------------------- Instance Variables String sig=";jsessionid="; int foundAt=-1; if( debug>0 ) cm.log(" XXX RURI=" + request.getRequestURI()); if ((foundAt=request.getRequestURI().indexOf(sig))!=-1){ sessionId=request.getRequestURI().substring(foundAt+sig.length()); // rewrite URL, do I need to do anything more? request.setRequestURI(request.getRequestURI().substring(0, foundAt)); sessionId=validateSessionId(request, sessionId); if (sessionId!=null){ request.setRequestedSessionIdFromURL(true); } } return 0; } // XXX what is the correct behavior if the session is invalid ? // We may still set it and just return session invalid. /** Validate and fix the session id. If the session is not valid return null. * It will also clean up the session from load-balancing strings. * @return sessionId, or null if not valid */ private String validateSessionId(Request request, String sessionId){ // GS, We piggyback the JVM id on top of the session cookie // Separate them ... if( debug>0 ) cm.log(" Orig sessionId " + sessionId ); if (null != sessionId) { int idex = sessionId.lastIndexOf(SESSIONID_ROUTE_SEP); if(idex > 0) { sessionId = sessionId.substring(0, idex); } } if (sessionId != null && sessionId.length()!=0) { // GS, We are in a problem here, we may actually get // multiple Session cookies (one for the root // context and one for the real context... or old session // cookie. We must check for validity in the current context. Context ctx=request.getContext(); SessionManager sM = ctx.getSessionManager(); if(null != sM.findSession(ctx, sessionId)) { sM.accessed(ctx, request, sessionId ); request.setRequestedSessionId(sessionId); if( debug>0 ) cm.log(" Final session id " + sessionId ); return sessionId; } } return null; } /** * Name to register for the background thread. */ private String threadName = "StandardManager"; /** * The interval (in seconds) between checks for expired sessions. */ private int checkInterval = 60; * Remove all sessions because our associated Context is being shut down. * * @param ctx The context that is being shut down */ /** * The HTTP session context associated with this session. */ private static HttpSessionContext sessionContext = null; } /** * Has this component been configured yet? */ private boolean configured = false; // ----------------------------------------------------------Constructors public void removeSessions(Context ctx) { /** * The current accessed time for this session. */ private long thisAccessedTime = creationTime; /** * 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 HttpSessionContext getSessionContext() { if (sessionContext == null) sessionContext = new StandardSessionContext(); return (sessionContext); } // XXX XXX a manager may be shared by multiple /** /** * 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 IllegalStateException if this component has not yet been * configured (if required for this component) * @exception IllegalStateException if this component has already been * started * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void start() throws LifecycleException { // Validate and update our current component state if (!configured) throw new LifecycleException (sm.getString("standardManager.notConfigured")); if (started) throw new LifecycleException (sm.getString("standardManager.alreadyStarted")); started = true; // Start the background reaper thread threadStart(); } } * Create a new SessionManager that adapts to the corresponding Manager * implementation. */ public StandardSessionManager() { // contexts, we just want to remove the sessions of ctx! // The manager will still run after that ( i.e. keep database // connection open if (manager instanceof Lifecycle) { try { ((Lifecycle) manager).stop(); } catch (LifecycleException e) { manager = new StandardManager(); if (manager instanceof Lifecycle) { try { ((Lifecycle) manager).configure(null); ((Lifecycle) manager).start(); } catch (LifecycleException e) { throw new IllegalStateException("" + e); } } /** * Used by context to configure the session manager's inactivity timeout. * * The SessionManager 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 conforgure the // ----------------------------------------------------- Instance Variables * session manager according to this value. * * @param minutes The session inactivity timeout in minutes. */ /** * The Manager implementation we are actually using. */ private Manager manager = null; } } public void setSessionTimeOut(int minutes) { if(-1 != minutes) { // The manager works with seconds... manager.setMaxInactiveInterval(minutes * 60); } } } throw new IllegalStateException("" + e); // ---------------------------------------------------- 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 setCreationTime(long time) { this.creationTime = time; this.lastAccessedTime = time; this.thisAccessedTime = time; } // ---------------------------------------------HttpSession Public Methods /** * 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>readObject()</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 writeObject(ObjectOutputStream stream) throws IOException { // Write the scalar instance variables (except Manager) stream.writeObject(new Long(creationTime)); stream.writeObject(id); stream.writeObject(new Long(lastAccessedTime)); stream.writeObject(new Integer(maxInactiveInterval)); stream.writeObject(new Boolean(isNew)); stream.writeObject(new Boolean(isValid)); // Accumulate the names of serializable attributes Vector results = new Vector(); Enumeration attrs = getAttributeNames(); while (attrs.hasMoreElements()) { String attr = (String) attrs.nextElement(); Object value = attributes.get(attr); if (value instanceof Serializable) results.addElement(attr); } // Serialize the attribute count and the attribute values stream.writeObject(new Integer(results.size())); Enumeration names = results.elements(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); stream.writeObject(name); stream.writeObject(attributes.get(name)); } /** * The maximum number of active Sessions allowed, or -1 for no limit. */ protected int maxActiveSessions = -1; /** * The string manager for this package. */ private StringManager sm = StringManager.getManager("org.apache.tomcat.session"); /** * Return the session identifier for this session. */ public String getId() { return (this.id); } /** * 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 IllegalStateException if this method is called on an * invalidated session */ public Object getAttribute(String name) { return (attributes.get(name)); } /** * Has this component been started yet? */ private boolean started = false; /** * The background thread. */ private Thread thread = null; /** * The background thread completion semaphore. */ private boolean threadDone = false; ServerSession package org.apache.tomcat.session; import org.apache.tomcat.core.*; import org.apache.tomcat.util.StringManager; import java.io.*; import java.net.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; /** * Core implementation of a server session * * @author James Duncan Davidson [[email protected]] * @author James Todd [[email protected]] */ } public class ServerSession { private StringManager sm = StringManager.getManager("org.apache.tomcat.session"); private Hashtable values = new Hashtable(); private Hashtable appSessions = new Hashtable(); private String id; private long creationTime = System.currentTimeMillis();; private long thisAccessTime = creationTime; private long lastAccessed = creationTime; private int inactiveInterval = -1; ServerSession(String id) { this.id = id; } public String getId() { return id; } } public long getCreationTime() { return creationTime; } } public long getLastAccessedTime() { return lastAccessed; } public ApplicationSession getApplicationSession(Context context, boolean create) { ApplicationSession appSession = (ApplicationSession)appSessions.get(context); if (appSession == null && create) { // XXX // sync to ensure valid? appSession = new ApplicationSession(id, this, context); appSessions.put(context, appSession); } // XXX // make sure that we haven't gone over the end of our // inactive interval -- if so, invalidate and create // a new appSession return appSession; } void removeApplicationSession(Context context) { appSessions.remove(context); } /** * Called by context when request comes in so that accesses and * inactivities can be dealt with accordingly. */ void accessed() { // set last accessed to thisAccessTime as it will be left over // from the previous access lastAccessed = thisAccessTime; thisAccessTime = System.currentTimeMillis(); } } } void validate() } } public Enumeration getValueNames() { return values.keys(); } public void removeValue(String name) { values.remove(name); } public void setMaxInactiveInterval(int interval) { inactiveInterval = interval; } public int getMaxInactiveInterval() { return inactiveInterval; } // 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. synchronized void reap() { Enumeration enum = appSessions.keys(); removeValue(name); // remove any existing binding values.put(name, value); } synchronized void invalidate() { Enumeration enum = appSessions.keys(); while (enum.hasMoreElements()) { Object key = enum.nextElement(); ApplicationSession appSession = (ApplicationSession)appSessions.get(key); appSession.invalidate(); } } void validate() { // if we have an inactive interval, check to see if // we've exceeded it if (inactiveInterval != -1) { int thisInterval = (int)(System.currentTimeMillis() - lastAccessed) / 1000; if (thisInterval > inactiveInterval) { invalidate(); ServerSessionManager ssm = ServerSessionManager.getManager(); ssm.removeSession(this); } /** * Set the session identifier for this session. * * @param id The new session identifier */ public void setId(String id) { if ((this.id != null) && (manager != null) && (manager instanceof ManagerBase)) ((ManagerBase) manager).remove(this); this.id = id; if ((manager != null) && (manager instanceof ManagerBase)) ((ManagerBase) manager).add(this); } /** * Return an <code>Enumeration</code> of <code>String</code> objects * containing the names of the objects bound to this session. * * @exception IllegalStateException if this method is called on an * invalidated session */ public Enumeration getAttributeNames() { return (attributes.keys()); } // ------------------------------------------------------------- Properties /** * 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 IllegalStateException if this component has not been started * @exception IllegalStateException if this component has already * been stopped * @exception LifecycleException if this component detects a fatal error * that needs to be reported */ public void stop() throws LifecycleException { // Validate and update our current component state if (!started) throw new LifecycleException (sm.getString("standardManager.notStarted")); started = false; // Stop the background reaper thread threadStop(); // Expire all active sessions Session sessions = findSessions(); for (int i = 0; i < sessions.length; i++) { StandardSession session = (StandardSession) sessions[i]; if (!session.isValid()) continue; session.expire(); } } /** * Return the check interval (in seconds) for this Manager. */ public int getCheckInterval() { return (this.checkInterval); } } crosscut invalidate(StandardSession s): s & (int getMaxInactiveInterval() | long getCreationTime() | Object getAttribute(String) | Enumeration getAttributeNames() | String getValueNames() | void invalidate() | boolean isNew() | void removeAttribute(String) | void setAttribute(String, Object)); static advice(StandardSession s): invalidate(s) { before { if (!s.isValid()) throw new IllegalStateException (s.sm.getString("standardSession." + thisJoinPoint.methodName + ".ise")); } } } /** * Return descriptive information about this Session implementation and * the corresponding version number, in the format * <code>&lt;description&gt;/&lt;version&gt;</code>. */ public String getInfo() { 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 IllegalStateException if this method is called on an * invalidated session * * @deprecated As of Version 2.2, this method is replaced by * <code>getAttribute()</code> */ public Object getValue(String name) { return (getAttribute(name)); } ServerSessionManager 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.*; /** * * @author James Duncan Davidson [[email protected]] * @author Jason Hunter [[email protected]] * @author James Todd [[email protected]] */ public class ServerSessionManager implements SessionManager { private StringManager sm = StringManager.getManager("org.apache.tomcat.session"); private static ServerSessionManager manager; // = new ServerSessionManager(); } protected int inactiveInterval = -1; // 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. synchronized void reap() { Enumeration enum = sessions.keys(); while (enum.hasMoreElements()) { Object key = enum.nextElement(); ServerSession session = (ServerSession)sessions.get(key); session.reap(); session.validate(); } } synchronized void removeSession(ServerSession session) { String id = session.getId(); session.invalidate(); sessions.remove(id); /** * Set the check interval (in seconds) for this Manager. * * @param checkInterval The new check interval */ public void setCheckInterval(int checkInterval) { this.checkInterval = checkInterval; } // -------------------------------------------------------- Private Methods /** * Return descriptive information about this Manager implementation and * the corresponding version number, in the format * <code>&lt;description&gt;/&lt;version&gt;</code>. */ public String getInfo() { return (this.info); } /** * Invalidate all sessions that have expired. */ private void processExpires() { long timeNow = System.currentTimeMillis(); Session sessions = findSessions(); for (int i = 0; i < sessions.length; i++) { StandardSession session = (StandardSession) sessions[i]; if (!session.isValid()) continue; int maxInactiveInterval = session.getMaxInactiveInterval(); if (maxInactiveInterval < 0) continue; int timeIdle = // Truncate, do not round up (int) ((timeNow - session.getLastAccessedTime()) / 1000L); if (timeIdle >= maxInactiveInterval) session.expire(); } } } } // -------------------------------------------------------------- Private Class /** * 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 getLastAccessedTime() { return (this.lastAccessedTime); /** * Return the set of names of objects bound to this session. If there * are no such objects, a zero-length array is returned. * * @exception IllegalStateException if this method is called on an * invalidated session * * @deprecated As of Version 2.2, this method is replaced by * <code>getAttributeNames()</code> */ public String getValueNames() { Vector results = new Vector(); Enumeration attrs = getAttributeNames(); while (attrs.hasMoreElements()) { String attr = (String) attrs.nextElement(); results.addElement(attr); } String names = new String[results.size()]; for (int i = 0; i < names.length; i++) names[i] = (String) results.elementAt(i); return (names); } /** * This class is a dummy implementation of the <code>HttpSessionContext</code> * interface, to conform to the requirement that such an object be returned * when <code>HttpSession.getSessionContext()</code> is called. * * @author Craig R. McClanahan * * @deprecated As of Java Servlet API 2.1 with no replacement. The * interface will be removed in a future version of this API. */ final class StandardSessionContext implements HttpSessionContext { /** * Return the maximum number of active Sessions allowed, or -1 for * no limit. */ public int getMaxActiveSessions() { return (this.maxActiveSessions); } public void putValue(String name, Object value) { if (name == null) { String msg = sm.getString("serverSession.value.iae"); throw new IllegalArgumentException(msg); } private Vector dummy = new Vector(); /** * 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 getIds() { return (dummy.elements()); static { manager = new ServerSessionManager(); } public static ServerSessionManager getManager() { return manager; } private Hashtable sessions = new Hashtable(); private Reaper reaper; private ServerSessionManager() { reaper = Reaper.getReaper(); reaper.setServerSessionManager(this); reaper.start(); } public void accessed( Context ctx, Request req, String id ) { ApplicationSession apS=(ApplicationSession)findSession( ctx, id); if( apS==null) return; ServerSession servS=apS.getServerSession(); servS.accessed(); apS.accessed(); // cache it - no need to compute it again req.setSession( apS ); } return (null); /** * Return the Manager within which this Session is valid. */ public Manager getManager() { return (this.manager); public void removeSessions(Context context) { Enumeration enum = sessions.keys(); while (enum.hasMoreElements()) { Object key = enum.nextElement(); ServerSession session = (ServerSession)sessions.get(key); ApplicationSession appSession = session.getApplicationSession(context, false); if (appSession != null) { appSession.invalidate(); } } } /** * Used by context to configure the session manager's inactivity timeout. * * The SessionManager 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 conforgure the * session manager according to this value. * * @param minutes The session inactivity timeout in minutes. */ public void setSessionTimeOut(int minutes) { if(-1 != minutes) { // The manager works with seconds... inactiveInterval = (minutes * 60); } } } /** * Set the maximum number of actives Sessions allowed, or -1 for * no limit. * * @param max The new maximum number of sessions */ public void setMaxActiveSessions(int max) { this.maxActiveSessions = max; } /** * Sleep for the duration specified by the <code>checkInterval</code> * property. */ private void threadSleep() { try { Thread.sleep(checkInterval * 1000L); } catch (InterruptedException e) { ; } } public Object getValue(String name) { if (name == null) { String msg = sm.getString("serverSession.value.iae"); throw new IllegalArgumentException(msg); } return values.get(name); } // --------------------------------------------------------- Public Methods /** * Set the Manager within which this Session is valid. * * @param manager The new Manager */ public void setManager(Manager manager) { this.manager = manager; } /** * Invalidates this session and unbinds any objects bound to it. * * @exception IllegalStateException if this method is called on * an invalidated session */ public void invalidate() { // Cause this session to expire expire(); } } /** * 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 IllegalStateException if this method is called on * an invalidated session */ public int getMaxInactiveInterval() { return (this.maxInactiveInterval); } /** * Return the <code>HttpSession</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 HttpSession getSession(String id) { /** * 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 getId() * method of the returned session. If a new session cannot be created * for any reason, return <code>null</code>. * * @exception IllegalStateException if a new session cannot be * instantiated for any reason */ public Session createSession() { if ((maxActiveSessions >= 0) && (sessions.size() >= maxActiveSessions)) throw new IllegalStateException (sm.getString("standardManager.createSession.ise")); return (super.createSession()); } /** * Start the background thread that will periodically check for * session timeouts. */ private void threadStart() { if (thread != null) return; threadDone = false; thread = new Thread(this, threadName); thread.setDaemon(true); thread.start(); } while (enum.hasMoreElements()) { Object key = enum.nextElement(); ApplicationSession appSession = (ApplicationSession)appSessions.get(key); appSession.validate(); /** * 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 setMaxInactiveInterval(int interval) { this.maxInactiveInterval = interval; } /** * 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 IllegalStateException if this method is called on an * invalidated session */ public boolean isNew() { return (this.isNew); } } } public HttpSession createSession(Context ctx) { String sessionId = SessionIdGenerator.generateId(); ServerSession session = new ServerSession(sessionId); sessions.put(sessionId, session); if(-1 != inactiveInterval) { session.setMaxInactiveInterval(inactiveInterval); } return session.getApplicationSession( ctx, true ); } public HttpSession findSession(Context ctx, String id) { ServerSession sSession=(ServerSession)sessions.get(id); if(sSession==null) return null; return sSession.getApplicationSession(ctx, false); } /** * Stop the background thread that is periodically checking for * session timeouts. */ private void threadStop() { if (thread == null) return; threadDone = true; thread.interrupt(); try { thread.join(); } catch (InterruptedException e) { ; } thread = null; } // ------------------------------------------------------ Background Thread /** * The background thread that checks for session timeouts and shutdown. */ public void run() { // Loop until the termination semaphore is set while (!threadDone) { threadSleep(); processExpires(); } } CS585 } 30/ Aspect Oriented Programming Separate FC from Aspectual Components: – Addresses cross-cutting concerns explicitly – Provide higher level of abstraction Aspects – cut-across functional components thus increase their dependency Code tangling problem – – – – – – – Increases dependencies between components Comprehensibility difficult to understand and reason about Destroys modularity Reuse-ability Maintainability Reduces software quality CS585 31/ Concerns OO and AO Concerns like security cut across the natural units of modularity. – For object-oriented programming languages, the natural unit of modularity is the class. – But in object-oriented programming languages, crosscutting concerns are not easily turned into classes precisely because they cut across classes, and so these aren't reusable, they can't be refined or inherited, they are spread through out the program in an undisciplined way. Aspect-oriented programming is a way of modularizing crosscutting concerns much like object-oriented programming is a way of modularizing common concerns. AspectJ is an implementation of aspect-oriented programming for Java. CS585 32/ Aspect Oriented Programming Weaving Mechanisms: – Use of Aspect Definition – express aspects as linguistics construct in ADL – express components in general purpose language, – inline aspects into components before compilation – Design Approaches CS585 33/ Aspect Oriented Programming Aspect-J Aspect J is a general-purpose AO language Aspect J extends Java with support for two kinds of crosscutting implementation – based on a set of extensions to Java – supports modular implementation of cross cutting concerns New constructs to Java: – – – – Join Points - concept Point Cut Advice Aspect The basic trick is “write it somewhere else” CS585 34/ Aspect J - Join Points model These constructs are constructed around the Join Points model – The Join Points “model” provides a reference in a program where the aspects and the functional code are intermixed together – Join points are “points in the execution” of the programs CS585 35/ Aspect J There are several types of Join Points: – Method Calls. A method call is called a join point when the main program you reference is a function. – Method Call Receptions. It occurs in the called object. When an object receives a method it occurs at the point where control flow has been transferred to the called object, but before any particular method has been called – Method Execution. When an individual method is invoked – Field Gets, and Sets. When a field in an object is read or has been set – Exception Handler Executions. When an exception handler has been invoked CS585 36/ Aspect J Language construct that Aspect J adds to Java are: – Point Cut. A Point Cut is a set of Join Points combined together. Point cuts types: • Primitive pointcuts. Pick out sets of join points and values at those points • User-defined pointcuts. Named collections of join points and values – Advice. Defines additional actions to take at join points in a pointcut. It associates the body of the code with a point cut and the time at which a point cut should execute a certain code. Before and after are examples of the advice construct. – Aspect. A crosscutting type that contains the definitions of advice, pointcuts, and method declarations. CS585 37/ The Figure Example A Figure consists of a number of FigureElements, which can be either Points or Lines. The Figure class provides factory services. There is also a Display. Most example programs later in this chapter are based on this system as well. CS585 38/ Aspect Oriented Programming Without Aspect-J CS585 39/ class helps tracking movements CS585 41/ Aspect Oriented Programming Figure 15: Example of a program written in AspectJ [43] With Aspect-J Line/Point unchanged!) CS585 43/ ...
View Full Document

This document was uploaded on 04/23/2010.

Ask a homework question - tutors are online