/******************************************************************************* * Copyright (c) 2002-2006 Innoopract Informationssysteme 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: * Innoopract Informationssysteme GmbH - initial API and implementation ******************************************************************************/ package com.w4t.util; import java.lang.ref.WeakReference; import java.util.*; import javax.servlet.http.HttpSession; import org.eclipse.rwt.SessionSingletonBase; import org.eclipse.rwt.internal.*; import org.eclipse.rwt.internal.service.*; import com.w4t.*; import com.w4t.event.WebFormEvent; import com.w4t.internal.adaptable.IFormAdapter; /** * <p>This is a helping class for the WebComponentApplication to keep access * to a single WebComponent by hashing the component with its ID as key.</p> */ public class WebComponentRegistry extends SessionSingletonBase { /** the time at which this WebComponentRegistry was created */ private final long creationTime; private final Map registry; private final HttpSession session; private WebComponentRegistry() { this.registry = new WeakHashMap(); this.creationTime = System.currentTimeMillis(); this.session = ContextProvider.getRequest().getSession(); } /** * Returns the session singletion instance. */ public static WebComponentRegistry getInstance() { return ( WebComponentRegistry )getInstance( WebComponentRegistry.class ); } /** * adds a webComponent to the registry * @webComponent WebComponent to add */ public synchronized void add( final WebComponent webComponent ) { registry.put( webComponent, new WeakReference( webComponent ) ); } /** <p>returns a Statistics object with registry statistics * information: how many components of which types are contained in * this WebComponentRegistry, how much memory is used etc.</p> * + writes out the list to console (temp only) */ public WebComponentStatistics getStatistics() { WebComponentStatistics result = new WebComponentStatistics(); long statsStartTime = System.currentTimeMillis(); Hashtable stats = new Hashtable(); int regSize = countRegisteredComponents( stats ); // provide the WebComponentStatistics with the collected info: // component counting result.applyComponentCounts( stats ); result.setComponentCountAltogether( regSize ); // runtime statistics Runtime rt = Runtime.getRuntime(); result.setOccupiedMemoryKB( ( rt.totalMemory() - rt.freeMemory() ) / 1024 ); result.setApplicationUptime( System.currentTimeMillis() - this.creationTime ); // the last thing to do is to say how long doing statistics took itself result.setStatisticsTime( System.currentTimeMillis() - statsStartTime ); return result; } /** Loops over the whole registry and count how many instances of the * various types of webComponents are contained in it. */ private int countRegisteredComponents( final Hashtable stats ) { int result = 0; Object[] componentRefs = registry.values().toArray(); for( int i = 0; i < componentRefs.length; i++ ) { Object content = ( ( WeakReference )componentRefs[ i ] ).get(); if( content != null ) { WebComponent component = ( WebComponent )content; String className = component.getClass().getName(); int count = 1; if( stats.containsKey( className ) ) { count = ( ( Integer )stats.get( className ) ).intValue(); count++; } result++; stats.put( className, new Integer( count ) ); } } return result; } /** Free the registry from expired WebComponents, and throw the closing * event on closed WebForms */ public synchronized void cleanup() { List closingList = new ArrayList(); Object[] componentRefs = registry.values().toArray(); for( int i = 0; i < componentRefs.length; i++ ) { Object content = ( ( WeakReference )componentRefs[ i ] ).get(); if( content != null ) { WebComponent component = ( WebComponent )content; if( component instanceof WebForm ) { WebForm wf = ( WebForm )component; long closingTimeout = getClosingTimout(); if( wf.getClosingTimeout() != -1 ) { closingTimeout = wf.getClosingTimeout(); } long now = System.currentTimeMillis(); IFormAdapter adapter = ( IFormAdapter )wf.getAdapter( IFormAdapter.class ); long timeStamp = adapter.getTimeStamp(); boolean active = WebComponentControl.isActive( wf ); if( active && ( now - timeStamp ) > closingTimeout ) { closingList.add( wf ); } } } } int toClose = closingList.size(); for( int i = 0; i < toClose; i++ ) { WebForm wf = ( WebForm )closingList.get( i ); closeForm( wf ); } closingList.clear(); notifyAll(); } private long getClosingTimout() { IConfiguration configuration = ConfigurationReader.getConfiguration(); IInitialization initialization = configuration.getInitialization(); long closingTimeout = initialization.getClosingTimeout(); return closingTimeout; } private void closeForm( final WebForm form ) { WebComponentControl.setActive( form, false ); Request request = new Request( session ); Response response = new Response(); ContextProvider.setContext( new ServiceContext( request, response ) ); ContextProvider.getContext().setStateInfo( new ServiceStateInfo() ); try { int webEventType = WebFormEvent.WEBFORM_CLOSING; WebFormEvent webFormEvent = new WebFormEvent( form, webEventType ); webFormEvent.processEvent(); } catch( final Exception e ) { if( form != null ) { System.out.println( "Exception in registry cleanup call \nduring " + "process closing Event of WebForm '" + form.getClass().getName() + " " + form.getName() + "]: \n" + e.toString() ); } else { System.out.println( "Exception in registry cleanup call \nduring " + "process closing Event of a WebForm \n'" + e.toString() ); } e.printStackTrace(); } finally { ContextProvider.disposeContext(); } } /** returns the time at which this WebComponentRegistry was created */ long getCreationTime() { return creationTime; } }