blob: 023ce0508f6386041313670a4887a2852ab9ee40 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 Poznan Supercomputing and Networking Center
* 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:
* Jan Konczak (PSNC) - initial implementation
******************************************************************************/
package org.eclipse.ptp.rm.smoa.ui.actions;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.expressions.EvaluationContext;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.ptp.remote.core.IRemoteFileManager;
import org.eclipse.ptp.remote.core.PTPRemoteCorePlugin;
import org.eclipse.ptp.rm.smoa.core.rservices.SMOAConnection;
import org.eclipse.ptp.rm.smoa.core.rservices.SMOARemoteServices;
import org.eclipse.ptp.rm.smoa.ui.SMOAUIPlugin;
import org.eclipse.ptp.rm.smoa.ui.rservices.SMOAUIFileManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
/**
* Provides dialog for selecting the connection and remote directory.
*
* Has also option to display rules for {@link SMOAToLocalSyncAction} and
* {@link SMOAToRemoteSyncAction} classes.
*/
/* package access */class SelectConnetionAndDestDir {
// Locations in {@link IProject}'s store for keeping settings of this dialog
private static final QualifiedName SMOA_SYNC_PATH = new QualifiedName(
SMOAUIPlugin.PLUGIN_ID, "smoa.sync.rm.path"); //$NON-NLS-1$
private static final QualifiedName SMOA_SYNC_RM = new QualifiedName(
SMOAUIPlugin.PLUGIN_ID, "smoa.sync.rm.name"); //$NON-NLS-1$
private static final QualifiedName SMOA_SYNC_CREATE = new QualifiedName(
SMOAUIPlugin.PLUGIN_ID, "smoa.sync.rm.create"); //$NON-NLS-1$
private static final QualifiedName SMOA_SYNC_RULES = new QualifiedName(
SMOAUIPlugin.PLUGIN_ID, "smoa.sync.rsync.rules"); //$NON-NLS-1$
/**
* Set of default ignore rules, loaded when the project has none in it's
* settings
*/
private static final String DEFAULT_RULES = Messages.SelectConnetionAndDestDir_DefaultRules;
/** Tries to retrieve the IProject from event */
static public IProject getSelectedProject(ExecutionEvent execEvent)
throws ExecutionException {
Object object = execEvent.getApplicationContext();
if (!(object instanceof EvaluationContext)) {
throw new ExecutionException("EvaluationContext"); //$NON-NLS-1$
}
final EvaluationContext context = (EvaluationContext) execEvent
.getApplicationContext();
object = context.getDefaultVariable();
if (!(object instanceof List)) {
throw new ExecutionException("List"); //$NON-NLS-1$
}
@SuppressWarnings("unchecked")
final List<Object> list = (List<Object>) object;
object = list.get(0);
if (!(object instanceof IProject)) {
throw new ExecutionException("IProject"); //$NON-NLS-1$
}
final IProject project = (IProject) object;
return project;
}
private final IProject project;
private final SMOARemoteServices rservices = (SMOARemoteServices) PTPRemoteCorePlugin
.getDefault().getRemoteServices("org.eclipse.ptp.remote.SMOARemoteServices"); //$NON-NLS-1$
private String remoteDir = null;
private SMOAConnection connection = null;
private boolean mkdirIfNotExists = false;
private boolean showRules = false;
private String rules = null;
private boolean succeeded = false;
private String windowTitle;
public SelectConnetionAndDestDir(final IProject project) {
this.project = project;
}
public SMOAConnection getConnection() {
return connection;
}
/** Returns directory selected by user for remote synchronization */
public String getRemoteDir() {
return remoteDir;
}
/** Gets remote file store */
public IFileStore getRemoteFileStore() throws CoreException {
if (!succeeded) {
return null;
}
final IRemoteFileManager fileManager = rservices.getFileManager(connection);
final IFileStore resource = fileManager.getResource(remoteDir);
if (mkdirIfNotExists) {
resource.mkdir(0, null);
}
return resource;
}
/** Returns interpreted ignore rules */
public List<Pattern> getRules() {
if (rules == null) {
return null;
}
final Vector<Pattern> v = new Vector<Pattern>();
for (final String rule : rules.split("\n")) { //$NON-NLS-1$
if (!rule.isEmpty()) {
v.add(Pattern.compile(rule));
}
}
return v;
}
/** Returns if the user triggered 'Ok' on the dialog */
public boolean hasSucceeded() {
return succeeded;
}
public boolean isMkdirIfNotExists() {
return mkdirIfNotExists;
}
public boolean isShowRules() {
return showRules;
}
/**
* Opens the dialog and waits till completion
*
* If user selected and accepted the dialog, returns true. False otherwise.
*/
@SuppressWarnings({ "unused", "null" })
public boolean open() throws CoreException {
final Shell topShell = Display.getCurrent().getActiveShell();
final Map<String, SMOAConnection> connections = rservices
.getConnectionManager().getOpenConnections();
// re-labelling connections
final Set<SMOAConnection> temp = new HashSet<SMOAConnection>(
connections.values());
connections.clear();
for (final SMOAConnection c : temp) {
connections.put(c.getRMName(), c);
}
if (connections.isEmpty()) {
final MessageBox mb = new MessageBox(topShell, SWT.ICON_INFORMATION
| SWT.OK);
mb.setText(Messages.SelectConnetionAndDestDir_ErrorNoActiveConnectionTitle);
mb.setMessage(Messages.SelectConnetionAndDestDir_ErrorNoActiveConnection);
mb.open();
return false;
}
final Shell shell = new Shell(topShell, new Shell().getStyle()
| SWT.APPLICATION_MODAL);
shell.setLayout(new GridLayout(3, false));
shell.setText(windowTitle != null ? windowTitle
: Messages.SelectConnetionAndDestDir_DefaultWindowTitle);
new Label(shell, SWT.NONE).setText(Messages.SelectConnetionAndDestDir_ResourceManager);
final Combo combo = new Combo(shell, SWT.READ_ONLY);
final GridData gridData1 = new GridData(GridData.FILL_HORIZONTAL);
combo.setLayoutData(gridData1);
gridData1.horizontalSpan = 2;
for (final String conn : connections.keySet()) {
combo.add(conn);
}
new Label(shell, SWT.NONE)
.setText(Messages.SelectConnetionAndDestDir_RemoteRootPath);
final Text remoteRootPath = new Text(shell, SWT.SINGLE | SWT.BORDER);
remoteRootPath.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
final Button browse = new Button(shell, SWT.PUSH | SWT.BORDER);
browse.setText(Messages.SelectConnetionAndDestDir_Browse);
new Label(shell, SWT.NONE);
final Button cbCreateDir = new Button(shell, SWT.CHECK | SWT.BORDER);
cbCreateDir.setText(Messages.SelectConnetionAndDestDir_CreateIfNotExists);
cbCreateDir.setSelection(true);
new Label(shell, SWT.NONE);
final StyledText rules;
final boolean showRulesLocal = showRules;
if (showRulesLocal) {
final Composite rulesComp = new Composite(shell, SWT.NONE);
final GridData gridData2 = new GridData(GridData.FILL_HORIZONTAL);
rulesComp.setLayoutData(gridData2);
gridData2.horizontalSpan = 3;
rulesComp.setLayout(new GridLayout(1, false));
new Label(rulesComp, SWT.NONE)
.setText(Messages.SelectConnetionAndDestDir_ExcludeRules);
rules = new StyledText(rulesComp, SWT.MULTI | SWT.BORDER
| SWT.V_SCROLL | SWT.H_SCROLL);
rules.getHorizontalBar().setVisible(true);
final GridData gridData = new GridData(GridData.FILL_BOTH);
rules.setLayoutData(gridData);
gridData.minimumHeight = rules.getLineHeight() * 5;
} else {
rules = null;
}
final Composite buttons = new Composite(shell, SWT.NONE);
final GridData gridData3 = new GridData(GridData.FILL_HORIZONTAL);
buttons.setLayoutData(gridData3);
gridData3.horizontalSpan = 3;
buttons.setLayout(new GridLayout(3, false));
new Label(buttons, SWT.NONE).setLayoutData(new GridData(
GridData.FILL_HORIZONTAL));
final Button ok = new Button(buttons, SWT.PUSH | SWT.BORDER);
ok.setText(Messages.SelectConnetionAndDestDir_Ok);
final Button cancel = new Button(buttons, SWT.PUSH | SWT.BORDER);
cancel.setText(Messages.SelectConnetionAndDestDir_Cancel);
remoteRootPath.setEnabled(false);
browse.setEnabled(false);
ok.setEnabled(false);
final Runnable check = new Runnable() {
String previousRM = null;
String previousDir = null;
boolean previousResult = false;
public void run() {
if (showRulesLocal) {
if (rules.getStyleRanges().length != 0) {
ok.setEnabled(false);
return;
}
}
if (combo.getSelectionIndex() == -1) {
ok.setEnabled(false);
return;
}
if (remoteRootPath.getText().isEmpty()) {
ok.setEnabled(false);
return;
}
if (cbCreateDir.getSelection()) {
ok.setEnabled(true);
return;
}
if (combo.getText().equals(previousRM)
&& remoteRootPath.getText().equals(previousDir)) {
ok.setEnabled(previousResult);
return;
}
previousRM = combo.getText();
previousDir = remoteRootPath.getText();
final IRemoteFileManager fileManager = rservices
.getFileManager(connections.get(previousRM));
final IFileStore resource = fileManager.getResource(previousDir);
try {
ok.setEnabled(resource.fetchInfo(0, null).isDirectory());
} catch (final CoreException e) {
final MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR
| SWT.OK);
mb.setText(Messages.SelectConnetionAndDestDir_ErrorByFetchInfoTitle);
mb.setMessage(e.getMessage());
}
previousResult = ok.getEnabled();
}
};
combo.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent arg0) {
widgetSelected(arg0);
}
public void widgetSelected(SelectionEvent arg0) {
remoteRootPath.setEnabled(true);
browse.setEnabled(true);
remoteRootPath.setText(connections.get(combo.getText())
.getHomeDir() + "/" + project.getName()); //$NON-NLS-1$
check.run();
}
});
remoteRootPath.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent arg0) {
check.run();
}
});
browse.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent arg0) {
}
public void widgetSelected(SelectionEvent arg0) {
final SMOAUIFileManager uifm = new SMOAUIFileManager(rservices);
uifm.showConnections(false);
uifm.setConnection(connections.get(combo.getText()));
final String chosen = uifm.browseDirectory(shell,
Messages.SelectConnetionAndDestDir_DirBrowserTitle, remoteRootPath.getText(), 0);
if (chosen != null) {
remoteRootPath.setText(chosen);
}
}
});
if (showRulesLocal) {
rules.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent arg0) {
rules.setStyleRanges(new StyleRange[0]);
int start = 0;
final String[] array = rules.getText().split("\n"); //$NON-NLS-1$
for (int i = 0; i < array.length; ++i) {
if (array[i].isEmpty()) {
start++;
continue;
}
try {
Pattern.compile(array[i]);
} catch (final PatternSyntaxException e) {
final TextStyle textStyle = new TextStyle();
textStyle.underline = true;
textStyle.underlineColor = new Color(rules
.getDisplay(), 255, 0, 0);
textStyle.underlineStyle = SWT.UNDERLINE_ERROR;
final StyleRange style = new StyleRange(textStyle);
style.start = start;
style.length = array[i].length();
rules.setStyleRange(style);
}
start += array[i].length() + 1;
}
check.run();
}
});
}
cancel.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent arg0) {
}
public void widgetSelected(SelectionEvent arg0) {
shell.close();
}
});
cbCreateDir.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent arg0) {
}
public void widgetSelected(SelectionEvent arg0) {
check.run();
}
});
final String[] result = new String[2];
final SMOAConnection[] conn = new SMOAConnection[1];
final boolean[] mkdir = new boolean[1];
ok.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent arg0) {
}
public void widgetSelected(SelectionEvent arg0) {
result[0] = remoteRootPath.getText();
if (showRulesLocal) {
result[1] = rules.getText();
}
conn[0] = connections.get(combo.getText());
mkdir[0] = cbCreateDir.getSelection();
shell.close();
}
});
final String create = project.getPersistentProperty(SMOA_SYNC_CREATE);
if (create != null) {
cbCreateDir.setSelection(create.equals("true")); //$NON-NLS-1$
}
final String rm = project.getPersistentProperty(SMOA_SYNC_RM);
if (rm != null) {
final SMOAConnection c = connections.get(rm);
if (c != null) {
combo.select(combo.indexOf(rm));
}
remoteRootPath.setEnabled(true);
browse.setEnabled(true);
}
final String path = project.getPersistentProperty(SMOA_SYNC_PATH);
if (path != null) {
remoteRootPath.setText(path);
}
if (showRulesLocal) {
final String rulesVar = project.getPersistentProperty(SMOA_SYNC_RULES);
if (rulesVar != null) {
rules.setText(rulesVar);
} else {
rules.setText(DEFAULT_RULES);
}
}
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!shell.getDisplay().readAndDispatch()) {
shell.getDisplay().sleep();
}
}
if (result[0] == null || result[0].isEmpty()) {
return false;
}
connection = conn[0];
remoteDir = result[0];
mkdirIfNotExists = mkdir[0];
if (showRulesLocal) {
this.rules = result[1];
}
project.setPersistentProperty(SMOA_SYNC_PATH, result[0]);
project.setPersistentProperty(SMOA_SYNC_RM, conn[0].getRMName());
project.setPersistentProperty(SMOA_SYNC_CREATE, mkdir[0] ? "true" //$NON-NLS-1$
: "false"); //$NON-NLS-1$
if (showRulesLocal) {
project.setPersistentProperty(SMOA_SYNC_RULES, result[1]);
}
succeeded = true;
return true;
}
/** Adds to the GUI proper dialog for the ignore rules */
public void setShowRules(boolean showRules) {
this.showRules = showRules;
}
public void setWindowTitle(String title) {
windowTitle = title;
}
}