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   //     LogManager.traceDebug(0, "OpenMSPSyncMessageFactory get message for listener  :"+((OpenMSPSyncListener)listenerList.get(i)).getSyncName());
00110       ((OpenMSPSyncListener)listenerList.get(i)).sendData(message);
00111      } catch (Throwable ex)  {
00112        LogManager.traceError(LogServices.WEBSERVICE, ex);
00113      }
00114    }
00115    if (!message.isEmpty()) {
00116      this.saveCommandMessageIDs(message);
00117    }
00118    return message;
00119    
00120   }
00121 
00122   /*
00123    * Dispath the server answer OpenMSP message to the appropriate syncListener.
00124    * To manager status properly, we create a hashtable containing for each cmdId of the sent message
00125    * and the associated syncName.
00126    */
00127   public void receiveOpenMSPMessage(Array synclistenerList, Message message)  throws OpenMSPException {
00128     long newSessionID =message.getHeader().getSessionID();
00129     this.setSessionID(newSessionID);
00130     message.resetCursor();
00131     while (message.hasMoreMessage()) {
00132       ContainerMessage container = message.nextMessage();
00133       Element element = container.getElement();
00134       container.resetCursor(); //reset cursor before processing. Avoid problems if the cursor has been modified before by other processing (use in unit test).
00135       try {
00136          if ( (element.getElementType() == Element.SYNC) ) {
00137           String target = ((Command)element).getTarget();
00138           OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList, target);              
00139           if (listener != null) {
00140             listener.receiveSyncCommand(container, newSessionID);
00141           }
00142          } else  if (element.getElementType() == Element.MAP) {
00143            String target = ((Command)element).getTarget();
00144            OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList, target);              
00145            if (listener != null) {
00146              listener.receiveMapCommand(container);
00147            }
00148          } else  if (element.getElementType() == Element.GET) {
00149            String target = ((Command)element).getTarget();
00150            OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList, target);              
00151            if (listener != null) {
00152              Credential cred = CredentialCodec.getOpenMSPCredential(((Command)element).getCrendential());
00153              listener.receiveGetCommand( cred, container, newSessionID);
00154            }
00155         } else if (element.getElementType() == Element.RESULT) {
00156             Result result = (Result)container.getElement();
00157             String syncName = (String)synchroCmdIDServiceMapTable.get(new Integer(result.getCmdRef()));
00158             if (syncName != null) {
00159               OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList,syncName);              
00160               if (listener != null) {
00161                 ContainerMessage initialContainer = (ContainerMessage)synchroCmdIDCommandMapTable.get(new Integer(result.getCmdRef()));
00162                 listener.receiveResultCommand(container, initialContainer);
00163               }
00164             }
00165         } else if (element.getElementType() == Element.STATUS) {
00166             Status status = (Status)container.getElement();
00167             String syncName = (String)synchroCmdIDServiceMapTable.get(new Integer(status.getCmdRef()));
00168             if (syncName != null) {
00169               OpenMSPSyncListener listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList,syncName);              
00170               if (listener != null) {
00171                 ContainerMessage initialContainer = (ContainerMessage)synchroCmdIDCommandMapTable.get(new Integer(status.getCmdRef()));
00172                 listener.receiveStatusCommand(status, initialContainer);
00173               }
00174             }
00175         } else  // unknown command
00176             LogManager.traceError(LogServices.WEBSERVICE, "Unknown command : " + element.getElementType());
00177       } catch (Throwable ex)  {
00178         LogManager.traceError(LogServices.WEBSERVICE, ex);
00179         try     {
00180                   OpenMSPSyncListener listener = null;
00181                   if (element instanceof Command)       {
00182                         String target = ((Command)element).getTarget();
00183                         listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList, target);
00184                   } else if (element instanceof Result) {
00185                   Result result = (Result)container.getElement();
00186                   String syncName = (String)synchroCmdIDServiceMapTable.get(new Integer(result.getCmdRef()));
00187                   if (syncName != null) {
00188                     listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList,syncName);              
00189                   }
00190                 } else if (element.getElementType() == Element.STATUS) {
00191                   Status status = (Status)container.getElement();
00192                   String syncName = (String)synchroCmdIDServiceMapTable.get(new Integer(status.getCmdRef()));
00193                   if (syncName != null) {
00194                     listener = (OpenMSPSyncListener)this.getListenerFromListWithName(synclistenerList,syncName);              
00195                   }
00196                   }
00197                 if (listener != null) {
00198                   listener.notifySynchroFailure();
00199                 }
00200         } catch (Throwable ex2) {
00201           LogManager.traceError(LogServices.WEBSERVICE, "Error during Listener synchro error management. Can't notify to listener synchro error.");
00202           LogManager.traceError(LogServices.WEBSERVICE, ex2);
00203         }
00204       }
00205     } //end while nextMessage()
00206   }
00207   
00208   private OpenMSPSyncListener getListenerFromListWithName(Array list, String name)  {
00209     for (int i=0; i<list.size(); i++) {
00210       OpenMSPSyncListener listener = (OpenMSPSyncListener) list.get(i);
00211       if (listener.getSyncName().equals(name))  {
00212         return listener;
00213       }
00214     }
00215     return null;
00216   }
00217   
00218 
00219   private long getSessionID() {
00220     return sessionID;
00221   }
00222 
00223   private void setSessionID (long sessionid) {
00224     NumSyncManagerDB.getManager().saveSyncNumberForService(sessionid, sessionIDServiceName);
00225     sessionID = sessionid;
00226   }
00227 
00228   private void saveCommandMessageIDs(Message message)  {
00229     synchroCmdIDServiceMapTable.clear();
00230     synchroCmdIDCommandMapTable.clear();
00231     message.resetCursor();
00232     while (message.hasMoreMessage())  {
00233       ContainerMessage container = message.nextMessage();
00234       saveOpenMSPSourcesAndIDs(container, null);
00235       saveOpenMSPCommandAndIds(container);
00236     }
00237   }
00238 
00239   private void saveOpenMSPSourcesAndIDs(ContainerMessage container, String currentSourceName) {
00240     container.resetCursor();
00241     Element element = container.getElement();
00242     if (element instanceof Command) {
00243       Command command = (Command)element;
00244       if (command.getSource() != null)  {
00245         currentSourceName = command.getSource();
00246       }
00247       synchroCmdIDServiceMapTable.put(new Integer(command.getCmdId()), currentSourceName);
00248     } else if (element instanceof RequestCommand) {
00249       RequestCommand command = (RequestCommand)element;
00250       if (currentSourceName != null)  {
00251         synchroCmdIDServiceMapTable.put(new Integer(command.getCmdId()), currentSourceName);
00252       } else  {
00253         LogManager.traceError(LogServices.SYNCHROSERVICE, "CmlID with no source in message. Can't make reference in return message :"+command.getCmdId());
00254       }
00255     }
00256 
00257     while (container.hasMoreMessage())  {
00258       saveOpenMSPSourcesAndIDs(container.nextMessage(), currentSourceName);
00259     }
00260   }
00261 
00262   private void saveOpenMSPCommandAndIds(ContainerMessage container) {
00263     Element element = container.getElement();
00264     if (element instanceof AbstractCommand) {
00265       synchroCmdIDCommandMapTable.put(new Integer(((AbstractCommand)element).getCmdId()), container);
00266       if (element.getElementType() == Element.SYNC)  {
00267         container.resetCursor();
00268         while (container.hasMoreMessage())  {
00269           saveOpenMSPCommandAndIds(container.nextMessage());
00270         }
00271       }
00272     }
00273   }
00274 
00275 }

Generated on Mon Jan 11 21:19:16 2010 for OpenMobileIS by  doxygen 1.5.4