/*
* Copyright 2004 - 2009 Christian Sprajc. All rights reserved.
*
* This file is part of PowerFolder.
*
* PowerFolder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*
* PowerFolder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PowerFolder. If not, see <http://www.gnu.org/licenses/>.
*
* $Id: SendMessageTask.java 9008 2009-08-13 12:56:12Z harry $
*/
package de.dal33t.powerfolder.task;
import java.util.logging.Level;
import java.util.logging.Logger;
import de.dal33t.powerfolder.clientserver.ServerClient;
import de.dal33t.powerfolder.clientserver.ServerClientEvent;
import de.dal33t.powerfolder.clientserver.ServerClientListener;
import de.dal33t.powerfolder.light.AccountInfo;
import de.dal33t.powerfolder.util.Reject;
/**
* Task that get executed when the server is connected.
*
* @author sprajc
*/
public abstract class ServerRemoteCallTask extends PersistentTask {
private static final Logger LOG = Logger
.getLogger(ServerRemoteCallTask.class.getName());
private static final long serialVersionUID = 100L;
private transient ServerClientListener listener;
/**
* The issuer of the remote call.
*/
private final AccountInfo issuer;
/**
* @param issuer
* the issuer of the task. The same user must be logged in to the
* server for a successful executing. Otherwise task will be
* scheduled until the original issuer re-logs in.
* @param daysToExpire
* day to expire/remove if not successfully executed.
*/
protected ServerRemoteCallTask(AccountInfo issuer, int daysToExpire) {
super(daysToExpire);
Reject.ifNull(issuer, "Account issuer");
this.issuer = issuer;
}
/**
* It does not matter what user/account executes this remote call.
*
* @param daysToExpire
* day to expire/remove if not successfully executed.
*/
protected ServerRemoteCallTask(int daysToExpire) {
super(daysToExpire);
this.issuer = null;
}
/**
* @return the issuer of this task. if set task will only execute if the
* client is logged in with the same account at the server.
*/
protected AccountInfo getIssuer() {
return issuer;
}
@Override
public void initialize() {
if (isExpired()) {
// Expired
remove();
return;
}
ServerClient client = getController().getOSClient();
if (!checkAndExecute(client)) {
// Queue for later executing
listener = new MyServerClientListener();
client.addListener(listener);
}
}
@Override
public void remove() {
super.remove();
if (listener != null) {
getController().getOSClient().removeListener(listener);
}
}
/**
* Execute a remote call to the service. When this method is called it is
* guranteed that the server is connected. The call is responsible for
* removing the task via {@link #remove()}.
*
* @param client
* @throws Exception
* if something went wrong. Task will be KEPT for later
* execution re-try.
*/
protected abstract void executeRemoteCall(ServerClient client)
throws Exception;
// Internal ***************************************************************
private boolean checkAndExecute(ServerClient client) {
if (!client.isConnected()) {
return false;
}
if (issuer != null) {
// Check if issuer matches the currently logged in user.
AccountInfo currentLogin = client.getAccountInfo();
if (currentLogin == null) {
return false;
}
if (!issuer.equals(currentLogin)) {
// Mismatch, don't do it.
return false;
}
}
try {
executeRemoteCall(client);
return true;
} catch (Exception e) {
LOG.log(Level.SEVERE,
"Exception while executing remote call. " + e, e);
return false;
}
}
private class MyServerClientListener implements ServerClientListener {
public void accountUpdated(ServerClientEvent event) {
checkAndExecute(event.getClient());
}
public void login(ServerClientEvent event) {
checkAndExecute(event.getClient());
}
public void serverConnected(ServerClientEvent event) {
checkAndExecute(event.getClient());
}
public void nodeServerStatusChanged(ServerClientEvent event) {
checkAndExecute(event.getClient());
}
public void serverDisconnected(ServerClientEvent event) {
}
public boolean fireInEventDispatchThread() {
return false;
}
}
}