📄 syncsession.java
字号:
/**
* @(#)$RCSfile: SyncSession.java,v $ $Revision: 1.2 $
*
* ====================================================================
* Copyright 2001, Reaxion Corp.,
* 11418 105th PL NE, Kirkland, WA, 98033, USA
* All rights reserved.
* ====================================================================
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Tequila SyncML.
*
* The Initial Developer of the Original Code is Reaxion Corp.
* All Rights Reserved.
*/
package com.reaxion.tequila.syncml.sync;
import java.util.*;
import com.reaxion.tequila.syncml.*;
import com.reaxion.tequila.syncml.sync.doc.*;
import com.reaxion.tequila.syncml.sync.stack.*;
import com.reaxion.tequila.syncml.util.*;
/**
* This class represents a SyncML session.
* Several documents could be synchronized throuh the session.
* Each document represented by SyncDocument
* The instance of this class leaves only through the session of synchronization.
* It should be created before starting the synchronization
* and removed after finishing the process of synchronization.
*
* @version $1.0$
* @author Oleg A. Oksyuk
*/
public abstract class SyncSession implements ISyncServer
{
/**
* Called for each document related command in received SyncML package
*/
protected abstract Enumeration processDocCommand(SyncCmdIdOwner inCommand);
protected Hashtable syncDocs = new Hashtable();
protected SessionStack sessionStack;
private String sessionId;
protected String targetUri;
protected String sourceUri;
private SyncIterator syncIterator;
protected String currMsgFromId;
private String lastMsgToId;
private boolean statusReceivedOnLastMsg;
protected boolean needToRespHeader;
protected boolean sessionFinished = false;
public SyncSession(String aSessionId,
String aTargetUri, String aSourceUri)
{
log("init");
sessionId = aSessionId;
targetUri = aTargetUri;
sourceUri = aSourceUri;
syncIterator = new SyncIterator();
}
//Sync session related commands
/**
* This method processed received package and returns result package.
* It calls method startPackage, then processCommand for each command
* in the package and then endPackage.
* If there is no responce it returns null
*/
public SyncPackage processPackage(SyncPackage inPack)
{
log("processPackage...");
if (!sessionId.equals(inPack.getHeader().getSessionID().getSessionId()))
{
throw new SyncException("Wrong session Id");
}
Enumeration inCommands = inPack.getBody().getCommands();
Enumeration outCommands = new Vector().elements();
Enumeration docOutCommands;
SyncCmdIdOwner inCommand, outCommand;
currMsgFromId = inPack.getHeader().getMsgID().getMsgId();
needToRespHeader = !inPack.getHeader().isNoResp();
docOutCommands = startPackage();
outCommands = Utils.addEnums(outCommands, docOutCommands);
statusReceivedOnLastMsg = (lastMsgToId == null);
while (inCommands.hasMoreElements())
{
inCommand = (SyncCmdIdOwner) inCommands.nextElement();
docOutCommands = processCommand(inCommand);
outCommands = Utils.addEnums(outCommands, docOutCommands);
}
if ((HDR_RESP_NEEDED) && (!statusReceivedOnLastMsg))
{
throw new SyncException("No status received on the last message");
}
docOutCommands = endPackage();
outCommands = Utils.addEnums(outCommands, docOutCommands);
SyncPackage outPack = createSyncPackage(outCommands);
sessionStack.addCommands(outPack);
tryToFinishSession();
if (outPack.isEmpty())
{
outPack = null;
}
log("processPackage OK");
return outPack;
}
public boolean isSesisonFinished()
{
return sessionFinished;
}
//Sync package related commands
/**
* This method called at the begin of package processing in processPackage method
*
* @return Enumeration of responce commands
*/
private Enumeration startPackage()
{
log("startPackage("+currMsgFromId+")");
Enumeration keys = syncDocs.keys();
ISyncDocument doc;
Enumeration outCommands = new Vector().elements();
Enumeration docOutCommands = null;
if (needToRespHeader)
{
SyncStatus syncStatus = new SyncStatus(currMsgFromId, SyncHeader.HDR_CMD_ID,
SyncCommandNames.HDR, sourceUri,
targetUri, SyncStatuses.OK);
outCommands = Utils.addElToEnum(outCommands, syncStatus);
}
while (keys.hasMoreElements())
{
doc = (ISyncDocument) syncDocs.get(keys.nextElement());
docOutCommands = doc.startPackage(currMsgFromId, needToRespHeader);
outCommands = Utils.addEnums(outCommands, docOutCommands);
}
return outCommands;
}
/**
* This method called for each command in processPackage method.
* If the command is not refferred to any sync document (in this case
* it could only be Status command refferred to package header) the
* command is processed in this method, otherwise method processDocCommand
* called
*
* @return Enumeration of responce commands
*/
private Enumeration processCommand(SyncCmdIdOwner inCommand)
{
log("processCommand("+inCommand.getName()+")");
if ((SyncCommandNames.STATUS.equals(inCommand.getName())) &&
(SyncCommandNames.HDR.equals(((SyncStatus) inCommand).getCmd().getCmd())))
{
SyncStatus status = (SyncStatus) inCommand;
if (!lastMsgToId.equals(status.getMsgRef().getMsgRef()))
{
throw new SyncException("Status on other than last message received on SyncAgent");
}
if (SyncStatuses.OK != status.getCode())
{
throw new SyncException("Non OK status received on the last message");
}
if (statusReceivedOnLastMsg)
{
throw new SyncException("Status already received on the last message");
}
statusReceivedOnLastMsg = true;
return null;
}
else
{
return processDocCommand(inCommand);
}
}
/**
* This method called at the end of package processing in processPackage method
*
* @return Enumeration of responce commands
*/
private Enumeration endPackage()
{
log("endSyncStep");
Enumeration keys = syncDocs.keys();
ISyncDocument doc;
Enumeration outCommands = new Vector().elements();
Enumeration docOutCommands = null;
while (keys.hasMoreElements())
{
doc = (ISyncDocument) syncDocs.get(keys.nextElement());
docOutCommands = doc.endPackage();
outCommands = Utils.addEnums(outCommands, docOutCommands);
}
return outCommands;
}
private void tryToFinishSession()
{
Enumeration keys = syncDocs.keys();
ISyncDocument doc;
boolean needToFinishSesison = true;
while (keys.hasMoreElements())
{
doc = (ISyncDocument) syncDocs.get(keys.nextElement());
if (!doc.isSyncFinished())
{
if (!doc.tryToEndSync())
{
needToFinishSesison = false;
}
}
}
if (needToFinishSesison)
{
sessionFinished = true;
}
}
//Additional methods
/**
* This method creates SyncML package from the ennumeration of commands
*
* @return responce package
*/
protected SyncPackage createSyncPackage(Enumeration outCommands)
{
SyncBody body = new SyncBody(outCommands);
lastMsgToId = syncIterator.generateNewId();
SyncHeader header = new SyncHeader(sessionId, lastMsgToId, targetUri, sourceUri, !HDR_RESP_NEEDED);
SyncPackage pack = new SyncPackage(header, body);
pack.setIds();
return pack;
}
/**
* This method returns target database name for the command.
* If the command is status the target database name taken from the stack
*
* @return target database name
*/
protected String getTargetDbName(SyncCmdIdOwner command)
{
SyncTarget target;
String targetDBName;
if (SyncCommandNames.SYNC.equals(command.getName()))
{
SyncSync sync = (SyncSync) command;
target = sync.getTarget();
targetDBName = target.getURI().getData();
}
else if (SyncCommandNames.ALERT.equals(command.getName()))
{
SyncAlert alert = (SyncAlert) command;
target = alert.getTarget();
targetDBName = target.getURI().getData();
}
else if (SyncCommandNames.STATUS.equals(command.getName()))
{
SyncStatus status = (SyncStatus) command;
targetDBName = sessionStack.getCommand(status.getMsgRef().getData(), status.getCmdRef().getData());
if (null == targetDBName) {
throw new SyncException("Server send Status command on wrong command");
}
}
else
{
throw new SyncMLDocStructureException("Wrong command name in SyncBody");
}
log("getTargetDbName("+command.getName()+")="+targetDBName);
return targetDBName;
}
/**
* All debug logs for child classes should be print through this method
*
* @param msg message to log
*/
protected void log(String msg)
{
StringBuffer res = new StringBuffer(" ");
res.append(this.getClass().getName());
res.append(":");
res.append(msg);
Log.println(res);
}
}
/* -----------------------------------------------------------------------------
* Change log:
* -----------------------------------------------------------------------------
* $Log: SyncSession.java,v $
* Revision 1.2 2001/10/17 15:27:42 OlegO
* changed comments for better javadoc
*
* Revision 1.1.1.1 2001/10/11 13:13:32 OlegO
* no message
*
* Revision 1.2 2001/07/27 07:44:52 OlegO
* no message
*
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -