add MibewAgent, offline/online icon

git-svn-id: https://webim.svn.sourceforge.net/svnroot/webim/trunk@732 c66351dc-e62f-0410-b875-e3a5c0b9693f
This commit is contained in:
Evgeny Gryaznov 2010-01-17 21:15:31 +00:00
parent cb85159474
commit e453ed2757
10 changed files with 281 additions and 37 deletions

View File

@ -0,0 +1,143 @@
package org.mibew.api;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.security.NoSuchAlgorithmException;
import java.util.LinkedList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
/**
* @author inspirer
*/
public class MibewAgent {
private final MibewAgentOptions fOptions;
private final MibewAgentListener fListener;
private final MibewUpdateThread fThread;
private volatile boolean started;
public MibewAgent(MibewAgentOptions options, MibewAgentListener listener) {
fOptions = options;
fListener = listener;
fThread = new MibewUpdateThread();
started = false;
}
public synchronized void launch() {
if(!started) {
fThread.start();
started = true;
}
}
public synchronized void stop() {
if(started) {
fThread.disconnect();
started = false;
}
}
public boolean isOnline() {
return fThread.isOnline();
}
private void logError(String message, Throwable th) {
System.err.println(message);
}
private class MibewUpdateThread extends Thread {
private volatile boolean fExiting;
private volatile boolean isOnline = false;
private final Object fSync = new Object();
public MibewUpdateThread() {
setName("Mibew Connection thread");
fExiting = false;
}
public void disconnect() {
synchronized (fSync) {
fExiting = true;
fSync.notifyAll();
}
}
@Override
public void run() {
while(!fExiting) {
try {
connectAndTrack();
} catch(InterruptedException ex) {
/* ignore */
} catch(Throwable th) {
logError(th.getMessage(), th);
}
}
setOnline(false);
}
private void setOnline(boolean online) {
if(isOnline != online) {
isOnline = online;
fListener.onlineStateChanged(online);
}
}
public boolean isOnline() {
return isOnline;
}
private void connectAndTrack() throws InterruptedException, UnsupportedEncodingException, NoSuchAlgorithmException, MalformedURLException, ParserConfigurationException, SAXException {
setOnline(false);
MibewConnection conn = new MibewConnection(fOptions.getUrl(), fOptions.getLogin(), fOptions.getPassword()) {
@Override
protected void handleError(String message, Exception ex) {
logError(message, ex);
}
};
if(!conn.connect()) {
logError("Wrong server, login or password.", null);
interruptableSleep(fOptions.getPollingInterval() * 3);
return;
}
final List<MibewThread> createdThreads = new LinkedList<MibewThread>();
MibewTracker mt = new MibewTracker(conn, new MibewTrackerListener(){
@Override
public void threadCreated(MibewThread thread) {
createdThreads.add(thread);
}
});
long maxTime = System.currentTimeMillis() + fOptions.getConnectionRefreshTimeout()*1000;
while(!fExiting && (System.currentTimeMillis() < maxTime)) {
try {
createdThreads.clear();
mt.update();
fListener.updated(mt.getThreads(), createdThreads.toArray(new MibewThread[createdThreads.size()]));
} catch (Exception e) {
setOnline(false);
interruptableSleep(fOptions.getPollingInterval() / 2);
continue;
}
setOnline(true);
interruptableSleep(fOptions.getPollingInterval());
}
conn.disconnect();
}
private void interruptableSleep(long millis) throws InterruptedException {
synchronized (fSync ) {
if(fExiting) {
return;
}
fSync.wait(millis);
}
}
}
}

View File

@ -0,0 +1,10 @@
package org.mibew.api;
public abstract class MibewAgentListener {
protected void onlineStateChanged(boolean isOnline) {
}
protected void updated(MibewThread[] all, MibewThread[] created) {
}
}

View File

@ -0,0 +1,40 @@
package org.mibew.api;
/**
* @author inspirer
*/
public class MibewAgentOptions {
private String fUrl;
private String fLogin;
private String fPassword;
private int fConnectionRefreshTimeout = 900; // 15 minutes
private int fPollingInterval = 3000; // 2 sec
public MibewAgentOptions(String fUrl, String fLogin, String fPassword) {
super();
this.fUrl = fUrl;
this.fLogin = fLogin;
this.fPassword = fPassword;
}
public String getLogin() {
return fLogin;
}
public String getPassword() {
return fPassword;
}
public String getUrl() {
return fUrl;
}
public int getConnectionRefreshTimeout() {
return fConnectionRefreshTimeout;
}
public int getPollingInterval() {
return fPollingInterval;
}
}

View File

