blob: f033f3ed2b376834e84bd2d82fd4ea408350b116 [file] [log] [blame]
/*********************************************************************
* Copyright (c) 2009 - 2013 SpringSource, a division of VMware, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.virgo.ide.bundlor.ui.internal.properties;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.ui.viewsupport.FilteredElementTreeSelectionDialog;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.JavaElementSorter;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
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.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.virgo.ide.bundlor.internal.core.BundlorCorePlugin;
import org.eclipse.virgo.ide.bundlor.ui.BundlorUiPlugin;
import org.osgi.service.prefs.BackingStoreException;
/**
* {@link PropertyPage} to configure properties files for Bundlor variable substitution
*
* @author Christian Dupuis
* @author Leo Dos Santos
* @author Miles Parker
* @since 2.0.0
*/
@SuppressWarnings("deprecation")
public class BundlorPreferencePage extends PropertyPage {
private IProject project;
private boolean modified = false;
private Table filenameTable;
private TableViewer filenamesTableViewer;
private Button addButton;
private Button pathButton;
private Button deleteButton;
private List<String> filenames;
private Button scanByteCode;
private Button formatManifests;
private boolean checkScanByteCodeButton;
private boolean checkFormatManifestsButton;
@Override
protected Control createContents(Composite parent) {
Font font = parent.getFont();
Composite parentComposite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
parentComposite.setLayout(layout);
parentComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
parentComposite.setFont(font);
initialize();
this.scanByteCode = new Button(parentComposite, SWT.CHECK);
this.scanByteCode.setText("Scan output folders instead of source folders to generate MANIFEST.MF");
this.scanByteCode.setSelection(this.checkScanByteCodeButton);
this.scanByteCode.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
BundlorPreferencePage.this.modified = true;
}
});
this.formatManifests = new Button(parentComposite, SWT.CHECK);
this.formatManifests.setText("Auto-format generated MANIFEST.MF and TEST.MF files");
this.formatManifests.setSelection(this.checkFormatManifestsButton);
this.formatManifests.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
BundlorPreferencePage.this.modified = true;
}
});
Label description = createDescriptionLabel(parentComposite);
description.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
Composite composite = new Composite(parentComposite, SWT.NONE);
layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = 5;
layout.marginWidth = 0;
layout.verticalSpacing = 5;
layout.horizontalSpacing = 0;
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_FILL));
this.filenameTable = new Table(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
GridData data = new GridData(GridData.FILL_BOTH);
this.filenameTable.setLayoutData(data);
this.filenamesTableViewer = new TableViewer(this.filenameTable);
this.filenamesTableViewer.setContentProvider(new PropertiesFileContentProvider());
this.filenamesTableViewer.setLabelProvider(new FilenameLabelProvider());
this.filenamesTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
Object obj = ((IStructuredSelection) event.getSelection()).getFirstElement();
if (obj != null) {
BundlorPreferencePage.this.deleteButton.setEnabled(true);
} else {
BundlorPreferencePage.this.deleteButton.setEnabled(false);
}
}
});
Composite buttonComposite = new Composite(composite, SWT.NONE);
buttonComposite.setLayout(new GridLayout(1, true));
data = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
buttonComposite.setLayoutData(data);
this.addButton = new Button(buttonComposite, SWT.PUSH);
this.addButton.setText("Add...");
data = new GridData();
data.widthHint = 100;
this.addButton.setLayoutData(data);
this.addButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FilteredElementTreeSelectionDialog selDialog = new FilteredElementTreeSelectionDialog(Display.getCurrent().getActiveShell(),
new JavaElementLabelProvider(), new WorkspaceResourceContentProvider());
selDialog.setTitle("Select properties files");
selDialog.setMessage("Select properties files in the workspace that should be\nused for variable substitution:");
selDialog.setValidator(new ISelectionStatusValidator() {
public IStatus validate(Object[] selection) {
for (Object object : selection) {
if (object instanceof IStorage) {
return new Status(IStatus.OK, BundlorUiPlugin.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$ ;
}
}
return new Status(IStatus.ERROR, BundlorUiPlugin.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$ ;
}
});
selDialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
selDialog.setSorter(new JavaElementSorter());
if (selDialog.open() == Window.OK) {
IResource resource = (IResource) selDialog.getFirstResult();
if (resource instanceof IFile) {
if (resource.getProject().equals(BundlorPreferencePage.this.project)) {
IPath projectRelativePath = resource.getProjectRelativePath();
String string = projectRelativePath.toString();
BundlorPreferencePage.this.filenames.add(string);
} else {
BundlorPreferencePage.this.filenames.add(resource.getFullPath().toString());
}
}
BundlorPreferencePage.this.modified = true;
BundlorPreferencePage.this.filenamesTableViewer.setInput(BundlorPreferencePage.this.project);
}
}
});
this.pathButton = new Button(buttonComposite, SWT.PUSH);
this.pathButton.setText("Enter Path...");
data = new GridData();
data.widthHint = 100;
this.pathButton.setLayoutData(data);
this.pathButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
BundlorPropertiesPathDialog pathDialog = new BundlorPropertiesPathDialog(getShell());
if (pathDialog.open() == IDialogConstants.OK_ID) {
String path = pathDialog.getPropertiesPath();
BundlorPreferencePage.this.filenames.add(path);
BundlorPreferencePage.this.modified = true;
BundlorPreferencePage.this.filenamesTableViewer.setInput(BundlorPreferencePage.this.project);
}
}
});
this.deleteButton = new Button(buttonComposite, SWT.PUSH);
this.deleteButton.setText("Delete");
this.deleteButton.setLayoutData(data);
this.deleteButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
Object selected = ((IStructuredSelection) BundlorPreferencePage.this.filenamesTableViewer.getSelection()).getFirstElement();
BundlorPreferencePage.this.filenames.remove(selected);
BundlorPreferencePage.this.filenamesTableViewer.setInput(BundlorPreferencePage.this.project);
BundlorPreferencePage.this.modified = true;
}
});
this.filenamesTableViewer.setInput(this.project);
return parentComposite;
}
private void initialize() {
this.project = (IProject) getElement().getAdapter(IResource.class);
noDefaultAndApplyButton();
setDescription("Define properties files that should be used for variable substitution during\ngeneration of MANIFEST.MF file:");
if (this.project != null) {
IEclipsePreferences node = getProjectPreferences(this.project);
String properties = node.get(BundlorCorePlugin.TEMPLATE_PROPERTIES_FILE_KEY, BundlorCorePlugin.TEMPLATE_PROPERTIES_FILE_DEFAULT);
this.filenames = new ArrayList<String>(Arrays.asList(StringUtils.split(properties, ";")));
this.checkScanByteCodeButton = node.getBoolean(BundlorCorePlugin.TEMPLATE_BYTE_CODE_SCANNING_KEY,
BundlorCorePlugin.TEMPLATE_BYTE_CODE_SCANNING_DEFAULT);
this.checkFormatManifestsButton = node.getBoolean(BundlorCorePlugin.FORMAT_GENERATED_MANIFESTS_KEY,
BundlorCorePlugin.FORMAT_GENERATED_MANIFESTS_DEFAULT);
} else {
this.filenames = new ArrayList<String>();
this.checkScanByteCodeButton = BundlorCorePlugin.TEMPLATE_BYTE_CODE_SCANNING_DEFAULT;
this.checkFormatManifestsButton = BundlorCorePlugin.FORMAT_GENERATED_MANIFESTS_DEFAULT;
}
}
public IEclipsePreferences getProjectPreferences(IProject project) {
IScopeContext context = new ProjectScope(project);
IEclipsePreferences node = context.getNode(BundlorCorePlugin.PLUGIN_ID);
return node;
}
@Override
public boolean performOk() {
if (!this.modified) {
return true;
}
IEclipsePreferences node = getProjectPreferences(this.project);
node.put(BundlorCorePlugin.TEMPLATE_PROPERTIES_FILE_KEY, StringUtils.join(this.filenames, ";"));
boolean oldScanByteCode = node.getBoolean(BundlorCorePlugin.TEMPLATE_BYTE_CODE_SCANNING_KEY,
BundlorCorePlugin.TEMPLATE_BYTE_CODE_SCANNING_DEFAULT);
node.putBoolean(BundlorCorePlugin.TEMPLATE_BYTE_CODE_SCANNING_KEY, this.scanByteCode.getSelection());
node.putBoolean(BundlorCorePlugin.FORMAT_GENERATED_MANIFESTS_KEY, this.formatManifests.getSelection());
try {
node.flush();
} catch (BackingStoreException e) {
throw new RuntimeException(e);
}
if (oldScanByteCode != this.scanByteCode.getSelection()) {
BundlorCorePlugin.getDefault().getManifestManager().clearPartialManifest(JavaCore.create(this.project));
}
return true;
}
class PropertiesFileContentProvider implements ITreeContentProvider {
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
public Object[] getElements(Object inputElement) {
if (inputElement instanceof IProject) {
return BundlorPreferencePage.this.filenames.toArray();
}
return new Object[0];
}
public Object[] getChildren(Object parentElement) {
return getElements(parentElement);
}
public Object getParent(Object element) {
return null;
}
public boolean hasChildren(Object element) {
return getChildren(element).length > 0;
}
}
class FilenameLabelProvider extends LabelProvider {
@Override
public Image getImage(Object element) {
return BundlorUiPlugin.getImage("full/obj16/file_obj.gif");
}
@Override
public String getText(Object element) {
return element.toString();
}
}
class WorkspaceResourceContentProvider implements ITreeContentProvider {
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof IContainer) {
try {
return ((IContainer) parentElement).members();
} catch (CoreException e) {
}
}
return new Object[0];
}
public Object getParent(Object element) {
if (element instanceof IResource) {
return ((IResource) element).getParent();
}
return null;
}
public boolean hasChildren(Object element) {
return getChildren(element).length > 0;
}
public Object[] getElements(Object inputElement) {
if (inputElement instanceof IWorkspaceRoot) {
List<IProject> projects = new ArrayList<IProject>();
for (IProject project : ((IWorkspaceRoot) inputElement).getProjects()) {
if (project.isOpen() && project.isAccessible()) {
projects.add(project);
}
}
return projects.toArray();
}
return new Object[0];
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
}