blob: faad321aed690156737418d59467c1cfa75bfbca [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.debug.internal.core.memory;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.internal.core.DebugCoreMessages;
/**
* @since 3.0
*/
public class MemoryRenderingManager implements IMemoryRenderingManager, IDebugEventSetListener, IMemoryBlockListener
{
private ArrayList listeners = new ArrayList();
private ArrayList fRenderings = new ArrayList();
private Hashtable fMemoryRenderingInfo = new Hashtable();
private ArrayList fRenderingInfoOrderList = new ArrayList();
private Hashtable fDefaultRenderings = new Hashtable();
private Hashtable fRenderingBinds = new Hashtable();
private Hashtable fDynamicRenderingMap = new Hashtable();
private Hashtable fDynamicRenderingFactory = new Hashtable();
private static final int ADDED = 0;
private static final int REMOVED = 1;
private static final String RENDERING_EXT = "memoryRenderings"; //$NON-NLS-1$
private static final String RENDERING_ELEMENT = "rendering"; //$NON-NLS-1$
private static final String RENDERING_PROPERTY_ELEMENT = "rendering_property"; //$NON-NLS-1$
private static final String RENDERING_ID = "renderingId"; //$NON-NLS-1$
private static final String NAME = "name"; //$NON-NLS-1$
private static final String VALUE = "value"; //$NON-NLS-1$
private static final String DEFAULT_RENDERING="default_renderings"; //$NON-NLS-1$
private static final String MEMORYBLOCKCLASS = "memoryBlockClass"; //$NON-NLS-1$
private static final String RENDERINGS="renderingIds"; //$NON-NLS-1$
private static final String RENDERING_BIND = "rendering_binding"; //$NON-NLS-1$
private static final String RENDERING_FACTORY = "renderingFactory"; //$NON-NLS-1$
private static final String DYNAMIC_RENDERING_FACTORY = "dynamicRenderingFactory"; //$NON-NLS-1$
private boolean fHandleAddEvent = true;
/**
* Notifies a memory block listener in a safe runnable to
* handle exceptions.
*/
class MemoryRenderingManagerNotifier implements ISafeRunnable {
private IMemoryRenderingListener fListener;
private int fType;
private IMemoryRendering fRendering;
/**
* @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
*/
public void handleException(Throwable exception) {
DebugPlugin.log(exception);
}
/**
* @see org.eclipse.core.runtime.ISafeRunnable#run()
*/
public void run() throws Exception {
switch (fType) {
case ADDED:
fListener.MemoryBlockRenderingAdded(fRendering);
break;
case REMOVED:
fListener.MemoryBlockRenderingRemoved(fRendering);
break;
}
}
/**
* Notfied listeners of added/removed rendering events
*/
public void notify(int update, IMemoryRendering rendering) {
if (listeners != null) {
fType = update;
fRendering = rendering;
Object[] copiedListeners= listeners.toArray(new IMemoryRenderingListener[listeners.size()]);
for (int i= 0; i < copiedListeners.length; i++) {
fListener = (IMemoryRenderingListener)copiedListeners[i];
Platform.run(this);
}
}
fListener = null;
}
}
public MemoryRenderingManager()
{
MemoryBlockManager.getMemoryBlockManager().addListener(this);
buildMemoryRenderingInfo();
}
/**
* Build rendering info in the manager
* Then read in extended rendering types
*/
private void buildMemoryRenderingInfo()
{
// get rendering extensions
getExtendedRendering();
}
/**
* Read in and store extension to rendering
*/
private void getExtendedRendering() {
IExtensionPoint rendering= Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), RENDERING_EXT);
IExtension[] extensions = rendering.getExtensions();
for (int i=0; i<extensions.length; i++)
{
IConfigurationElement[] elements = extensions[i].getConfigurationElements();
for (int j=0; j<elements.length; j++)
{
if (elements[j].getName().equals(RENDERING_ELEMENT))
{
addRendering(elements[j]);
}
else if (elements[j].getName().equals(RENDERING_PROPERTY_ELEMENT))
{
addRenderingProperty(elements[j]);
}
else if (elements[j].getName().equals(DEFAULT_RENDERING))
{
addDefaultRenderings(elements[j]);
}
else if (elements[j].getName().equals(RENDERING_BIND))
{
addRenderingBind(elements[j]);
}
else
{
DebugPlugin.logMessage("Unknown element in rendering extenstion: " + elements[j].getName(), null); //$NON-NLS-1$
}
}
}
}
/**
* @param elements
* @param j
*/
private void addRendering(IConfigurationElement element) {
String renderingId = element.getAttribute(RENDERING_ID);
String name = element.getAttribute(NAME);
// if any of them is null, do not add, log an error
if (renderingId == null ||
name == null)
{
String extension = element.getDeclaringExtension().getUniqueIdentifier();
DebugPlugin.logMessage("Rendering defined is malformed: " + extension, null); //$NON-NLS-1$
}
else
{
MemoryRenderingInfo info = new MemoryRenderingInfo(renderingId, name, element);
if (fMemoryRenderingInfo.containsKey(renderingId))
{
// if a rendering already exists with the same id, log a warning of duplicated rendering
Status status = new Status(IStatus.WARNING, DebugPlugin.getUniqueIdentifier(), 0,
"Duplicated rendering definition: " + renderingId, null); //$NON-NLS-1$
DebugPlugin.log(status);
}
fMemoryRenderingInfo.put(renderingId, info);
fRenderingInfoOrderList.add(renderingId);
}
// get sub-elements from rendering and parse as properties
IConfigurationElement[] subElements = element.getChildren();
for (int k=0; k < subElements.length; k++)
{
if (subElements[k].getName().equals(RENDERING_PROPERTY_ELEMENT))
{
addRenderingProperty(subElements[k]);
}
else
{
DebugPlugin.logMessage("Unknown element in rendering extenstion: " + element.getName(), null); //$NON-NLS-1$
}
}
}
/**
* @param elements
* @param j
*/
private void addRenderingProperty(IConfigurationElement element) {
String renderingId = element.getAttribute(RENDERING_ID);
String propertyId = element.getAttribute(NAME);
String propertyValue = element.getAttribute(VALUE);
if (renderingId == null ||
propertyId == null ||
propertyValue == null)
{
String extension = element.getDeclaringExtension().getUniqueIdentifier();
DebugPlugin.logMessage("Rendering property defined is malformed: " + extension, null); //$NON-NLS-1$
}
else
{
// find the rendering
MemoryRenderingInfo info = (MemoryRenderingInfo)fMemoryRenderingInfo.get(renderingId);
if (info == null){
DebugPlugin.logMessage("Rendering info for this property is not found: " + propertyId, null); //$NON-NLS-1$
}
else
{
// add the property to the rendering
info.addProperty(propertyId, element);
}
}
}
/**
* Process the configuration element into default rendering for
* a type of memory block.
* @param element
*/
private void addDefaultRenderings(IConfigurationElement element)
{
String memoryBlockClass = element.getAttribute(MEMORYBLOCKCLASS);
String renderings = element.getAttribute(RENDERINGS);
if(memoryBlockClass == null || renderings == null)
{
String extension = element.getDeclaringExtension().getUniqueIdentifier();
DebugPlugin.logMessage("Default rendering defined is malformed: " + extension, null); //$NON-NLS-1$
return;
}
ArrayList renderingsArray = new ArrayList();
// seperate renderings and create an array
int idx = renderings.indexOf(","); //$NON-NLS-1$
if (idx == -1)
{
renderingsArray.add(renderings);
}
else
{
StringTokenizer tokenizer = new StringTokenizer(renderings, ","); //$NON-NLS-1$
while (tokenizer.hasMoreElements())
{
String rendering = tokenizer.nextToken();
rendering = rendering.trim();
// check if rendering is valid
renderingsArray.add(rendering);
}
}
if (fDefaultRenderings == null)
{
fDefaultRenderings = new Hashtable();
}
// check hash table to see if something is alreay added
ArrayList definedrenderings = (ArrayList)fDefaultRenderings.get(memoryBlockClass);
if (definedrenderings == null)
{
// add renderings to hashtable
fDefaultRenderings.put(memoryBlockClass, renderingsArray);
}
else
{
for (int i=0; i<renderingsArray.size(); i++)
{
// append to the list
if (!definedrenderings.contains(renderingsArray.get(i)))
{
definedrenderings.add(renderingsArray.get(i));
}
}
}
}
private void addRenderingBind(IConfigurationElement element){
String memoryBlockClass = element.getAttribute(MEMORYBLOCKCLASS);
String renderings = element.getAttribute(RENDERINGS);
if(memoryBlockClass == null || renderings == null)
{
String extension = element.getDeclaringExtension().getUniqueIdentifier();
DebugPlugin.logMessage("Rendering bind defined is malformed: " + extension, null); //$NON-NLS-1$
return;
}
ArrayList renderingsArray = new ArrayList();
// seperate renderings and create an array
int idx = renderings.indexOf(","); //$NON-NLS-1$
if (idx == -1)
{
renderingsArray.add(renderings);
}
else
{
StringTokenizer tokenizer = new StringTokenizer(renderings, ","); //$NON-NLS-1$
while (tokenizer.hasMoreElements())
{
String rendering = tokenizer.nextToken();
rendering = rendering.trim();
// check if rendering is valid
renderingsArray.add(rendering);
}
}
if (fRenderingBinds == null)
{
fRenderingBinds = new Hashtable();
}
// check hash table to see if something is alreay added
ArrayList renderingIds = (ArrayList)fRenderingBinds.get(memoryBlockClass);
if (renderingIds == null)
{
// add renderings to hashtable
fRenderingBinds.put(memoryBlockClass, renderingsArray);
}
else
{
for (int i=0; i<renderingsArray.size(); i++)
{
// append to the list
if (!renderingIds.contains(renderingsArray.get(i)))
{
renderingIds.add(renderingsArray.get(i));
}
}
}
}
private MemoryRenderingManagerNotifier getMemoryBlockNotifier() {
return new MemoryRenderingManagerNotifier();
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#addMemoryBlockRendering(org.eclipse.debug.core.model.IMemoryBlock, java.lang.String)
*/
public IMemoryRendering addMemoryBlockRendering(IMemoryBlock mem, String renderingId) throws DebugException
{
if (fRenderings == null)
return null;
IMemoryRendering newRendering = createRendering(mem, renderingId);
// if an error has occurred, or if user has canceled
if (newRendering == null)
return newRendering;
if (fRenderings.contains(newRendering))
return newRendering;
fRenderings.add(newRendering);
// add listener for the first memory block added
if (fRenderings.size() == 1)
{
DebugPlugin.getDefault().addDebugEventListener(this);
}
notifyListeners(ADDED, newRendering);
return newRendering;
}
/**
* @param mem
* @param renderingId
* @return the memory rendering created by the factory or default rendering.
* Returns null if an error has occurred
*/
public IMemoryRendering createRendering(IMemoryBlock mem, String renderingId) throws DebugException{
IMemoryRenderingInfo info = getRenderingInfo(renderingId);
if (info != null){
IConfigurationElement element = info.getConfigElement();
if (element != null){
String factoryAtt = element.getAttribute(RENDERING_FACTORY);
if (factoryAtt != null){
Object obj = null;
try {
obj = element.createExecutableExtension(RENDERING_FACTORY);
} catch (CoreException e) {
// throw a debug exception due to error
IStatus stat = e.getStatus();
DebugException de = new DebugException(stat);
throw de;
}
if (obj == null)
return new MemoryRendering(mem, renderingId);
if(obj instanceof IMemoryRenderingFactory)
{
IMemoryRenderingFactory factory = (IMemoryRenderingFactory)obj;
IMemoryRendering rendering = null;
rendering = factory.createRendering(mem, renderingId);
return rendering;
}
}
}
else
{
String message= MessageFormat.format(DebugCoreMessages.getString("MemoryRenderingManager.ErrorMsg"), new String[]{renderingId}); //$NON-NLS-1$
// throw a debug exception because the rendering info cannot be located
Status status = new Status(IStatus.ERROR,
DebugPlugin.getUniqueIdentifier(),
0, message , null); //$NON-NLS-1$
DebugException de = new DebugException(status);
throw de;
}
}
else
{
String message= MessageFormat.format(DebugCoreMessages.getString("MemoryRenderingManager.ErrorMsg"), new String[]{renderingId}); //$NON-NLS-1$
// throw a debug exception because the rendering info cannot be located
Status status = new Status(IStatus.ERROR,
DebugPlugin.getUniqueIdentifier(),
0, message, null); //$NON-NLS-1$
DebugException de = new DebugException(status);
throw de;
}
return new MemoryRendering(mem, renderingId);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#removeMemoryBlockRendering(org.eclipse.debug.core.model.IMemoryBlock, java.lang.String)
*/
public void removeMemoryBlockRendering(IMemoryBlock mem, String renderingId)
{
if(fRenderings == null)
return;
IMemoryRendering[] toRemove = getRenderings(mem, renderingId);
for (int i=0; i<toRemove.length; i++)
{
fRenderings.remove(toRemove[i]);
// remove listener after the last memory block has been removed
if (fRenderings.size() == 0)
{
DebugPlugin.getDefault().removeDebugEventListener(this);
}
notifyListeners(REMOVED, toRemove[i]);
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#addMemoryBlockRendering(org.eclipse.debug.ui.IMemoryRendering)
*/
public void addMemoryBlockRendering(IMemoryRendering rendering) throws DebugException{
// do not allow duplicated objects
if (fRenderings.contains(rendering))
return;
fRenderings.add(rendering);
// add listener for the first memory block added
if (fRenderings.size() == 1)
{
DebugPlugin.getDefault().addDebugEventListener(this);
}
notifyListeners(ADDED, rendering);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#removeMemoryBlockRendering(org.eclipse.debug.ui.IMemoryRendering)
*/
public void removeMemoryBlockRendering(IMemoryRendering rendering) {
if(rendering == null)
return;
if(!fRenderings.contains(rendering))
return;
fRenderings.remove(rendering);
// remove listener after the last memory block has been removed
if (fRenderings.size() == 0)
{
DebugPlugin.getDefault().removeDebugEventListener(this);
}
notifyListeners(REMOVED, rendering);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#getRenderings(org.eclipse.debug.core.model.IMemoryBlock, java.lang.String)
*/
public IMemoryRendering[] getRenderings(IMemoryBlock mem, String renderingId)
{
if (renderingId == null)
{
return getRenderingsFromMemoryBlock(mem);
}
ArrayList ret = new ArrayList();
for (int i=0; i<fRenderings.size(); i++)
{
if (fRenderings.get(i) instanceof IMemoryRendering)
{
IMemoryRendering rendering = (IMemoryRendering)fRenderings.get(i);
if (rendering.getBlock() == mem && renderingId.equals(rendering.getRenderingId()))
{
ret.add(rendering);
}
}
}
return (IMemoryRendering[])ret.toArray(new IMemoryRendering[ret.size()]);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#getRenderingsFromDebugTarget(org.eclipse.debug.core.model.IDebugTarget)
*/
public IMemoryRendering[] getRenderingsFromDebugTarget(IDebugTarget target)
{
ArrayList ret = new ArrayList();
for (int i=0; i<fRenderings.size(); i++)
{
if (fRenderings.get(i) instanceof IMemoryRendering)
{
IMemoryRendering rendering = (IMemoryRendering)fRenderings.get(i);
if (rendering.getBlock().getDebugTarget() == target)
{
ret.add(rendering);
}
}
}
return (IMemoryRendering[])ret.toArray(new IMemoryRendering[ret.size()]);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#getRenderingsFromMemoryBlock(org.eclipse.debug.core.model.IMemoryBlock)
*/
public IMemoryRendering[] getRenderingsFromMemoryBlock(IMemoryBlock block)
{
ArrayList ret = new ArrayList();
for (int i=0; i<fRenderings.size(); i++)
{
if (fRenderings.get(i) instanceof IMemoryRendering)
{
IMemoryRendering rendering = (IMemoryRendering)fRenderings.get(i);
if (rendering.getBlock() == block)
{
ret.add(rendering);
}
}
}
return (IMemoryRendering[])ret.toArray(new IMemoryRendering[ret.size()]);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#addListener(org.eclipse.debug.ui.IMemoryBlockListener)
*/
public void addListener(IMemoryRenderingListener listener)
{
if(listeners == null)
return;
if(listener == null){
DebugPlugin.logMessage("Null argument passed into IMemoryRenderingManager.addListener", null); //$NON-NLS-1$
return;
}
if (!listeners.contains(listener))
listeners.add(listener);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#removeListener(org.eclipse.debug.ui.IMemoryBlockListener)
*/
public void removeListener(IMemoryRenderingListener listener)
{
if(listeners == null)
return;
if(listener == null){
DebugPlugin.logMessage("Null argument passed into IMemoryRenderingManager.removeListener", null); //$NON-NLS-1$
return;
}
if (listeners.contains(listener))
listeners.remove(listener);
}
private void notifyListeners(int update, IMemoryRendering rendering)
{
getMemoryBlockNotifier().notify(update, rendering);
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
*/
public void handleDebugEvents(DebugEvent[] events) {
for (int i=0; i < events.length; i++)
handleDebugEvent(events[i]);
}
public void handleDebugEvent(DebugEvent event) {
Object obj = event.getSource();
IDebugTarget dt = null;
if (event.getKind() == DebugEvent.TERMINATE)
{
// a terminate event could happen from an IThread or IDebugTarget
// Only handle terminate event from debug target
if (obj instanceof IDebugTarget)
{
dt = ((IDebugTarget)obj);
}
// returns empty array if dt == null
IMemoryRendering[] deletedrendering = getRenderingsFromDebugTarget(dt);
for (int i=0; i<deletedrendering.length; i++)
{
removeMemoryBlockRendering(deletedrendering[i].getBlock(), deletedrendering[i].getRenderingId());
}
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryBlockListener#MemoryBlockAdded(org.eclipse.debug.core.model.IMemoryBlock)
*/
public void MemoryBlockAdded(IMemoryBlock memory)
{
if (fHandleAddEvent)
{
// get default renderings
String renderingIds[] = getDefaultRenderings(memory);
// add renderings
for (int i=0; i<renderingIds.length; i++)
{
try {
addMemoryBlockRendering(memory, renderingIds[i]);
} catch (DebugException e) {
// catch error silently
// log error
DebugPlugin.logMessage("Cannot create default rendering: " + renderingIds[i], null); //$NON-NLS-1$
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryBlockListener#MemoryBlockRemoved(org.eclipse.debug.core.model.IMemoryBlock)
*/
public void MemoryBlockRemoved(IMemoryBlock memory)
{
// remove all renderings related to the deleted memory block
IMemoryRendering[] renderings = getRenderingsFromMemoryBlock(memory);
for (int i=0; i<renderings.length; i++)
{
removeMemoryBlockRendering(renderings[i].getBlock(), renderings[i].getRenderingId());
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#getRenderingInfo(java.lang.String)
*/
public IMemoryRenderingInfo getRenderingInfo(String renderingId)
{
MemoryRenderingInfo info = (MemoryRenderingInfo)fMemoryRenderingInfo.get(renderingId);
if (info != null) {
return info;
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#getAllRenderingInfo(java.lang.Object)
*/
public IMemoryRenderingInfo[] getAllRenderingInfo(Object obj)
{
String[] hierarchy = getHierarchy(obj);
ArrayList renderingIds = new ArrayList();
ArrayList renderingInfos = new ArrayList();
// get all rendering ids
for (int i=0; i<hierarchy.length; i++)
{
ArrayList ids = (ArrayList)fRenderingBinds.get(hierarchy[i]);
if (ids != null)
{
for (int j=0; j<ids.size(); j++)
{
if (!renderingIds.contains(ids.get(j)))
renderingIds.add(ids.get(j));
}
}
}
// get all rendering infos
for (int i=0; i<renderingIds.size(); i++){
IMemoryRenderingInfo info = (IMemoryRenderingInfo)fMemoryRenderingInfo.get(renderingIds.get(i));
IDynamicRenderingInfo[] dynamic = null;
if (info != null)
dynamic = getDynamicRenderingInfo(info);
if (dynamic != null)
{
for (int j=0; j<dynamic.length; j++)
{
IMemoryRenderingInfo dynamicInfo = (IMemoryRenderingInfo)fMemoryRenderingInfo.get(dynamic[j].getRenderingId());
renderingInfos.add(dynamicInfo);
}
}
else if (info!= null)
{
renderingInfos.add(info);
}
}
return (IMemoryRenderingInfo[])renderingInfos.toArray(new IMemoryRenderingInfo[renderingInfos.size()]);
}
private IDynamicRenderingInfo[] getDynamicRenderingInfo(IMemoryRenderingInfo rendering)
{
IConfigurationElement element = rendering.getPropertyConfigElement(DYNAMIC_RENDERING_FACTORY);
try {
if (element != null){
Object obj;
obj = fDynamicRenderingFactory.get(rendering.getRenderingId());
if (obj == null)
obj = element.createExecutableExtension(VALUE);
if (obj != null && obj instanceof IDynamicRenderingFactory)
{
fDynamicRenderingFactory.put(rendering.getRenderingId(), obj);
IDynamicRenderingInfo[] dynamicRenderingTypes = ((IDynamicRenderingFactory)obj).getRenderingInfos();
if (dynamicRenderingTypes != null)
{
addRenderingInfo(dynamicRenderingTypes);
// now compare the returned list to what is orginally cached
Enumeration enum = fDynamicRenderingMap.keys();
while (enum.hasMoreElements())
{
String dynamicRenderingId = (String)enum.nextElement();
String staticRenderingId = (String)fDynamicRenderingMap.get(dynamicRenderingId);
if (staticRenderingId.equals(rendering.getRenderingId()))
{
boolean found = false;
// check that this dynamic rendering still exists
for (int i=0; i<dynamicRenderingTypes.length; i++)
{
if (dynamicRenderingTypes[i].getRenderingId().equals(dynamicRenderingId))
{
found = true;
break;
}
}
if (!found)
{
// if the rendering no longer exists, remove rendering info
fMemoryRenderingInfo.remove(dynamicRenderingId);
fDynamicRenderingMap.remove(dynamicRenderingId);
}
}
}
// update map before returning
String staticRenderingId = rendering.getRenderingId();
for (int i=0; i<dynamicRenderingTypes.length; i++)
{
fDynamicRenderingMap.put(dynamicRenderingTypes[i].getRenderingId(), staticRenderingId);
}
return dynamicRenderingTypes;
}
return null;
}
}
} catch (CoreException e) {
DebugPlugin.logMessage("Cannot create the dynamic rendering factory for " + element.getDeclaringExtension().getUniqueIdentifier(), null); //$NON-NLS-1$
return null;
}
return null;
}
private IMemoryRenderingInfo createRenderingInfo(IDynamicRenderingInfo info)
{
if (info == null)
return null;
if (info.getParentRenderingInfo() == null)
{
DebugPlugin.logMessage("Dynamic rendering info does not have a parent " + info.getRenderingId(), null); //$NON-NLS-1$
return null;
}
IMemoryRenderingInfo parent = info.getParentRenderingInfo();
MemoryRenderingInfo dynamicInfo = new MemoryRenderingInfo(info.getRenderingId(), info.getName(), info.getParentRenderingInfo().getConfigElement());
IConfigurationElement[] properties = parent.getAllProperties();
for (int i=0; i<properties.length; i++)
{
String name = properties[i].getAttribute(NAME);
if (name != null)
{
if (!name.equals(DYNAMIC_RENDERING_FACTORY))
dynamicInfo.addProperty(name, properties[i]);
}
}
return dynamicInfo;
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.IMemoryRenderingManager#getDefaultRenderings(java.lang.Object)
*/
public String[] getDefaultRenderings(Object obj) {
if (fDefaultRenderings == null)
{
return new String[0];
}
if (obj == null)
{
return new String[0];
}
// get all rendering info supporting the object
IMemoryRenderingInfo[] supported = getAllRenderingInfo(obj);
ArrayList results = new ArrayList();
// match it with default renderings
String hierarchy[] = getHierarchy(obj);
// get defaults for the entire hierarchy
for (int i=0; i<hierarchy.length; i++)
{
ArrayList defaults = (ArrayList)fDefaultRenderings.get(hierarchy[i]);
// if defaults is defined
if (defaults != null)
{
for (int j=0; j<defaults.size(); j++)
{
// check if the default is supported
for (int k=0; k<supported.length; k++)
{
if (supported[k].getRenderingId().equals(defaults.get(j)))
{
results.add(supported[k].getRenderingId());
}
}
}
}
}
// return the list
return (String[])results.toArray(new String[results.size()]);
}
protected void addRenderingInfo (IDynamicRenderingInfo[] dynamicRenderingTypes)
{
if (dynamicRenderingTypes != null)
{
// store in fMemoryRenderingInfo arrays so they can be queried
for (int i=0; i<dynamicRenderingTypes.length; i++)
{
IMemoryRenderingInfo dynamicInfo;
if (fMemoryRenderingInfo.get(dynamicRenderingTypes[i].getRenderingId()) == null)
{
dynamicInfo = createRenderingInfo(dynamicRenderingTypes[i]);
if (dynamicInfo != null)
{
fMemoryRenderingInfo.put(dynamicRenderingTypes[i].getRenderingId(), dynamicInfo);
}
}
}
}
}
/**
* @param obj
* @return all superclasses and interfaces
*/
private String[] getHierarchy(Object obj)
{
ArrayList hierarchy = new ArrayList();
// get class name
hierarchy.add(obj.getClass().getName());
// get all super classes
Class superClass = obj.getClass().getSuperclass();
while (superClass != null)
{
hierarchy.add(superClass.getName());
superClass = superClass.getSuperclass();
}
// get all interfaces
ArrayList interfaces = new ArrayList();
Class[] baseInterfaces = obj.getClass().getInterfaces();
for (int i=0; i<baseInterfaces.length; i++)
{
interfaces.add(baseInterfaces[i]);
}
getInterfaces(interfaces, baseInterfaces);
for (int i=0; i<interfaces.size(); i++)
{
hierarchy.add(((Class)interfaces.get(i)).getName());
}
return (String[])hierarchy.toArray(new String[hierarchy.size()]);
}
private void getInterfaces(ArrayList list, Class[] interfaces)
{
Class[] superInterfaces = new Class[0];
for (int i=0 ;i<interfaces.length; i++)
{
superInterfaces = interfaces[i].getInterfaces();
for (int j=0; j<superInterfaces.length; j++)
{
list.add(superInterfaces[j]);
}
getInterfaces(list, superInterfaces);
}
}
/**
* Clean up when the plugin is shut down.
*/
public void shutdown()
{
// clean up
if (listeners != null)
{
listeners.clear();
listeners = null;
}
if (fRenderings != null)
{
fRenderings.clear();
fRenderings = null;
}
if (fMemoryRenderingInfo != null)
{
fMemoryRenderingInfo.clear();
fMemoryRenderingInfo = null;
}
if (fRenderingInfoOrderList != null)
{
fRenderingInfoOrderList.clear();
fRenderingInfoOrderList = null;
}
if (fDynamicRenderingMap != null)
{
fDynamicRenderingMap.clear();
fDynamicRenderingMap = null;
}
if (fDynamicRenderingFactory != null)
{
fDynamicRenderingFactory.clear();
fDynamicRenderingFactory = null;
}
// remove listener
MemoryBlockManager.getMemoryBlockManager().removeListener(this);
}
public void setHandleMemoryBlockAddedEvent(boolean handleEvt)
{
fHandleAddEvent = handleEvt;
}
}