/******************************************************************************* * Copyright (c) 2007, 2011 Wind River Systems, Inc. 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 *******************************************************************************/ package org.eclipse.tcf.internal.debug.ui.model; import java.util.HashMap; import java.util.Map; import org.eclipse.tcf.protocol.IToken; import org.eclipse.tcf.services.IMemory; import org.eclipse.tcf.services.IRunControl; import org.eclipse.tcf.util.TCFDataCache; /** * This class is used to maintain a dynamic list of both executable contexts and memory spaces * that are children of a given parent context. The job is slightly complicated by necessity * to merge results from two independent services. */ public class TCFChildrenExecContext extends TCFChildren { private final TCFChildren mem_children; private final TCFChildren run_children; TCFChildrenExecContext(final TCFNode node) { super(node); mem_children = new TCFChildren(node) { @Override protected boolean startDataRetrieval() { IMemory mem = node.model.getLaunch().getService(IMemory.class); if (mem == null) { set(null, null, new HashMap<String,TCFNode>()); return true; } assert command == null; command = mem.getChildren(node.id, new IMemory.DoneGetChildren() { public void doneGetChildren(IToken token, Exception error, String[] contexts) { Map<String,TCFNode> data = null; if (command == token && error == null) { int cnt = 0; data = new HashMap<String,TCFNode>(); for (String id : contexts) { TCFNode n = node.model.getNode(id); if (n == null) n = new TCFNodeExecContext(node, id); ((TCFNodeExecContext)n).setMemSeqNo(cnt++); assert n.parent == node; data.put(id, n); } } set(token, error, data); } }); return false; } }; run_children = new TCFChildren(node) { @Override protected boolean startDataRetrieval() { IRunControl run = node.model.getLaunch().getService(IRunControl.class); if (run == null) { set(null, null, new HashMap<String,TCFNode>()); return true; } assert command == null; command = run.getChildren(node.id, new IRunControl.DoneGetChildren() { public void doneGetChildren(IToken token, Exception error, String[] contexts) { Map<String,TCFNode> data = null; if (command == token && error == null) { int cnt = 0; data = new HashMap<String,TCFNode>(); for (String id : contexts) { TCFNode n = node.model.getNode(id); if (n == null) n = new TCFNodeExecContext(node, id); ((TCFNodeExecContext)n).setExeSeqNo(cnt++); assert n.parent == node; data.put(id, n); } } set(token, error, data); } }); return false; } }; } @Override protected boolean startDataRetrieval() { TCFDataCache<?> pending = null; if (!mem_children.validate()) pending = mem_children; if (!run_children.validate()) pending = run_children; if (pending != null) { pending.wait(this); return false; } Throwable error = mem_children.getError(); if (error == null) error = run_children.getError(); Map<String,TCFNode> data = new HashMap<String,TCFNode>(); Map<String,TCFNode> m1 = mem_children.getData(); Map<String,TCFNode> m2 = run_children.getData(); if (m1 != null) data.putAll(m1); if (m2 != null) data.putAll(m2); set(null, error, data); return true; } void onContextAdded(IRunControl.RunControlContext context) { // To preserve children order need to reset children list. reset(); run_children.reset(); mem_children.reset(); assert !node.isDisposed(); String id = context.getID(); TCFNodeExecContext n = (TCFNodeExecContext)node.model.getNode(id); if (n == null) { n = new TCFNodeExecContext(node, id); n.postContextAddedDelta(); add(n); } else { n.postAllChangedDelta(); } run_children.add(n); n.setRunContext(context); } void onContextAdded(IMemory.MemoryContext context) { // To preserve children order need to reset children list. reset(); run_children.reset(); mem_children.reset(); assert !node.isDisposed(); String id = context.getID(); TCFNodeExecContext n = (TCFNodeExecContext)node.model.getNode(id); if (n == null) { n = new TCFNodeExecContext(node, id); n.postContextAddedDelta(); add(n); } else { n.postAllChangedDelta(); } mem_children.add(n); n.setMemoryContext(context); } void onAncestorContextChanged() { for (TCFNode n : getNodes()) ((TCFNodeExecContext)n).onAncestorContextChanged(); } }