/* * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.osgi.bnd.resolve; import com.intellij.icons.AllIcons; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.LayeredIcon; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.components.JBList; import com.intellij.ui.treeStructure.Tree; import icons.OsmorcIdeaIcons; import org.jetbrains.annotations.NotNull; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.framework.namespace.PackageNamespace; import org.osgi.namespace.contract.ContractNamespace; import org.osgi.namespace.extender.ExtenderNamespace; import org.osgi.namespace.implementation.ImplementationNamespace; import org.osgi.namespace.service.ServiceNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Resource; import org.osgi.resource.Wire; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; public class ResolveConfirm { private JPanel myContentPane; private JBList<Resource> myRequiredResources; private Tree myReason; private static final Icon OSGI_BUNDLE_ICON; static { LayeredIcon icon = new LayeredIcon(2); icon.setIcon(AllIcons.Nodes.PpLib, 0); Icon osgiSmall = new LayeredIcon(OsmorcIdeaIcons.Osgi).scale(0.5f); icon.setIcon(osgiSmall, 1, SwingConstants.SOUTH_EAST); OSGI_BUNDLE_ICON = icon; } public ResolveConfirm(Map<Resource, List<Wire>> resolveResult) { DefaultListModel<Resource> requiredResourcesModel = new DefaultListModel<>(); resolveResult.keySet().stream() .sorted() .forEach(requiredResourcesModel::addElement); DefaultTreeModel reasonModel = new DefaultTreeModel(new DefaultMutableTreeNode()); myReason.setModel(reasonModel); myRequiredResources.setModel(requiredResourcesModel); myRequiredResources.addListSelectionListener(event -> { Resource selectedResource = myRequiredResources.getSelectedValue(); updateReasonModel(resolveResult, reasonModel, selectedResource); }); myRequiredResources.setCellRenderer(new ColoredListCellRenderer<Resource>() { @Override protected void customizeCellRenderer(@NotNull JList list, Resource resource, int index, boolean selected, boolean hasFocus) { setIcon(OSGI_BUNDLE_ICON); List<Capability> capabilities = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE); if (capabilities.size() == 1) { Capability capability = capabilities.get(0); String identity = Objects.toString(capability.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE)); Object version = capability.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE); append(identity, SimpleTextAttributes.REGULAR_ATTRIBUTES, true); if (version != null) { append(", version ", SimpleTextAttributes.GRAYED_ATTRIBUTES, true); append(version.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES, true); } } else { append(resource.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES, true); } } }); myReason.setCellRenderer(new ColoredTreeCellRenderer() { @Override public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; Object userObject = node.getUserObject(); if (userObject instanceof Capability) { Capability capability = (Capability)userObject; String identity = Objects.toString(capability.getAttributes().get(capability.getNamespace())); Object version = capability.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE); append(((Capability)userObject).getNamespace(), SimpleTextAttributes.GRAYED_ATTRIBUTES, true); append("=", SimpleTextAttributes.GRAYED_ATTRIBUTES, true); append(identity, SimpleTextAttributes.REGULAR_ATTRIBUTES, true); if (version != null) { append(", version ", SimpleTextAttributes.GRAYED_ATTRIBUTES , true); append(version.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES, true); } switch (capability.getNamespace()) { case PackageNamespace.PACKAGE_NAMESPACE: setIcon(AllIcons.Nodes.Package); break; case IdentityNamespace.IDENTITY_NAMESPACE: setIcon(OSGI_BUNDLE_ICON); break; case ContractNamespace.CONTRACT_NAMESPACE: case ImplementationNamespace.IMPLEMENTATION_NAMESPACE: case ExtenderNamespace.EXTENDER_NAMESPACE: case ServiceNamespace.SERVICE_NAMESPACE: setIcon(OsmorcIdeaIcons.Osgi); break; } } else if (userObject instanceof Resource) { Resource resource = (Resource)userObject; setIcon(null); List<Capability> list = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE); if (list.size() == 1) { Capability capability = list.get(0); String identity = Objects.toString(capability.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE)); Object version = capability.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE); append("REQUIRED BY: ", SimpleTextAttributes.GRAYED_ATTRIBUTES, true); append(identity, SimpleTextAttributes.REGULAR_ATTRIBUTES, true); if (version != null) { append(", version ", SimpleTextAttributes.GRAYED_ATTRIBUTES , true); append(version.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES, true); } } else { append("REQUIRED BY: " + resource.toString(), SimpleTextAttributes.REGULAR_ATTRIBUTES, true); } } else { setIcon(null); append(Objects.toString(userObject), SimpleTextAttributes.REGULAR_ATTRIBUTES, true); } } }); } private static void updateReasonModel(Map<Resource, List<Wire>> resolve, DefaultTreeModel reasonModel, Resource selectedResource) { DefaultMutableTreeNode root = new DefaultMutableTreeNode(); if (selectedResource != null) { addRequirer(root, selectedResource, resolve); } reasonModel.setRoot(root); } private static void addRequirer(DefaultMutableTreeNode root, Resource resource, Map<Resource, List<Wire>> resolve) { List<Wire> wires = resolve.get(resource); if (wires == null) return; Map<Capability, DefaultMutableTreeNode> map = new HashMap<>(); wires.forEach(wire -> { DefaultMutableTreeNode requirement = map.computeIfAbsent(wire.getCapability(), DefaultMutableTreeNode::new); DefaultMutableTreeNode child = new DefaultMutableTreeNode(wire.getRequirer()); requirement.add(child); addRequirer(child, wire.getRequirer(), resolve); }); map.values().forEach(root::add); } public JPanel getContentPane() { return myContentPane; } }