/******************************************************************************* * Copyright (c) 2009 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.wst.sse.core.internal.util; import java.util.ArrayList; import java.util.Arrays; import java.util.Hashtable; import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Platform; import org.eclipse.wst.sse.core.internal.Logger; import org.eclipse.wst.sse.core.internal.SSECorePlugin; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.ServiceRegistration; import org.osgi.service.event.Event; import org.osgi.service.event.EventAdmin; import org.osgi.service.event.EventConstants; import org.osgi.service.event.EventHandler; /** * This responds to memory events. * * Create an instance of a child of this class with the events you are interested in. * Then call connect() to start listening. To stop listening call disconnect(); */ public abstract class AbstractMemoryListener implements EventHandler { /** * The event that indicates that memory is running low at the lowest severity. * Listeners are requested to release caches that can easily be recomputed. * The Java VM is not seriously in trouble, but process size is getting higher than * is deemed acceptable. */ public static final String SEV_NORMAL = "org/eclipse/equinox/events/MemoryEvent/NORMAL"; //$NON-NLS-1$ /** * The event that indicates that memory is running low at medium severity. * Listeners are requested to release intermediate build results, complex models, etc. * Memory is getting low and may cause operating system level stress, such as swapping. */ public static final String SEV_SERIOUS = "org/eclipse/equinox/events/MemoryEvent/SERIOUS"; //$NON-NLS-1$ /** * The event that indicates that memory is running low at highest severity. * Listeners are requested to do things like close editors and perspectives, close database connections, etc. * Restoring these resources and caches constitutes lots of work, but memory is so low that * drastic measures are required. */ public static final String SEV_CRITICAL = "org/eclipse/equinox/events/MemoryEvent/CRITICAL"; //$NON-NLS-1$ /** * All of the valid memory severities */ public static final String[] SEV_ALL = { SEV_NORMAL, SEV_SERIOUS, SEV_CRITICAL }; /** * Used to register the {@link EventAdmin} listener */ private static BundleContext CONTEXT = (SSECorePlugin.getDefault() != null) ? SSECorePlugin.getDefault().getBundle().getBundleContext() : null; /** * the severities that will be reacted to */ private final List fSeverities; /** * service used to register this listener */ private ServiceRegistration fRegisterService; /** * Will listen to all memory events */ public AbstractMemoryListener() { this(AbstractMemoryListener.SEV_ALL); } /** * Will listen to memory events of the given <code>severity</code> * * @param severity listen for memory events of this severity */ public AbstractMemoryListener(String severity) { Assert.isNotNull(severity, "Severity can not be null"); //$NON-NLS-1$ List severities = new ArrayList(1); severities.add(severity); fSeverities = severities; } /** * Will listen to memory events of the given <code>severities</code> * * @param severities listen for memory events for any of these severities */ public AbstractMemoryListener(String[] severities) { Assert.isNotNull(severities, "Severities can not be null"); //$NON-NLS-1$ Assert.isLegal(severities.length > 0, "Severities must specify at least one severity"); //$NON-NLS-1$ fSeverities = Arrays.asList(severities); } /** * Will listen to memory events of the given <code>severities</code> * * @param severities listen for memory events for any of these severities */ public AbstractMemoryListener(List severities) { Assert.isNotNull(severities, "Severities can not be null"); //$NON-NLS-1$ Assert.isLegal(!severities.isEmpty(), "Severities must specify at least one severity"); //$NON-NLS-1$ fSeverities = severities; } /** * Connect this listener to the {@link EventAdmin} */ public final void connect() { if (CONTEXT != null) { // NOTE: This is TEMPORARY CODE needed to load the plugin // until its done automatically by the product // TODO: Remove me Bundle b = Platform.getBundle("org.eclipse.equinox.event"); //$NON-NLS-1$ if (b != null && b.getState() == Bundle.RESOLVED) { try { b.start(Bundle.START_TRANSIENT); } catch (BundleException e) { e.printStackTrace(); } } // end remove me //register this handler String[] severities = (String[])fSeverities.toArray(new String[fSeverities.size()]); Hashtable prop = new Hashtable(1); prop.put(EventConstants.EVENT_TOPIC, severities); fRegisterService = CONTEXT.registerService(EventHandler.class.getName(), this, prop); //call any implementer specific connect code doConnect(); } else { Logger.log(Logger.WARNING, "Error accessing bundle context. Is Platform running? Not tracking memory events. "); //$NON-NLS-1$ } } /** * Disconnect this listener to the {@link EventAdmin} */ public final void disconnect() { if (fRegisterService != null) { fRegisterService.unregister(); fRegisterService = null; } //call any implementer specific disconnect code doDisconnect(); } /** * <p>Filter out any events that are not of the type that this listener handles</p> * * @see org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event) */ public final void handleEvent(Event event) { if (fSeverities.contains(event.getTopic())) { handleMemoryEvent(event); } } /** * Implementing child classes may assume that only {@link Event}s of the types * given to the constructor will be given to this method. * * @param event the {@link Event} with a topic equal to one of the memory * severities that this listener is listening for */ protected abstract void handleMemoryEvent(Event event); /** * Implementers may overrun this method to do setup after connection of this listener */ protected void doConnect() { //do nothing by default } /** * Implementers may overrun this method to do tear down after disconnection of this listener */ protected void doDisconnect() { //do nothing by default } }