@ -1,14 +1,18 @@
package org.mibew.api;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.mibew.api.handlers.UpdateHandler;
import org.xml.sax.SAXException;
/**
* @author inspirer
@ -28,26 +32,18 @@ public class MibewTracker {
this.fThreads = new HashMap<Long, MibewThread>();
}
public void track() throws InterruptedException {
for(int i = 0; i < 5; i++) {
try {
public void update() throws IOException, SAXException, ParserConfigurationException {
MibewResponse response = fConnection.request("operator/update.php", "since=" + fSince);
SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
UpdateHandler handler = new UpdateHandler();
sp.parse(new ByteArrayInputStream(response.getResponse()), handler);
handleResponse(response, handler);
} catch(Exception e) {
System.err.println("update exception: " + e.getMessage());
}
Thread.sleep(1000);
}
}
private void handleResponse(MibewResponse response, UpdateHandler handler) {
private void handleResponse(MibewResponse response, UpdateHandler handler) throws IOException {
if (handler.getResponse() == UpdateHandler.UPD_ERROR) {
System.out.println("Update error: " + handler.getMessage());
throw new IOException("Update error: " + handler.getMessage());
} else if (handler.getResponse() == UpdateHandler.UPD_THREADS) {
System.out.println("Updated.... " + handler.getRevision());
fSince = handler.getRevision();
fLastUpdate = handler.getTime();
List<MibewThread> threads = handler.getThreads();
@ -55,8 +51,7 @@ public class MibewTracker {
processUpdate(threads);
}
} else {
System.out.println("Update error");
System.out.println(response.getResponseText());
throw new IOException("Update error: " + response.getResponseText());
}
}
@ -82,4 +77,9 @@ public class MibewTracker {
public long getLastUpdate() {
return fLastUpdate;
}
public MibewThread[] getThreads() {
Collection<MibewThread> values = fThreads.values();
return values.toArray(new MibewThread[values.size()]);
}
}

View File

@ -56,7 +56,7 @@ public class Application {
}
});
mt.track();
//mt.track();
connection.disconnect();
}

View File

@ -0,0 +1,24 @@
package org.mibew.notifier;
import org.mibew.api.MibewAgent;
import org.mibew.api.MibewAgentListener;
import org.mibew.api.MibewAgentOptions;
public class ConsoleApp {
public static void main(String[] args) {
MibewAgent agent = new MibewAgent(new MibewAgentOptions("http://localhost:8080/webim/", "admin", "1"), new MibewAgentListener() {
@Override
protected void onlineStateChanged(boolean isOnline) {
System.out.println("now " + (isOnline ? "online" : "offline"));
}
});
agent.launch();
try {
Thread.sleep(3500);
} catch (InterruptedException e) {
}
agent.stop();
}
}

View File

@ -1,11 +1,17 @@
package org.mibew.notifier;
import org.mibew.api.MibewAgent;
import org.mibew.api.MibewAgentOptions;
public class NotifyApp {
public static void main(String[] args) {
TrayNotifier tn = new TrayNotifier();
tn.init();
MibewAgent agent = new MibewAgent(new MibewAgentOptions("http://localhost:8080/webim/", "admin", "1"), tn);
agent.launch();
tn.setAgent(agent);
}
}

View File

@ -13,9 +13,17 @@ import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.net.URL;
public class TrayNotifier {
import org.mibew.api.MibewAgent;
import org.mibew.api.MibewAgentListener;
import org.mibew.api.MibewThread;
public class TrayNotifier extends MibewAgentListener {
private TrayIcon trayIcon;
private MibewAgent agent;
private Image online;
private Image offline;
public TrayNotifier() {
}
@ -24,19 +32,22 @@ public class TrayNotifier {
if (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
URL url = this.getClass().getResource("tray.png");
Image image = Toolkit.getDefaultToolkit().getImage(url);
online = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("tray_on.png"));
offline = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("tray_off.png"));
PopupMenu popup = new PopupMenu();
MenuItem exitItem = new MenuItem("Exit", new MenuShortcut(KeyEvent.VK_X));
exitItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(agent != null) {
agent.stop();
}
System.exit(0);
}
});
popup.add(exitItem);
trayIcon = new TrayIcon(image, "Mibew Notifier", popup);
trayIcon = new TrayIcon(offline, "Mibew Notifier", popup);
trayIcon.setImageAutoSize(true);
try {
@ -51,6 +62,16 @@ public class TrayNotifier {
}
}
public void setStatus(boolean online) {
@Override
protected void onlineStateChanged(boolean isOnline) {
trayIcon.setImage(isOnline ? online : offline);
}
@Override
protected void updated(MibewThread[] all, MibewThread[] created) {
}
public void setAgent(MibewAgent agent) {
this.agent = agent;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB