/*******************************************************************************
* Copyright (c) 2004 - 2013 Spring IDE Developers
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.beans.ui.properties;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.StringTokenizer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.internal.core.JarEntryFile;
import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
import org.eclipse.jdt.ui.IJavaElementSearchConstants;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.JavaElementSorter;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.dialogs.ITypeInfoFilterExtension;
import org.eclipse.jdt.ui.dialogs.ITypeInfoRequestor;
import org.eclipse.jdt.ui.dialogs.TypeSelectionExtension;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
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.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.CheckedTreeSelectionDialog;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.SelectionDialog;
import org.eclipse.ui.dialogs.SelectionStatusDialog;
import org.springframework.ide.eclipse.beans.core.BeansCorePlugin;
import org.springframework.ide.eclipse.beans.core.internal.model.BeansConfigFactory;
import org.springframework.ide.eclipse.beans.core.model.IBeansConfig;
import org.springframework.ide.eclipse.beans.core.model.IBeansProject;
import org.springframework.ide.eclipse.beans.core.model.IImportedBeansConfig;
import org.springframework.ide.eclipse.beans.core.model.locate.BeansConfigLocatorFactory;
import org.springframework.ide.eclipse.beans.core.model.locate.ProjectScanningBeansConfigLocator;
import org.springframework.ide.eclipse.beans.core.model.locate.ProjectScanningJavaConfigLocator;
import org.springframework.ide.eclipse.beans.ui.BeansUIPlugin;
import org.springframework.ide.eclipse.beans.ui.properties.model.PropertiesModel;
import org.springframework.ide.eclipse.beans.ui.properties.model.PropertiesModelLabelProvider;
import org.springframework.ide.eclipse.beans.ui.properties.model.PropertiesProject;
import org.springframework.ide.eclipse.core.StringUtils;
import org.springframework.ide.eclipse.core.io.ZipEntryStorage;
import org.springframework.ide.eclipse.core.model.IModelChangeListener;
import org.springframework.ide.eclipse.core.model.IModelElement;
import org.springframework.ide.eclipse.core.model.ModelChangeEvent;
import org.springframework.ide.eclipse.ui.dialogs.FilteredElementTreeSelectionDialog;
import org.springframework.ide.eclipse.ui.dialogs.StorageSelectionValidator;
import org.springframework.ide.eclipse.ui.viewers.JavaFileSuffixFilter;
import org.springsource.ide.eclipse.commons.core.JdtUtils;
import org.springsource.ide.eclipse.commons.core.SpringCorePreferences;
import org.springsource.ide.eclipse.commons.core.SpringCoreUtils;
import org.springsource.ide.eclipse.commons.core.StatusHandler;
import org.springsource.ide.eclipse.commons.ui.SpringUIUtils;
/**
* Property page tab for defining the list of beans config file extensions and the selected beans config files.
* @author Torsten Juergeleit
* @author Christian Dupuis
* @author Leo Dos Santos
*/
@SuppressWarnings({ "deprecation", "restriction" })
public class ConfigFilesTab {
private static final String PREFIX = "ConfigurationPropertyPage." + "tabConfigFiles.";
private static final String DESCRIPTION = PREFIX + "description";
private static final String SUFFIXES_LABEL = PREFIX + "suffixes.label";
private static final String ERROR_NO_SUFFIXES = PREFIX + "error.noSuffixes";
private static final String ERROR_INVALID_SUFFIXES = PREFIX + "error.invalidSuffixes";
private static final String ADD_XML_CONFIG_BUTTON = PREFIX + "addXMLConfigButton";
private static final String ADD_JAVA_CONFIG_BUTTON = PREFIX + "addJavaConfigButton";
private static final String REMOVE_BUTTON = PREFIX + "removeButton";
private static final String DIALOG_TITLE = PREFIX + "addConfigDialog.title";
private static final String DIALOG_MESSAGE = PREFIX + "addConfigDialog.message";
private static final int TABLE_WIDTH = 250;
private static final String ENABLE_IMPORT_LABEL = PREFIX + "enableImports.label";
private static final String IGNORE_MISSING_NAMESPACEHANDLER_LABEL = PREFIX + "ignoreMissingNamespaceHandler.label";
private static final String NOTE_LABEL = PREFIX + "note.label";
private static final String SCAN_NOTE_LABEL = PREFIX + "scan.note.label";
private PropertiesModel model;
private PropertiesProject project;
private Text suffixesText;
private Table configsTable;
private TableViewer configsViewer;
private Label errorLabel;
private Button addButton, addJavaConfigButton, removeButton, scanButton;
private Button enableImportText;
private IModelElement selectedElement;
private Color grayColor = new Color(Display.getDefault(), 150, 150, 150);
private SelectionListener buttonListener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleButtonPressed((Button) e.widget);
}
};
private IModelChangeListener modelChangeListener = new IModelChangeListener() {
public void elementChanged(ModelChangeEvent event) {
if (configsViewer != null && !configsViewer.getControl().isDisposed()) {
configsViewer.refresh();
}
}
};
private boolean hasUserMadeChanges;
private Button ignoreMissingNamespaceHandlerText;
public ConfigFilesTab(PropertiesModel model, PropertiesProject project, IModelElement selectedModelElement) {
this.model = model;
this.project = project;
calculateSelectedElement(selectedModelElement);
}
private void calculateSelectedElement(IModelElement modelElement) {
if (modelElement != null && this.project != null) {
this.selectedElement = this.project.getConfig(modelElement.getElementName());
}
}
public boolean hasUserMadeChanges() {
return hasUserMadeChanges;
}
public Control createControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight = 3;
layout.marginWidth = 3;
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
Label description = new Label(composite, SWT.WRAP);
description.setText(BeansUIPlugin.getResourceString(DESCRIPTION));
description.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Composite tableAndButtons = new Composite(composite, SWT.NONE);
tableAndButtons.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.numColumns = 2;
tableAndButtons.setLayout(layout);
// Create table and viewer for Spring bean config files
configsTable = new Table(tableAndButtons, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION
| SWT.BORDER);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.widthHint = TABLE_WIDTH;
data.heightHint = TABLE_WIDTH;
configsTable.setLayoutData(data);
configsTable.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleTableSelectionChanged();
}
});
configsViewer = new TableViewer(configsTable);
configsViewer.setContentProvider(new ConfigFilesContentProvider(project));
configsViewer.setLabelProvider(new PropertiesModelLabelProvider());
configsViewer.setInput(this); // activate content provider
configsViewer.setSorter(new ConfigFilesSorter());
if (this.selectedElement != null) {
configsViewer.setSelection(new StructuredSelection(selectedElement), true);
}
if (BeansConfigLocatorFactory.hasEnabledBeansConfigLocatorDefinitions(project.getProject())) {
Label note = new Label(composite, SWT.WRAP);
note.setText(BeansUIPlugin.getResourceString(NOTE_LABEL));
note.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
}
Label options = new Label(composite, SWT.WRAP);
options.setText("Options:");
options.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
// Create enable import checkbox
enableImportText = SpringUIUtils
.createCheckBox(composite, BeansUIPlugin.getResourceString(ENABLE_IMPORT_LABEL));
enableImportText.setSelection(project.isImportsEnabled());
enableImportText.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleImportEnabledChanged();
}
});
// Create ignore missing namespace handler checkbox
ignoreMissingNamespaceHandlerText = SpringUIUtils.createCheckBox(composite,
BeansUIPlugin.getResourceString(IGNORE_MISSING_NAMESPACEHANDLER_LABEL));
ignoreMissingNamespaceHandlerText.setSelection(SpringCorePreferences.getProjectPreferences(
project.getProject(), BeansCorePlugin.PLUGIN_ID).getBoolean(
BeansCorePlugin.IGNORE_MISSING_NAMESPACEHANDLER_PROPERTY,
BeansCorePlugin.IGNORE_MISSING_NAMESPACEHANDLER_PROPERTY_DEFAULT));
ignoreMissingNamespaceHandlerText.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
hasUserMadeChanges = true;
}
});
// Create suffix text field
suffixesText = SpringUIUtils.createTextField(composite, BeansUIPlugin.getResourceString(SUFFIXES_LABEL));
suffixesText.setText(StringUtils.collectionToDelimitedString(project.getConfigSuffixes(), ","));
suffixesText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
handleSuffixesTextModified();
}
});
// Create error label
errorLabel = new Label(composite, SWT.NONE);
errorLabel.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
errorLabel.setForeground(JFaceColors.getErrorText(parent.getDisplay()));
errorLabel.setBackground(JFaceColors.getErrorBackground(parent.getDisplay()));
// Create button area
Composite buttonArea = new Composite(tableAndButtons, SWT.NONE);
layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
buttonArea.setLayout(layout);
buttonArea.setLayoutData(new GridData(GridData.FILL_VERTICAL));
addButton = SpringUIUtils.createButton(buttonArea, BeansUIPlugin.getResourceString(ADD_XML_CONFIG_BUTTON), buttonListener);
addJavaConfigButton = SpringUIUtils.createButton(buttonArea, BeansUIPlugin.getResourceString(ADD_JAVA_CONFIG_BUTTON), buttonListener);
removeButton = SpringUIUtils.createButton(buttonArea, BeansUIPlugin.getResourceString(REMOVE_BUTTON),
buttonListener, 0, false);
scanButton = SpringUIUtils.createButton(buttonArea, "Scan...", buttonListener);
model.addChangeListener(modelChangeListener);
handleSuffixesTextModified();
hasUserMadeChanges = false;
// handleSuffixTextModified() has set this to true
handleTableSelectionChanged();
return composite;
}
public boolean shouldIgnoreMissingNamespaceHandler() {
return this.ignoreMissingNamespaceHandlerText.getSelection();
}
private void handleImportEnabledChanged() {
if (project.isImportsEnabled() && !enableImportText.getSelection()) {
hasUserMadeChanges = true;
project.setImportsEnabled(enableImportText.getSelection());
}
else if (!project.isImportsEnabled() && enableImportText.getSelection()) {
hasUserMadeChanges = true;
project.setImportsEnabled(enableImportText.getSelection());
}
}
public void dispose() {
model.removeChangeListener(modelChangeListener);
}
/**
* The user has modified the comma-separated list of config suffixes. Validate the input and update the "Add" button
* enablement and error label accordingly.
*/
private void handleSuffixesTextModified() {
String errorMessage = null;
Set<String> suffixes = new LinkedHashSet<String>();
String extText = suffixesText.getText().trim();
if (extText.length() == 0) {
errorMessage = BeansUIPlugin.getResourceString(ERROR_NO_SUFFIXES);
}
else {
StringTokenizer tokenizer = new StringTokenizer(extText, ",");
while (tokenizer.hasMoreTokens()) {
String suffix = tokenizer.nextToken().trim();
if (isValidSuffix(suffix)) {
suffixes.add(suffix);
}
else {
errorMessage = BeansUIPlugin.getResourceString(ERROR_INVALID_SUFFIXES);
break;
}
}
if (errorMessage == null) {
project.setConfigSuffixes(suffixes);
hasUserMadeChanges = true;
}
}
if (errorMessage != null) {
errorLabel.setText(errorMessage);
addButton.setEnabled(false);
}
else {
errorLabel.setText("");
addButton.setEnabled(true);
}
errorLabel.getParent().update();
}
private boolean isValidSuffix(String suffix) {
if (suffix.length() == 0) {
return false;
}
return true;
}
/**
* The user has selected a different configuration in table. Update button enablement.
*/
private void handleTableSelectionChanged() {
IStructuredSelection selection = (IStructuredSelection) configsViewer.getSelection();
if (selection.isEmpty()) {
removeButton.setEnabled(false);
}
else {
if (selection.getFirstElement() instanceof IBeansConfig
&& ((IBeansConfig) selection.getFirstElement()).getType() == IBeansConfig.Type.MANUAL) {
removeButton.setEnabled(true);
}
else {
removeButton.setEnabled(false);
}
}
}
/**
* One of the buttons has been pressed, act accordingly.
*/
private void handleButtonPressed(Button button) {
if (button == addButton) {
handleAddButtonPressed();
} else if (button == addJavaConfigButton) {
handleJavaConfigButtonPressed();
}
else if (button == removeButton) {
handleRemoveButtonPressed();
}
else if (button == scanButton) {
handleScanButtonPressed();
}
handleTableSelectionChanged();
configsTable.setFocus();
}
protected void handleScanButtonPressed() {
ScannedFilesContentProvider contentProvider = new ScannedFilesContentProvider(suffixesText.getText());
CheckedTreeSelectionDialog dialog = new CheckedTreeSelectionDialog(SpringUIUtils.getStandardDisplay()
.getActiveShell(), new ScannedFilesLabelProvider(), contentProvider) {
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
Label note = new Label(composite, SWT.WRAP);
note.setText(BeansUIPlugin.getResourceString(SCAN_NOTE_LABEL));
note.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
return composite;
}
};
dialog.setTitle(BeansUIPlugin.getResourceString(DIALOG_TITLE));
dialog.setMessage(BeansUIPlugin.getResourceString(DIALOG_MESSAGE));
dialog.addFilter(new ScannedFilesFilter(project.getConfigSuffixes()));
dialog.setValidator(new ScannedFilesValidator(true));
dialog.setInput(project.getProject());
dialog.setSorter(new JavaElementSorter());
dialog.setInitialSelections(contentProvider.getElements(project.getProject()));
if (dialog.open() == Window.OK) {
Object[] selection = dialog.getResult();
if (selection != null && selection.length > 0) {
for (Object element : selection) {
String config;
if (element instanceof IType) {
IType type = (IType) element;
config = BeansConfigFactory.JAVA_CONFIG_TYPE + type.getFullyQualifiedName();
}
else if (element instanceof ZipEntryStorage) {
ZipEntryStorage storage = (ZipEntryStorage) element;
config = storage.getFullName();
}
else {
IFile file = (IFile) element;
config = file.getProjectRelativePath().toString();
}
project.addConfig(config, IBeansConfig.Type.MANUAL);
}
configsViewer.refresh(false);
hasUserMadeChanges = true;
}
}
}
private void handleJavaConfigButtonPressed() {
SelectionDialog dialog = createFilteredTypesDialog();
if (dialog != null && dialog.open() == Window.OK) {
Object[] selection = dialog.getResult();
if (selection != null && selection.length > 0) {
for (Object element : selection) {
String config = null;
if (element instanceof IType) {
IType type = (IType) element;
config = BeansConfigFactory.JAVA_CONFIG_TYPE + type.getFullyQualifiedName();
}
if (config != null) {
project.addConfig(config, IBeansConfig.Type.MANUAL);
}
}
}
configsViewer.refresh(false);
hasUserMadeChanges = true;
}
}
private SelectionDialog createFilteredTypesDialog() {
SelectionDialog dialog = null;
IJavaProject javaProj = JdtUtils.getJavaProject(project.getProject());
if (javaProj != null) {
IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProj });
Set<IType> annotatedTypes =org.springframework.ide.eclipse.core.java.JdtUtils.searchForJavaConfigs(scope);
final Set<String> filteredResults = new HashSet<String>();
for (IType type : annotatedTypes) {
filteredResults.add(type.getPackageFragment().getElementName() + "/" + type.getTypeQualifiedName('.'));
}
try {
dialog = JavaUI.createTypeDialog(SpringUIUtils.getStandardDisplay().getActiveShell(), PlatformUI.getWorkbench()
.getProgressService(), scope, IJavaElementSearchConstants.CONSIDER_ALL_TYPES, true, "**",
new TypeSelectionExtension() {
@Override
public ITypeInfoFilterExtension getFilterExtension() {
return new ITypeInfoFilterExtension() {
public boolean select(ITypeInfoRequestor typeInfoRequestor) {
StringBuffer buffer = new StringBuffer();
buffer.append(typeInfoRequestor.getPackageName()).append('/');
String enclosingName = typeInfoRequestor.getEnclosingName();
if (enclosingName.length() > 0) {
buffer.append(enclosingName).append('.');
}
buffer.append(typeInfoRequestor.getTypeName());
return filteredResults.contains(buffer.toString());
}
};
}
});
dialog.setTitle(BeansUIPlugin.getResourceString(DIALOG_TITLE));
dialog.setMessage(BeansUIPlugin.getResourceString(DIALOG_MESSAGE));
} catch (JavaModelException e) {
StatusHandler.log(new Status(IStatus.ERROR, BeansUIPlugin.PLUGIN_ID,
"An error occurred while opening dialog.", e));
}
}
return dialog;
}
/**
* The user has pressed the add button. Opens the configuration selection dialog and adds the selected
* configuration.
*/
private void handleAddButtonPressed() {
SelectionStatusDialog dialog;
if (SpringCoreUtils.isEclipseSameOrNewer(3, 2)) {
FilteredElementTreeSelectionDialog selDialog = new FilteredElementTreeSelectionDialog(SpringUIUtils
.getStandardDisplay().getActiveShell(), new LabelProvider(), new NonJavaResourceContentProvider());
selDialog.addFilter(new ConfigFileFilter(project.getConfigSuffixes()));
selDialog.setValidator(new StorageSelectionValidator(true));
selDialog.setInput(project.getProject());
selDialog.setSorter(new JavaElementSorter());
dialog = selDialog;
}
else {
ElementTreeSelectionDialog selDialog = new ElementTreeSelectionDialog(SpringUIUtils.getStandardDisplay()
.getActiveShell(), new LabelProvider(), new NonJavaResourceContentProvider());
selDialog.addFilter(new ConfigFileFilter(project.getConfigSuffixes()));
selDialog.setValidator(new StorageSelectionValidator(true));
selDialog.setInput(project.getProject());
selDialog.setSorter(new JavaElementSorter());
dialog = selDialog;
}
dialog.setTitle(BeansUIPlugin.getResourceString(DIALOG_TITLE));
dialog.setMessage(BeansUIPlugin.getResourceString(DIALOG_MESSAGE));
if (dialog.open() == Window.OK) {
Object[] selection = dialog.getResult();
if (selection != null && selection.length > 0) {
for (Object element : selection) {
String config = null;
if (element instanceof ZipEntryStorage) {
ZipEntryStorage storage = (ZipEntryStorage) element;
config = storage.getFullName();
}
else if (element instanceof IFile) {
IFile file = (IFile) element;
config = file.getProjectRelativePath().toString();
}
else if (element instanceof JarEntryFile) {
IPath fullPath = ((JarPackageFragmentRoot) ((JarEntryFile) element).getPackageFragmentRoot())
.getPath();
String entryName = ((JarEntryFile) element).getFullPath().toString();
for (String name : JavaCore.getClasspathVariableNames()) {
IPath variablePath = JavaCore.getClasspathVariable(name);
if (variablePath != null && variablePath.isPrefixOf(fullPath)) {
if (MessageDialog.openQuestion(SpringUIUtils.getStandardDisplay().getActiveShell(),
"Use classpath variable", "Do you want to use the classpath variable '" + name
+ "' to refer to the config file\n'" + entryName + "'?")) {
fullPath = new Path(name).append(fullPath.removeFirstSegments(variablePath
.segmentCount()));
}
break;
}
}
config = IBeansConfig.EXTERNAL_FILE_NAME_PREFIX + fullPath.toString()
+ ZipEntryStorage.DELIMITER + entryName;
}
if (config != null) {
project.addConfig(config, IBeansConfig.Type.MANUAL);
}
}
configsViewer.refresh(false);
hasUserMadeChanges = true;
}
}
}
/**
* The user has pressed the remove button. Delete the selected configuration.
*/
private void handleRemoveButtonPressed() {
IStructuredSelection selection = (IStructuredSelection) configsViewer.getSelection();
if (!selection.isEmpty()) {
Iterator elements = selection.iterator();
while (elements.hasNext()) {
IBeansConfig config = (IBeansConfig) elements.next();
project.removeConfig(config.getElementName());
}
configsViewer.refresh(false);
hasUserMadeChanges = true;
}
}
private final class ScannedFilesContentProvider implements ITreeContentProvider {
private Object[] scannedFiles = null;
public ScannedFilesContentProvider(final String fileSuffixes) {
final Set<Object> files = new HashSet<Object>();
IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
ProjectScanningBeansConfigLocator locator = new ProjectScanningBeansConfigLocator(fileSuffixes);
files.addAll(locator.locateBeansConfigs(project.getProject(), monitor));
ProjectScanningJavaConfigLocator javaLocator = new ProjectScanningJavaConfigLocator();
files.addAll(javaLocator.locateJavaConfigs(project.getProject(), monitor));
}
};
try {
IRunnableContext context = new ProgressMonitorDialog(SpringUIUtils.getStandardDisplay()
.getActiveShell());
context.run(true, true, runnable);
}
catch (InvocationTargetException e) {
StatusHandler.log(new Status(IStatus.ERROR, BeansUIPlugin.PLUGIN_ID,
"An error occurred while scanning for config files.", e));
}
catch (InterruptedException e) {
StatusHandler.log(new Status(IStatus.ERROR, BeansUIPlugin.PLUGIN_ID,
"An error occurred while scanning for config files.", e));
}
scannedFiles = files.toArray();
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
public Object[] getChildren(Object parentElement) {
return IModelElement.NO_CHILDREN;
}
public Object getParent(Object element) {
return null;
}
public boolean hasChildren(Object element) {
return false;
}
public Object[] getElements(Object inputElement) {
return scannedFiles;
}
}
private class ConfigFilesContentProvider implements IStructuredContentProvider {
private IBeansProject project;
public ConfigFilesContentProvider(IBeansProject project) {
this.project = project;
}
public Object[] getElements(Object obj) {
return new LinkedHashSet<IBeansConfig>(project.getConfigs()).toArray();
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
public void dispose() {
grayColor.dispose();
}
}
private static class ConfigFilesSorter extends ViewerSorter {
private enum Category {
SUB_DIR, ROOT_DIR, OTHER
};
@Override
public int category(Object element) {
if (element instanceof IBeansConfig) {
if (((IBeansConfig) element).getElementName().indexOf('/') == -1) {
return Category.ROOT_DIR.ordinal();
}
return Category.SUB_DIR.ordinal();
}
return Category.OTHER.ordinal();
}
}
private class ConfigFileFilter extends JavaFileSuffixFilter {
public ConfigFileFilter(Set<String> allowedFileExtensions) {
super(allowedFileExtensions);
}
@Override
public boolean select(Viewer viewer, Object parent, Object element) {
if (super.select(viewer, parent, element)) {
if (element instanceof JarPackageFragmentRoot) {
try {
IResource resource = ((JarPackageFragmentRoot) element).getUnderlyingResource();
// Exclude jars that come from different workspace projects; only jars
// coming from outside the workspace have no underlying resource
return resource == null || resource.getProject().equals(project.getProject());
}
catch (JavaModelException e) {
StatusHandler.log(new Status(IStatus.ERROR, BeansUIPlugin.PLUGIN_ID,
"An error occurred while searching for config files.", e));
}
}
else if (element instanceof JarEntryFile) {
String name = ((JarEntryFile) element).getName();
return !"pom.xml".equals(name);
}
return true;
}
return false;
}
@Override
protected boolean selectFile(IFile element) {
if ("pom.xml".equals(element.getName())) {
return false;
}
IBeansProject project = BeansCorePlugin.getModel().getProject(element.getProject());
if (project != null) {
IBeansConfig beansConfig = project.getConfig(element);
return beansConfig == null;
}
return false;
}
}
private class ScannedFilesFilter extends ConfigFileFilter {
public ScannedFilesFilter(Set<String> allowedFileExtensions) {
super(allowedFileExtensions);
}
@Override
public boolean select(Viewer viewer, Object parent, Object element) {
if (element instanceof IType) {
IBeansProject beansProj = BeansCorePlugin.getModel().getProject(project.getProject());
if (beansProj != null) {
IType type = (IType) element;
IBeansConfig beansConfig = project.getConfig(BeansConfigFactory.JAVA_CONFIG_TYPE
+ type.getFullyQualifiedName());
return beansConfig == null;
}
return true;
}
return super.select(viewer, parent, element);
}
}
private class LabelProvider extends JavaElementLabelProvider implements IColorProvider {
public LabelProvider() {
super(JavaElementLabelProvider.SHOW_BASICS | JavaElementLabelProvider.SHOW_OVERLAY_ICONS
| JavaElementLabelProvider.SHOW_SMALL_ICONS);
}
@Override
public String getText(Object element) {
String label = super.getText(element);
if (element instanceof IFile) {
IBeansConfig bc = BeansCorePlugin.getModel().getConfig((IFile) element, true);
if (bc instanceof IImportedBeansConfig) {
label += " [imported]";
}
if (bc != null && bc.getType() == IBeansConfig.Type.AUTO_DETECTED) {
label += " [auto detected]";
}
}
else if (element instanceof ZipEntryStorage) {
return ((ZipEntryStorage) element).getEntryName();
}
if (label != null && label.startsWith(IBeansConfig.EXTERNAL_FILE_NAME_PREFIX)) {
label = label.substring(IBeansConfig.EXTERNAL_FILE_NAME_PREFIX.length());
}
return label;
}
public Color getBackground(Object element) {
return null;
}
public Color getForeground(Object element) {
if (element instanceof IBeansConfig
&& ((IBeansConfig) element).getType() == IBeansConfig.Type.AUTO_DETECTED) {
return grayColor;
}
return null;
}
}
private class ScannedFilesLabelProvider extends JavaElementLabelProvider {
@Override
public String getText(Object element) {
if (element instanceof IType) {
return ((IType) element).getFullyQualifiedName();
}
if (element instanceof IFile) {
return ((IFile) element).getProjectRelativePath().toString();
}
return super.getText(element);
}
}
private class ScannedFilesValidator extends StorageSelectionValidator {
public ScannedFilesValidator(boolean multiSelect) {
super(multiSelect);
}
@Override
public boolean isValid(Object selection) {
if (selection instanceof IType) {
return true;
}
return super.isValid(selection);
}
}
}