📄 simplesessionhandler.java
字号:
moveTo(STATE_INITIALIZATION_PROCESSED); } break; } case STATE_INITIALIZATION_PROCESSED: moveTo(STATE_SYNCHRONIZATION_PROCESSING); case STATE_SYNCHRONIZATION_PROCESSING: syncResponse = processSyncMessage(message); if (syncWithInit) { response = mergeResponse(response, syncResponse); } else { response = mergeResponse(null, syncResponse); } storeClientMappings(); resetClientMappings(); if (message.getSyncBody().isFinalMsg()) { nextTimestamp.end = System.currentTimeMillis(); commit(); moveTo(STATE_SYNCHRONIZATION_COMPLETION); } else { finalMsg = false; response.getSyncBody().setFinalMsg(new Boolean(false)); } break; case STATE_SYNCHRONIZATION_COMPLETION: response = processCompletionMessage(message); storeClientMappings(); resetClientMappings(); if (message.getSyncBody().isFinalMsg()) { response.setLastMessage(true); moveTo(STATE_END); } break; default: logout(); throw new ProtocolException("Illegal state: " + currentState); } } catch (ProtocolException e) { log.throwing(getClass().getName(), "processMessage", e); moveTo(STATE_ERROR); throw e; } catch (NotFoundException e) { log.throwing(getClass().getName(), "processMessage", e); moveTo(STATE_ERROR); throw new InvalidCredentialsException("Invalid credential error", e); } catch (PersistentStoreException e) { log.throwing(getClass().getName(), "processMessage", e); moveTo(STATE_ERROR); throw new ProtocolException("Persistent store error", e); } catch (Throwable t) { t.printStackTrace(); log.throwing(getClass().getName(), "processMessage", t); moveTo(STATE_ERROR); } if (log.isLoggable(Level.FINER)) { log.finer("About returning message: " + Util.toXML(response)); } return response; } /** * Merges Initalization and Synchronization responses into a single message. * * @param init Initialization Response Message * @param sync Synchronization Response Message * * @throws sync4.framework.core.RepresentationException in case of a * representation error * * @return the combined message */ private SyncML mergeResponse(SyncML init, SyncML sync) throws RepresentationException { SyncHdr header = null; SyncBody body = null; // // The StatusCommand Objects must be sorted for cmdRef. // TreeMap tmOtherCmd = new TreeMap(); ArrayList alStatus = new ArrayList(); ArrayList al = new ArrayList(); if (init != null) { AbstractCommand[] initCmd = (AbstractCommand[])init.getSyncBody().getCommands().toArray( new AbstractCommand[0]); for(int i=0; i<initCmd.length; ++i) { if (initCmd[i] instanceof Status) { alStatus.add(initCmd[i]); } else { String key = initCmd[i].getCmdID().getCmdID(); tmOtherCmd.put(new Integer(key), initCmd[i]); } } } if (sync != null) { AbstractCommand[] syncCmd = (AbstractCommand[])sync.getSyncBody().getCommands().toArray( new AbstractCommand[0]); for(int i=0; i<syncCmd.length; ++i){ if (syncCmd[i] instanceof Status) { boolean isSyncHdr = false; if ("0".equals(((Status)syncCmd[i]).getCmdRef()) && "SyncHdr".equals(((Status)syncCmd[i]).getCmd())) { for (int a=0;a<alStatus.size();a++) { Status sc = (Status)alStatus.get(a); if(sc.getCmdRef().equals("0") && sc.getCmd().equals("SyncHdr")) { isSyncHdr = true; break; } } if(!isSyncHdr) alStatus.add(syncCmd[i]); continue; } alStatus.add(syncCmd[i]); } else { String key = syncCmd[i].getCmdID().getCmdID(); tmOtherCmd.put(new Integer(key), syncCmd[i]); } } } List list = Arrays.asList(sortStatusCommand(alStatus.toArray(new AbstractCommand[0]))); al.addAll(list); java.util.Set set1 = tmOtherCmd.keySet(); java.util.Iterator it1 = set1.iterator(); while(it1.hasNext()) { Integer key = (Integer)it1.next(); al.add(tmOtherCmd.get(key)); } AbstractCommand[] cmds = (AbstractCommand[])al.toArray(new AbstractCommand[0]); if (init != null) { header = init.getSyncHdr(); body = new SyncBody(cmds, init.getSyncBody().isFinalMsg()); } else { header = sync.getSyncHdr(); body = new SyncBody(cmds, sync.getSyncBody().isFinalMsg()); } return (new SyncML(header, body)); } public static Object[] sortStatusCommand(Object[] statusToSort) { StatusComparator comparator = new StatusComparator(); Arrays.sort(statusToSort, comparator); return statusToSort; } /** * Processes an error condition. This method is called when the error is * is not fatal and is manageable at a protocol/session level. This results * in a well formed SyncML message with an appropriete error code. * <p> * Note that the offending message <i>msg</i> cannot be null, meaning that * at least the incoming message was a SyncML message. In this context, * <i>RepresentationException</i>s are excluded. * * @param the offending message - NOT NULL * @param the exception representing the error condition - NOT NULL * * @throws sync4j.framework.core.Sync4jException in case of unexpected errors * * @return the response message */ public SyncML processError(SyncML msg, Throwable error) throws Sync4jException { SyncHdr msgHeader = msg.getSyncHdr(); Item[] items = new Item[0]; int status = StatusCode.SERVER_FAILURE; if (syncEngine.isDebug()) { items = new Item[1]; items[0] = new Item( null, // target null, // source null, // meta new ComplexData(error.getMessage()), false //MoreData ); } if (error instanceof ServerException) { status = ((ServerException)error).getStatusCode(); } Status statusCommand = new Status( cmdIdGenerator.next() , msgHeader.getMsgID() , "0" /* command ref */ , "SyncHdr" /* see SyncML specs */ , new TargetRef(msgHeader.getTarget()), new SourceRef(msgHeader.getSource()), null /* credential */ , null /* challenge */ , new Data(status) , new Item[0] ); String serverURI = syncEngine.getConfiguration().getStringValue(syncEngine.CFG_SERVER_URI); SyncHdr syncHeader = new SyncHdr ( msgHeader.getVerDTD() , msgHeader.getVerProto() , msgHeader.getSessionID() , msgHeader.getMsgID() , new Target(msgHeader.getSource().getLocURI()), new Source(serverURI) , null /* response URI */ , false , null /* credentials */ , null /* metadata */ ); SyncBody syncBody = new SyncBody( new AbstractCommand[] { statusCommand }, true /* final */ ); moveTo(STATE_ERROR); return new SyncML(syncHeader, syncBody); } /** * Called by the <i>SessionManager</i> when the session is expired. * It logs out the credential and release aquired resources. */ public void expire() { logout(); } /** * Called to interrupt the processing in case of errors depending on * extenal causes (i.e. the transport). The current implementation just move * the session state to the error state. * <p> * NOTE that the current implementation simply moves the state of the session * to <i>STATE_ERROR</i>. * * @param statusCode the error code * * @see sync4j.framework.core.StatusCode for valid status codes * */ public void abort(int statusCode) { moveTo(STATE_ERROR); } /** * Called to permanently commit the synchronization. It does the following: * <ul> * <li>persists the <i>last</i> timestamp to the database for the sources * successfully synchronized * </ul> */ public void commit() { assert (loggedPrincipal != null); LastTimestamp last = null; PersistentStore ps = syncEngine.getStore(); Database[] dbsGen = syncEngine.getDbs(); for (int i = 0; (dbsGen != null) && (i < dbsGen.length); ++i) { if (dbsGen[i].getStatusCode() != StatusCode.OK) { // // This database is in error. Do not commit it. // continue; } last = new LastTimestamp( loggedPrincipal.getId(), dbsGen[i].getName(), dbsGen[i].getAnchor().getNext(), nextTimestamp.start, nextTimestamp.end ); if (log.isLoggable(Level.FINE)) { log.fine("Commiting database " + dbsGen[i].getName() + " ( " + last + " )" ); } try { boolean stored = ps.store(last); log.fine("LastTimeStamp stored: " + stored); } catch (Sync4jException e) { log.severe("Error in saving persistent data"); log.throwing(getClass().getName(), "commit", e); } } } // --------------------------------------------------------- Private methods /** * If property "isGuestEnabled" is true and credential is null use the * credential of user guest * * @return true if the property "isGuestEnabled" is true else false */ private boolean isGuestEnabled() { return this.guestEnabled; } /** * If flag "isValidCredential" is true then the login and password are correct * else are invalid credential */ private boolean isValidCredential() { return this.validCredentials; } /** * Processes the given initialization message. * * @param message the message to be processed * * @return the response message * * @throws ProtocolException */ private SyncML processInitMessage(SyncML message) throws ProtocolException { syncInit = new SyncInitialization(message.getSyncHdr() , message.getSyncBody()); //Store the informations that will be used in the Syncronization process syncState.addClientCommands(syncInit.getClientCommands()); syncState.addClientAlerts(syncInit.getClientAlerts()); syncInit.setIdGenerator(cmdIdGenerator); syncInit.setFlag(Flags.FLAG_FINAL_MESSAGE); if (isAuthenticated()) { syncInit.setAuthorizedStatusCode(StatusCode.AUTHENTICATION_ACCEPTED); syncInit.setClientCapabilitiesRequired(false); // // Gets the databases requested for synchronization and for each of // them checks if the database exists on the server and if the // credential is allowed to synchronize it // dbs = syncInit.getDatabasesToBeSynchronized(); // // This will change the status code of the elements of clientDBs to // reflect the availability and accessibility of the given databases // on the server // syncEngine.prepareDatabases(loggedPrincipal, dbs, nextTimestamp); if (log.isLoggable(Level.FINEST)) { log.finest("Requested databases: " + Arrays.asList(dbs)); } boolean noDataSource = true; // there are no datasource to allowed to synchronize for (int i = 0; ((dbs != null) && (i < dbs.length)); ++i) { syncInit.setStatusCodeForCommand( dbs[i].getAlertCommand(), dbs[i].getStatusCode() ); if (dbs[i].getStatusCode() == StatusCode.OK) { noDataSource = false; syncEngine.addClientSource( new MemorySyncSource( dbs[i].getName(), null, dbs[i].getSource().getLocURI()) ); } } syncEngine.setDbs(dbs); // // Setting the databases to synchronize. This will force the relative // <Alert>s to be inserted in the response. //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -