Package com.sissi.server.exchange.impl

Source Code of com.sissi.server.exchange.impl.DegelationTransferBuilder$DelegationTransfer

package com.sissi.server.exchange.impl;

import io.netty.buffer.ByteBuf;
import io.netty.util.ReferenceCountUtil;

import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sissi.commons.Trace;
import com.sissi.commons.apache.IOUtil;
import com.sissi.context.JIDBuilder;
import com.sissi.persistent.Persistent;
import com.sissi.pipeline.Transfer;
import com.sissi.pipeline.TransferBuffer;
import com.sissi.pipeline.TransferBuilder;
import com.sissi.pipeline.TransferParam;
import com.sissi.protocol.iq.si.Si;
import com.sissi.resource.ResourceCounter;
import com.sissi.server.exchange.Delegation;
import com.sissi.server.exchange.Recall;

/**
* 离线代理传输
*
* @author kim 2014年2月25日
*/
public class DegelationTransferBuilder implements TransferBuilder {

  private final String resoure = this.getClass().getSimpleName();

  private final Log log = LogFactory.getLog(this.getClass());

  private final ResourceCounter resourceCounter;

  private final Persistent persistent;

  private final JIDBuilder jidBuilder;

  private final Delegation delegation;

  private final Recall recall;

  public DegelationTransferBuilder(Persistent persistent, ResourceCounter resourceCounter, Delegation delegation, JIDBuilder jidBuilder, Recall recall) {
    super();
    this.resourceCounter = resourceCounter;
    this.persistent = persistent;
    this.delegation = delegation;
    this.jidBuilder = jidBuilder;
    this.recall = recall;
  }

  @Override
  public DelegationTransfer build(TransferParam param) {
    return new DelegationTransfer(param.find(TransferParam.KEY_SI, Si.class));
  }

  private class DelegationTransfer implements Transfer {

    /**
     * 已读字节
     */
    private final AtomicLong readable = new AtomicLong();

    /**
     * 有序锁
     */
    private final Lock lock = new ReentrantLock(true);

    private final OutputStream output;

    private final Si si;

    public DelegationTransfer(Si si) {
      super();
      this.si = si;
      this.output = DegelationTransferBuilder.this.delegation.allocate(si.getId());
      DegelationTransferBuilder.this.resourceCounter.increment(DegelationTransferBuilder.this.resoure);
    }

    @Override
    public DelegationTransfer transfer(TransferBuffer buffer) {
      ByteBuf buf = ByteBuf.class.cast(buffer.getBuffer());
      try {
        this.lock.lock();
        int readable = buf.readableBytes();
        buf.readBytes(this.output, readable);
        this.readable.addAndGet(readable);
        return this;
      } catch (Exception e) {
        DegelationTransferBuilder.this.log.error(e);
        Trace.trace(DegelationTransferBuilder.this.log, e);
        throw new RuntimeException(e);
      } finally {
        this.lock.unlock();
        if (buf.refCnt() > 0) {
          ReferenceCountUtil.release(buf);
        }
      }
    }

    @Override
    public void close() {
      IOUtil.closeQuietly(this.output);
      DegelationTransferBuilder.this.persistent.push(this.si);
      DegelationTransferBuilder.this.resourceCounter.decrement(DegelationTransferBuilder.this.resoure);
      DegelationTransferBuilder.this.recall.call(DegelationTransferBuilder.this.jidBuilder.build(si.parent().getTo()).asStringWithBare());
    }
  }
}
TOP

Related Classes of com.sissi.server.exchange.impl.DegelationTransferBuilder$DelegationTransfer

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.