OpenMSPSyncMessageFactory.java

00001 /*
00002  * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM)
00003  * Copyright (C) 2004-2006 Philippe Delrieu
00004  * All rights reserved.
00005  * Contact: pdelrieu@openmobileis.org
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00020  * USA
00021  *
00022  *  Author : Philippe Delrieu
00023  * 
00024  */
00025 package org.openmobileis.synchro.openmsp.client.core;
00026 
00027 import java.util.Hashtable;
00028 
00029 import org.openmobileis.common.util.codec.GeneralCoder;
00030 import org.openmobileis.common.util.collection.Array;
00031 import org.openmobileis.common.util.log.LogManager;
00032 import org.openmobileis.common.util.log.LogServices;
00033 import org.openmobileis.synchro.client.SynchroDescriptor;
00034 import org.openmobileis.synchro.openmsp.OpenMSPException;
00035 import org.openmobileis.synchro.openmsp.client.OpenMSPSyncListener;
00036 import org.openmobileis.synchro.openmsp.protocol.AbstractCommand;
00037 import org.openmobileis.synchro.openmsp.protocol.Command;
00038 import org.openmobileis.synchro.openmsp.protocol.ContainerMessage;
00039 import org.openmobileis.synchro.openmsp.protocol.Element;
00040 import org.openmobileis.synchro.openmsp.protocol.Header;
00041 import org.openmobileis.synchro.openmsp.protocol.Message;
00042 import org.openmobileis.synchro.openmsp.protocol.MessageFactory;
00043 import org.openmobileis.synchro.openmsp.protocol.RequestCommand;
00044 import org.openmobileis.synchro.openmsp.protocol.Result;
00045 import org.openmobileis.synchro.openmsp.protocol.Status;
00046 import org.openmobileis.synchro.security.auth.Credential;
00047 import org.openmobileis.synchro.security.auth.CredentialCodec;
00048 
00056 public final class OpenMSPSyncMessageFactory {
00057   public static final String OpenMSPTARGET = "OpenMSPService";
00058   public static final String OpenMSPSOURCE = "OpenMSPSource";
00059   
00060   private static final String sessionIDServiceName = "OpenMSPSynchroManager";
00061 
00062   private Credential credential;
00063   private long sessionID = 0;
00064 
00068   private Hashtable synchroCmdIDServiceMapTable;
00069 
00073   private Hashtable synchroCmdIDCommandMapTable;
00074 
00078   public OpenMSPSyncMessageFactory() {
00079     super();
00080     sessionID = NumSyncManagerDB.getManager().getSyncNumberForService(sessionIDServiceName);
00081     synchroCmdIDServiceMapTable = new Hashtable();
00082     synchroCmdIDCommandMapTable = new Hashtable();
00083   }
00084   
00085   public void beginSynchro(Credential cred, SynchroDescriptor descriptor) throws OpenMSPException {
00086     this.credential = cred;
00087   }
00088   
00089   public void endSynchro() throws OpenMSPException {
00090     this.credential = null;
00091     synchroCmdIDCommandMapTable.clear();
00092     synchroCmdIDServiceMapTable.clear();
00093   }
00094   
00095   public Message getOpenMSPMessage(Array listenerList)  throws OpenMSPException {
00096    Header header = new Header(this.getSessionID(), OpenMSPSyncMessageFactory.OpenMSPSOURCE, OpenMSPSyncMessageFactory.OpenMSPTARGET);
00097    // add credential
00098    try {
00099      String currentCredential = this.credential.getPrincipal()+":"+this.credential.getPassword();
00100      header.setCredential("<Type>OpenMSP:auth-basic</Type><Format>b64</Format>", new String(GeneralCoder.encodeBase64(currentCredential.getBytes())));
00101    } catch (Throwable ex)  {
00102      LogManager.traceError(LogServices.WEBSERVICE, "Error during B64 encoding of synchro credential. Synchro abort.");
00103      throw new OpenMSPException(ex);
00104    }
00105    Message message = MessageFactory.getFactory().createMessage(header);
00106     int lsize = listenerList.size();
00107    for (int i=0; i<lsize; i++) {
00108      try {
00109        ((OpenMSPSyncListener)listenerList.get(i)).sendData(message);
00110      } catch (Throwable ex)  {
00111        LogManager.traceError(LogServices.WEBSERVICE, ex);
00112      }
00113    }
00114    if (!message.isEmpty()) {
00115      this.saveCommandMessageIDs(message);
00116    }
00117    return message;
00118    
00119   }
00120 
00121   /*
00122    * Dispath the server answer OpenMSP message to the appropriate syncListener.
00123    * To manager status properly, we create a hashtable containing for each cmdId of the sent message
00124    * and the associated syncName.
00125    */
00126   public void receiveOpenMSPMessage(Array synclistenerList, Message message)  throws OpenMSPException {
00127     long newSessionID =message.getHeader().getSessionID();
00128     this.setSessionID(newSessionID);
00129     message.resetCursor();
00130     while (message.hasMoreMessage()) {
00131       ContainerMessage container = message.nextMessage();
00132       Element element = container.getElement();
00133       container.resetCursor(); //reset cursor before processing. Avoid problems if the cursor has been modified before by other processing (use in unit test).
00134       try {
00135          if ( (element.getElementType() == Element.SYNC) ) {
00136           String target = ((Command)element).getTarget();
00137           OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList, target);              
00138           if (listener != null) {
00139             listener.receiveSyncCommand(container, newSessionID);
00140           }
00141          } else  if (element.getElementType() == Element.MAP) {
00142            String target = ((Command)element).getTarget();
00143            OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList, target);              
00144            if (listener != null) {
00145              listener.receiveMapCommand(container);
00146            }
00147          } else  if (element.getElementType() == Element.GET) {
00148            String target = ((Command)element).getTarget();
00149            OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList, target);              
00150            if (listener != null) {
00151              Credential cred = CredentialCodec.getOpenMSPCredential(((Command)element).getCrendential());
00152              listener.receiveGetCommand( cred, container, newSessionID);
00153            }
00154         } else if (element.getElementType() == Element.RESULT) {
00155             Result result = (Result)container.getElement();
00156             String syncName = (String)synchroCmdIDServiceMapTable.get(new Integer(result.getCmdRef()));
00157             if (syncName != null) {
00158               OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList,syncName);              
00159               if (listener != null) {
00160                 ContainerMessage initialContainer = (ContainerMessage)synchroCmdIDCommandMapTable.get(new Integer(result.getCmdRef()));
00161                 listener.receiveResultCommand(container, initialContainer);
00162               }
00163             }
00164         } else if (element.getElementType() == Element.STATUS) {
00165             Status status = (Status)container.getElement();
00166             String syncName = (String)synchroCmdIDServiceMapTable.get(new Integer(status.getCmdRef()));
00167             if (syncName != null) {
00168               OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList,syncName);              
00169               if (listener != null) {
00170                 ContainerMessage initialContainer = (ContainerMessage)synchroCmdIDCommandMapTable.get(new Integer(status.getCmdRef()));
00171                 listener.receiveStatusCommand(status, initialContainer);
00172               }
00173             }
00174         } else  // unknown command
00175             LogManager.traceError(LogServices.WEBSERVICE, "Unknown command : " + element.getElementType());
00176       } catch (Throwable ex)  {
00177         LogManager.traceError(LogServices.WEBSERVICE, ex);
00178         try     {
00179                   OpenMSPSyncListener listener = null;
00180                   if (element instanceof Command)       {
00181                         String target = ((Command)element).getTarget();
00182                         listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList, target);
00183                   } else if (element instanceof Result) {
00184                   Result result = (Result)container.getElement();
00185                   String syncName = (String)synchroCmdIDServiceMapTable.get(new Integer(result.getCmdRef()));
00186                   if (syncName != null) {
00187                     listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList,syncName);              
00188                   }
00189                 } else if (element.getElementType() == Element.STATUS) {
00190                   Status status = (Status)container.getElement();
00191                   String syncName = (String)synchroCmdIDServiceMapTable.get(new Integer(status.getCmdRef()));
00192                   if (syncName != null) {
00193                     listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList,syncName);              
00194                   }
00195                   }
00196                 if (listener != null) {
00197                   listener.notifySynchroFailure();
00198                 }
00199         } catch (Throwable ex2) {
00200           LogManager.traceError(LogServices.WEBSERVICE, "Error during Listener synchro error management. Can't notify to listener synchro error.");
00201           LogManager.traceError(LogServices.WEBSERVICE, ex2);
00202         }
00203       }
00204     } //end while nextMessage()
00205   }
00206   
00207   private OpenMSPSyncListener getListenerFromListWithName(Array list, String name)  {
00208     for (int i=0; i<list.size(); i++) {
00209       OpenMSPSyncListener listener = (OpenMSPSyncListener) list.get(i);
00210       if (listener.getSyncName().equals(name))  {
00211         return listener;
00212       }
00213     }
00214     return null;
00215   }
00216   
00217 
00218   private long getSessionID() {
00219     return sessionID;
00220   }
00221 
00222   private void setSessionID (long sessionid) {
00223     NumSyncManagerDB.getManager().saveSyncNumberForService(sessionid, sessionIDServiceName);
00224     sessionID = sessionid;
00225   }
00226 
00227   private void saveCommandMessageIDs(Message message)  {
00228     synchroCmdIDServiceMapTable.clear();
00229     synchroCmdIDCommandMapTable.clear();
00230     message.resetCursor();
00231     while (message.hasMoreMessage())  {
00232       ContainerMessage container = message.nextMessage();
00233       saveOpenMSPSourcesAndIDs(container, null);
00234       saveOpenMSPCommandAndIds(container);
00235     }
00236   }
00237 
00238   private void saveOpenMSPSourcesAndIDs(ContainerMessage container, String currentSourceName) {
00239     container.resetCursor();
00240     Element element = container.getElement();
00241     if (element instanceof Command) {
00242       Command command = (Command)element;
00243       if (command.getSource() != null)  {
00244         currentSourceName = command.getSource();
00245       }
00246       synchroCmdIDServiceMapTable.put(new Integer(command.getCmdId()), currentSourceName);
00247     } else if (element instanceof RequestCommand) {
00248       RequestCommand command = (RequestCommand)element;
00249       if (currentSourceName != null)  {
00250         synchroCmdIDServiceMapTable.put(new Integer(command.getCmdId()), currentSourceName);
00251       } else  {
00252         LogManager.traceError(LogServices.SYNCHROSERVICE, "CmlID with no source in message. Can't make reference in return message :"+command.getCmdId());
00253       }
00254     }
00255 
00256     while (container.hasMoreMessage())  {
00257       saveOpenMSPSourcesAndIDs(container.nextMessage(), currentSourceName);
00258     }
00259   }
00260 
00261   private void saveOpenMSPCommandAndIds(ContainerMessage container) {
00262     Element element = container.getElement();
00263     if (element instanceof AbstractCommand) {
00264       synchroCmdIDCommandMapTable.put(new Integer(((AbstractCommand)element).getCmdId()), container);
00265       if (element.getElementType() == Element.SYNC)  {
00266         container.resetCursor();
00267         while (container.hasMoreMessage())  {
00268           saveOpenMSPCommandAndIds(container.nextMessage());
00269         }
00270       }
00271     }
00272   }
00273 
00274 }

Generated on Mon Dec 4 11:03:28 2006 for OpenMobileIS by  doxygen 1.5.1-p1