package bndtools.wizards.workspace;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import org.bndtools.api.ILogger;
import org.bndtools.api.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
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.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.Constants;
import aQute.bnd.osgi.Jar;
import bndtools.Plugin;
import bndtools.types.Pair;
import bndtools.utils.FileExtensionFilter;
public class AddFilesToRepositoryWizardPage extends WizardPage {
private static final ILogger logger = Logger.getLogger(AddFilesToRepositoryWizardPage.class);
private final Image jarImg = AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/jar_obj.gif").createImage();
private final Image warnImg = AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/warning_obj.gif").createImage();
private final Image errorImg = AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/error.gif").createImage();
private final Image okayImg = AbstractUIPlugin.imageDescriptorFromPlugin(Plugin.PLUGIN_ID, "/icons/tick.png").createImage();
private final Map<File,Pair<String,String>> bsnMap = new HashMap<File,Pair<String,String>>();
private final List<File> files = new ArrayList<File>(1);
private TableViewer viewer;
public AddFilesToRepositoryWizardPage(String pageName) {
super(pageName);
}
public void setFiles(File[] files) {
this.files.clear();
for (File file : files) {
analyseFile(file);
this.files.add(file);
}
if (viewer != null && !viewer.getControl().isDisposed()) {
viewer.refresh();
validate();
}
}
public List<File> getFiles() {
return files;
}
void analyseFile(File file) {
Jar jar = null;
try {
jar = new Jar(file);
Attributes attribs = jar.getManifest().getMainAttributes();
String bsn = attribs.getValue(Constants.BUNDLE_SYMBOLICNAME);
String version = attribs.getValue(Constants.BUNDLE_VERSION);
bsnMap.put(file, Pair.newInstance(bsn, version));
} catch (Exception e) {
logger.logError("Error reading JAR file content", e);
} finally {
if (jar != null)
jar.close();
}
}
@SuppressWarnings("unused")
public void createControl(Composite parent) {
setTitle("Add Files to Repository");
Composite composite = new Composite(parent, SWT.NONE);
new Label(composite, SWT.NONE).setText("Selected files:");
new Label(composite, SWT.NONE); // Spacer;
Table table = new Table(composite, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER);
table.setLinesVisible(true);
table.setHeaderVisible(true);
TableColumn col;
col = new TableColumn(table, SWT.NONE);
col.setText("Path");
col.setWidth(300);
col = new TableColumn(table, SWT.NONE);
col.setText("Bundle Name/Version");
col.setWidth(300);
viewer = new TableViewer(table);
viewer.setContentProvider(new ArrayContentProvider());
viewer.setLabelProvider(new StyledCellLabelProvider() {
@Override
public void update(ViewerCell cell) {
File file = (File) cell.getElement();
Pair<String,String> bundleId = bsnMap.get(file);
int index = cell.getColumnIndex();
if (index == 0) {
if (bundleId == null) {
cell.setImage(errorImg);
} else {
cell.setImage(jarImg);
}
StyledString label = new StyledString(file.getName());
String parentPath = file.getParent();
if (parentPath != null) {
label.append(" (" + parentPath + ")", StyledString.QUALIFIER_STYLER);
}
cell.setText(label.getString());
cell.setStyleRanges(label.getStyleRanges());
} else if (index == 1) {
if (bundleId == null) {
cell.setImage(errorImg);
cell.setText("Not a JAR file");
} else {
String bsn = bundleId.getFirst();
String version = bundleId.getSecond();
if (bsn == null) {
cell.setImage(warnImg);
cell.setText("Not a Bundle JAR");
} else {
cell.setImage(okayImg);
StyledString styledString = new StyledString(bsn);
if (version != null) {
styledString.append(" [" + version + "]", StyledString.COUNTER_STYLER);
cell.setText(styledString.getString());
cell.setStyleRanges(styledString.getStyleRanges());
}
}
}
}
}
});
viewer.setInput(files);
validate();
final Button btnAdd = new Button(composite, SWT.PUSH);
btnAdd.setText("Add JARs...");
final Button btnAddExternal = new Button(composite, SWT.PUSH);
btnAddExternal.setText("Add External JARs...");
final Button btnRemove = new Button(composite, SWT.NONE);
btnRemove.setText("Remove");
btnRemove.setEnabled(false);
// LISTENERS
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
btnRemove.setEnabled(!viewer.getSelection().isEmpty());
}
});
btnAdd.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
doAdd();
}
});
btnAddExternal.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
doAddExternal();
}
});
btnRemove.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
doRemove();
}
});
// LAYOUT
composite.setLayout(new GridLayout(2, false));
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 4));
btnAdd.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
btnRemove.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
setControl(composite);
}
void doAdd() {
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider());
dialog.setValidator(new ISelectionStatusValidator() {
public IStatus validate(Object[] selection) {
if (selection.length > 0 && selection[0] instanceof IFile) {
return new Status(IStatus.OK, Plugin.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$
}
return new Status(IStatus.ERROR, Plugin.PLUGIN_ID, IStatus.ERROR, "", null); //$NON-NLS-1$
}
});
dialog.setAllowMultiple(true);
dialog.setTitle("JAR File Selection");
dialog.addFilter(new FileExtensionFilter("jar")); //$NON-NLS-1$
dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
if (dialog.open() == Window.OK) {
Object[] result = dialog.getResult();
List<File> added = new ArrayList<File>(result.length);
for (Object fileObj : result) {
IFile ifile = (IFile) fileObj;
File file = ifile.getLocation().toFile();
analyseFile(file);
files.add(file);
added.add(file);
}
if (!added.isEmpty()) {
viewer.add(added.toArray());
validate();
}
}
}
void doAddExternal() {
FileDialog dialog = new FileDialog(getShell(), SWT.OPEN | SWT.MULTI);
dialog.setFilterExtensions(new String[] {
"*.jar"}); //$NON-NLS-1$
String res = dialog.open();
if (res != null) {
IPath filterPath = new Path(dialog.getFilterPath());
String[] fileNames = dialog.getFileNames();
List<File> added = new ArrayList<File>(fileNames.length);
for (String fileName : fileNames) {
added.add(filterPath.append(fileName).toFile());
}
if (!added.isEmpty()) {
for (File addedFile : added) {
analyseFile(addedFile);
files.add(addedFile);
}
viewer.add(added.toArray(new File[added.size()]));
validate();
}
}
}
void doRemove() {
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
if (!selection.isEmpty()) {
for (Iterator< ? > iter = selection.iterator(); iter.hasNext();) {
Object item = iter.next();
files.remove(item);
viewer.remove(item);
}
validate();
}
}
void validate() {
String error = null;
String warning = null;
for (File file : files) {
Pair<String,String> pair = bsnMap.get(file);
if (pair == null) {
error = "One or more selected files is not a JAR.";
} else {
String bsn = pair.getFirst();
if (bsn == null) {
warning = "One or more selected files is not a Bundle JAR";
}
}
}
setErrorMessage(error);
setMessage(warning, WARNING);
setPageComplete(!files.isEmpty() && error == null);
}
@Override
public void dispose() {
super.dispose();
jarImg.dispose();
warnImg.dispose();
errorImg.dispose();
okayImg.dispose();
}
}