/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Project : WebQQCore Package : iqq.im File : WebQQClient.java Author : solosky
* < solosky772@qq.com >
* Created : 2012-8-1 License : Apache License 2.0
*/
package iqq.im;
import iqq.im.actor.QQActor;
import iqq.im.actor.QQActorDispatcher;
import iqq.im.bean.QQAccount;
import iqq.im.bean.QQBuddy;
import iqq.im.bean.QQDiscuz;
import iqq.im.bean.QQGroup;
import iqq.im.bean.QQGroupSearchList;
import iqq.im.bean.QQMsg;
import iqq.im.bean.QQStatus;
import iqq.im.bean.QQStranger;
import iqq.im.bean.QQUser;
import iqq.im.bean.content.CFaceItem;
import iqq.im.bean.content.OffPicItem;
import iqq.im.core.QQContext;
import iqq.im.core.QQModule;
import iqq.im.core.QQService;
import iqq.im.core.QQSession;
import iqq.im.core.QQSession.State;
import iqq.im.core.QQStore;
import iqq.im.event.QQActionEvent;
import iqq.im.event.QQActionFuture;
import iqq.im.event.QQNotifyEvent;
import iqq.im.event.QQNotifyEventArgs;
import iqq.im.event.QQNotifyEventArgs.ImageVerify.VerifyType;
import iqq.im.event.future.ProcActionFuture;
import iqq.im.module.BuddyModule;
import iqq.im.module.CategoryModule;
import iqq.im.module.ChatModule;
import iqq.im.module.DiscuzModule;
import iqq.im.module.GroupModule;
import iqq.im.module.LoginModule;
import iqq.im.module.ProcModule;
import iqq.im.module.UserModule;
import iqq.im.service.ApacheHttpService;
import iqq.im.service.HttpService;
import iqq.im.service.HttpService.ProxyType;
import java.io.File;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
/**
*
* WebQQ客户的实现
*
* @author solosky <solosky772@qq.com>
*
*/
public class WebQQClient implements QQClient, QQContext {
private static final Logger LOG = Logger.getLogger(WebQQClient.class);
private Map<QQService.Type, QQService> services;
private Map<QQModule.Type, QQModule> modules;
private QQActorDispatcher actorDispatcher;
private QQAccount account;
private QQSession session;
private QQStore store;
private QQNotifyListener notifyListener;
public WebQQClient(String username, String password,
QQNotifyListener notifyListener, QQActorDispatcher actorDispatcher) {
this.modules = new HashMap<QQModule.Type, QQModule>();
this.services = new HashMap<QQService.Type, QQService>();
this.modules.put(QQModule.Type.LOGIN, new LoginModule());
this.modules.put(QQModule.Type.PROC, new ProcModule());
this.modules.put(QQModule.Type.USER, new UserModule());
this.modules.put(QQModule.Type.BUDDY, new BuddyModule());
this.modules.put(QQModule.Type.CATEGORY, new CategoryModule());
this.modules.put(QQModule.Type.GROUP, new GroupModule());
this.modules.put(QQModule.Type.CHAT, new ChatModule());
this.modules.put(QQModule.Type.DISCUZ, new DiscuzModule());
this.services.put(QQService.Type.HTTP, new ApacheHttpService());
this.account = new QQAccount();
this.account.setUsername(username);
this.account.setPassword(password);
this.session = new QQSession();
this.store = new QQStore();
this.notifyListener = notifyListener;
this.actorDispatcher = actorDispatcher;
this.init();
}
@SuppressWarnings("unchecked")
@Override
public <T extends QQModule> T getModule(QQModule.Type type) {
return (T) modules.get(type);
}
@SuppressWarnings("unchecked")
@Override
public <T extends QQService> T getSerivce(QQService.Type type) {
return (T) services.get(type);
}
@Override
public void setHttpUserAgent(String userAgent) {
HttpService http = getSerivce(QQService.Type.HTTP);
http.setUserAgent(userAgent);
}
@Override
public void setHttpProxy(ProxyType proxyType, String proxyHost,
int proxyPort, String proxyAuthUser, String proxyAuthPassword) {
HttpService http = getSerivce(QQService.Type.HTTP);
http.setHttpProxy(proxyType, proxyHost, proxyPort,
proxyAuthUser, proxyAuthPassword);
}
@Override
public QQAccount getAccount() {
return account;
}
@Override
public QQStore getStore() {
return store;
}
@Override
public void pushActor(QQActor actor) {
actorDispatcher.pushActor(actor);
}
private void init() {
try {
for (QQService.Type type : services.keySet()) {
QQService service = services.get(type);
service.init(this);
}
for (QQModule.Type type : modules.keySet()) {
QQModule module = modules.get(type);
module.init(this);
}
actorDispatcher.init(this);
store.init(this);
} catch (QQException e) {
LOG.warn("init error:", e);
}
}
public void destroy() {
try {
for (QQModule.Type type : modules.keySet()) {
QQModule module = modules.get(type);
module.destroy();
}
for (QQService.Type type : services.keySet()) {
QQService service = services.get(type);
service.destroy();
}
actorDispatcher.destroy();
store.destroy();
} catch (QQException e) {
LOG.warn("destroy error:", e);
}
}
@Override
public QQActionFuture login(QQStatus status, final QQActionListener listener) {
//检查客户端状态,是否允许登陆
if (session.getState() == State.ONLINE) {
throw new IllegalArgumentException("client is aready online !!!");
}
getAccount().setStatus(status);
getSession().setState(QQSession.State.LOGINING);
ProcModule procModule = (ProcModule) getModule(QQModule.Type.PROC);
return procModule.login(listener);
}
@Override
public QQActionFuture relogin(QQStatus status, final QQActionListener listener) {
if (session.getState() == State.ONLINE) {
throw new IllegalArgumentException("client is aready online !!!");
}
getAccount().setStatus(status);
getSession().setState(QQSession.State.LOGINING);
ProcModule procModule = (ProcModule) getModule(QQModule.Type.PROC);
return procModule.relogin(status, listener);
}
public void getCaptcha(QQActionListener listener) {
LoginModule loginModule = (LoginModule) getModule(QQModule.Type.LOGIN);
loginModule.getCaptcha(getAccount().getUin(), listener);
}
@Override
public QQSession getSession() {
return session;
}
@Override
public void fireNotify(QQNotifyEvent event) {
if (notifyListener != null) {
try {
notifyListener.onNotifyEvent(event);
} catch (Throwable e) {
LOG.warn("fireNotify Error!!", e);
}
}
}
@Override
public void beginPollMsg() {
if (session.getState() == QQSession.State.OFFLINE) {
throw new IllegalArgumentException("client is aready offline !!!");
}
ProcModule procModule = (ProcModule) getModule(QQModule.Type.PROC);
procModule.doPollMsg();
}
@Override
public QQActionFuture getBuddyList(QQActionListener listener) {
CategoryModule categoryModule = (CategoryModule) getModule(QQModule.Type.CATEGORY);
return categoryModule.getCategoryList(listener);
}
@Override
public QQActionFuture getGroupList(QQActionListener listener) {
GroupModule groupModule = (GroupModule) getModule(QQModule.Type.GROUP);
return groupModule.getGroupList(listener);
}
@Override
public QQActionFuture getOnlineList(QQActionListener qqActionListener) {
BuddyModule buddyModule = getModule(QQModule.Type.BUDDY);
return buddyModule.getOnlineBuddy(qqActionListener);
}
@Override
public QQActionFuture getRecentList(QQActionListener qqActionListener) {
BuddyModule buddyModule = getModule(QQModule.Type.BUDDY);
return buddyModule.getRecentList(qqActionListener);
}
@Override
public QQActionFuture getUserQQ(QQUser user, QQActionListener qqActionListener) {
UserModule userModule = getModule(QQModule.Type.USER);
return userModule.getUserAccount(user, qqActionListener);
}
@Override
public QQActionFuture logout(final QQActionListener listener) {
if (session.getState() == QQSession.State.OFFLINE) {
throw new IllegalArgumentException("client is aready offline !!!");
}
ProcModule procModule = (ProcModule) getModule(QQModule.Type.PROC);
return procModule.doLogout(new QQActionListener() {
public void onActionEvent(QQActionEvent event) {
// 无论退出登录失败还是成功,都需要释放资源
if (event.getType() == QQActionEvent.Type.EVT_OK
|| event.getType() == QQActionEvent.Type.EVT_ERROR) {
session.setState(QQSession.State.OFFLINE);
destroy();
}
if (listener != null) {
listener.onActionEvent(event);
}
}
});
}
@Override
public QQActionFuture changeStatus(final QQStatus status, final QQActionListener listener) {
UserModule userModule = (UserModule) getModule(QQModule.Type.USER);
return userModule.changeStatus(status, listener);
}
@Override
public QQActionFuture getGroupFace(QQGroup group, QQActionListener qqActionListener) {
GroupModule mod = getModule(QQModule.Type.GROUP);
return mod.getGroupFace(group, qqActionListener);
}
@Override
public QQActionFuture getGroupInfo(QQGroup group, QQActionListener qqActionListener) {
GroupModule mod = getModule(QQModule.Type.GROUP);
return mod.getGroupInfo(group, qqActionListener);
}
@Override
public QQActionFuture getGroupGid(QQGroup group, QQActionListener qqActionListener) {
GroupModule mod = getModule(QQModule.Type.GROUP);
return mod.getGroupGid(group, qqActionListener);
}
@Override
public QQActionFuture getUserFace(QQUser user, QQActionListener qqActionListener) {
UserModule mod = getModule(QQModule.Type.USER);
return mod.getUserFace(user, qqActionListener);
}
@Override
public QQActionFuture getUserSign(QQUser user, QQActionListener qqActionListener) {
UserModule mod = getModule(QQModule.Type.USER);
return mod.getUserSign(user, qqActionListener);
}
@Override
public QQActionFuture getUserLevel(QQUser user, QQActionListener qqActionListener) {
UserModule mod = getModule(QQModule.Type.USER);
return mod.getUserLevel(user, qqActionListener);
}
@Override
public QQActionFuture getUserInfo(QQUser user, QQActionListener qqActionListener) {
UserModule mod = getModule(QQModule.Type.USER);
return mod.getUserInfo(user, qqActionListener);
}
@Override
public QQActionFuture getStrangerInfo(QQUser user, QQActionListener qqActionListener) {
UserModule mod = getModule(QQModule.Type.USER);
return mod.getStrangerInfo(user, qqActionListener);
}
@Override
public QQActionFuture sendMsg(QQMsg msg, QQActionListener qqActionListener) {
ChatModule mod = getModule(QQModule.Type.CHAT);
return mod.sendMsg(msg, qqActionListener);
}
@Override
public QQActionFuture sendShake(QQUser user, QQActionListener qqActionListener) {
ChatModule mod = getModule(QQModule.Type.CHAT);
return mod.sendShake(user, qqActionListener);
}
@Override
public QQActionFuture getOffPic(OffPicItem offpic, QQMsg msg, OutputStream picout,
QQActionListener listener) {
ChatModule mod = getModule(QQModule.Type.CHAT);
return mod.getOffPic(offpic, msg, picout, listener);
}
@Override
public QQActionFuture getUserPic(CFaceItem cface, QQMsg msg,
OutputStream picout, QQActionListener listener) {
ChatModule mod = getModule(QQModule.Type.CHAT);
return mod.getUserPic(cface, msg, picout, listener);
}
@Override
public QQActionFuture getGroupPic(CFaceItem cface, QQMsg msg,
OutputStream picout, QQActionListener listener) {
ChatModule mod = getModule(QQModule.Type.CHAT);
return mod.getGroupPic(cface, msg, picout, listener);
}
@Override
public QQActionFuture uploadOffPic(QQUser user, File file, QQActionListener listener) {
ChatModule mod = getModule(QQModule.Type.CHAT);
return mod.uploadOffPic(user, file, listener);
}
@Override
public QQActionFuture uploadCustomPic(File file, QQActionListener listener) {
ChatModule mod = getModule(QQModule.Type.CHAT);
return mod.uploadCFace(file, listener);
}
@Override
public QQActionFuture sendInputNotify(QQUser user, QQActionListener listener) {
ChatModule mod = getModule(QQModule.Type.CHAT);
return mod.sendInputNotify(user, listener);
}
@Override
public QQActionFuture getDiscuzList(QQActionListener qqActionListener) {
DiscuzModule mod = getModule(QQModule.Type.DISCUZ);
return mod.getDiscuzList(qqActionListener);
}
@Override
public QQActionFuture getDiscuzInfo(QQDiscuz discuz, QQActionListener qqActionListener) {
DiscuzModule mod = getModule(QQModule.Type.DISCUZ);
return mod.getDiscuzInfo(discuz, qqActionListener);
}
@Override
public QQActionFuture getSessionMsgSig(QQStranger user, QQActionListener qqActionListener) {
ChatModule mod = getModule(QQModule.Type.CHAT);
return mod.getSessionMsgSig(user, qqActionListener);
}
public QQActionFuture getGroupMemberStatus(QQGroup group, QQActionListener listener) {
GroupModule mod = getModule(QQModule.Type.GROUP);
return mod.getMemberStatus(group, listener);
}
@Override
public void submitVerify(String code, QQNotifyEvent verifyEvent) {
QQNotifyEventArgs.ImageVerify verify
= (QQNotifyEventArgs.ImageVerify) verifyEvent.getTarget();
if (verify.type == VerifyType.LOGIN) {
ProcModule mod = getModule(QQModule.Type.PROC);
mod.loginWithVerify(code, (ProcActionFuture) verify.future);
}
}
@Override
public QQActionFuture freshVerify(QQNotifyEvent verifyEvent, QQActionListener listener) {
LoginModule mod = getModule(QQModule.Type.LOGIN);
return mod.getCaptcha(account.getUin(), listener);
}
@Override
public QQActionFuture updateGroupMessageFilter(QQActionListener listener) {
GroupModule mod = getModule(QQModule.Type.GROUP);
return mod.updateGroupMessageFilter(listener);
}
@Override
public QQActionFuture searchGroupGetList(QQGroupSearchList resultList, QQActionListener listener) {
GroupModule mod = getModule(QQModule.Type.GROUP);
return mod.searchGroup(resultList, listener);
}
@Override
public void cancelVerify(QQNotifyEvent verifyEvent) throws QQException {
QQNotifyEventArgs.ImageVerify verify
= (QQNotifyEventArgs.ImageVerify) verifyEvent.getTarget();
verify.future.cancel();
}
@Override
public List<QQBuddy> getBuddyList() {
return getStore().getBuddyList();
}
@Override
public List<QQGroup> getGroupList() {
return getStore().getGroupList();
}
@Override
public List<QQDiscuz> getDiscuzList() {
return getStore().getDiscuzList();
}
@Override
public QQBuddy getBuddyByUin(long uin) {
return getStore().getBuddyByUin(uin);
}
@Override
public boolean isOnline() {
return getSession().getState() == QQSession.State.ONLINE;
}
@Override
public boolean isLogining() {
return getSession().getState() == QQSession.State.LOGINING;
}
@Override
public QQActionFuture setLongNick(String longNick, QQActionListener listener) {
UserModule mod = getModule(QQModule.Type.USER);
return mod.setLongNick(longNick, listener);
}
}