|
18 | 18 |
|
19 | 19 | package org.eclipse.pde.internal.ui.editor.plugin;
|
20 | 20 |
|
| 21 | +import java.io.BufferedReader; |
| 22 | +import java.io.IOException; |
| 23 | +import java.io.InputStream; |
| 24 | +import java.io.InputStreamReader; |
21 | 25 | import java.util.ArrayList;
|
22 | 26 | import java.util.Collection;
|
23 | 27 | import java.util.Collections;
|
| 28 | +import java.util.Enumeration; |
| 29 | +import java.util.HashSet; |
| 30 | +import java.util.List; |
24 | 31 | import java.util.Map;
|
25 | 32 | import java.util.Optional;
|
| 33 | +import java.util.Set; |
| 34 | +import java.util.jar.JarEntry; |
| 35 | +import java.util.jar.JarFile; |
26 | 36 |
|
| 37 | +import org.eclipse.core.resources.IFolder; |
27 | 38 | import org.eclipse.core.resources.IProject;
|
28 | 39 | import org.eclipse.core.resources.IResource;
|
29 | 40 | import org.eclipse.core.runtime.CoreException;
|
30 | 41 | import org.eclipse.jdt.core.IJavaProject;
|
31 | 42 | import org.eclipse.jdt.core.IPackageFragment;
|
32 | 43 | import org.eclipse.jdt.core.JavaCore;
|
33 | 44 | import org.eclipse.jdt.core.JavaModelException;
|
| 45 | +import org.eclipse.jdt.ui.ISharedImages; |
34 | 46 | import org.eclipse.jdt.ui.JavaElementLabelProvider;
|
35 | 47 | import org.eclipse.jdt.ui.JavaUI;
|
36 | 48 | import org.eclipse.jdt.ui.actions.FindReferencesAction;
|
37 | 49 | import org.eclipse.jdt.ui.actions.ShowInPackageViewAction;
|
38 | 50 | import org.eclipse.jface.action.Action;
|
39 | 51 | import org.eclipse.jface.action.IMenuManager;
|
40 | 52 | import org.eclipse.jface.action.Separator;
|
| 53 | +import org.eclipse.jface.dialogs.MessageDialog; |
41 | 54 | import org.eclipse.jface.viewers.ILabelProvider;
|
42 | 55 | import org.eclipse.jface.viewers.ISelection;
|
43 | 56 | import org.eclipse.jface.viewers.IStructuredContentProvider;
|
44 | 57 | import org.eclipse.jface.viewers.IStructuredSelection;
|
| 58 | +import org.eclipse.jface.viewers.LabelProvider; |
45 | 59 | import org.eclipse.jface.viewers.StructuredSelection;
|
46 | 60 | import org.eclipse.jface.viewers.TableViewer;
|
47 | 61 | import org.eclipse.jface.viewers.Viewer;
|
|
75 | 89 | import org.eclipse.search.ui.NewSearchUI;
|
76 | 90 | import org.eclipse.swt.SWT;
|
77 | 91 | import org.eclipse.swt.custom.BusyIndicator;
|
| 92 | +import org.eclipse.swt.graphics.Image; |
78 | 93 | import org.eclipse.swt.layout.GridData;
|
79 | 94 | import org.eclipse.swt.widgets.Composite;
|
80 | 95 | import org.eclipse.swt.widgets.Display;
|
@@ -226,7 +241,22 @@ protected boolean canPaste(Object targetObject, Object[] sourceObjects) {
|
226 | 241 | }
|
227 | 242 |
|
228 | 243 | private boolean canAddExportedPackages() {
|
229 |
| - return isEditable() && getProjectWithJavaNature().isPresent(); |
| 244 | + IPluginModelBase model = (IPluginModelBase) getPage().getModel(); |
| 245 | + final IProject project = model.getUnderlyingResource().getProject(); |
| 246 | + try { |
| 247 | + if (isEditable() && getProjectWithJavaNature().isPresent()) { |
| 248 | + return true; |
| 249 | + } else if (isEditable() && hasPluginNature(project)) { |
| 250 | + return true; |
| 251 | + } |
| 252 | + } catch (CoreException e) { |
| 253 | + e.printStackTrace(); |
| 254 | + } |
| 255 | + return false; |
| 256 | + } |
| 257 | + |
| 258 | + private boolean hasPluginNature(IProject project) throws CoreException { |
| 259 | + return project.isNatureEnabled("org.eclipse.pde.PluginNature"); //$NON-NLS-1$ |
230 | 260 | }
|
231 | 261 |
|
232 | 262 | private Optional<IProject> getProjectWithJavaNature() {
|
@@ -406,11 +436,11 @@ private void handleRemove() {
|
406 | 436 | private void handleAdd() {
|
407 | 437 | IPluginModelBase model = (IPluginModelBase) getPage().getModel();
|
408 | 438 | final IProject project = model.getUnderlyingResource().getProject();
|
| 439 | + final Collection<String> pckgs = fHeader == null ? Collections.emptySet() : fHeader.getPackageNames(); |
409 | 440 | try {
|
410 | 441 | if (project.hasNature(JavaCore.NATURE_ID)) {
|
411 | 442 | ILabelProvider labelProvider = new JavaElementLabelProvider();
|
412 | 443 | final ConditionalListSelectionDialog dialog = new ConditionalListSelectionDialog(PDEPlugin.getActiveWorkbenchShell(), labelProvider, PDEUIMessages.ExportPackageSection_dialogButtonLabel);
|
413 |
| - final Collection<String> pckgs = fHeader == null ? Collections.emptySet() : fHeader.getPackageNames(); |
414 | 444 | final boolean allowJava = "true".equals(getBundle().getHeader(ICoreConstants.ECLIPSE_JREBUNDLE)); //$NON-NLS-1$
|
415 | 445 | Runnable runnable = () -> {
|
416 | 446 | ArrayList<IPackageFragment> elements = new ArrayList<>();
|
@@ -444,25 +474,160 @@ private void handleAdd() {
|
444 | 474 | fHeader.addPackage(new ExportPackageObject(fHeader, candidate, getVersionAttribute()));
|
445 | 475 | }
|
446 | 476 | } else {
|
447 |
| - getBundle().setHeader(getExportedPackageHeader(), getValue(selected)); |
448 |
| - // the way events get triggered, updateButtons isn't called |
449 |
| - if (selected.length > 0) |
450 |
| - getTablePart().setButtonEnabled(CALCULATE_USE_INDEX, true); |
| 477 | + addPackageIntoManifestFile(selected); |
451 | 478 | }
|
452 | 479 | }
|
453 | 480 | labelProvider.dispose();
|
| 481 | + } else if (hasPluginNature(project)) { |
| 482 | + ILabelProvider labelProvider = nonJavaLabelProvider(); |
| 483 | + final ConditionalListSelectionDialog dialog = new ConditionalListSelectionDialog( |
| 484 | + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), labelProvider, |
| 485 | + PDEUIMessages.ExportPackageSection_dialogButtonLabel); |
| 486 | + try { |
| 487 | + InputStream inputStream = project.getFile("META-INF/MANIFEST.MF").getContents(); //$NON-NLS-1$ |
| 488 | + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); |
| 489 | + List<String> jarPaths = extractJars(reader); |
| 490 | + Set<String> packageNames = new HashSet<>(); |
| 491 | + packageNames.addAll(getPackageNamesFromJar(jarPaths, pckgs, project)); |
| 492 | + if (!packageNames.isEmpty()) { |
| 493 | + dialogforNonJavaPrj(dialog, packageNames); |
| 494 | + if (dialog.open() == Window.OK) { |
| 495 | + Object[] selected = dialog.getResult(); |
| 496 | + if (fHeader != null) { |
| 497 | + for (Object selectedObject : selected) { |
| 498 | + fHeader.addPackage(new ExportPackageObject(fHeader, selectedObject.toString(), null, |
| 499 | + getVersionAttribute())); |
| 500 | + } |
| 501 | + } else { |
| 502 | + addPackageIntoManifestFile(selected); |
| 503 | + } |
| 504 | + } |
| 505 | + } else { |
| 506 | + MessageDialog.openInformation(Display.getDefault().getActiveShell(), "Information", //$NON-NLS-1$ |
| 507 | + "No packages are available for export."); //$NON-NLS-1$ |
| 508 | + } |
| 509 | + } catch (IOException e) { |
| 510 | + e.printStackTrace(); |
| 511 | + } finally { |
| 512 | + labelProvider.dispose(); |
| 513 | + } |
454 | 514 | }
|
455 | 515 | } catch (CoreException e) {
|
456 | 516 | }
|
457 | 517 | }
|
458 | 518 |
|
| 519 | + private void dialogforNonJavaPrj(final ConditionalListSelectionDialog dialog, Set<String> packageNames) { |
| 520 | + dialog.setElements(packageNames.toArray()); |
| 521 | + dialog.setMultipleSelection(true); |
| 522 | + dialog.setMessage(PDEUIMessages.PackageSelectionDialog_label); |
| 523 | + dialog.setTitle(PDEUIMessages.ExportPackageSection_title); |
| 524 | + dialog.create(); |
| 525 | + PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), IHelpContextIds.EXPORT_PACKAGES); |
| 526 | + } |
| 527 | + |
| 528 | + private void addPackageIntoManifestFile(Object[] selected) { |
| 529 | + getBundle().setHeader(getExportedPackageHeader(), getValue(selected)); |
| 530 | + // the way events get triggered, updateButtons isn't |
| 531 | + // called |
| 532 | + if (selected.length > 0) |
| 533 | + getTablePart().setButtonEnabled(CALCULATE_USE_INDEX, true); |
| 534 | + } |
| 535 | + |
| 536 | + private ILabelProvider nonJavaLabelProvider() { |
| 537 | + ILabelProvider labelProvider = new LabelProvider() { |
| 538 | + @Override |
| 539 | + public Image getImage(Object element) { |
| 540 | + return JavaUI.getSharedImages().getImage(ISharedImages.IMG_OBJS_PACKAGE); |
| 541 | + } |
| 542 | + }; |
| 543 | + return labelProvider; |
| 544 | + } |
| 545 | + |
| 546 | + private List<String> extractJars(BufferedReader reader) throws IOException { |
| 547 | + List<String> jarPaths = new ArrayList<>(); |
| 548 | + String line; |
| 549 | + while ((line = reader.readLine()) != null) { |
| 550 | + if (line.startsWith("Bundle-ClassPath:")) { //$NON-NLS-1$ |
| 551 | + String[] entries = line.substring("Bundle-ClassPath:".length()).trim().split(","); //$NON-NLS-1$ //$NON-NLS-2$ |
| 552 | + for (String entry : entries) { |
| 553 | + entry = entry.trim(); |
| 554 | + if (!entry.isEmpty() && !entry.equals(".") && !entry.equals("*")) { //$NON-NLS-1$ //$NON-NLS-2$ |
| 555 | + jarPaths.add(entry); |
| 556 | + } |
| 557 | + } |
| 558 | + while ((line = reader.readLine()) != null && Character.isWhitespace(line.charAt(0))) { |
| 559 | + entries = line.trim().split(","); //$NON-NLS-1$ |
| 560 | + for (String entry : entries) { |
| 561 | + entry = entry.trim(); |
| 562 | + if (!entry.isEmpty() && !entry.equals(".") && !entry.equals("*")) { //$NON-NLS-1$ //$NON-NLS-2$ |
| 563 | + jarPaths.add(entry); |
| 564 | + } |
| 565 | + } |
| 566 | + } |
| 567 | + break; |
| 568 | + } |
| 569 | + } |
| 570 | + return jarPaths; |
| 571 | + } |
| 572 | + |
| 573 | + public static IResource getPackageResource(IProject project, String packageName) { |
| 574 | + IFolder folder = project.getFolder(packageName.replace('.', '/')); |
| 575 | + if (folder.exists()) { |
| 576 | + return folder; |
| 577 | + } |
| 578 | + return null; |
| 579 | + } |
| 580 | + |
| 581 | + public static Set<String> getPackageNamesFromJar(List<String> jarPaths, Collection<String> existingPackages, |
| 582 | + IProject project) { |
| 583 | + Set<String> packName = new HashSet<>(); |
| 584 | + String location = project.getLocation().toOSString(); |
| 585 | + for (String jarFilePath : jarPaths) { |
| 586 | + try (JarFile jarFile = new JarFile(location + "\\" + jarFilePath)) { //$NON-NLS-1$ |
| 587 | + Enumeration<JarEntry> entries = jarFile.entries(); |
| 588 | + while (entries.hasMoreElements()) { |
| 589 | + JarEntry entry = entries.nextElement(); |
| 590 | + if (entry.isDirectory() && !entry.getName().equals("META-INF")) { //$NON-NLS-1$ |
| 591 | + String packageName = entry.getName().replace('/', '.'); |
| 592 | + if (!existingPackages.contains(packageName)) { |
| 593 | + packName.add(packageName); |
| 594 | + } |
| 595 | + } else if (entry.getName().endsWith(".class")) { //$NON-NLS-1$ |
| 596 | + String packageName = getPackageNameFromClassName(entry.getName()); |
| 597 | + if (!existingPackages.contains(packageName)) { |
| 598 | + packName.add(packageName); |
| 599 | + } |
| 600 | + } |
| 601 | + } |
| 602 | + } catch (IOException e) { |
| 603 | + e.printStackTrace(); |
| 604 | + } |
| 605 | + } |
| 606 | + return packName; |
| 607 | + } |
| 608 | + |
| 609 | + private static String getPackageNameFromClassName(String className) { |
| 610 | + int lastSlashIndex = className.lastIndexOf('/'); |
| 611 | + if (lastSlashIndex != -1) { |
| 612 | + return className.substring(0, lastSlashIndex).replace('/', '.'); |
| 613 | + } |
| 614 | + return ""; |
| 615 | + } |
| 616 | + |
459 | 617 | private String getValue(Object[] objects) {
|
460 | 618 | StringBuilder buffer = new StringBuilder();
|
461 | 619 | for (Object object : objects) {
|
462 |
| - IPackageFragment fragment = (IPackageFragment) object; |
463 |
| - if (buffer.length() > 0) |
464 |
| - buffer.append("," + getLineDelimiter() + " "); //$NON-NLS-1$ //$NON-NLS-2$ |
465 |
| - buffer.append(fragment.getElementName()); |
| 620 | + if (object instanceof IPackageFragment) { |
| 621 | + IPackageFragment fragment = (IPackageFragment) object; |
| 622 | + if (buffer.length() > 0) |
| 623 | + buffer.append("," + getLineDelimiter() + " "); //$NON-NLS-1$ //$NON-NLS-2$ |
| 624 | + buffer.append(fragment.getElementName()); |
| 625 | + } else if (object instanceof String) { |
| 626 | + String str = (String) object; |
| 627 | + if (buffer.length() > 0) |
| 628 | + buffer.append("," + getLineDelimiter() + " "); //$NON-NLS-1$ //$NON-NLS-2$ |
| 629 | + buffer.append(str); |
| 630 | + } |
466 | 631 | }
|
467 | 632 | return buffer.toString();
|
468 | 633 | }
|
|
0 commit comments