📄 sync4jengine.java
字号:
/** * Copyright (C) 2003-2004 Funambol * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package sync4j.server.engine;import java.util.*;import java.util.Map;import java.util.logging.Logger;import java.util.logging.Level;import java.security.Principal;import java.sql.Timestamp;import sync4j.framework.engine.*;import sync4j.framework.engine.source.SyncSource;import sync4j.framework.engine.source.SyncSourceInfo;import sync4j.framework.security.Officer;import sync4j.framework.security.Sync4jPrincipal;import sync4j.framework.logging.Sync4jLogger;import sync4j.framework.tools.beans.BeanFactory;import sync4j.framework.core.*;import sync4j.framework.database.Database;import sync4j.framework.protocol.CommandIdGenerator;import sync4j.framework.config.Configuration;import sync4j.framework.server.*;import sync4j.framework.server.store.*;import sync4j.server.engine.Sync4jSource;/** * This is the Sync4j implementation of the synchronization engine. * * LOG NAME: sync4j.engine * * @author Stefano Fornari @ Funambol * @version $Id: Sync4jEngine.java,v 1.51 2004/04/29 08:00:28 luigiafassina Exp $ */public class Sync4jEngineextends AbstractSyncEngineimplements java.io.Serializable { // --------------------------------------------------------------- Constants public static final String CFG_SECURITY_OFFICER = "security.officer" ; public static final String CFG_STRATEGY_CLASS = "engine.strategy" ; public static final String CFG_SYNCML_DTDVERSION = "syncml.dtdversion" ; public static final String CFG_ENGINE_MANIFACTURER = "engine.manifacturer" ; public static final String CFG_ENGINE_MODELNAME = "engine.modelname" ; public static final String CFG_ENGINE_OEM = "engine.oem" ; public static final String CFG_ENGINE_FWVERSION = "engine.firmwareversion"; public static final String CFG_ENGINE_SWVERSION = "engine.softwareversion"; public static final String CFG_ENGINE_HWVERSION = "engine.hardwareversion"; public static final String CFG_ENGINE_DEVICEID = "engine.deviceid" ; public static final String CFG_ENGINE_DEVICETYPE = "engine.devicetype" ; public static final String CFG_PERSISTENT_STORE = "engine.store" ; public static final String CFG_SERVER_URI = "server.uri" ; public static final String CFG_SERVER_DEBUG = "server.debug" ; public static final int SERVER = 0; public static final int CLIENT = 1; public static final String LOG_NAME = "engine"; // ------------------------------------------------------------ Private data /** * The configuration properties */ private Configuration configuration = null; public Configuration getConfiguration() { return configuration; } /** * The security officer */ private Officer officer = null; public Officer getOfficer() { return this.officer; } /** * The underlying persistent store */ private PersistentStore store = null; /** Getter for property store. * @return Value of property store. * */ public PersistentStore getStore() { return store; } /** Setter for property store. * @param store New value of property store. * */ public void setStore(PersistentStore store) { this.store = store; } /** * The sources this engine deals with */ private ArrayList serverSources = new ArrayList(); private ArrayList clientSources = new ArrayList(); /** * The modification objects of the last synchronization */ private HashMap operations = null; /** * The modification objects of the last synchronization */ private SyncOperationStatus[] operationStatus = null; /** * Logger */ //protected transient Logger log = Sync4jLogger.getLogger(); protected transient Logger log = null; // ------------------------------------------------------------ Constructors /** * To allow deserializazion of subclasses. */ protected Sync4jEngine() { } /** * Creates a new instance of Sync4jEngine. <p> * NOTE: This is a sample implementation that deals with a single source on * the file system. * * @throws ConfigurationException a runtime exception in case of misconfiguration */ public Sync4jEngine(Configuration configuration) { log = Sync4jLogger.getLogger(LOG_NAME); this.configuration = configuration; // // Set the underlying persistent store // HashMap psConfig = new HashMap(1); psConfig.put("class-loader", configuration.getClassLoader()); store = (PersistentStore)configuration.getBeanInstance(CFG_PERSISTENT_STORE); try { store.configure(psConfig); } catch (ConfigPersistentStoreException e) { log.severe("Error configuring the persistent store: " + e); log.throwing(getClass().getName(), "<init>", e); } // // Set the security officer // officer = (Officer)configuration.getBeanInstance(CFG_SECURITY_OFFICER); // // Set SyncSources // Sync4jSource[] sources = null; try { sources = (Sync4jSource[])store.read(Sync4jSource.class); } catch (PersistentStoreException e) { if (log.isLoggable(Level.SEVERE)) { log.severe("Error reading registered sources: " + e.getMessage()); } log.throwing(getClass().getName(), "<init>", e); } for (int i=0; ((sources != null) && (i<sources.length)); ++i) { if (log.isLoggable(Level.FINE)) { log.fine("sources[" + i + "]: " + sources[i]); } try { serverSources.add( BeanFactory.getBeanInstance(configuration.getClassLoader(), sources[i].getConfig()) ); } catch (Exception e){ String msg = "Unable to create sync source " + sources[i] + ": " + e.getMessage(); log.severe(msg); log.throwing(getClass().getName(), "<init>", e); } } // // Set the SyncStrategy object to use for comparisons // SyncStrategy strategy = (SyncStrategy)configuration.getClassInstance(CFG_STRATEGY_CLASS); setStrategy(strategy); if (log.isLoggable(Level.INFO)) { log.info("Engine configuration:"); log.info("store: " + store ); log.info("officer: " + officer ); log.info("strategy: " + strategy); } } // ------------------------------------------------ Configuration properties /** * The id generator */ private CommandIdGenerator cmdIdGenerator = null; /** * Set the id generator for commands * * @param cmdIdGenerator the id generator */ public void setCommandIdGenerator(CommandIdGenerator cmdIdGenerator) { this.cmdIdGenerator = cmdIdGenerator; } /** * Return the id generator * * @return the id generator */ public CommandIdGenerator getCommandIdGenerator() { return cmdIdGenerator; } // ------------------------------------------------------ Runtime properties /** * The database to be synchronized */ private HashMap dbs = new HashMap(); public void setDbs(HashMap dbs) { if (this.dbs != null) { this.dbs.clear(); } else { this.dbs = new HashMap(dbs.size()); } this.dbs.putAll(dbs); } public void setDbs(Database[] dbs) { if (this.dbs == null) { this.dbs = new HashMap(dbs.length); } for (int i=0; ((dbs != null) && (i<dbs.length)); ++i) { this.dbs.put(dbs[i].getName(), dbs[i]); } } public Database[] getDbs() { if (this.dbs == null) { return new Database[0]; } Iterator i = this.dbs.values().iterator(); Database[] ret = new Database[this.dbs.size()]; int j = 0; while(i.hasNext()) { ret[j++] = (Database)i.next(); } return ret; } /** * The existing LUID-GUID mapping. It is used and modify by sync() */ private Map clientMappings = new HashMap(); public void setClientMappings(Map clientMappings) { this.clientMappings = clientMappings; } // ---------------------------------------------------------- Public methods /** * Fires and manages the synchronization process. * * @param principal the principal who is requesting the sync * * @throws Sync4jException in case of error */ public void sync(Sync4jPrincipal principal) throws Sync4jException { log.info("Starting synchronization ..."); SyncStrategy syncStrategy = getStrategy(); SyncSource clientSource = null, serverSource = null; Database db = null; ArrayList status = new ArrayList(); // // Create maps for server sources so that they can be accessed throught // their name // HashMap sourceMap = new HashMap(serverSources.size()); Iterator s = serverSources.iterator(); while(s.hasNext()) { serverSource = (SyncSource)s.next(); sourceMap.put(serverSource.getSourceURI(), serverSource); } // // Now process clientSources // operations = new HashMap(); String uri = null; Iterator c = clientSources.iterator(); while(c.hasNext()) { clientSource = (SyncSource)c.next(); uri = clientSource.getSourceURI(); serverSource = (SyncSource)sourceMap.get(uri); db = (Database)dbs.get(clientSource.getSourceURI()); SyncSource[] sources = new SyncSource[] { serverSource, clientSource }; try { Sync4jPrincipal p = (Sync4jPrincipal)db.getPrincipal(); p.setId(principal.getId()); // // Call beginSync() // serverSource.beginSync(p, db.getMethod()); if ( (db.getMethod() == AlertCode.SLOW) || (db.getMethod() == AlertCode.REFRESH_FROM_SERVER)) { operations.put(uri, syncStrategy.prepareSlowSync(sources, p)); } else { // // Read the last timestamp from the persistent store, than // prepare for fast synchronization // LastTimestamp last = new LastTimestamp( p.getId() , db.getName() ); try { store.read(last); } catch (PersistentStoreException e) { throw new SyncException("Error reading last timestamp", e); } Timestamp since = new Timestamp(last.start); operations.put(uri, syncStrategy.prepareFastSync(sources, p, since)); } // // Now synchronize the sources // status.addAll( Arrays.asList( syncStrategy.sync((SyncOperation[])operations.get(uri)) ) ); operationStatus = (SyncOperationStatus[])status.toArray(new SyncOperationStatus[0]); // // Call endSync() // serverSource.endSync(p); log.info("Ending synchronization ..."); syncStrategy.endSync(); } catch (SyncException e) { log.throwing(getClass().getName(), "sync", e); throw new Sync4jException(e.getMessage(), e); } } // next i (client source) } /** * Returns the operations of the last synchronization * * @param uri the URI of the source the operations are applied to * * @return the operations of the last synchronization */ public SyncOperation[] getSyncOperations(String uri) { return (SyncOperation[])operations.get(uri); } /** * Returns the operation status of the operations executed in the last * synchronization * * @param msgId the id of the SyncML message * * @return the operations status of the operations executed in the last synchronization */ public Status[] getModificationsStatusCommands(String msgId) { if ((operationStatus == null) || (operationStatus.length == 0)) { return new Status[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -