coreRuntime/src/sc/sync/SyncDestination.java
public boolean applySyncLayer(String input, String receiveLanguage, ScopeDefinition syncScope, boolean applyingRemoteReset, String detail) {
      SyncManager.SyncState oldSyncState = SyncManager.getSyncState();

      // applyingRemoteReset is true when this received layer is restoring sync'd state from a new client - either
      // we lost the session or are using request scope components.
      // After we've resolved all of the objects which are referenced on the client, we call sendSync with 'markAsSentOnly=true'
      // to skip the send of stuff we already sent when we initialized this client.
      // TODO: maybe the client should send two different layers during a reset - for the committed and uncommitted changes.
      // That way, all of the committed changes would be applied before the resetSync.  As it is now, those changes will be applied after this sendSync call.
      if (applyingRemoteReset) {
         SyncManager.sendSync(name, null, false, true, null, null, null);
      }

      // We'll queue only the validate events. That way, listeners still receive invalidate events while deserializing the stream.
      // This helps for a use case involving properties that dynamically expose new component trees for synchronization that are
      // based on properties set earlier in the sync. If we don't deliver the events, we don't know the list value to use for
      // creating the components which are set later on. So basically that component needs to flush out current events, sync it's
      // repeat value, then turn the queue back on again. We do want to queue events to batch up changes, eliminating costly or
      // invalid intermediate results caused when trying to send the events using syncType=immediate. The list components are
      // framework components so they can do a little more work. They listen for the immediate invalidate events to mark their
      // state as invalid. When an attempt is made to resolve a child, it will flush the events, then validate it's children.
      BindingContext ctx = new BindingContext(IListener.SyncType.QUEUE_VALIDATE_EVENTS);
      BindingContext oldBindCtx = BindingContext.getBindingContext();
      BindingContext.setBindingContext(ctx);

      boolean anyChanges = false;
      int flags = 0;

      while (input != null && input.length() > 0) {
         String layerDef = input;
         boolean success = false;
         int layerDefLen = layerDef.length();
         // When no receiveLanguage is known at this time, we must parse it from the header in the value itself
         if (receiveLanguage == null) {
            // Otherwise, it's a string of the form sync:language:len:data:sync:language:len:data
            // Supporting more than one format - e.g. json and js when there are code updates to be applied
            if (layerDef.startsWith(SYNC_LAYER_START)) {
               int endLangIx = layerDef.indexOf(':', SYNC_LAYER_START_LEN);
               if (endLangIx != -1) {
                  receiveLanguage = layerDef.substring(SYNC_LAYER_START_LEN, endLangIx);
                  int flagsStart = endLangIx + 1;
                  if (layerDefLen > flagsStart) {
                     int endFlagsIx = layerDef.indexOf(':', flagsStart);
                     if (endFlagsIx != -1) {
                        String flagsStr = layerDef.substring(flagsStart, endFlagsIx);
                        if (flagsStr.length() > 0) {
                           try {
                              flags = Integer.parseInt(flagsStr);
                           }
                           catch (NumberFormatException exc) {
                              System.err.println("*** Invalid flags in sync request");
                           }
                        }

                        int lenStart = endFlagsIx + 1;
                        if (layerDefLen > lenStart) {
                           int endLenIx = layerDef.indexOf(':', lenStart);
                           if (endLenIx != -1) {
                              String lenStr = layerDef.substring(lenStart, endLenIx);
                              try {
                                 int syncLen = Integer.parseInt(lenStr);
                                 int layerDefStart = endLenIx + 1;
                                 layerDef = layerDef.substring(layerDefStart, layerDefStart + syncLen);
                                 // Process the next chunk on the next iteration of the loop.
                                 input = input.substring(layerDefStart + syncLen + 1);
                                 success = true;
                              }
                              catch (NumberFormatException exc) {
                                 System.err.println("*** Invalid length in sync request");
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
         else {
            success = true;
            input = null;
         }

         try {
            if (receiveLanguage == null || !success)
               throw new IllegalArgumentException("Invalid sync layer header for applySyncLayer");
            SyncManager.setSyncState(SyncManager.SyncState.ApplyingChanges);
            SerializerFormat format = SerializerFormat.getFormat(receiveLanguage);
            if (format != null) {
               if (format.applySyncLayer(name, syncScope == null ? defaultScope : syncScope.name, layerDef, applyingRemoteReset, allowCodeEval, ctx))
                  anyChanges = true;
            }
            else
               throw new IllegalArgumentException("Unrecognized receive language for applySyncLayer: " + receiveLanguage);
         }
         finally {
            BindingContext.setBindingContext(oldBindCtx);
            ctx.dispatchEvents(null);
            SyncManager.setSyncState(oldSyncState);
         }

         if (input != null)
            receiveLanguage = null; // Reset this so we look for it the next time
      }

      if (anyChanges)
         SyncManager.callAfterApplySync();

      // Session was reset from the remote side
      if ((flags & 1) != 0) {
         // First step - clear the state on the client
         needsClearSync = true;
         // Second step - on the next sync, add a parameter to have the server return the new initSync for this page
         needsInitSync = true;
         initSyncPending = false;
      }

      return anyChanges;
   }
/**
    * Applies the changes received from the sync layers received from the remote definition. Called on both the client and server to apply received
    * changes and handles different formats.
    * When receiving JS on the client, eval the returned Javascript.
    * When receiving SC or json, parse the layer definition and apply it as a set of changes to the instances.
    * The receiveLanguage may be specified or if null, looks for SYNC_LAYER_START to find the receive language in the text received.
    * The detail is for debug messages - in what context is the applySyncLayer being performed (e.g. init, response)
    * Returns true if any changes were applied.
    */
Applies the changes received from the sync layers received from the remote definition. Called on both the client and server to apply received
changes and handles different formats.
When receiving JS on the client, eval the returned Javascript.
When receiving SC or json, parse the layer definition and apply it as a set of changes to the instances.
The receiveLanguage may be specified or if null, looks for SYNC_LAYER_START to find the receive language in the text received.
The detail is for debug messages - in what context is the applySyncLayer being performed
Returns true if any changes were applied.
Applies the changes received from the sync layers received from the remote definition . Called on both the client and server to apply received changes and handles different formats . When receiving JS on the client eval the returned Javascript . When receiving SC or json parse the layer definition and apply it as a set of changes to the instances . The receiveLanguage may be specified or if null looks for SYNC_LAYER_START to find the receive language in the text received . The detail is for debug messages - in what context is the applySyncLayer being performed Returns true if any changes were applied .
public boolean applySyncLayer(String input, String receiveLanguage, ScopeDefinition syncScope, boolean applyingRemoteReset, String detail) {
      SyncManager.SyncState oldSyncState = SyncManager.getSyncState();
      if (applyingRemoteReset) {
         SyncManager.sendSync(name, null, false, true, null, null, null);
      }
      BindingContext ctx = new BindingContext(IListener.SyncType.QUEUE_VALIDATE_EVENTS);
      BindingContext oldBindCtx = BindingContext.getBindingContext();
      BindingContext.setBindingContext(ctx);
      boolean anyChanges = false;
      int flags = 0;
      while (input != null && input.length() > 0) {
         String layerDef = input;
         boolean success = false;
         int layerDefLen = layerDef.length();
         if (receiveLanguage == null) {
            if (layerDef.startsWith(SYNC_LAYER_START)) {
               int endLangIx = layerDef.indexOf(':', SYNC_LAYER_START_LEN);
               if (endLangIx != -1) {
                  receiveLanguage = layerDef.substring(SYNC_LAYER_START_LEN, endLangIx);
                  int flagsStart = endLangIx + 1;
                  if (layerDefLen > flagsStart) {
                     int endFlagsIx = layerDef.indexOf(':', flagsStart);
                     if (endFlagsIx != -1) {
                        String flagsStr = layerDef.substring(flagsStart, endFlagsIx);
                        if (flagsStr.length() > 0) {
                           try {
                              flags = Integer.parseInt(flagsStr);
                           }
                           catch (NumberFormatException exc) {
                              System.err.println("*** Invalid flags in sync request");
                           }
                        }
                        int lenStart = endFlagsIx + 1;
                        if (layerDefLen > lenStart) {
                           int endLenIx = layerDef.indexOf(':', lenStart);
                           if (endLenIx != -1) {
                              String lenStr = layerDef.substring(lenStart, endLenIx);
                              try {
                                 int syncLen = Integer.parseInt(lenStr);
                                 int layerDefStart = endLenIx + 1;
                                 layerDef = layerDef.substring(layerDefStart, layerDefStart + syncLen);
                                 input = input.substring(layerDefStart + syncLen + 1);
                                 success = true;
                              }
                              catch (NumberFormatException exc) {
                                 System.err.println("*** Invalid length in sync request");
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
         else {
            success = true;
            input = null;
         }
         try {
            if (receiveLanguage == null || !success)
               throw new IllegalArgumentException("Invalid sync layer header for applySyncLayer");
            SyncManager.setSyncState(SyncManager.SyncState.ApplyingChanges);
            SerializerFormat format = SerializerFormat.getFormat(receiveLanguage);
            if (format != null) {
               if (format.applySyncLayer(name, syncScope == null ? defaultScope : syncScope.name, layerDef, applyingRemoteReset, allowCodeEval, ctx))
                  anyChanges = true;
            }
            else
               throw new IllegalArgumentException("Unrecognized receive language for applySyncLayer: " + receiveLanguage);
         }
         finally {
            BindingContext.setBindingContext(oldBindCtx);
            ctx.dispatchEvents(null);
            SyncManager.setSyncState(oldSyncState);
         }
         if (input != null)
            receiveLanguage = null; 
      }
      if (anyChanges)
         SyncManager.callAfterApplySync();
      if ((flags & 1) != 0) {
         needsClearSync = true;
         needsInitSync = true;
         initSyncPending = false;
      }
      return anyChanges;
   }
public boolean applySyncLayer ( String input , String receiveLanguage , ScopeDefinition syncScope , boolean applyingRemoteReset , String detail ) { SyncManager . SyncState oldSyncState = SyncManager . getSyncState ( ) ; if ( applyingRemoteReset ) { SyncManager . sendSync ( name , null , false , true , null , null , null ) ; } BindingContext ctx = new BindingContext ( IListener . SyncType . QUEUE_VALIDATE_EVENTS ) ; BindingContext oldBindCtx = BindingContext . getBindingContext ( ) ; BindingContext . setBindingContext ( ctx ) ; boolean anyChanges = false ; int flags = 0 ; while ( input != null && input . length ( ) > 0 ) { String layerDef = input ; boolean success = false ; int layerDefLen = layerDef . length ( ) ; if ( receiveLanguage == null ) { if ( layerDef . startsWith ( SYNC_LAYER_START ) ) { int endLangIx = layerDef . indexOf ( ':' , SYNC_LAYER_START_LEN ) ; if ( endLangIx != - 1 ) { receiveLanguage = layerDef . substring ( SYNC_LAYER_START_LEN , endLangIx ) ; int flagsStart = endLangIx + 1 ; if ( layerDefLen > flagsStart ) { int endFlagsIx = layerDef . indexOf ( ':' , flagsStart ) ; if ( endFlagsIx != - 1 ) { String flagsStr = layerDef . substring ( flagsStart , endFlagsIx ) ; if ( flagsStr . length ( ) > 0 ) { try { flags = Integer . parseInt ( flagsStr ) ; } catch ( NumberFormatException exc ) { System . err . println ( "*** Invalid flags in sync request" ) ; } } int lenStart = endFlagsIx + 1 ; if ( layerDefLen > lenStart ) { int endLenIx = layerDef . indexOf ( ':' , lenStart ) ; if ( endLenIx != - 1 ) { String lenStr = layerDef . substring ( lenStart , endLenIx ) ; try { int syncLen = Integer . parseInt ( lenStr ) ; int layerDefStart = endLenIx + 1 ; layerDef = layerDef . substring ( layerDefStart , layerDefStart + syncLen ) ; input = input . substring ( layerDefStart + syncLen + 1 ) ; success = true ; } catch ( NumberFormatException exc ) { System . err . println ( "*** Invalid length in sync request" ) ; } } } } } } } } else { success = true ; input = null ; } try { if ( receiveLanguage == null || ! success ) throw new IllegalArgumentException ( "Invalid sync layer header for applySyncLayer" ) ; SyncManager . setSyncState ( SyncManager . SyncState . ApplyingChanges ) ; SerializerFormat format = SerializerFormat . getFormat ( receiveLanguage ) ; if ( format != null ) { if ( format . applySyncLayer ( name , syncScope == null ? defaultScope : syncScope . name , layerDef , applyingRemoteReset , allowCodeEval , ctx ) ) anyChanges = true ; } else throw new IllegalArgumentException ( "Unrecognized receive language for applySyncLayer: " + receiveLanguage ) ; } finally { BindingContext . setBindingContext ( oldBindCtx ) ; ctx . dispatchEvents ( null ) ; SyncManager . setSyncState ( oldSyncState ) ; } if ( input != null ) receiveLanguage = null ; } if ( anyChanges ) SyncManager . callAfterApplySync ( ) ; if ( ( flags & 1 ) != 0 ) { needsClearSync = true ; needsInitSync = true ; initSyncPending = false ; } return anyChanges ; }
Applies the changes received from the sync layers received from the remote definition.
Applies the changes received from the sync layers received from the remote definition .
// applyingRemoteReset is true when this received layer is restoring sync'd state from a new client - either // we lost the session or are using request scope components. // After we've resolved all of the objects which are referenced on the client, we call sendSync with 'markAsSentOnly=true' // to skip the send of stuff we already sent when we initialized this client. // TODO: maybe the client should send two different layers during a reset - for the committed and uncommitted changes. // That way, all of the committed changes would be applied before the resetSync.  As it is now, those changes will be applied after this sendSync call. // We'll queue only the validate events. That way, listeners still receive invalidate events while deserializing the stream. // This helps for a use case involving properties that dynamically expose new component trees for synchronization that are // based on properties set earlier in the sync. If we don't deliver the events, we don't know the list value to use for // creating the components which are set later on. So basically that component needs to flush out current events, sync it's // repeat value, then turn the queue back on again. We do want to queue events to batch up changes, eliminating costly or // invalid intermediate results caused when trying to send the events using syncType=immediate. The list components are // framework components so they can do a little more work. They listen for the immediate invalidate events to mark their // state as invalid. When an attempt is made to resolve a child, it will flush the events, then validate it's children. // When no receiveLanguage is known at this time, we must parse it from the header in the value itself // Otherwise, it's a string of the form sync:language:len:data:sync:language:len:data // Supporting more than one format - e.g. json and js when there are code updates to be applied // Process the next chunk on the next iteration of the loop. // Reset this so we look for it the next time // Session was reset from the remote side // First step - clear the state on the client // Second step - on the next sync, add a parameter to have the server return the new initSync for this page