blob: 46c60a85e439c05dede4cd89a231a5f77ab7b532 [file] [log] [blame]
/*******************************************************************************
* 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
}
}