com.pureinfo.srmcenter.datasync.client.uploader.impl.SyncUploaderImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.pureinfo.srmcenter.datasync.client.uploader.impl.SyncUploaderImpl.java

Source

/**
 * PureInfo Quake
 * 
 * @(#)SyncUploaderImpl.java 1.0 Jan 18, 2006
 * 
 * Copyright(c) 2004-2005, PureInfo Information Technology Corp. Ltd. All rights
 * reserved, see the license file.
 * 
 * www.pureinfo.com.cn
 */

package com.pureinfo.srmcenter.datasync.client.uploader.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;

import com.pureinfo.ark.content.ArkContentHelper;
import com.pureinfo.dolphin.model.DolphinObject;
import com.pureinfo.dolphin.model.IObjects;
import com.pureinfo.force.exception.PureException;
import com.pureinfo.force.exception.PureRuntimeException;
import com.pureinfo.force.io.exception.IOTransferException;
import com.pureinfo.force.lang.ArrayUtil;
import com.pureinfo.force.xml.exception.IllegalXMLFormatException;
import com.pureinfo.srmcenter.datasync.client.ISchoolInfoMgr;
import com.pureinfo.srmcenter.datasync.client.ISyncConnection;
import com.pureinfo.srmcenter.datasync.client.ISyncDataBuilder;
import com.pureinfo.srmcenter.datasync.client.domain.impl.DataSyncInfoMgrImpl;
import com.pureinfo.srmcenter.datasync.client.model.DataSyncInfo;
import com.pureinfo.srmcenter.datasync.client.uploader.ISyncUploader;
import com.pureinfo.srmcenter.datasync.error.ISyncErrorHandler;
import com.pureinfo.srmcenter.datasync.finder.delete.IDeleteDataFinder;
import com.pureinfo.srmcenter.datasync.finder.update.IUpdateDataFinder;
import com.pureinfo.srmcenter.datasync.model.SyncDeleteData;
import com.pureinfo.srmcenter.datasync.model.SyncErrorData;
import com.pureinfo.srmcenter.datasync.model.SyncRequest;
import com.pureinfo.srmcenter.datasync.model.SyncResponse;

public class SyncUploaderImpl implements ISyncUploader {
    private static final long TIME_DELTA = DateUtils.MILLIS_PER_MINUTE * 10;

    /**
     * Logger for this class
     */
    private static final Logger logger = Logger.getLogger(SyncUploaderImpl.class);

    private ISyncConnection m_connection;

    private ISyncDataBuilder m_dataBuilder;

    private ISchoolInfoMgr m_schoolInfoMgr;

    private String m_sObjType;

    private String m_sObjTypeInSRMC;

    private IUpdateDataFinder m_updateDataFinder;

    private IDeleteDataFinder[] m_deleteDataFinders;

    private ISyncErrorHandler m_errorHandler;

    public void setErrorHandler(ISyncErrorHandler _errorHandler) {
        m_errorHandler = _errorHandler;
    }

    public void upload(String _sHostUrl, int _nRetryCount, int _nDataCountPerPost) {

        if (logger.isDebugEnabled()) {
            logger.debug("update " + m_sObjType + " - start");
        }
        DataSyncInfoMgrImpl syncInfoMgr;
        try {
            syncInfoMgr = (DataSyncInfoMgrImpl) ArkContentHelper.getContentMgrOf(DataSyncInfo.class);
        } catch (PureException ex1) {
            throw new PureRuntimeException(0, "", ex1);
        }
        try {
            Date lastUploadTime = syncInfoMgr.getLastUploadTime(m_sObjType);
            // 10
            Date thisUploadTime = new Date(new Date().getTime() - TIME_DELTA);

            IObjects objects = getUpdatedObjectsAfter(lastUploadTime);
            try {
                syncUpdate(objects, _sHostUrl, _nRetryCount, _nDataCountPerPost);
            } finally {
                objects.clear();
            }

            int[] ids = getDeletedIdsAfter(lastUploadTime);
            syncDelete(ids, _sHostUrl, _nRetryCount, _nDataCountPerPost);

            syncInfoMgr.updateLastUploadTime(m_sObjType, thisUploadTime);
        } catch (PureException ex) {
            ex.printStackTrace();
            logger.error("update " + m_sObjType, ex);
        }

        if (logger.isDebugEnabled()) {
            logger.debug("update " + m_sObjType + " - end");
        }
    }

    public void syncDelete(int[] ids, String _sHostUrl, int _nRetryCount, int _nDataCountPerPost) {
        for (int i = 0; i < ids.length; i += _nDataCountPerPost) {
            SyncRequest request = generateSyncDeleteRequest(ids, i, _nDataCountPerPost);
            SyncResponse response = postRequest(_sHostUrl, request, _nRetryCount);
            handleResponse(response);
        }
    }

    public void syncUpdate(IObjects _objects, String _sHostUrl, int _nRetryCount, int _nDataCountPerPost)
            throws PureException {
        SyncRequest request = generateSyncRequest(_objects, _nDataCountPerPost);
        while (request.hasDatas()) {
            doUpdatePost(_sHostUrl, request, _nRetryCount);
            request = generateSyncRequest(_objects, _nDataCountPerPost);
            try {
                Thread.sleep(20);
            } catch (Exception ex) {
            }
        }
    }

