📄 application.java
字号:
/*******************************************************************************
* Copyright (c) 2006 Koji Hisano <hisano@gmail.com> - UBION Inc. Developer
* Copyright (c) 2006 UBION Inc. <http://www.ubion.co.jp/>
*
* Copyright (c) 2006 Skype Technologies S.A. <http://www.skype.com/>
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Common Public License v1.0 which accompanies
* this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* Koji Hisano - initial API and implementation
* Bart Lamot - good javadocs
* Adrian Cockcroft - fixed null friend problem
******************************************************************************/
package com.skype;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.skype.connector.AbstractConnectorListener;
import com.skype.connector.Connector;
import com.skype.connector.ConnectorException;
import com.skype.connector.ConnectorListener;
import com.skype.connector.ConnectorMessageEvent;
/**
* Implements the AP2AP API.
*
* @see https://developer.skype.com/Docs/ApiDoc/Application_to_application_commands
* @author Koji Hisano
*/
public final class Application extends SkypeObject {
/**
* Collection of Application objects.
*/
private static final Map<String, Application> applications = new HashMap<String, Application>();
/**
* Returns the Application object by the specified id.
*
* @param id whose associated Application object is to be returned.
* @return Application object with ID == id.
* @throws SkypeException when connection has gone bad.
*/
static Application getInstance(final String id) throws SkypeException {
synchronized(applications) {
if(!applications.containsKey(id)) {
applications.put(id, new Application(id));
}
return applications.get(id);
}
}
/**
* Application name, used to register with the Skype client.
*/
private final String name;
/**
* Used for synchronisation.
*/
private final Object connectMutex = new Object();
/**
* List of listeners.
*/
private final List<ApplicationListener> listeners = Collections.synchronizedList(new ArrayList<ApplicationListener>());
/**
* Table of streams.
*/
private final Map<String, Stream> streams = new HashMap<String, Stream>();
/**
* Listener for messages received through Skype.
*/
private final ConnectorListener dataListener = new DataListener();
/**
* Boolean to check the application state.
*/
private boolean isFinished;
/**
* Ending synchronisation helper field.
*/
private final Object isFinishedFieldMutex = new Object();
/**
* Shutdownhook thread for cleaning up all instances.
*/
private Thread shutdownHookForFinish;
/**
* Application exception handler.
*/
private SkypeExceptionHandler exceptionHandler;
/**
* Constructor.
*
* @param newName An arbitrary name to identify the application that will be exchanging data.
* @throws SkypeException when connection to Skype client has gone bad.
*/
private Application(final String newName) throws SkypeException {
assert newName != null;
this.name = newName;
initialize();
}
/**
* Initializes the AP2AP.
*
* @throws SkypeException when connection is gone bad. if connection could not be established.
*/
void initialize() throws SkypeException {
try {
String response = Connector.getInstance().execute("CREATE APPLICATION " + name);
Utils.checkError(response);
Connector.getInstance().addConnectorListener(dataListener);
shutdownHookForFinish = new Thread() {
@Override
public void run() {
try {
Connector.getInstance().execute("DELETE APPLICATION " + Application.this.getName());
} catch(ConnectorException e) {
// because we are already stopping the app ignore the errors.
}
}
};
Runtime.getRuntime().addShutdownHook(shutdownHookForFinish);
} catch(ConnectorException e) {
Utils.convertToSkypeException(e);
}
}
/**
* Enable nice printing of Object, by returning the app name.
*
* @return AP2AP application name.
*/
public String toString() {
return getName();
};
/**
* End the AP2AP data connection.
*
* @throws SkypeException when connection is gone bad.
*/
public void finish() throws SkypeException {
synchronized(isFinishedFieldMutex) {
if(!isFinished) {
Connector.getInstance().removeConnectorListener(dataListener);
Runtime.getRuntime().removeShutdownHook(shutdownHookForFinish);
isFinished = true;
try {
String response = Connector.getInstance().execute("DELETE APPLICATION " + getName());
Utils.checkError(response);
} catch(ConnectorException e) {
Utils.convertToSkypeException(e);
}
}
}
}
/**
* Return the application name.
*
* @return the application name.
*/
public String getName() {
return name;
}
/**
* Find connetable users. Connections are only allowed to connectable users, online parties who are in the user's contact list or have active ongoing communication with the user.
*
* @return Stream of users.
* @throws SkypeException when connection is gone bad.
*/
public Stream[] connectToAll() throws SkypeException {
return connect(getAllConnectableFriends());
}
/**
* Setup an AP2AP connection with a Friend.
*
* @param friends The ppl to start a AP2AP with.
* @return The connected streams.
* @throws SkypeException when connection is gone bad.
*/
public Stream[] connect(final Friend... friends) throws SkypeException {
Utils.checkNotNull("friends", friends);
synchronized(connectMutex) {
try {
final Object wait = new Object();
ConnectorListener connectorListener = new AbstractConnectorListener() {
public void messageReceived(ConnectorMessageEvent event) {
String message = event.getMessage();
if(message.equals("APPLICATION " + getName() + " CONNECTING ")) {
synchronized(wait) {
wait.notify();
}
}
}
};
try {
Connector.getInstance().addConnectorListener(connectorListener);
synchronized(wait) {
for(Friend friend: friends) {
if(friend != null) {
String result = Connector.getInstance().execute("ALTER APPLICATION " + getName() + " CONNECT " + friend.getId());
Utils.checkError(result);
}
}
try {
// TODO Retuns when not attached to Skype
wait.wait();
} catch(InterruptedException e) {
throw new SkypeException("The connecting was interrupted.", e);
}
}
return getAllStreams(friends);
} catch(ConnectorException e) {
Utils.convertToSkypeException(e);
return null;
} finally {
Connector.getInstance().removeConnectorListener(connectorListener);
}
} catch(SkypeException e) {
for(Stream stream: getAllStreams(friends)) {
try {
stream.disconnect();
} catch(SkypeException e2) {
// do nothing
}
}
throw e;
}
}
}
/**
* Find a connected AP2AP stream with a connectable user.
*
* @param friends to search streams for.
* @return the found streams.
* @throws SkypeException when connection is gone bad.
*/
public Stream[] getAllStreams(final Friend... friends) throws SkypeException {
List<Stream> results = new ArrayList<Stream>();
for(Stream stream: getAllStreams()) {
Friend friend = stream.getFriend();
for(Friend comparedFriend: friends) {
if(friend.equals(comparedFriend)) {
results.add(stream);
}
}
}
return results.toArray(new Stream[0]);
}
/**
* Find all AP2AP streams started.
*
* @return all started streams.
* @throws SkypeException when connection is gone bad.
*/
public Stream[] getAllStreams() throws SkypeException {
String streamIds = Utils.getPropertyWithCommandId("APPLICATION", getName(), "STREAMS");
synchronized(streams) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -