Bug 313392 - Support Import operations on 'Plug-in Dependencies' entries
in Project and Package Explorer

Merge branch '313392_import_pkg_exp'

Conflicts:
	ui/org.eclipse.pde.ui/plugin.xml
diff --git a/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
index fd88cad..72c46e7 100644
--- a/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
@@ -76,7 +76,8 @@
  org.eclipse.equinox.p2.repository;bundle-version="[2.0.0,3.0.0]",
  org.eclipse.equinox.p2.metadata.repository;bundle-version="[1.0.100,2.0.0)",
  org.eclipse.equinox.p2.garbagecollector;bundle-version="[1.0.100,2.0.0)",
- org.eclipse.equinox.p2.touchpoint.eclipse;bundle-version="[2.0.0,3.0.0)"
+ org.eclipse.equinox.p2.touchpoint.eclipse;bundle-version="[2.0.0,3.0.0)",
+ org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)"
 Eclipse-LazyStart: true
 Bundle-RequiredExecutionEnvironment: J2SE-1.4
 Import-Package: com.ibm.icu.util
diff --git a/ui/org.eclipse.pde.core/plugin.xml b/ui/org.eclipse.pde.core/plugin.xml
index e7362b5..8bd40b5 100644
--- a/ui/org.eclipse.pde.core/plugin.xml
+++ b/ui/org.eclipse.pde.core/plugin.xml
@@ -353,4 +353,14 @@
       <factory class="org.eclipse.pde.internal.core.content.DefaultDocumentFactory"
                contentTypeId="org.eclipse.pde.schema"/>
     </extension>
+    <extension
+         point="org.eclipse.core.expressions.propertyTesters">
+      <propertyTester
+            class="org.eclipse.pde.internal.core.util.PackageFragmentRootPropertyTester"
+            id="org.eclipse.pde.core.packageFragmentRoot"
+            namespace="org.eclipse.pde.core"
+            properties="inPluginContainer"
+            type="org.eclipse.jdt.core.IPackageFragmentRoot">
+      </propertyTester>
+   </extension>
 </plugin>
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/PackageFragmentRootPropertyTester.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/PackageFragmentRootPropertyTester.java
new file mode 100644
index 0000000..0279f6e
--- /dev/null
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/util/PackageFragmentRootPropertyTester.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation 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:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.internal.core.util;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.jdt.core.*;
+import org.eclipse.pde.internal.core.PDECore;
+
+/**
+ * Tests whether an object is a package fragment root with
+ * a parent of the PDE classpath container (Plug-in Dependencies).  Intended for
+ * use with the command/menu framework.  This tester is registered for the type
+ * {@link IPackageFragmentRoot}.
+ * 
+ * <p>This class must always have a default contructor to function as a property tester</p>
+ */
+public class PackageFragmentRootPropertyTester extends PropertyTester {
+
+	/**
+	 * A property indicating a whether a package fragment root belongs to the PDE 
+	 * classpath container.  (value <code>"inPluginContainer"</code>). No expected
+	 * value is required. 
+	 */
+	public static final String PROP_IN_PLUGIN_CONTAINER = "inPluginContainer"; //$NON-NLS-1$
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+	 */
+	public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+		if (property.equals(PROP_IN_PLUGIN_CONTAINER)) {
+
+			if (receiver instanceof IPackageFragmentRoot) {
+				IPackageFragmentRoot element = (IPackageFragmentRoot) receiver;
+				try {
+					IClasspathEntry entry = element.getRawClasspathEntry();
+					if (entry.getPath().equals(PDECore.REQUIRED_PLUGINS_CONTAINER_PATH)) {
+						return true;
+					}
+				} catch (JavaModelException e) {
+					return false;
+				}
+			}
+		}
+		return false;
+	}
+
+}
diff --git a/ui/org.eclipse.pde.ui/plugin.properties b/ui/org.eclipse.pde.ui/plugin.properties
index 0dbd231..0a76fe9 100644
--- a/ui/org.eclipse.pde.ui/plugin.properties
+++ b/ui/org.eclipse.pde.ui/plugin.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2010 IBM Corporation and others.
+# Copyright (c) 2000, 2011 IBM Corporation 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
@@ -245,6 +245,10 @@
 pluginsearch.action.menu.name = Open &Plug-in Artifact...
 pluginsearch.action.desc = Open a plug-in artifact in the manifest editor
 
+importFromRepository.action.name = Import plug-in from a repository
+importFromRepository.action.menu.name = Import from repository...
+importFromRepository.action.desc = Imports a plug-in from a source repository
+
 addpluginstojavasearch.action.name = Add All Plug-ins to Java Search
 addpluginstojavasearch.action.desc = Adds all plug-ins in the target platform to java search
 
@@ -262,4 +266,4 @@
 commandParameter.name = The initial search pattern for the artifact search dialog
 consoleFactory.label = Host OSGi Console
 open.manifest.description = Open the plug-in manifest
-open.manifest.name = Open Manifest
\ No newline at end of file
+open.manifest.name = Open Manifest
diff --git a/ui/org.eclipse.pde.ui/plugin.xml b/ui/org.eclipse.pde.ui/plugin.xml
index 578d3bf..1648dbc 100644
--- a/ui/org.eclipse.pde.ui/plugin.xml
+++ b/ui/org.eclipse.pde.ui/plugin.xml
@@ -577,6 +577,11 @@
             id="org.eclipse.pde.ui.openManifest"
             name="%open.manifest.name">
       </command>
+      <command
+            description="%importFromRepository.action.desc"
+            id="org.eclipse.pde.ui.import.repository"
+            name="%importFromRepository.action.name">
+      </command>
    </extension>
    <extension
          point="org.eclipse.ui.popupMenus">
@@ -1917,6 +1922,10 @@
                 class="org.eclipse.pde.internal.ui.editor.OpenManifestHandler"
                 commandId="org.eclipse.pde.ui.openManifest">
           </handler>
+          <handler
+                class="org.eclipse.pde.internal.ui.views.plugins.ImportFromRepositoryActionDelegate"
+                commandId="org.eclipse.pde.ui.import.repository">
+          </handler>
        </extension>
        <extension
              point="org.eclipse.ui.menus">
@@ -1993,6 +2002,30 @@
                    style="push">
              </command>
           </menuContribution>
+          <menuContribution
+                allPopups="false"
+                locationURI="popup:org.eclipse.ui.popup.any?after=additions">
+             <command
+                   commandId="org.eclipse.pde.ui.import.repository"
+                   disabledIcon="icons/dtool16/imp_extplug.gif"
+                   icon="icons/etool16/imp_extplug.gif"
+                   label="%importFromRepository.action.menu.name"
+                   style="push"
+                   tooltip="%importFromRepository.action.desc">
+                <visibleWhen>
+                    <iterate
+                          ifEmpty="false"
+                          operator="or">
+                          <adapt
+                                type="org.eclipse.jdt.core.IPackageFragmentRoot">
+                             <test
+                                   property="org.eclipse.pde.core.inPluginContainer">
+                             </test>
+                          </adapt>
+    				</iterate>
+                </visibleWhen>
+             </command>
+          </menuContribution>
           <!--
           <menuContribution
                 locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions">
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties
index aaa0496..002bc19 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties
@@ -1067,7 +1067,7 @@
 TemplateSelectionPage_column_point = Extension Point
 
 ImportActionGroup_binaryWithLinkedContent=Binary Project with &Linked Content
-ImportActionGroup_cannot_import=The selected plug-ins cannot be imported from a repository.
+ImportActionGroup_cannot_import=The selected plug-ins cannot be imported from a repository. The plug-ins do not have an Eclipse-SourceReferences manifest header that can be processed. 
 ImportActionGroup_importContributingPlugin=&Import Contributing Plug-in as
 ImportActionGroup_Repository_project=P&roject from a Repository...
 
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/plugins/ImportActionGroup.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/plugins/ImportActionGroup.java
index d792f22..1cd3be6 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/plugins/ImportActionGroup.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/plugins/ImportActionGroup.java
@@ -12,6 +12,7 @@
 
 import java.util.*;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jface.action.*;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.viewers.ISelection;
@@ -81,7 +82,7 @@
 		}
 	}
 
-	private void handleImport(int importType, IStructuredSelection selection) {
+	static void handleImport(int importType, IStructuredSelection selection) {
 		ArrayList externalModels = new ArrayList();
 		for (Iterator iter = selection.iterator(); iter.hasNext();) {
 			IPluginModelBase model = getModel(iter.next());
@@ -111,7 +112,7 @@
 	 * @param models candidate models
 	 * @return  map of importer to import descriptions
 	 */
-	private Map getImportDescriptions(Shell shell, IPluginModelBase[] models) {
+	private static Map getImportDescriptions(Shell shell, IPluginModelBase[] models) {
 		BundleProjectService service = (BundleProjectService) BundleProjectService.getDefault();
 		try {
 			Map descriptions = service.getImportDescriptions(models); // all possible descriptions
@@ -149,10 +150,23 @@
 		} else if (next instanceof BundleDescription) {
 			model = PDECore.getDefault().getModelManager().findModel((BundleDescription) next);
 		} else if (next instanceof BundleSpecification) {
+			// Required for contents of Target Platform State View
 			BundleDescription desc = (BundleDescription) ((BundleSpecification) next).getSupplier();
 			if (desc != null) {
 				model = PDECore.getDefault().getModelManager().findModel(desc);
 			}
+		} else if (next instanceof IPackageFragmentRoot) {
+			// Required for context menu on PDE classpath container entries
+			IPackageFragmentRoot root = (IPackageFragmentRoot) next;
+			if (root.isExternal()) {
+				String path = root.getPath().toOSString();
+				IPluginModelBase[] externalModels = PDECore.getDefault().getModelManager().getExternalModels();
+				for (int i = 0; i < externalModels.length; i++) {
+					if (path.equals(externalModels[i].getInstallLocation())) {
+						return externalModels[i];
+					}
+				}
+			}
 		}
 		return model;
 
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/plugins/ImportFromRepositoryActionDelegate.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/plugins/ImportFromRepositoryActionDelegate.java
new file mode 100644
index 0000000..deb7578
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/plugins/ImportFromRepositoryActionDelegate.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation 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:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.internal.ui.views.plugins;
+
+import org.eclipse.core.commands.*;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.pde.internal.ui.wizards.imports.PluginImportOperation;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Action delegate to import a selected object if it represents a plug-in with a
+ * Eclipse-SourceReferences header that can be processed by Team.
+ * 
+ * @see ImportActionGroup
+ */
+public class ImportFromRepositoryActionDelegate extends AbstractHandler {
+
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+//			enable = ImportActionGroup.canImport((IStructuredSelection) selection);
+
+		ISelection selection = HandlerUtil.getCurrentSelection(event);
+		if (selection instanceof IStructuredSelection) {
+			ImportActionGroup.handleImport(PluginImportOperation.IMPORT_FROM_REPOSITORY, (IStructuredSelection) selection);
+		}
+		return null;
+	}
+}