/*******************************************************************************
* Copyright (c) 2006, 2012 Wind River Systems 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:
* Wind River Systems - initial API and implementation
* Ericsson AB - Modules view for DSF implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.modules;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IModules;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IModules.IModuleDMContext;
import org.eclipse.cdt.dsf.debug.service.IModules.IModuleDMData;
import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext;
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.cdt.dsf.internal.ui.DsfUILabelImage;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelFont;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.update.StaleDataLabelBackground;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.resource.JFaceResources;
/**
* @since 1.0
*/
public class ModulesVMNode extends AbstractDMVMNode
implements IElementLabelProvider, IElementPropertiesProvider
{
/**
* Marker type for the modules VM context. It allows action enablement
* expressions to check for module context type.
*/
public class ModuleVMContext extends DMVMContext {
protected ModuleVMContext(IDMContext dmc) {
super(dmc);
}
}
/**
* @since 2.0
*/
public static final String PROP_IS_LOADED = "is_loaded"; //$NON-NLS-1$
/**
* The label provider delegate. This VM node will delegate label updates to this provider
* which can be created by sub-classes.
*
* @since 2.0
*/
private IElementLabelProvider fLabelProvider;
/**
* Creates the label provider delegate. This VM node will delegate label
* updates to this provider which can be created by sub-classes.
*
* @return Returns the label provider for this node.
*
* @since 2.0
*/
protected IElementLabelProvider createLabelProvider() {
PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider();
provider.setColumnInfo(
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText(MessagesForModulesVM.ModulesVMNode_No_columns__text_format, new String[] { PROP_NAME }),
new DsfUILabelImage(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_LOADED) {
{ setPropertyNames(new String[] { PROP_IS_LOADED }); }
@Override
public boolean checkProperty(String propertyName, IStatus status, Map<String,Object> properties) {
if (PROP_IS_LOADED.equals(propertyName)) {
return Boolean.TRUE.equals( properties.get(propertyName) );
}
return super.checkProperty(propertyName, status, properties);
};
},
new DsfUILabelImage(IDsfDebugUIConstants.IMG_OBJS_SHARED_LIBRARY_SYMBOLS_UNLOADED),
new StaleDataLabelBackground(),
new LabelFont(JFaceResources.getFontDescriptor(IDebugUIConstants.PREF_VARIABLE_TEXT_FONT).getFontData()[0])
}));
return provider;
}
public ModulesVMNode(AbstractDMVMProvider provider, DsfSession session) {
super(provider, session, IModuleDMContext.class);
fLabelProvider = createLabelProvider();
}
@Override
public String toString() {
return "ModulesVMNode(" + getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
IModules modulesService = getServicesTracker().getService(IModules.class);
final ISymbolDMContext symDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), ISymbolDMContext.class) ;
if (modulesService == null || symDmc == null) {
handleFailedUpdate(update);
return;
}
modulesService.getModules(
symDmc,
new ViewerDataRequestMonitor<IModuleDMContext[]>(getSession().getExecutor(), update) {
@Override
public void handleCompleted() {
if (!isSuccess()) {
update.done();
return;
}
fillUpdateWithVMCs(update, getData());
update.done();
}});
}
@Override
protected IDMVMContext createVMContext(IDMContext dmc) {
return new ModuleVMContext(dmc);
}
/*
* @since 2.0
*/
@Override
public void update(final IPropertiesUpdate[] updates) {
try {
getSession().getExecutor().execute(new DsfRunnable() {
@Override
public void run() {
updatePropertiesInSessionThread(updates);
}});
} catch (RejectedExecutionException e) {
for (IPropertiesUpdate update : updates) {
handleFailedUpdate(update);
}
}
}
@Override
public void update(final ILabelUpdate[] updates) {
fLabelProvider.update(updates);
}
/**
* @since 2.0
*/
@ConfinedToDsfExecutor("getSession().getExecutor()")
protected void updatePropertiesInSessionThread(final IPropertiesUpdate[] updates) {
IModules modulesService = getServicesTracker().getService(IModules.class);
for (final IPropertiesUpdate update : updates) {
final IModuleDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IModuleDMContext.class);
// If either update or service are not valid, fail the update and exit.
if ( modulesService == null || dmc == null ) {
handleFailedUpdate(update);
return;
}
modulesService.getModuleData(
dmc,
new ViewerDataRequestMonitor<IModuleDMData>(getSession().getExecutor(), update) {
@Override
protected void handleSuccess() {
fillModuleDataProperties(update, getData());
update.done();
}
});
}
}
/**
* @since 2.0
*/
protected void fillModuleDataProperties(IPropertiesUpdate update, IModuleDMData data) {
update.setProperty(PROP_NAME, data.getName());
update.setProperty(PROP_IS_LOADED, data.isSymbolsLoaded());
}
@Override
public int getDeltaFlags(Object e) {
if (e instanceof IRunControl.ISuspendedDMEvent) {
return IModelDelta.CONTENT;
}
return IModelDelta.NO_CHANGE;
}
@Override
public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset, RequestMonitor rm) {
if (e instanceof IRunControl.ISuspendedDMEvent) {
// Create a delta that indicates all groups have changed
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
}
rm.done();
}
}