/**************************************************************************** * Copyright (c) 2008 Composent, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Composent, Inc. - initial API and implementation *****************************************************************************/ package org.eclipse.ecf.sync; import org.eclipse.core.runtime.IAdaptable; /** * Model synchronization strategy contract. Model synchronization strategy * instances are used to synchronize replicated instances of an arbitrary model. * This is done by creating instances implementing this interface on * participating processes, and then using them in the following manner. * <p> * First, assume for simplicity that there are two processes (A and B), each * with a replica of a given model (a and b). Also assume that prior to using a * synchronization strategy that the model is accurately and reliably replicated * to A and B (i.e. a == b). Further, assume that for both A and B an instance * of IModelSynchronizationStrategy is created (call them Sa and Sb) prior to * any changes being made to either a or b. * </p> * <p> * On process A assume that the user makes a change to a via a (local) editor. * Then the expected sequence of activities is as follows: * </p> * <ul> * <li>Process A should synchronously call * {@link #registerLocalChange(IModelChange)}. The IModelChange instance * provided must be 1) not <code>null</code>; and 2) Of a type that is * appropriate for this synchronization strategy.</li> * <li>Process A should take the resulting {@link IModelChangeMessage}, * serialize it (by calling {@link IModelChangeMessage#serialize()} and send the * message to remote processes (i.e. B).</li> * <li> * Process B should take the received byte array and call * {@link #deserializeRemoteChange(byte[])} to create an IModelChange instance.</li> * <li> * Process B should then pass the IModelChange instance to * {@link #transformRemoteChange(IModelChange)}. The synchronization * implementation will then return an array of IModelChange instances * (IModelChange []). These IModelChange instance should then be cast to the * appropriate type, and applied to the local instance of the model (i.e. b). * The {@link #transformRemoteChange(IModelChange)} metho will take the local * changes (previously registered with the synchronization strategy via * {@link #registerLocalChange(IModelChange)}), and the remote changes provided * via {@link #transformRemoteChange(IModelChange)}, and transform the changes * into a set that will result in a synchronized local copy.</li> * </ul> * <p> * Note that clients should generally call the * {@link #registerLocalChange(IModelChange)} and apply the IModelChanges * returned from {@link #transformRemoteChange(IModelChange)} on the same thread * that is responsible for modifying the underlying model. For example, if a * document model is modified by an editor (via UI thread) then the UI thread * should also synchronously call {@link #registerLocalChange(IModelChange)}, * and the changes from {@link #transformRemoteChange(IModelChange)} should also * be applied to the local document from within this same thread. * </p> * * @since 2.1 */ public interface IModelSynchronizationStrategy extends IAdaptable { /** * Register local model change with synchronization strategy. This method * should be synchronously called when a local model change has been made to * the underlying model. * * @param localChange * the IModelChange made to the local model. Must be non- * <code>null</code>, and must be of type appropriate for the * synchronization strategy. * @return IModelChangeMessage[] an array of change message to be delivered * to remote participants. If no change message can be created for * this local change (e.g. because the localChange is not of the * expected type, or because the change is not to be propogated to * remotes, then an empty array will be returned). */ public IModelChangeMessage[] registerLocalChange(IModelChange localChange); /** * Transform remote change into a set of local changes to be synchronously * applied to the local model. * * @param remoteChange * the remote model change instance to be transformed by this * synchronization strategy. * @return IModelChange[] to apply to local model. */ public IModelChange[] transformRemoteChange(IModelChange remoteChange); /** * Deserialization of given byte array to concrete instance of IModelChange * object to represent local change to be applied * * @param bytes * the bytes to be deserialized. * @return IModelChange instance from bytes. Will not be <code>null</code>. * @throws SerializationException * thrown if some problem deserializing given bytes. */ public IModelChange deserializeRemoteChange(byte[] bytes) throws SerializationException; }