/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
/**
*
*/
package org.xmind.core.internal.command.remote;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.osgi.util.NLS;
import org.xmind.core.command.remote.ICommandServiceDomain;
import org.xmind.core.command.remote.ICommandServiceDomainDirector;
/**
* @author Frank Shaka
*/
public class DefaultCommandServiceDomainDirector implements
ICommandServiceDomainDirector {
private ICommandServiceDomain domain;
private int connectionCount = 0;
private int status = INACTIVE;
private Object statusLock = new Object();
public DefaultCommandServiceDomainDirector() {
}
public void init(ICommandServiceDomain domain) {
this.domain = domain;
}
/**
* @return the domain
*/
public ICommandServiceDomain getDomain() {
return domain;
}
public IStatus connect(IProgressMonitor monitor) {
boolean shouldWait = false;
synchronized (statusLock) {
if (status == ACTIVE) {
connectionCount++;
monitor.done();
return Status.OK_STATUS;
} else if (status == INACTIVE) {
status = ACTIVATING;
} else if (status == ACTIVATING) {
shouldWait = true;
} else {
return Status.CANCEL_STATUS;
}
}
monitor.beginTask(NLS.bind(
Messages.DefaultCommandServiceDomainDirector_ConnectionRemoteCommand,
getDomain().getName()), 1);
if (shouldWait) {
try {
while (true) {
synchronized (statusLock) {
if (status == ACTIVE) {
connectionCount++;
monitor.done();
return Status.OK_STATUS;
} else if (status == INACTIVE || status == DEACTIVATING) {
return Status.CANCEL_STATUS;
}
}
Thread.sleep(5);
}
} catch (InterruptedException e) {
return Status.CANCEL_STATUS;
}
} else {
IStatus activated;
try {
activated = activate(new SubProgressMonitor(monitor, 1));
} catch (Throwable e) {
activated = new Status(IStatus.ERROR,
RemoteCommandPlugin.PLUGIN_ID, null, e);
}
if (activated != null && !activated.isOK()) {
synchronized (statusLock) {
status = DEACTIVATING;
}
try {
deactivate(new NullProgressMonitor());
} catch (Throwable e) {
RemoteCommandPlugin.log(
"Failed to deactivate command service domain.", e); //$NON-NLS-1$
}
synchronized (statusLock) {
status = INACTIVE;
return activated;
}
} else {
synchronized (statusLock) {
status = ACTIVE;
connectionCount++;
monitor.done();
return Status.OK_STATUS;
}
}
}
}
public IStatus disconnect(IProgressMonitor monitor) {
synchronized (statusLock) {
if (status == INACTIVE || status == DEACTIVATING) {
monitor.done();
return Status.OK_STATUS;
} else if (status == ACTIVATING) {
return Status.CANCEL_STATUS;
} else {
connectionCount--;
if (connectionCount > 0)
return Status.OK_STATUS;
status = DEACTIVATING;
}
}
monitor.beginTask(NLS.bind(
Messages.DefaultCommandServiceDomainDirector_DisconnectionRemoteCommand,
getDomain().getName()), 1);
IStatus deactivated;
try {
deactivated = deactivate(new SubProgressMonitor(monitor, 1));
} catch (Throwable e) {
deactivated = new Status(IStatus.ERROR,
RemoteCommandPlugin.PLUGIN_ID, null, e);
}
synchronized (statusLock) {
status = INACTIVE;
}
return deactivated;
}
/**
* @param monitor
* @return
*/
private IStatus activate(IProgressMonitor monitor) {
monitor.beginTask(null, 100);
IProgressMonitor subMonitor;
// Activate remote command service discoverer:
subMonitor = new SubProgressMonitor(monitor, 40);
IStatus activated = getDomain().getRemoteCommandServiceDiscoverer()
.activate(subMonitor);
if (activated != null && !activated.isOK())
return activated;
if (subMonitor.isCanceled())
return Status.CANCEL_STATUS;
subMonitor.done();
// Deploy local command server:
subMonitor = new SubProgressMonitor(monitor, 30);
IStatus deployed = getDomain().getCommandServer().deploy(subMonitor);
if (deployed != null && !deployed.isOK())
return deployed;
if (subMonitor.isCanceled())
return Status.CANCEL_STATUS;
subMonitor.done();
// Register local command server as a command service:
getDomain().getCommandServerAdvertiser().setRegisteringInfo(
getDomain().getCommandServer().getRegisteringInfo());
subMonitor = new SubProgressMonitor(monitor, 30);
IStatus registered = getDomain().getCommandServerAdvertiser().register(
subMonitor);
if (registered != null && !registered.isOK())
return registered;
if (subMonitor.isCanceled())
return Status.CANCEL_STATUS;
subMonitor.done();
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
monitor.done();
return Status.OK_STATUS;
}
/**
* @param nullProgressMonitor
* @return
*/
private IStatus deactivate(IProgressMonitor monitor) {
monitor.beginTask(null, 100);
IProgressMonitor subMonitor;
// Unregister local command server as a command service:
subMonitor = new SubProgressMonitor(monitor, 30);
IStatus unregistered = getDomain().getCommandServerAdvertiser()
.unregister(subMonitor);
if (unregistered != null && !unregistered.isOK())
return unregistered;
if (subMonitor.isCanceled())
return Status.CANCEL_STATUS;
subMonitor.done();
// Undeploy local command server:
subMonitor = new SubProgressMonitor(monitor, 30);
IStatus undeployed = getDomain().getCommandServer()
.undeploy(subMonitor);
if (undeployed != null && !undeployed.isOK())
return undeployed;
if (subMonitor.isCanceled())
return Status.CANCEL_STATUS;
subMonitor.done();
// Deactivate remote command service discoverer:
subMonitor = new SubProgressMonitor(monitor, 40);
IStatus deactivated = getDomain().getRemoteCommandServiceDiscoverer()
.deactivate(subMonitor);
if (deactivated != null && !deactivated.isOK())
return deactivated;
if (subMonitor.isCanceled())
return Status.CANCEL_STATUS;
subMonitor.done();
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
monitor.done();
return Status.OK_STATUS;
}
/*
* (non-Javadoc)
*
* @see
* org.xmind.core.command.remote.ICommandServiceDomainDirector#getStatus()
*/
public int getStatus() {
synchronized (statusLock) {
return status;
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object getAdapter(Class adapter) {
return null;
}
}