/** * Copyright (C) 2006-2007 Funambol * * This program is free software; you can redistribute it and/or modify * it under the terms of the Honest Public License. * * 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 * Honest Public License for more details. * * You should have received a copy of the Honest Public License * along with this program; if not, write to Funambol, * 643 Bair Island Road, Suite 305 - Redwood City, CA 94063, USA */ package br.com.prognus.psync.synclet; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import com.funambol.framework.core.AbstractCommand; import com.funambol.framework.core.Alert; import com.funambol.framework.core.Status; import com.funambol.framework.core.Results; import com.funambol.framework.core.Sync; import com.funambol.framework.core.Map; import com.funambol.framework.core.Item; import com.funambol.framework.core.DataStore; import com.funambol.framework.core.Source; import com.funambol.framework.core.Sync4jException; import com.funambol.framework.core.SyncBody; import com.funambol.framework.core.SyncML; import com.funambol.framework.core.Target; import com.funambol.framework.core.TargetRef; import com.funambol.framework.core.SourceRef; import com.funambol.framework.engine.pipeline.InputMessageProcessor; import com.funambol.framework.engine.pipeline.OutputMessageProcessor; import com.funambol.framework.engine.pipeline.MessageProcessingContext; import com.funambol.framework.logging.FunambolLogger; import com.funambol.framework.logging.FunambolLoggerFactory; import com.funambol.framework.protocol.ProtocolUtil; import com.funambol.framework.core.DevInfItem; /** * This class strips the source URIs with a './' if needed. * * This is done in order to allow any client to sync with the source URIs * defined, because some devices have a prefix of './'. * * @version $Id: SourceUriPrefixSynclet.java,v 1.4 2007-02-15 10:23:46 luigiafassina Exp $ */ public class SourceUriPrefixSynclet implements InputMessageProcessor, OutputMessageProcessor { // --------------------------------------------------------------- Constants private static final String SYNCLET_NAME = SourceUriPrefixSynclet.class.getName(); private static final String PROPERTY_SOURCENAME_CHANGED = "funambol.foundation.sourceuriprefix.SOURCENAME_CHANGED"; // ------------------------------------------------------------ Private data private static final FunambolLogger log = FunambolLoggerFactory.getLogger("engine.pipeline"); // ---------------------------------------------------------- Public methods /** * Process input message and set MessageProcessingContext property. * * @param processingContext the message processing context * @param message the message to be processed * @throws Sync4jException */ public void preProcessMessage(MessageProcessingContext processingContext, SyncML message ) throws Sync4jException { if (log.isTraceEnabled()) { log.trace(SYNCLET_NAME + ".preProcessMessage(...)"); } HashMap sourceReplacedMap = (HashMap)processingContext.getSessionProperty( PROPERTY_SOURCENAME_CHANGED); if (sourceReplacedMap == null) { sourceReplacedMap = new HashMap(); processingContext.setSessionProperty(PROPERTY_SOURCENAME_CHANGED, sourceReplacedMap ); } // // Store and change the source uri into commands // manageInputAlert (message, sourceReplacedMap); manageInputStatus(message, sourceReplacedMap); manageInputSync (message, sourceReplacedMap); manageInputMap (message, sourceReplacedMap); } /** * Process and manipulate the output message. * * @param processingContext the message processing context * @param message the message to be processed * @throws Sync4jException */ public void postProcessMessage(MessageProcessingContext processingContext, SyncML message) throws Sync4jException { if (log.isTraceEnabled()) { log.trace(SYNCLET_NAME + ".postProcessMessage(...)"); } HashMap sourceReplacedMap = (HashMap)processingContext.getSessionProperty( PROPERTY_SOURCENAME_CHANGED); if (!sourceReplacedMap.isEmpty()) { // // Replace original source uri into commands // manageOutputStatus (message, sourceReplacedMap); manageOutputResults(message, sourceReplacedMap); manageOutputAlert (message, sourceReplacedMap); manageOutputSync (message, sourceReplacedMap); } } // --------------------------------------------------------- Private Methods /** * Store and change Target URI into Alert commands * * @param message the client message * @param sourceReplacedMap the HashMap in which store uri to replace */ private void manageInputAlert(SyncML message, HashMap sourceReplacedMap) { if (log.isTraceEnabled()) { log.trace("Strip TargetURI into input Alert commands"); } SyncBody syncBody = message.getSyncBody(); AbstractCommand[] allClientCommands = (AbstractCommand[])syncBody.getCommands().toArray( new AbstractCommand[0]); ArrayList alertList = ProtocolUtil.filterCommands(allClientCommands, Alert.class); Iterator itAlertList = alertList.iterator(); Alert alert = null; ArrayList items = null; Iterator itItem = null; Item item = null; Target target = null; String targetUri = null; while (itAlertList.hasNext()) { alert = (Alert)itAlertList.next(); items = alert.getItems(); itItem = items.iterator(); while (itItem.hasNext()) { item = (Item)itItem.next(); target = item.getTarget(); if (target != null) { targetUri = target.getLocURI(); if (log.isTraceEnabled()) { log.trace("original targetUri: " + targetUri); } if (targetUri.startsWith("./")) { String targetNew = targetUri.substring(2); if (log.isTraceEnabled()) { log.trace("new targetUri: " + targetNew); } target.setLocURI(targetNew); sourceReplacedMap.put(targetNew, targetUri); } } } } } /** * Store and change SourceRef into Status commmads * * @param message the client message * @param sourceReplacedMap the HashMap in which store uri to replace */ private void manageInputStatus(SyncML message, HashMap sourceReplacedMap) { if (log.isTraceEnabled()) { log.trace("Strip SourceRef into input Status commands"); } SyncBody syncBody = message.getSyncBody(); AbstractCommand[] allClientCommands = (AbstractCommand[])syncBody.getCommands().toArray( new AbstractCommand[0]); ArrayList statusList = ProtocolUtil.filterCommands(allClientCommands, Status.class); Iterator itStatusList = statusList.iterator(); Status status = null; while (itStatusList.hasNext()) { status = (Status)itStatusList.next(); SourceRef[] srefs = (SourceRef[])status.getSourceRef().toArray(new SourceRef[0]); int s = srefs.length; for(int i=0;i 0) { if (items[0] instanceof DevInfItem) { DevInfItem item = (DevInfItem) items[0]; ArrayList dss = item.getDevInfData().getDevInf().getDataStores(); int s = dss.size(); for (int i = 0; i < s; i++) { DataStore ds = (DataStore) dss.get(i); String sourceRef = ds.getSourceRef().getValue(); if (sourceReplacedMap.containsKey(sourceRef)) { ds.getSourceRef().setValue((String) sourceReplacedMap. get(sourceRef)); } } } } } /** * Replace Source into Sync commands * * @param message the client message * @param sourceReplacedMap the HashMap with the uri to replace */ private void manageOutputSync(SyncML message, HashMap sourceReplacedMap) { if (log.isTraceEnabled()) { log.trace("Replace Source into output Sync commands"); } SyncBody syncBody = message.getSyncBody(); AbstractCommand[] allServerCommands = (AbstractCommand[])syncBody.getCommands().toArray( new AbstractCommand[0]); ArrayList syncList = ProtocolUtil.filterCommands(allServerCommands, Sync.class); Iterator itSyncList = syncList.iterator(); Sync sync = null; Source source = null; String sourceUri = null; while (itSyncList.hasNext()) { sync = (Sync) itSyncList.next(); source = sync.getSource(); if (source != null) { sourceUri = source.getLocURI(); if (sourceReplacedMap.containsKey(sourceUri)) { // // Here we have to create a new Source object because // the Sync can contain the same Source used in the // engine/sessionHandler to handle the Database. // If here we change the source object of the sync commands we // change also the source of the database because it's // the same object!!. // // Source newSource = new Source( (String) sourceReplacedMap.get(sourceUri), source.getLocName() ); sync.setSource(newSource); } } } } }