    private void doUpdatePost(String _sHostUrl, SyncRequest _request, int _nRetryCount) {
        SyncResponse response = null;
        boolean bFlag = true;
        for (int i = 0; i < _nRetryCount && bFlag; i++) {
            response = postRequest(_sHostUrl, _request, _nRetryCount);
            if (response == null) {
                logger.warn("retry post request #" + (i + 1));
                try {
                    Thread.sleep(100);
                } catch (Exception ex) {
                }
            } else {
                bFlag = false;
            }
        }
        if (response == null) {
            List updates = _request.getUpdates();
            if (updates.size() == 1) {
                logger.warn("update error " + updates);
            } else {
                SyncRequest request1 = copyRequest(_request);
                request1.setUpdates(updates.subList(0, updates.size() / 2));
                doUpdatePost(_sHostUrl, request1, _nRetryCount);
                SyncRequest request2 = copyRequest(_request);
                request2.setUpdates(updates.subList(updates.size() / 2, updates.size()));
                doUpdatePost(_sHostUrl, request2, _nRetryCount);
            }
        } else {
            handleResponse(response);
        }
    }

    private SyncRequest copyRequest(SyncRequest _request) {
        SyncRequest request1 = new SyncRequest();
        request1.setSchool(_request.getSchool());
        request1.setSerial(_request.getSerial());
        request1.setDataType(_request.getDataType());
        request1.setTimestampByDate(_request.getTimestampAsDate());
        request1.setType(_request.getType());
        return request1;
    }

    private SyncRequest generateSyncRequest(IObjects _objects, int _nDataCountPerPost) throws PureException {
        List updates = getDatas(_objects, _nDataCountPerPost);
        return generateSyncRequest(updates);
    }

    private SyncResponse postRequest(String _sHostUrl, SyncRequest request, int _nRetryCount) {
        SyncResponse response = null;
        for (int i = 1; i <= _nRetryCount; i++) {
            try {
                response = m_connection.send(_sHostUrl, request);
            } catch (IOTransferException ex) {
                logger.error("m_connection.send()", ex);
                logger.info("Because of transfer error,retry #" + i);
            } catch (IllegalXMLFormatException ex) {
                throw new PureRuntimeException(ex.getErrNo(), request.toString(), ex);
            }
            if (response != null)
                return response;
        }
        return response;
    }

    private SyncRequest generateSyncDeleteRequest(int[] ids, int _current, int _nDataCountPerPost) {
        SyncRequest request = newSyncRequest();
        for (int i = _current; i < ids.length && i < _current + _nDataCountPerPost; i++) {
            SyncDeleteData data = new SyncDeleteData();
            data.setId(ids[i]);
            request.addDelete(data);
        }
        return request;
    }

    private SyncRequest generateSyncRequest(List _datas) {
        SyncRequest request = newSyncRequest();
        for (Iterator iter = _datas.iterator(); iter.hasNext();) {
            DolphinObject object = (DolphinObject) iter.next();
            try {
                request.addUpdate(m_dataBuilder.bulidDatasForRequest(object));
            } catch (PureException ex) {
                logger.error("_builder.bulidDatasForRequest", ex);
            }
        }
        return request;
    }

    /* private */List getDatas(IObjects objects, int _nDataCountPerPost) throws PureException {
        if (objects == null)
            throw new PureException(PureException.INVALID_REQUEST, "objects");
        if (_nDataCountPerPost <= 0)
            throw new PureException(PureException.INVALID_REQUEST, "count");

        List datas = new ArrayList();
        for (int i = 0; i < _nDataCountPerPost; i++) {
            DolphinObject object = objects.next();
            if (object == null) {
                break;
            } else {
                datas.add(object);
            }
        }
        return datas;
    }

    private SyncRequest newSyncRequest() {
        SyncRequest request = new SyncRequest(SyncRequest.TYPE_UPLOAD);
        request.setSchool(m_schoolInfoMgr.getCode());
        request.setSerial(m_schoolInfoMgr.getSerialNo());
        request.setDataType(m_sObjTypeInSRMC);
        return request;
    }

    private void handleResponse(SyncResponse response) {
        if (response == null) {
            System.out.println("connection error");
        } else if (response.hasError()) {
            for (Iterator iter = response.getErrors().iterator(); iter.hasNext();) {
                SyncErrorData error = (SyncErrorData) iter.next();
                m_errorHandler.handle(error);
            }
        }
    }

    public int[] getDeletedIdsAfter(Date _date) throws PureException {
        int[][] ids = new int[m_deleteDataFinders.length][];
        for (int i = 0; i < ids.length; i++) {
            ids[i] = m_deleteDataFinders[i].findDeletes(m_sObjType, _date);
        }
        return ArrayUtil.join(ids);
    }

    public IObjects getUpdatedObjectsAfter(Date _date) throws PureException {
        return m_updateDataFinder.findUpdates(m_sObjType, _date);
    }

    public void setConnection(ISyncConnection _nConnection) {
        m_connection = _nConnection;
    }

    public void setDataBuilder(ISyncDataBuilder _nDataBuilder) {
        m_dataBuilder = _nDataBuilder;
    }

    public void setDeleteDataFinders(IDeleteDataFinder[] _nDeleteDataFinder) {
        m_deleteDataFinders = _nDeleteDataFinder;
    }

    public void setSchoolInfoMgr(ISchoolInfoMgr _nSchoolInfoMgr) {
        m_schoolInfoMgr = _nSchoolInfoMgr;
    }

    public void setObjType(String _nObjType) {
        m_sObjType = _nObjType;
    }

    public void setUpdateDataFinder(IUpdateDataFinder _nUpdateDataFinders) {
        m_updateDataFinder = _nUpdateDataFinders;
    }

    public void setObjTypeInSRMC(String _nObjTypeInSRMC) {
        m_sObjTypeInSRMC = _nObjTypeInSRMC;
    }

}