Package net.solosky.maplefetion.client.response

Source Code of net.solosky.maplefetion.client.response.AbstractResponseHandler

/*
* 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  : MapleFetion2
* Package  : net.solosky.maplefetion.client.response
* File     : AbstractResponseHandler.java
* Author   : solosky < solosky772@qq.com >
* Created  : 2010-1-18
* License  : Apache License 2.0
*/
package net.solosky.maplefetion.client.response;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.solosky.maplefetion.FetionContext;
import net.solosky.maplefetion.FetionException;
import net.solosky.maplefetion.NotifyEventListener;
import net.solosky.maplefetion.bean.VerifyImage;
import net.solosky.maplefetion.client.HttpApplication;
import net.solosky.maplefetion.client.ResponseHandler;
import net.solosky.maplefetion.client.SystemException;
import net.solosky.maplefetion.client.dialog.Dialog;
import net.solosky.maplefetion.event.ActionEvent;
import net.solosky.maplefetion.event.action.ActionEventListener;
import net.solosky.maplefetion.event.action.FailureEvent;
import net.solosky.maplefetion.event.action.FailureType;
import net.solosky.maplefetion.event.action.SuccessEvent;
import net.solosky.maplefetion.event.action.SystemErrorEvent;
import net.solosky.maplefetion.event.action.TimeoutEvent;
import net.solosky.maplefetion.event.action.TransferErrorEvent;
import net.solosky.maplefetion.event.action.failure.RequestFailureEvent;
import net.solosky.maplefetion.event.action.failure.SipcFailureEvent;
import net.solosky.maplefetion.event.notify.ImageVerifyEvent;
import net.solosky.maplefetion.sipc.SipcHeader;
import net.solosky.maplefetion.sipc.SipcRequest;
import net.solosky.maplefetion.sipc.SipcResponse;
import net.solosky.maplefetion.sipc.SipcStatus;
import net.solosky.maplefetion.util.XMLHelper;

import org.apache.log4j.Logger;
import org.jdom.Element;

/**
* 所有回复处理器的基类
*
* 提供了回复的处理的模板,根据不同回复状态来回调不同的处理函数
* 子类可以重载自己所需要处理的状态回调来完成不同的处理逻辑
* 默认1xx,2xx的回复状态返回的是成功事件
* 4xx,5xx的回复返回的是失败事件
*
* @author solosky <solosky772@qq.com>
*/
public abstract class AbstractResponseHandler implements ResponseHandler
{
  //客户端
  protected FetionContext context;
  //对话框
  protected Dialog dialog;
  //监听器
  protected ActionEventListener listener;
  //logger
  protected static Logger logger = Logger.getLogger(ResponseHandler.class);
 
  /**
   * 构造函数
   * @param client
   * @param dialog
   * @param listener
   */
  public AbstractResponseHandler(FetionContext context, Dialog dialog, ActionEventListener listener)
  {
    this.context = context;
    this.dialog = dialog;
    this.listener = listener;
  }
 
  /* (non-Javadoc)
     * @see net.solosky.maplefetion.client.ResponseHandler#handle(net.solosky.maplefetion.sipc.SipcResponse)
     */
    @Override
    public void handle(SipcResponse response) throws FetionException
    {
      try {
        //交给子类处理这个回复,并捕获所有异常
        ActionEvent event = this.doHandle(response);
        if(event!=null) {
          this.fireEvent(event);
        }
    } catch (FetionException e) {
      this.fireEvent(new SystemErrorEvent(e));
      throw e;              //重新抛出已知异常
    } catch(Throwable t){
      this.fireEvent(new SystemErrorEvent(t));
      throw new SystemException(t, response.getRequest(), response);    //包装下未知异常为系统异常,重新抛出
    }
    }

   
    /**
     * 超时错误
     */
    public void timeout(SipcRequest request)
    {
    this.fireEvent(new TimeoutEvent());
    }
   
   
    /**
     * 发生了网络错误
     */
    public void ioerror(SipcRequest request)
    {
      this.fireEvent(new TransferErrorEvent());
    }
   
   
   
    /* (non-Javadoc)
   * @see net.solosky.maplefetion.client.ResponseHandler#syserror(net.solosky.maplefetion.sipc.SipcRequest)
   */
  @Override
  public void syserror(SipcRequest request, Throwable t)
  {
    this.fireEvent(new SystemErrorEvent(t));
  }

  /**
     * 触发操作事件
     */
    private void fireEvent(ActionEvent event)
    {
      //用户设置的回调函数调用时可能会出现异常,这里捕获掉所有的异常并记录,防止异常传递到处理链而引起客户端退出
      if(this.listener!=null){
        try {
          this.listener.fireEevent(event);
      } catch (Throwable e) {   
        logger.warn("FireActionEvent error.", e );
      }
    }
    }
    /**
     * 处理这个回复,根据不同的状态回调不同的方法,子类可以重载这个
     * @param response  回复对象
     * @return 处理后会产生一个结果事件
     * @throws FetionException
     */
    protected ActionEvent doHandle(SipcResponse response) throws FetionException
    {
      switch(response.getStatusCode()){
        case SipcStatus.TRYING:          return this.doTrying(response);
        case SipcStatus.ACTION_OK:          return this.doActionOK(response);
        case SipcStatus.SEND_SMS_OK:        return this.doSendSMSOK(response);
        case SipcStatus.NOT_AUTHORIZED:     return this.doNotAuthorized(response);
        case SipcStatus.NOT_FOUND:          return this.doNotFound(response);
        case SipcStatus.EXTENSION_REQUIRED:  return this.doExtensionRequired(response);
        case SipcStatus.BAD_EXTENSION:    return this.doBadExtension(response);
        case SipcStatus.TA_EXIST:           return this.doTaExsit(response);
        case SipcStatus.NO_SUBSCRIPTION:    return this.doNoSubscription(response);
        case SipcStatus.TIME_OUT:           return this.doTimeout(response);
        case SipcStatus.BUSY_HERE:          return this.doBusyHere(response);
        case SipcStatus.FORBIDDEN:          return this.doForbidden(response);
        case SipcStatus.REQUEST_FAILURE:    return this.doRequestFailure(response);
        case SipcStatus.REQUEST_FAILUREV4:  return this.doRequestFailureV4(response);
        case SipcStatus.SERVER_UNAVAILABLE: return this.doServerUnavaliable(response);
       
        default
        logger.warn("Unhandled sipc response status, default make action fail. status="
            +response.getStatusCode()+", response="+response);
        return new SipcFailureEvent(FailureType.SIPC_FAIL, response);
      }
    }

