at.spardat.xma.session.XMASessionServer Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
// @(#) $Id: XMASessionServer.java 2089 2007-11-28 13:56:13Z s3460 $
package at.spardat.xma.session;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.security.auth.Subject;
import javax.servlet.http.HttpSession;
import at.spardat.xma.boot.comp.data.XMAApp;
import at.spardat.xma.boot.comp.data.XMAComponent;
import at.spardat.xma.boot.server.ServerAppLoader;
import at.spardat.xma.component.ComponentServer;
import at.spardat.xma.plugins.PluginManager;
import at.spardat.xma.plugins.PluginManagerServer;
import at.spardat.xma.security.XMAContext;
/**
* The representation of a XMA session at the server side.
*
* @author YSD, 13.05.2003 11:42:00
*/
public class XMASessionServer extends XMASession {
/**
* The Servlet Session this XMASession object is bound to.
*/
private HttpSession httpSession_;
/**
* The key which is used to bind an object of this class to httpSession_.
*/
static final String SESSION_ATTRIBUTE_KEY = "XMA_SESSION";
/**
* Key to store the BOOTRUNTIME_VERSION in HTTP Session
*/
static final String CLIENT_BOOTRUNTIME_VERSION = "at.spardat.xma.BootRuntimeVersion";
/**
* Key to store the CLIENT_IP_ADRESS in HTTP Session
*/
static final String CLIENT_IP_ADDRESS = "at.spardat.xma.ClientIPAdress";
/**
* Manages all stateful components this XMASessionServer is
* aware of. Note that the set of Components the corresponding
* client session manages might differ in the following ways:
*
*
* - The server does not manage components that are stateless.
* Stateless components are constructed before the server side
* event executes and destroyed afterwards without registering
* the component with this.
*
- This XMASessionServer may hold references to stateful
* components that are already destroyed at the client but the
* server does not know about this fact yet.
*
*
* The keys in the HashMap are Shorts, the ids of the components.
* The values are the components themselves.
*/
private HashMap components_ = new HashMap();
/**
* Necessary to bind an XMASession to a thread
*/
private static final ThreadLocal xmaSessionThreadLocal_ = new ThreadLocal();
/**
* The subject holds the user/context information
*/
private Subject subject_;
/**
* application description used for plugin lookups
*/
private XMAApp appDes;
/**
* The context path of the web-application without leading slash.
*/
private String contextPath_;
/**
* String - Integer (server - highCount)
* stores the last polled highCount of the GlobalEvents for each server.
*/
private Map serverHighCounts_ = new HashMap();
/**
* Constructor which creates an XMASessionServer and binds
* this as an attribute to the provided httpSession.
*
* @param httpSession the servlet session this is an attribute of.
* @param contextPath the context path of the webapplication without leading slash.
* @exception IllegalStateException if there is already an XMASession bound
* to the provided httpSession.
*/
public XMASessionServer (HttpSession httpSession, Subject subject, String contextPath) {
httpSession_ = httpSession;
subject_ = subject;
contextPath_ = contextPath;
if (httpSession.getAttribute(SESSION_ATTRIBUTE_KEY) != null) throw new IllegalStateException();
httpSession.setAttribute(SESSION_ATTRIBUTE_KEY, this);
}
/**
* Returns the context path of the enclosing web-application.
*
* @return a String never null. The leading slash of the context path
* is not returned.
*/
public String getContextPath () {
if (contextPath_ == null) return "";
return contextPath_;
}
/**
* Returns the XMASessionServer object that is bound to the given
* httpSession or null if none is bound yet.
*/
public static XMASessionServer getXMASession (HttpSession httpSession) {
return (XMASessionServer) httpSession.getAttribute(SESSION_ATTRIBUTE_KEY);
}
/**
* Returns the execution context of this session. All callers of this
* method may rely on the fact that the information stored in the
* XMAContext remain stable, i.e., won't change over the
* lifetime of this session. This pertains to the authenticated user,
* the mandant and the environment.
*
* @return context never null.
*/
public XMAContext getContext () {
Set principals = subject_.getPrincipals(XMAContext.class);
return (XMAContext)principals.iterator().next();
}
/**
* Returns the subject as supplied by the JAAS conforming login module.
* @return the subject provided by the login module.
*/
public Subject getSubject() {
return subject_;
}
/**
* Sets the subject; may only be used by the runtime.
* @param subject as provided by the login module.
*/
void setSubject(Subject subject) {
subject_ = subject;
}
/**
* Registers a Component with this session if the component is stateful.
*
* @param cs the Component to register. cs is required to
* 1) have a valid id set and 2) that a component
* with this id is not registered yet.
* @exception IllegalArgumentException if some of above mentioned conditions is violated.
*/
public void registerComponent (ComponentServer cs) {
if (!cs.isStateless()) {
Short id = new Short(cs.getId());
if (id.shortValue() <= 0) throw new IllegalArgumentException();
if (components_.get(id) != null) throw new IllegalArgumentException();
components_.put (id, cs);
}
}
/**
* Removes a component with a given id from this. This method does nothing
* if there is no component with the provided id managed in this.
*
* May only be called from ComponentServer!!!!!
*/
public void removeComponent (short id) {
components_.remove(new Short(id));
}
/**
* Returns the ComponentServer registered for the provided id
* or null if there is no such component.
*/
public ComponentServer getComponent (short id) {
return (ComponentServer) components_.get (new Short (id));
}
/**
* Given the short name of a component (which is also the name
* of the class without the package name), this method returns
* the fully qualified name of the components class.
*
* @param namComponent the name of the component
* @return the fully qualified class name
*/
public String getComponentClassName (String namComponent) {
if( namComponent == null) throw new IllegalStateException( "argument namComponent is null");
if( appDes == null ) {
appDes = ServerAppLoader.getXmaapp();
if( appDes == null ) throw new RuntimeException( "unable to load application description");
}
XMAComponent cmp = appDes.getComponent( namComponent );
String strPackage = cmp.getImplPackage_();
if( strPackage == null)
throw new RuntimeException( "package name for component not found: " + namComponent );
return strPackage + ".server." + namComponent;
}
/**
* Requires that counts holds an array of size at least 3
* and returns the following counts in the array elements: The
* number of stateful components active in this session, the
* number of pages in all these components and the estimated
* number of bytes of all pages in all components in this session.
*/
public void getCounts (int [] counts) {
counts[0] = components_.size(); // number of components
counts[1] = 0; // number of pages
counts[2] = 0; // number of bytes
Iterator iter = components_.values().iterator();
while (iter.hasNext()) {
ComponentServer c = (ComponentServer) iter.next();
counts[1] += c.getNumPageModels();
counts[2] += c.estimateMemory();
}
}
/**
* Returns the servlet session that this XMASession is an attribute of.
*
* @return HttpSession never null.
*/
public HttpSession getHttpSession() {
return httpSession_;
}
/**
* Returns the XMASession bound to the currently executing thread.
* You may use this mehthod only after a RemoteCall has
* been dispatched to the XMA server which executes in this thread
* and the thread did not change. This is normally the case but
* it needs not be so in all cases.
*/
public static XMASession getXMASession () {
return (XMASession) xmaSessionThreadLocal_.get();
}
/**
* Sets the provided session as the current threads session. May
* be null to reset the session at the end of an
* RemoteCall execution.
*/
public static void setSessionAsThreadLocal (XMASessionServer session) {
xmaSessionThreadLocal_.set(session);
}
/* (non-Javadoc)
* @see at.spardat.xma.session.XMASession#getPluginManager()
*/
public PluginManager getPluginManager() {
return PluginManagerServer.getInstance();
}
/**
* Application Hash-Code built from application descriptors.
*
* @return Application Version Hash-Code
*/
public byte[] getApplicationVersion() {
return ServerAppLoader.getDigest();
}
/**
* @see at.spardat.xma.session.XMASession#isAtServer()
*/
public boolean isAtServer() {
return true;
}
/**
* @return Returns the serverHighCounts_.
*/
public Map getServerHighCounts() {
return serverHighCounts_;
}
/**
*
* @return The Clients Bootruntime Version. Returns '<1.4.0' for a Bootruntime before 1.4.0.
* @since version_number
* @author s3460
*/
public String getBootRuntimeVersion(){
return (String) httpSession_.getAttribute(CLIENT_BOOTRUNTIME_VERSION);
}
/**
*
* @return The Clients IP Address Version
* @since version_number
* @author s3460
*/
public String getClientIPAddress(){
return (String) httpSession_.getAttribute(CLIENT_IP_ADDRESS);
}
}