Skip to content

Commit 3d80ca9

Browse files
Dinesh0723laeubi
authored andcommitted
Export package does not work when jar is not on classpath
Introduced new support for exporting packages in projects with plugin nature as well. Fixes: eclipse-pde#885
1 parent 692af00 commit 3d80ca9

File tree

1 file changed

+175
-10
lines changed

1 file changed

+175
-10
lines changed

ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExportPackageSection.java

+175-10
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,44 @@
1818

1919
package org.eclipse.pde.internal.ui.editor.plugin;
2020

21+
import java.io.BufferedReader;
22+
import java.io.IOException;
23+
import java.io.InputStream;
24+
import java.io.InputStreamReader;
2125
import java.util.ArrayList;
2226
import java.util.Collection;
2327
import java.util.Collections;
28+
import java.util.Enumeration;
29+
import java.util.HashSet;
30+
import java.util.List;
2431
import java.util.Map;
2532
import java.util.Optional;
33+
import java.util.Set;
34+
import java.util.jar.JarEntry;
35+
import java.util.jar.JarFile;
2636

37+
import org.eclipse.core.resources.IFolder;
2738
import org.eclipse.core.resources.IProject;
2839
import org.eclipse.core.resources.IResource;
2940
import org.eclipse.core.runtime.CoreException;
3041
import org.eclipse.jdt.core.IJavaProject;
3142
import org.eclipse.jdt.core.IPackageFragment;
3243
import org.eclipse.jdt.core.JavaCore;
3344
import org.eclipse.jdt.core.JavaModelException;
45+
import org.eclipse.jdt.ui.ISharedImages;
3446
import org.eclipse.jdt.ui.JavaElementLabelProvider;
3547
import org.eclipse.jdt.ui.JavaUI;
3648
import org.eclipse.jdt.ui.actions.FindReferencesAction;
3749
import org.eclipse.jdt.ui.actions.ShowInPackageViewAction;
3850
import org.eclipse.jface.action.Action;
3951
import org.eclipse.jface.action.IMenuManager;
4052
import org.eclipse.jface.action.Separator;
53+
import org.eclipse.jface.dialogs.MessageDialog;
4154
import org.eclipse.jface.viewers.ILabelProvider;
4255
import org.eclipse.jface.viewers.ISelection;
4356
import org.eclipse.jface.viewers.IStructuredContentProvider;
4457
import org.eclipse.jface.viewers.IStructuredSelection;
58+
import org.eclipse.jface.viewers.LabelProvider;
4559
import org.eclipse.jface.viewers.StructuredSelection;
4660
import org.eclipse.jface.viewers.TableViewer;
4761
import org.eclipse.jface.viewers.Viewer;
@@ -75,6 +89,7 @@
7589
import org.eclipse.search.ui.NewSearchUI;
7690
import org.eclipse.swt.SWT;
7791
import org.eclipse.swt.custom.BusyIndicator;
92+
import org.eclipse.swt.graphics.Image;
7893
import org.eclipse.swt.layout.GridData;
7994
import org.eclipse.swt.widgets.Composite;
8095
import org.eclipse.swt.widgets.Display;
@@ -226,7 +241,22 @@ protected boolean canPaste(Object targetObject, Object[] sourceObjects) {
226241
}
227242

228243
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$
230260
}
231261

232262
private Optional<IProject> getProjectWithJavaNature() {
@@ -406,11 +436,11 @@ private void handleRemove() {
406436
private void handleAdd() {
407437
IPluginModelBase model = (IPluginModelBase) getPage().getModel();
408438
final IProject project = model.getUnderlyingResource().getProject();
439+
final Collection<String> pckgs = fHeader == null ? Collections.emptySet() : fHeader.getPackageNames();
409440
try {
410441
if (project.hasNature(JavaCore.NATURE_ID)) {
411442
ILabelProvider labelProvider = new JavaElementLabelProvider();
412443
final ConditionalListSelectionDialog dialog = new ConditionalListSelectionDialog(PDEPlugin.getActiveWorkbenchShell(), labelProvider, PDEUIMessages.ExportPackageSection_dialogButtonLabel);
413-
final Collection<String> pckgs = fHeader == null ? Collections.emptySet() : fHeader.getPackageNames();
414444
final boolean allowJava = "true".equals(getBundle().getHeader(ICoreConstants.ECLIPSE_JREBUNDLE)); //$NON-NLS-1$
415445
Runnable runnable = () -> {
416446
ArrayList<IPackageFragment> elements = new ArrayList<>();
@@ -444,25 +474,160 @@ private void handleAdd() {
444474
fHeader.addPackage(new ExportPackageObject(fHeader, candidate, getVersionAttribute()));
445475
}
446476
} 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);
451478
}
452479
}
453480
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+
}
454514
}
455515
} catch (CoreException e) {
456516
}
457517
}
458518

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+
459617
private String getValue(Object[] objects) {
460618
StringBuilder buffer = new StringBuilder();
461619
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+
}
466631
}
467632
return buffer.toString();
468633
}

0 commit comments

Comments
 (0)