/*****************************************************************************
* Copyright (c) 2006-2013, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
*****************************************************************************/
package org.eclipse.buckminster.ui.prefs;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.buckminster.core.CorePlugin;
import org.eclipse.buckminster.core.materializer.MaterializationJob;
import org.eclipse.buckminster.core.metadata.WorkspaceInfo;
import org.eclipse.buckminster.core.prefedit.IPreferenceDescriptor;
import org.eclipse.buckminster.core.prefedit.IPreferenceValidator;
import org.eclipse.buckminster.core.resolver.IResolverFactory;
import org.eclipse.buckminster.core.resolver.ResolverFactoryMaintainer;
import org.eclipse.buckminster.runtime.IBuckminsterPreferenceConstants;
import org.eclipse.buckminster.runtime.Trivial;
import org.eclipse.buckminster.ui.Messages;
import org.eclipse.buckminster.ui.UiPlugin;
import org.eclipse.buckminster.ui.UiUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.DirectoryFieldEditor;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.FileFieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.jface.preference.PathEditor;
import org.eclipse.jface.preference.RadioGroupFieldEditor;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Group;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
/**
* @author Thomas Hallgren
*
*/
public class DynamicPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage, IBuckminsterPreferenceConstants {
private static IPreferenceValidator nullValidator = new IPreferenceValidator() {
@Override
public boolean validate(String value) {
return true;
}
};
private Composite resolversParent;
private StackLayout resolversStack;
public DynamicPreferencePage() {
super(GRID);
setDescription(Messages.buckminster_preferences);
setPreferenceStore(UiPlugin.getDefault().getBuckminsterPreferenceStore());
}
@Override
public void init(IWorkbench workbench) {
}
@Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(FieldEditor.VALUE)) {
if (event.getSource() instanceof ResolutionResolverListEditor)
selectResolverPropertyPane(event.getNewValue());
} else
super.propertyChange(event);
}
protected void addDynamicFieldEditors(Composite parent, String nodeName, IPreferenceDescriptor[] descriptors) {
final IPreferenceStore nodePrefs = UiPlugin.getDefault().getBuckminsterPreferenceStore(nodeName);
for (final IPreferenceDescriptor descriptor : descriptors) {
String name = descriptor.getName();
String label = descriptor.getLabel();
IPreferenceValidator descValidator = descriptor.getValidator();
if (descValidator == null)
descValidator = nullValidator;
final IPreferenceValidator validator = descValidator;
FieldEditor editor;
switch (descriptor.getType()) {
case Boolean:
editor = new BooleanFieldEditor(name, label, parent) {
@Override
public IPreferenceStore getPreferenceStore() {
return nodePrefs;
}
};
break;
case Directory:
editor = new DirectoryFieldEditor(name, label, parent) {
@Override
public IPreferenceStore getPreferenceStore() {
return nodePrefs;
}
@Override
protected boolean checkState() {
return super.checkState() && validator.validate(UiUtils.trimmedValue(getTextControl()));
}
};
break;
case Enum:
Enum<?>[] enums = descriptor.getEnums();
int idx = enums.length;
String[][] labelsAndValues = new String[idx][2];
while (--idx >= 0) {
labelsAndValues[idx][0] = enums[idx].toString();
labelsAndValues[idx][1] = enums[idx].name();
}
editor = new RadioGroupFieldEditor(name, label, 1, labelsAndValues, parent) {
@Override
public IPreferenceStore getPreferenceStore() {
return nodePrefs;
}
};
break;
case File:
editor = new FileFieldEditor(name, label, parent) {
@Override
public IPreferenceStore getPreferenceStore() {
return nodePrefs;
}
@Override
protected boolean checkState() {
return super.checkState() && validator.validate(UiUtils.trimmedValue(getTextControl()));
}
};
break;
case Integer:
editor = new IntegerFieldEditor(name, label, parent, descriptor.getTextWidth()) {
@Override
public IPreferenceStore getPreferenceStore() {
return nodePrefs;
}
@Override
protected boolean checkState() {
return super.checkState() && validator.validate(UiUtils.trimmedValue(getTextControl()));
}
};
int[] range = descriptor.getIntegerRange();
if (range != null)
((IntegerFieldEditor) editor).setValidRange(range[0], range[1]);
break;
case Path:
editor = new PathEditor(name, label, label, parent) {
@Override
public IPreferenceStore getPreferenceStore() {
return nodePrefs;
}
};
break;
case Password:
editor = new PasswordFieldEditor(name, label, descriptor.getTextWidth(), parent, nodeName) {
@Override
public IPreferenceStore getPreferenceStore() {
return nodePrefs;
}
@Override
protected boolean checkState() {
return validator.validate(UiUtils.trimmedValue(getTextControl()));
}
};
break;
default:
editor = new StringFieldEditor(name, label, descriptor.getTextWidth(), parent) {
@Override
public IPreferenceStore getPreferenceStore() {
return nodePrefs;
}
@Override
protected boolean checkState() {
return validator.validate(UiUtils.trimmedValue(getTextControl()));
}
};
}
addField(editor);
}
}
@Override
protected void createFieldEditors() {
addField(new StringFieldEditor(SITE_NAME, Messages.site_name, getFieldEditorParent()));
addField(new DirectoryFieldEditor(BUCKMINSTER_PROJECT_CONTENTS, Messages.buckminster_project_folder, getFieldEditorParent()));
addField(new EnumFieldEditor(LOG_LEVEL_CONSOLE, Messages.console_logger_level_with_colon, LogLevel.values(), getFieldEditorParent()));
addField(new EnumFieldEditor(LOG_LEVEL_ECLIPSE_LOGGER, Messages.eclipse_logger_level_with_colon, LogLevel.values(), getFieldEditorParent()));
addField(new EnumFieldEditor(LOG_LEVEL_ANT_LOGGER, Messages.ant_logger_level_with_colon, LogLevel.values(), getFieldEditorParent()));
addField(new BooleanFieldEditor(LOG_ECLIPSE_TO_CONSOLE, Messages.copy_eclipse_log_events_to_console, getFieldEditorParent()));
IntegerFieldEditor intEditor = new IntegerFieldEditor(MaterializationJob.MAX_PARALLEL_JOBS, Messages.max_number_of_parallel_materializations,
getFieldEditorParent());
intEditor.setValidRange(1, 12);
addField(intEditor);
intEditor = new IntegerFieldEditor(CONNECTION_RETRY_COUNT, Messages.connection_retry_count, getFieldEditorParent());
intEditor.setValidRange(0, 5);
addField(intEditor);
intEditor = new IntegerFieldEditor(CONNECTION_RETRY_DELAY, Messages.connection_retry_delay_in_seconds, getFieldEditorParent());
intEditor.setValidRange(0, 60);
addField(intEditor);
addField(new ResolutionResolverListEditor(QUERY_RESOLVER_SORT_ORDER, Messages.resolver_order, getFieldEditorParent()));
IResolverFactory[] factories = ResolverFactoryMaintainer.getInstance().getResolverFactories();
int top = factories.length;
if (top == 1) {
IResolverFactory factory = factories[0];
factory.initDefaultPreferences();
NestedFieldEditor nfe = new NestedFieldEditor(factory.getId(), getFieldEditorParent());
addDynamicFieldEditors(nfe.getControl(), factory.getId(), factory.getPreferenceDescriptors());
addField(nfe);
} else if (top > 1) {
// We need a parent that will allow us to switch pane
// dependent on what resolver factory that is selected
//
NestedFieldEditor resolvers = new NestedFieldEditor("", getFieldEditorParent()); //$NON-NLS-1$
addField(resolvers);
resolversParent = resolvers.getControl();
for (int idx = 0; idx < top; ++idx) {
IResolverFactory factory = factories[idx];
factory.initDefaultPreferences();
String factoryId = factory.getId();
NestedFieldEditor nfe = new NestedFieldEditor(factoryId, resolversParent);
Composite nfeComp = nfe.getControl();
nfeComp.setData(factoryId);
addDynamicFieldEditors(nfeComp, factoryId, factory.getPreferenceDescriptors());
addField(nfe);
}
resolversStack = new StackLayout();
resolversParent.setLayout(resolversStack);
resolversParent.setVisible(false);
}
Group tsGroup = new Group(getFieldEditorParent(), SWT.NONE);
tsGroup.setLayout(new GridLayout(2, false));
tsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
tsGroup.setText(Messages.troubleshooting);
UiUtils.createPushButton(tsGroup, Messages.clear_url_cache, new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
CorePlugin plugin = CorePlugin.getDefault();
plugin.clearRemoteFileCache();
plugin.clearURLCache();
}
});
UiUtils.createPushButton(tsGroup, Messages.refresh_meta_data, new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent ev) {
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow wbWin = workbench.getActiveWorkbenchWindow();
if (wbWin == null) {
// Not very likely. Just run it in the UI thread without
// monitor
//
WorkspaceInfo.forceRefreshOnAll(new NullProgressMonitor());
return;
}
try {
wbWin.run(true, true, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
WorkspaceInfo.forceRefreshOnAll(monitor);
} catch (OperationCanceledException e) {
throw new InterruptedException();
}
}
});
} catch (InterruptedException e) {
} catch (Exception e) {
CorePlugin.getLogger().error(e, e.toString());
// We don't care to display exceptions here
}
}
});
}
void selectResolverPropertyPane(Object factoryId) {
if (resolversParent == null)
return;
Control[] children = resolversParent.getChildren();
int idx = children.length;
while (--idx >= 0) {
Control child = children[idx];
if (Trivial.equalsAllowNull(child.getData(), factoryId)) {
resolversStack.topControl = child;
break;
}
}
boolean visible = idx >= 0;
resolversParent.setVisible(visible);
if (visible)
resolversParent.layout();
}
}