Java tutorial
/** * 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; } }