/*******************************************************************************
* Copyright (c) 2006-2007, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
******************************************************************************/
package org.eclipse.buckminster.jnlp.wizard;
import static org.eclipse.buckminster.jnlp.MaterializationConstants.ERROR_CODE_BOM_IO_EXCEPTION;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Pattern;
import org.eclipse.buckminster.core.cspec.ICSpecData;
import org.eclipse.buckminster.core.cspec.model.ComponentName;
import org.eclipse.buckminster.core.cspec.model.ComponentRequest;
import org.eclipse.buckminster.core.helpers.SmartArrayList;
import org.eclipse.buckminster.core.metadata.model.BOMNode;
import org.eclipse.buckminster.core.metadata.model.BillOfMaterials;
import org.eclipse.buckminster.core.metadata.model.Resolution;
import org.eclipse.buckminster.core.mspec.builder.MaterializationNodeBuilder;
import org.eclipse.buckminster.core.mspec.builder.MaterializationSpecBuilder;
import org.eclipse.buckminster.jnlp.JNLPException;
import org.eclipse.buckminster.jnlp.MaterializationUtils;
import org.eclipse.buckminster.jnlp.Messages;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TreeEvent;
import org.eclipse.swt.events.TreeListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
/**
* @author Karel Brezina
*
*/
public class MSpecDetailsPanel implements IUnresolvedNodeHandler
{
class LabelProvider implements ILabelProvider
{
List<ILabelProviderListener> m_listeners = new ArrayList<ILabelProviderListener>();
private static final String ICON_RESOLVED = "node.resolved.gif"; //$NON-NLS-1$
private static final String ICON_UNRESOLVED = "node.unresolved.gif"; //$NON-NLS-1$
private static final String ICON_UNRESOLVED_CHILD = "node.resolved_warning.gif"; //$NON-NLS-1$
private final Image m_iconResolved = MaterializationUtils.getImage(ICON_RESOLVED);
private final Image m_iconUnresolved = MaterializationUtils.getImage(ICON_UNRESOLVED);
private final Image m_iconUnresolvedChild = MaterializationUtils.getImage(ICON_UNRESOLVED_CHILD);
public void addListener(ILabelProviderListener listener)
{
m_listeners.add(listener);
}
public void dispose()
{
// nothing
}
public Image getImage(Object element)
{
TreeNode treeNode = (TreeNode)element;
switch(treeNode.getHandler().getResolveStatus())
{
case RESOLVED:
return m_iconResolved;
case UNRESOLVED:
return m_iconUnresolved;
case UNRESOLVED_CHILD:
return m_iconUnresolvedChild;
default:
return null;
}
}
public String getText(Object element)
{
TreeNode treeNode = (TreeNode)element;
return treeNode.getHandler().getComponentShortDescription();
}
public boolean isLabelProperty(Object element, String property)
{
return false;
}
public void removeListener(ILabelProviderListener listener)
{
m_listeners.remove(listener);
}
}
class MaterializationNodeHandler
{
private MaterializationNodeBuilder m_node;
private ComponentRequest m_request;
private ICSpecData m_cspec;
private List<TreeNode> m_cloneItems = new ArrayList<TreeNode>();
private ResolveStatus m_resolveStatus;
public MaterializationNodeHandler(List<MaterializationNodeBuilder> nodes, MaterializationNodeBuilder node,
ComponentRequest request, ICSpecData cspec, boolean resolved)
{
m_node = node;
nodes.add(node);
m_request = request;
m_cspec = cspec;
if(resolved)
m_resolveStatus = ResolveStatus.RESOLVED;
else
{
m_resolveStatus = ResolveStatus.UNRESOLVED;
}
}
public TreeNode createTreeNodeClone(TreeNode parentTreeNode)
{
TreeNode treeNode = null;
Map<MaterializationNodeHandler, TreeNode> map = m_treeNodeCache.get(this);
if(map != null && parentTreeNode.getHandler() != null)
{
treeNode = map.get(parentTreeNode.getHandler());
}
if(treeNode == null)
{
treeNode = new TreeNode(this, parentTreeNode, !m_node.isExclude());
if(parentTreeNode.getHandler() != null)
{
if(map == null)
{
map = new HashMap<MaterializationNodeHandler, TreeNode>();
m_treeNodeCache.put(this, map);
}
map.put(parentTreeNode.getHandler(), treeNode);
}
m_cloneItems.add(treeNode);
}
else
{
parentTreeNode.addChild(treeNode);
treeNode.addUncle(parentTreeNode);
}
if(m_resolveStatus == ResolveStatus.UNRESOLVED || m_resolveStatus == ResolveStatus.UNRESOLVED_CHILD)
{
Set<TreeNode> visitedNodes = new HashSet<TreeNode>();
setParentToUnresolvedChild(parentTreeNode, visitedNodes);
}
return treeNode;
}
public String getComponentDescription()
{
SmartArrayList<String> smartList = new SmartArrayList<String>();
if(m_cspec != null)
{
if(m_resolveStatus == ResolveStatus.UNRESOLVED_CHILD)
smartList.add(Messages.uppercase_depends_on_an_unresolved_artifact);
if(m_cspec.getShortDesc() != null)
{
smartList.add(Messages.description_with_colon + m_cspec.getShortDesc());
}
if(m_cspec.getComponentIdentifier().getName() != null)
{
smartList.add(Messages.nema_with_colon + m_cspec.getComponentIdentifier().getName());
}
if(m_cspec.getComponentIdentifier().getComponentTypeID() != null)
{
smartList.add(Messages.metadata_extractor_with_colon
+ MaterializationUtils.getHumanReadableComponentType(m_cspec.getComponentIdentifier()
.getComponentTypeID()));
}
if(m_cspec.getVersion() != null)
{
smartList.add(Messages.version_with_colon + m_cspec.getVersion());
}
if(m_node.getInstallLocation() != null)
{
smartList.add(Messages.destination_address_with_colon
+ m_node.getInstallLocation().removeTrailingSeparator().toOSString());
}
if(m_node.getConflictResolution() != null)
{
smartList.add(Messages.conflict_resolution_with_colon + m_node.getConflictResolution());
}
}
else
{
smartList.add(Messages.uppercase_unresolved_artifact);
smartList.add(Messages.requested_name_with_colon + m_request.getName());
smartList.add(Messages.requested_metadata_extractor_with_colon
+ MaterializationUtils.getHumanReadableComponentType(m_request.getComponentTypeID()));
smartList.add(Messages.requested_version_with_colon + (m_request.getVersionDesignator() == null
? Messages.any
: m_request.getVersionDesignator()));
}
return smartList.toString("\n"); //$NON-NLS-1$
}
public String getComponentShortDescription()
{
if(m_cspec == null)
return m_request.getName()
+ "/" + MaterializationUtils.getHumanReadableComponentType(m_request.getComponentTypeID()); //$NON-NLS-1$
return (m_cspec.getShortDesc() == null
? m_cspec.getComponentIdentifier().getName()
: m_cspec.getShortDesc())
+ "/" + MaterializationUtils.getHumanReadableComponentType(m_cspec.getComponentIdentifier().getComponentTypeID()); //$NON-NLS-1$
}
public MaterializationNodeBuilder getNodeBuilder()
{
return m_node;
}
public ResolveStatus getResolveStatus()
{
return m_resolveStatus;
}
public List<TreeNode> getTreeNodeClones()
{
return m_cloneItems;
}
public boolean isExclude()
{
return m_node.isExclude();
}
public void setExclude(boolean exclude)
{
m_node.setExclude(exclude);
for(TreeNode tn : m_cloneItems)
{
tn.setChecked(!exclude);
}
}
public boolean setExcludeAccordingToClonesCheckConflicts(boolean checked)
{
boolean totalAnd = true;
boolean totalOr = false;
for(TreeNode tn : m_cloneItems)
{
boolean nodeChecked = tn.isChecked();
totalAnd = totalAnd && nodeChecked;
totalOr = totalOr || nodeChecked;
if(totalAnd != totalOr)
break;
}
// all clones have the same check status
if(totalAnd == totalOr)
{
setExclude(!totalAnd);
return false;
}
setExclude(false);
if(!checked)
rollbackChecked(); // subtree needs to be rollbacked
return true;
}
public void setUnresolvedChild()
{
if(m_resolveStatus != ResolveStatus.UNRESOLVED)
m_resolveStatus = ResolveStatus.UNRESOLVED_CHILD;
}
private void rollbackChecked()
{
Set<TreeNode> visitedNodes = new HashSet<TreeNode>();
for(TreeNode nodeClone : m_cloneItems)
for(TreeNode childClone : nodeClone.getChildren())
rollbackSubtreeChecked(childClone, visitedNodes);
}
private void rollbackSubtreeChecked(TreeNode node, Set<TreeNode> visitedNodes)
{
if(visitedNodes.contains(node))
return;
node.setChecked(node.isOldChecked());
visitedNodes.add(node);
for(TreeNode child : node.getChildren())
rollbackSubtreeChecked(child, visitedNodes);
}
private void setParentToUnresolvedChild(TreeNode treeNode, Set<TreeNode> visitedNodes)
{
if(visitedNodes.contains(treeNode))
return;
visitedNodes.add(treeNode);
MaterializationNodeHandler handler = treeNode.getHandler();
if(handler == null)
return;
if(handler.getResolveStatus() == ResolveStatus.UNRESOLVED
|| handler.getResolveStatus() == ResolveStatus.UNRESOLVED_CHILD)
return;
handler.setUnresolvedChild();
for(TreeNode clone : handler.getTreeNodeClones())
{
setParentToUnresolvedChild(clone.getParent(), visitedNodes);
}
}
}
class TreeContentProvider implements ITreeContentProvider
{
public void dispose()
{
// nothing
}
public Object[] getChildren(Object parentElement)
{
TreeNode treeNode = (TreeNode)parentElement;
return treeNode.getChildren().toArray();
}
public Object[] getElements(Object inputElement)
{
return getChildren(inputElement);
}
public Object getParent(Object element)
{
TreeNode treeNode = (TreeNode)element;
return treeNode.getParent();
}
public boolean hasChildren(Object element)
{
TreeNode treeNode = (TreeNode)element;
return treeNode.getChildren().size() > 0;
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
// nothing
}
}
class TreeNode
{
private MaterializationNodeHandler m_handler;
private TreeNode m_parent;
private Set<TreeNode> m_uncles = new HashSet<TreeNode>(); // secondary parents
private List<TreeNode> m_children = new ArrayList<TreeNode>();
private boolean m_checked;
private boolean m_oldChecked;
public TreeNode(MaterializationNodeHandler handler, TreeNode parentTreeNode, boolean checked)
{
m_handler = handler;
m_parent = parentTreeNode;
m_checked = checked;
m_oldChecked = false;
if(m_parent != null)
m_parent.addChild(this);
}
public void addChild(TreeNode node)
{
if(!m_children.contains(node))
m_children.add(node);
}
public void addUncle(TreeNode parentTreeNode)
{
m_uncles.add(parentTreeNode);
}
public List<TreeNode> getChildren()
{
return m_children;
}
public MaterializationNodeHandler getHandler()
{
return m_handler;
}
public TreeNode getParent()
{
return m_parent;
}
public boolean isChecked()
{
return m_checked;
}
public boolean isOldChecked()
{
return m_oldChecked;
}
public void setChecked(boolean checked)
{
m_checked = checked;
}
public void setOldChecked(boolean checked)
{
m_oldChecked = checked;
}
}
private enum ResolveStatus
{
RESOLVED, UNRESOLVED, UNRESOLVED_CHILD
}
private Map<MaterializationNodeHandler, Map<MaterializationNodeHandler, TreeNode>> m_treeNodeCache = new HashMap<MaterializationNodeHandler, Map<MaterializationNodeHandler, TreeNode>>();
private final static String TOOL_TIP_UNPACK = Messages.unpack_component_after_materialization;
private MaterializationSpecBuilder m_mspec;
private BillOfMaterials m_bom;
private List<MaterializationNodeBuilder> m_originalNodeBuilders;
private String m_defaultInstallLocation;
private DestinationForm m_destinationForm;
private boolean m_showBrowseButtons;
private CheckboxTreeViewer m_treeViewer;
private TreeNode m_treeRoot;
private Set<TreeItem> m_expandedTreeItems = new HashSet<TreeItem>();
private MaterializationNodeBuilder m_selectedNodeBuilder;
private DestinationForm m_detailDestForm;
private Button m_unpackCheckBox;
private Map<ComponentName, MaterializationNodeHandler> m_componentMap = new HashMap<ComponentName, MaterializationNodeHandler>();
private Set<MaterializationNodeHandler> m_unresolved = new HashSet<MaterializationNodeHandler>();
public MSpecDetailsPanel(MaterializationSpecBuilder mspec, String defaultInstallLocation, boolean showBrowseButtons)
{
m_mspec = mspec;
m_defaultInstallLocation = defaultInstallLocation;
m_showBrowseButtons = showBrowseButtons;
}
public Control createControl(Composite parent)
{
Composite pageComposite = new Composite(parent, SWT.NONE);
pageComposite.setLayout(new GridLayout(3, false));
pageComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
m_destinationForm = new DestinationForm(m_mspec, m_defaultInstallLocation, true, false, true, false,
m_showBrowseButtons);
m_destinationForm.createControl(pageComposite);
new Label(pageComposite, SWT.NONE);
new Label(pageComposite, SWT.NONE);
new Label(pageComposite, SWT.NONE);
Group treeGroup = new Group(pageComposite, SWT.NONE);
treeGroup.setText(Messages.components_for_materialization);
treeGroup.setLayout(new GridLayout(2, true));
GridData data = new GridData(GridData.FILL_BOTH);
data.horizontalSpan = 3;
treeGroup.setLayoutData(data);
m_treeViewer = new CheckboxTreeViewer(treeGroup, SWT.BORDER);
final Tree tree = m_treeViewer.getTree();
data = new GridData(GridData.FILL_BOTH);
data.horizontalSpan = 1;
tree.setLayoutData(data);
m_treeViewer.setContentProvider(new TreeContentProvider());
m_treeViewer.setLabelProvider(new LabelProvider());
m_treeViewer.setInput(null);
tree.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
TreeNode node = (TreeNode)e.item.getData();
MaterializationNodeHandler handler = node.getHandler();
if(e.detail == SWT.NONE)
{
m_selectedNodeBuilder = handler.getNodeBuilder();
m_detailDestForm.setBuilder(m_selectedNodeBuilder);
m_detailDestForm.update();
m_unpackCheckBox.setSelection(m_selectedNodeBuilder.isUnpack());
setEnableDetails(!handler.isExclude());
}
else if(e.detail == SWT.CHECK)
{
boolean checked = !node.isChecked();
handler.setExclude(!checked);
Set<TreeNode> visitedNodes = new HashSet<TreeNode>();
for(TreeNode nodeClone : handler.getTreeNodeClones())
setCheckedSubtree(nodeClone, checked, visitedNodes);
// the second run is just for one clone - they are identical
TreeNode nodeClone = handler.getTreeNodeClones().get(0);
visitedNodes = new HashSet<TreeNode>();
if(nodeClone != null && checkAndRepairSubtreeCloneConflicts(nodeClone, visitedNodes, checked))
if(!checked)
// TODO display warning - some components are used in a different subtree - you can uncheck
// them manually
;
setupVisibleCheckboxes();
// enable / disable details for current selection
if(m_treeViewer.getTree().getSelectionCount() == 1)
setEnableDetails(!((TreeNode)m_treeViewer.getTree().getSelection()[0].getData()).getHandler()
.isExclude());
}
}
private boolean checkAndRepairSubtreeCloneConflicts(TreeNode node, Set<TreeNode> visitedNodes,
boolean checked)
{
if(visitedNodes.contains(node))
return false; // don't care about the original conflict status - if it was originally TRUE, TRUE
// gets to the top anyway
visitedNodes.add(node);
boolean conflict = false;
MaterializationNodeHandler handler = node.getHandler();
conflict = conflict || handler.setExcludeAccordingToClonesCheckConflicts(checked);
for(TreeNode child : node.getChildren())
{
boolean newConflict = checkAndRepairSubtreeCloneConflicts(child, visitedNodes, checked);
conflict = conflict || newConflict;
}
return conflict;
}
private void setCheckedSubtree(TreeNode node, boolean checked, Set<TreeNode> visitedNodes)
{
if(visitedNodes.contains(node))
return;
node.setOldChecked(node.isChecked());
node.setChecked(checked);
visitedNodes.add(node);
for(TreeNode child : node.getChildren())
setCheckedSubtree(child, checked, visitedNodes);
}
});
tree.addMouseTrackListener(new MouseTrackAdapter()
{
@Override
public void mouseExit(MouseEvent e)
{
tree.setToolTipText(null);
}
@Override
public void mouseHover(MouseEvent e)
{
TreeItem item = tree.getItem(new Point(e.x, e.y));
String toolTipText = null;
if(item != null)
{
toolTipText = ((TreeNode)item.getData()).getHandler().getComponentDescription();
}
tree.setToolTipText(toolTipText);
}
});
tree.addTreeListener(new TreeListener()
{
public void treeCollapsed(TreeEvent e)
{
m_expandedTreeItems.remove(e.item);
}
public void treeExpanded(TreeEvent e)
{
m_expandedTreeItems.add((TreeItem)e.item);
setupVisibleCheckboxes();
}
});
Composite detailsComposite = new Composite(treeGroup, SWT.NONE);
GridLayout gridLayout = new GridLayout(3, false);
gridLayout.marginHeight = gridLayout.marginWidth = 0;
detailsComposite.setLayout(gridLayout);
detailsComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
Label headerLabel = new Label(detailsComposite, SWT.BOLD);
headerLabel.setText(Messages.override_with_colon);
headerLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_BLUE));
GridData gridData = new GridData();
gridData.horizontalSpan = 3;
headerLabel.setLayoutData(gridData);
m_detailDestForm = new DestinationForm(null, "", true, true, true, true, m_showBrowseButtons); //$NON-NLS-1$
m_detailDestForm.createControl(detailsComposite);
Label label = new Label(detailsComposite, SWT.NONE);
label.setText(Messages.unpack_component_with_colon);
label.setToolTipText(TOOL_TIP_UNPACK);
m_unpackCheckBox = new Button(detailsComposite, SWT.CHECK);
m_unpackCheckBox.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
if(m_selectedNodeBuilder != null)
m_selectedNodeBuilder.setUnpack(m_unpackCheckBox.getSelection());
}
});
m_unpackCheckBox.setToolTipText(TOOL_TIP_UNPACK);
new Label(detailsComposite, SWT.NONE);
setEnableDetails(false);
return pageComposite;
}
public void excludeUnresolvedNodes()
{
for(MaterializationNodeHandler handler : m_unresolved)
handler.setExclude(true);
setupVisibleCheckboxes();
}
/*
* Initializes tree and creates new MSpec nodes. This has to be called even if the Advanced Page is not needed,
* because it excludes cssite components from materialization.
*/
public void initializeMSpecTree(BillOfMaterials bom)
{
m_bom = bom;
m_originalNodeBuilders = new ArrayList<MaterializationNodeBuilder>();
m_originalNodeBuilders.addAll(m_mspec.getNodeBuilders());
initializeTree();
}
public boolean isUnresolvedNodeIncluded()
{
for(MaterializationNodeHandler handler : m_unresolved)
{
if(!handler.getNodeBuilder().isExclude())
return true;
}
return false;
}
public void update()
{
m_destinationForm.update();
if(m_treeViewer.getInput() == null)
{
m_treeViewer.setInput(m_treeRoot);
m_treeViewer.setExpandedElements(m_treeRoot.getChildren().toArray());
// add the root TreeItems
m_expandedTreeItems.addAll(Arrays.asList(m_treeViewer.getTree().getItems()));
setupVisibleCheckboxes();
}
}
private void addChildrenItems(TreeNode parentTN, BOMNode parentDN) throws CoreException
{
for(BOMNode bomNode : getSortedChildren(parentDN))
{
MaterializationNodeHandler handler = getHandler(bomNode);
if(handler != null)
{
TreeNode treeNode = handler.createTreeNodeClone(parentTN);
addChildrenItems(treeNode, bomNode);
}
}
}
private MaterializationNodeHandler getHandler(BOMNode bomNode) throws CoreException
{
Resolution resolution = bomNode.getResolution();
ComponentName componentNameId;
if(resolution == null)
componentNameId = bomNode.getRequest();
else
componentNameId = resolution.getComponentIdentifier();
MaterializationNodeHandler handler = m_componentMap.get(componentNameId);
if(handler == null)
{
ICSpecData cspec = null;
if(resolution != null)
cspec = resolution.getCSpec();
String componentName;
String componentType;
if(cspec != null)
{
componentName = cspec.getName();
componentType = cspec.getComponentTypeID();
}
else
{
componentName = bomNode.getRequest().getName();
componentType = bomNode.getRequest().getComponentTypeID();
}
MaterializationNodeBuilder nodeBuilder = new MaterializationNodeBuilder();
for(MaterializationNodeBuilder origNodeBuilder : m_originalNodeBuilders)
{
if(origNodeBuilder.getNamePattern().matcher(componentName).matches()
&& (origNodeBuilder.getComponentTypeID() == null || origNodeBuilder.getComponentTypeID()
.equals(componentType)))
{
nodeBuilder.initFrom(origNodeBuilder.createMaterializationNode());
break;
}
}
nodeBuilder.setNamePattern(Pattern.compile("^\\Q" + componentName + "\\E$")); //$NON-NLS-1$ //$NON-NLS-2$
if(nodeBuilder.getInstallLocation() != null)
nodeBuilder.setInstallLocation(MaterializationUtils.expandPath(m_mspec, nodeBuilder
.getInstallLocation()));
if(componentType != null)
nodeBuilder.setComponentTypeID(componentType);
handler = new MaterializationNodeHandler(m_mspec.getNodeBuilders(), nodeBuilder, bomNode.getRequest(),
cspec, bomNode.getResolution() != null);
m_componentMap.put(componentNameId, handler);
if(bomNode.getResolution() == null)
m_unresolved.add(handler);
}
return handler;
}
private Collection<BOMNode> getSortedChildren(BOMNode parent) throws CoreException
{
Collection<BOMNode> children = parent.getChildren();
if(children.size() > 1)
{
Map<String, BOMNode> sortedMap = new TreeMap<String, BOMNode>();
for(BOMNode child : children)
{
Resolution resolution = child.getResolution();
String componentId;
if(resolution != null)
componentId = resolution.getComponentIdentifier().toString();
else
componentId = child.getRequest().toString();
sortedMap.put(componentId, child);
}
children = sortedMap.values();
}
return children;
}
private boolean hasUnresolvedChild(TreeNode node, Set<TreeNode> visitedNodes)
{
if(visitedNodes.contains(node))
return false;
visitedNodes.add(node);
boolean unresolvedChild = false;
for(TreeNode child : node.getChildren())
{
if(hasUnresolvedChild(child, visitedNodes))
{
unresolvedChild = true;
child.getHandler().setUnresolvedChild();
}
}
return unresolvedChild;
}
private void initializeTree()
{
m_mspec.getNodes().clear();
m_componentMap.clear();
m_unresolved.clear();
m_treeRoot = new TreeNode(null, null, false);
try
{
MaterializationNodeHandler handler = getHandler(m_bom);
if(handler != null)
{
TreeNode treeNode = handler.createTreeNodeClone(m_treeRoot);
addChildrenItems(treeNode, m_bom);
// set unresolved child nodes
Set<TreeNode> visitedNodes = new HashSet<TreeNode>();
hasUnresolvedChild(m_treeRoot, visitedNodes);
}
}
catch(CoreException e)
{
throw new JNLPException(
Messages.error_while_reading_artifact_specification_bill_of_materials_can_not_be_read,
ERROR_CODE_BOM_IO_EXCEPTION, e);
}
}
private void setEnableDetails(boolean enabled)
{
m_detailDestForm.setEnabled(enabled);
m_unpackCheckBox.setEnabled(enabled);
}
private void setupVisibleCheckboxes()
{
Set<TreeItem> elements = new HashSet<TreeItem>();
for(TreeItem item : m_expandedTreeItems)
{
elements.add(item);
elements.addAll(Arrays.asList(item.getItems()));
}
for(TreeItem item : elements)
{
item.setChecked(((TreeNode)item.getData()).isChecked());
}
}
}