package bndtools.views.repository;
import org.bndtools.core.ui.icons.Icons;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IMemento;
import org.osgi.framework.namespace.PackageNamespace;
import aQute.bnd.osgi.resource.CapReqBuilder;
import aQute.bnd.version.VersionRange;
public class PackageSearchPanel extends SearchPanel {
private String packageName;
private String versionRangeStr;
private Control focusControl;
@Override
public Control createControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(3, false);
layout.verticalSpacing = 10;
container.setLayout(layout);
Label lblInstruction = new Label(container, SWT.WRAP | SWT.LEFT);
lblInstruction.setText("Enter a package name, which may contain wildcard characters (\"*\").");
lblInstruction.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1));
new Label(container, SWT.NONE).setText("Package Name:");
final Text txtPackageName = new Text(container, SWT.BORDER);
if (packageName != null)
txtPackageName.setText(packageName);
txtPackageName.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
txtPackageName.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
packageName = txtPackageName.getText().trim();
validate();
}
});
new Label(container, SWT.NONE).setText("Version Range:");
final Text txtVersion = new Text(container, SWT.BORDER);
if (versionRangeStr != null)
txtVersion.setText(versionRangeStr);
txtVersion.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
txtVersion.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
versionRangeStr = txtVersion.getText();
validate();
}
});
Label lblVersionHint = new Label(container, SWT.NONE);
lblVersionHint.setText("Example: [1.0, 2.0)");
validate();
this.focusControl = txtPackageName;
return container;
}
private void validate() {
try {
String filter = null;
if (packageName == null || packageName.trim().isEmpty()) {
setError(null);
setRequirement(null);
return;
}
VersionRange versionRange = null;
if (versionRangeStr != null && versionRangeStr.trim().length() > 0) {
try {
versionRange = new VersionRange(versionRangeStr);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid version range: " + e.getMessage());
}
}
filter = formatPackageRequirement(packageName, versionRange);
if (filter != null)
setRequirement(new CapReqBuilder(PackageNamespace.PACKAGE_NAMESPACE).addDirective(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE, filter).buildSyntheticRequirement());
setError(null);
} catch (Exception e) {
setError(e.getMessage());
setRequirement(null);
}
}
private String formatPackageRequirement(String packageName, VersionRange versionRange) {
String filter;
if (versionRange == null) {
filter = String.format("(%s=%s)", PackageNamespace.PACKAGE_NAMESPACE, packageName.trim());
} else {
StringBuilder builder = new StringBuilder();
builder.append("(&(").append(PackageNamespace.PACKAGE_NAMESPACE).append('=').append(packageName).append(')');
if (versionRange.includeLow())
builder.append("(version>=").append(versionRange.getLow()).append(')');
else
builder.append("(!(version<=").append(versionRange.getLow()).append("))");
if (versionRange.isRange()) {
if (versionRange.includeHigh())
builder.append("(version<=").append(versionRange.getHigh()).append(')');
else
builder.append("(!(version>=").append(versionRange.getHigh()).append("))");
}
builder.append(')');
filter = builder.toString();
}
return filter;
}
@Override
public void setFocus() {
focusControl.setFocus();
}
@Override
public Image createImage(Device device) {
return Icons.desc("package").createImage(device);
}
@Override
public void saveState(IMemento memento) {
memento.putString("packageName", packageName);
memento.putString("versionRange", versionRangeStr);
}
@Override
public void restoreState(IMemento memento) {
packageName = memento.getString("packageName");
versionRangeStr = memento.getString("versionRange");
}
}