  //100
    protected ActionEvent doTrying(SipcResponse response) throws FetionException {
      return new SuccessEvent();
    }
   
    //200
    protected ActionEvent doActionOK(SipcResponse response) throws FetionException{
      return new SuccessEvent();
    }
   
    //208
    protected ActionEvent doSendSMSOK(SipcResponse response) throws FetionException{
      return new SuccessEvent();
    }
   
    //401
    protected ActionEvent doNotAuthorized(SipcResponse response) throws FetionException{
      return new SipcFailureEvent(FailureType.SIPC_FAIL, response);
    }
   
    //403
    protected ActionEvent doForbidden(SipcResponse response) throws FetionException{
      return new SipcFailureEvent(FailureType.SIPC_FAIL, response);
    }
   
    //404
    protected ActionEvent doNotFound(SipcResponse response) throws FetionException{
      return new SipcFailureEvent(FailureType.SIPC_FAIL, response);
    }
   
    //420
    protected ActionEvent doBadExtension(SipcResponse response) throws FetionException{
     
      //解析提示信息
      Element root = XMLHelper.build(response.getBody().toSendString());
    Element reason = root.getChild("reason");
    String text = reason.getAttributeValue("text")//原因
    String tips = reason.getAttributeValue("tips")//一些提示
   
    //解析一些获取验证图片的参数
    SipcHeader wwwHeader = response.getHeader(SipcHeader.WWWAUTHENTICATE);
    Pattern pt = Pattern.compile("Verify algorithm=\"(.*?)\",type=\"(.*?)\"");
    Matcher mc = pt.matcher(wwwHeader.getValue());
    if(mc.matches()) {
      String alg  = mc.group(1);    //验证图片算法
      String type = mc.group(2);    //类型???啥意思。。。
      VerifyImage verifyImage = null;
            try {
              verifyImage = HttpApplication.fetchVerifyImage(context.getFetionUser(),
                    context.getLocaleSetting(), alg, type);
            } catch (IOException e) {
              throw new IllegalStateException("fetch verify image failed.", e);
            }
     
            //通知设置的通知监听器处理这个验证码事件,如果没有设置监听器,将抛出异常
      NotifyEventListener listener = this.context.getNotifyEventListener();
      if(listener!=null) {
        listener.fireEvent(new ImageVerifyEvent(ImageVerifyEvent.SIPC_VERIFY,
            verifyImage, text, tips, response.getRequest(),
            this.dialog, this.listener));
      }else{
        throw new IllegalArgumentException("action need verify, but found no NotifyEventListener" +
          " to handle verify action, please set NotifyEventListener first.");
      }
    }else {
      throw new IllegalStateException("parse verify info failed. wwwHeader="+wwwHeader.getValue());
    }
   
      return null//返回null,表明处理这个回复事件
    }

  //421
    protected ActionEvent doExtensionRequired(SipcResponse response) throws FetionException{
      return this.doBadExtension(response);
    }
   
    //444
    protected ActionEvent doRequestFailureV4(SipcResponse response){
      return new SipcFailureEvent(FailureType.SIPC_FAIL, response);
    }
   
    //486
    protected ActionEvent doBusyHere(SipcResponse response) throws FetionException{
      return new SipcFailureEvent(FailureType.SIPC_FAIL, response);
  }
   
    //494
  protected ActionEvent doRequestFailure(SipcResponse response) throws FetionException {
    if(response.getBody()!=null){
      Element root = XMLHelper.build(response.getBody().toSendString());
      Element reason = root.getChild("reason");
      if(reason!=null){
        return new RequestFailureEvent(FailureType.REQEUST_FAIL,
            reason.getAttributeValue("text"),
            reason.getAttributeValue("refer-url"));
      }else{
        return new RequestFailureEvent(FailureType.REQEUST_FAIL, null, null);
      }
    }else{
      return new RequestFailureEvent(FailureType.REQEUST_FAIL, null, null);
    }
  }
   
    //521
    protected ActionEvent doTaExsit(SipcResponse response) throws FetionException{
      return new SipcFailureEvent(FailureType.SIPC_FAIL, response);
    }
   
    //522
    protected ActionEvent doNoSubscription(SipcResponse response) throws FetionException{
      return new SipcFailureEvent(FailureType.SIPC_FAIL, response);
    }
   
    //504
    protected ActionEvent doTimeout(SipcResponse response) throws FetionException{
      return new TimeoutEvent();
    }
   
    //503
  private ActionEvent doServerUnavaliable(SipcResponse response) {
    return new FailureEvent(FailureType.SERVER_BUSY);
  }
}
TOP

Related Classes of net.solosky.maplefetion.client.response.AbstractResponseHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.