OpenMSPSynchroManager.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  *  Modified by Manuel Gomez 2007.
00024  *
00025  */
00026 
00027 package org.openmobileis.synchro.openmsp.client;
00028 
00029 import java.io.ByteArrayOutputStream;
00030 import java.io.IOException;
00031 import java.util.zip.GZIPOutputStream;
00032 
00033 import org.openmobileis.common.context.ApplicationContextManager;
00034 import org.openmobileis.common.context.Plateform;
00035 import org.openmobileis.common.intl.IntlResourceManager;
00036 import org.openmobileis.common.user.UserNotFoundException;
00037 import org.openmobileis.common.util.PropertiesManager;
00038 import org.openmobileis.common.util.PersistentPropertiesManager;
00039 import org.openmobileis.common.util.codec.GeneralCoder;
00040 import org.openmobileis.common.util.collection.Array;
00041 import org.openmobileis.common.util.exception.SynchroException;
00042 import org.openmobileis.common.util.log.LogManager;
00043 import org.openmobileis.database.fastobjectdb.synchro.client.SynchroListenerAddNotifier;
00044 import org.openmobileis.synchro.client.SynchroDescriptor;
00045 import org.openmobileis.synchro.client.SynchroProcessor;
00046 import org.openmobileis.synchro.openmsp.OpenMSPException;
00047 import org.openmobileis.synchro.openmsp.client.conduit.ConduitParameter;
00048 import org.openmobileis.synchro.openmsp.client.core.ListenerOrdonancer;
00049 import org.openmobileis.synchro.openmsp.client.core.OpenMSPSyncMessageFactory;
00050 import org.openmobileis.synchro.openmsp.protocol.Message;
00051 import org.openmobileis.synchro.openmsp.protocol.MessageFactory;
00052 import org.openmobileis.synchro.openmsp.protocol.Status;
00053 import org.openmobileis.synchro.security.auth.Credential;
00054 
00062 public class OpenMSPSynchroManager implements SynchroProcessor {
00063   public static final String OPENMSPPROCESSORNAME="OpenMSPSync";
00064 
00065   private static OpenMSPSynchroManager manager;
00066   private ListenerOrdonancer listenerOrdonancer;
00067   private ListenerOrdonancer moduleOrdonancer;
00068   private OpenMSPSyncMessageFactory messageFactory;
00069   private String lastSynchroLogin;
00070   private int perglobalSynchroStatut;
00071   private SynchroListenerAddNotifier addlistener;
00072   private OpenMSPSynchroProcessListener processListener;
00073   private boolean continuesynchro = false;
00074   private boolean synchroPending = false;
00075 
00079   private OpenMSPSynchroManager() {
00080     super();
00081     this.listenerOrdonancer = new ListenerOrdonancer();
00082     this.moduleOrdonancer = new ListenerOrdonancer();
00083     this.messageFactory = new OpenMSPSyncMessageFactory();
00084     String ss = PersistentPropertiesManager.getManager().getProperty(OPENMSPPROCESSORNAME, "globalSynchroStatut");
00085     if (ss!=null){
00086         this.perglobalSynchroStatut =  Integer.parseInt(ss);
00087     }
00088   }
00089 
00090   public static OpenMSPSynchroManager getManager() {
00091     if (manager == null)  {
00092       synchronized (OpenMSPSynchroManager.class) {
00093         if (manager == null)  {
00094           manager = new OpenMSPSynchroManager();
00095           ApplicationContextManager.getManager().addManager(manager);
00096         }
00097       }
00098     }
00099     return manager;
00100   }
00101   
00102   public void setOpenMSPSynchroProcessListener(OpenMSPSynchroProcessListener listener)  {
00103         this.processListener = listener;
00104   }
00105 
00106   public void clearListeners(){
00107           this.listenerOrdonancer.clearListeners();
00108   }
00109 
00110   public String getProcessorName()  {
00111     return OpenMSPSynchroManager.OPENMSPPROCESSORNAME;
00112   }
00113 
00114   public void notifyFailure(String listernerName) {
00115     OpenMSPSyncListener listener = this.getListenerByName(listernerName);
00116     if (listener != null) {
00117       listener.notifySynchroFailure();
00118       listenerOrdonancer.notifySynchroError(listener.getSyncName());
00119       moduleOrdonancer.notifySynchroError(listener.getSyncName());
00120     }
00121     this.setGlobalSynchroStatut(Status.STATUS_FAILED);
00122   }
00123   
00129   public Array getAllListeners() {
00130           return listenerOrdonancer.getAllListeners();
00131   }
00132 
00138   public OpenMSPSyncListener getListenerByName(String listenerName) {
00139     return listenerOrdonancer.getListenerByName(listenerName);
00140   }
00141   
00148   public boolean removeListenerByName(String listenerName) {
00149           return listenerOrdonancer.removeListenerByName(listenerName);
00150   }
00151   
00157   public void inactivateListenerByName(String listenerName) {
00158           this.listenerOrdonancer.setInactivateListenerByName(listenerName, true);
00159   }
00160   
00166   public void activateListenerByName(String listenerName) {
00167           this.listenerOrdonancer.setInactivateListenerByName(listenerName, false);
00168   }
00169 
00178   public OpenMSPSyncListener getModuleListenerByName(String listenerName) {
00179     return moduleOrdonancer.getListenerByName(listenerName);
00180   }
00181   
00185   public synchronized void restartSynchro()     {
00186         this.continuesynchro = true;
00187     LogManager.traceDebug(0, "OpenMSPSynchroManager RESTARTSYNCHRO");
00188   }
00189   
00190   /***
00191    * This method block until the synchro end. Return immediatly if the synchro is not started.
00192    */
00193   public synchronized void waitSynchroEnd()     {
00194         if (synchroPending)     {
00195             LogManager.traceDebug(0, "OpenMSPSynchroManager waitSynchroEnd BEFORE WAIT");
00196             try {
00197                 this.wait();
00198             } catch(Throwable ex){
00199                     LogManager.traceDebug(0, "OpenMSPSynchroManager waitSynchroEnd ERROR");
00200                 LogManager.traceDebug(0, ex.toString());
00201             }
00202             LogManager.traceDebug(0, "OpenMSPSynchroManager waitSynchroEnd END WAIT");
00203         }
00204   }
00205 
00206   public void doSynchro(Credential cred, SynchroDescriptor descriptor) throws SynchroException {
00207         synchronized (this)     {
00208             LogManager.traceDebug(0, "OpenMSPSynchroManager doSynchro START");
00209                 synchroPending = true;
00210         }
00211         try     {
00212         this.setGlobalSynchroStatut(Status.STATUS_SYNC_IN_PROGRESS);
00213     if (processListener != null) processListener.notifySynchroStart();
00214     this.lastSynchroLogin = cred.getPrincipal();
00215 
00216     //save login
00217     PersistentPropertiesManager.getManager().saveProperty("OpenMSPSynchroManager", "login", this.lastSynchroLogin);
00218     
00219     this.continuesynchro = true;
00220     while (this.continuesynchro)        {
00221             synchronized(this)  {
00222                 this.continuesynchro = false;
00223             }
00224             ListenerOrdonancer currentOrdonnancer = this.listenerOrdonancer;
00225             currentOrdonnancer.beginSynchro();
00226             this.messageFactory.beginSynchro(cred, descriptor);
00227             Array listenerList = currentOrdonnancer.getNextListenerList();
00228 //          LogManager.traceDebug(0, "OpenMSPSynchroManager synchro listener list size :"+listenerList.size()+" continuesynchro:"+this.continuesynchro);
00229             boolean moduleSynchro = false;
00230             if (listenerList.size() == 0)   {
00231               currentOrdonnancer.endSynchro();
00232               currentOrdonnancer = this.moduleOrdonancer;
00233               currentOrdonnancer.beginSynchro();
00234               listenerList = currentOrdonnancer.getNextListenerList();
00235               moduleSynchro = true;
00236             }
00237             try {
00238               while (listenerList.size() != 0)  {
00239                 int listsize = listenerList.size();
00240                     LogManager.traceDebug(0, "OpenMSPSynchroManager synchro listener list size in while :"+listsize);
00241                 for (int i=0; i<listsize; i++)  {
00242                   OpenMSPSyncListener listener = (OpenMSPSyncListener) listenerList.get(i);
00243                   if (processListener != null) processListener.notifyListenerStartSync(listener.getSyncName());
00244                 //  LogManager.traceDebug(0, "OpenMSPSynchroManager start sync for listener  :"+listener.getSyncName());
00245                   listener.startSync(cred, descriptor);
00246                 }
00247                 while (true) {
00248                  if (processListener != null) processListener.notifyGenerateOpenMSPMessage();
00249                   Message message = this.messageFactory.getOpenMSPMessage(listenerList);
00250                   if (message.isEmpty()) {
00251                     //get next listener phase.
00252                     break;
00253                   }
00254                   String xmlString = message.encode();
00255                   ConduitParameter[] parameters = new ConduitParameter[] {new ConduitParameter("openMISGroup", descriptor.getSynchroGroup())};
00256                   if (processListener != null) processListener.notifyBeforeSendMessage();
00257                   String reqResult = descriptor.getSynchroConduit().sendRequest(parameters, new String(compressAndEncodeRequest(xmlString)), descriptor.getServerURL());
00258                   // third step : Process responses
00259                   if (processListener != null) processListener.notifyReceiveMessageReturn();
00260                   Message receivedMessage = MessageFactory.getFactory().getMessage(reqResult);
00261                   String target = receivedMessage.getHeader().getTarget();
00262                   if (processListener != null) processListener.notifyBeforeProcessMessageReturn();
00263                   if (!target.equals(OpenMSPSyncMessageFactory.OpenMSPSOURCE)) {
00264                     throw new OpenMSPException("Bad OpenMSP Sync Source in Server answer message. Synchro Abort.");
00265                   } else {
00266                     this.messageFactory.receiveOpenMSPMessage(listenerList, receivedMessage);
00267                   }
00268                   if (processListener != null) processListener.notifyAfterProcessMessageReturn();
00269                 }
00270                 for (int i=0; i<listsize; i++)  {
00271                   OpenMSPSyncListener listener = (OpenMSPSyncListener) listenerList.get(i);
00272                   if (processListener != null) processListener.notifyListenerEndSync(listener.getSyncName());
00273                   listener.endSync();
00274                 }
00275                 listenerList = currentOrdonnancer.getNextListenerList();
00276                 if (listenerList.size() == 0 && !moduleSynchro)   {
00277                   currentOrdonnancer.endSynchro();
00278                   currentOrdonnancer = this.moduleOrdonancer;
00279                   currentOrdonnancer.beginSynchro();
00280                   listenerList = currentOrdonnancer.getNextListenerList();
00281                   moduleSynchro = true;
00282                 }
00283               }
00284               if (processListener != null) processListener.notifyEndProcessListener();
00285               if (this.getGlobalSynchroStatut() == Status.STATUS_SYNC_IN_PROGRESS) this.setGlobalSynchroStatut(Status.STATUS_OK);
00286             } catch (UserNotFoundException ex)  {
00287               notifyFailureToListeners(listenerList);
00288               this.setGlobalSynchroStatut(Status.STATUS_UNAUTHORIZED);
00289               if (processListener != null) processListener.notifySynchroFailure(Status.STATUS_UNAUTHORIZED);
00290               throw new OpenMSPException(ex);
00291             } catch (Throwable ex)  {
00292               notifyFailureToListeners(listenerList);
00293               if (processListener != null) processListener.notifySynchroFailure(Status.STATUS_FAILED);
00294               throw new OpenMSPException(ex);
00295             } finally {
00296               this.listenerOrdonancer.endSynchro();
00297               this.moduleOrdonancer.endSynchro();
00298               this.messageFactory.endSynchro();
00299               if (processListener != null) processListener.notifySynchroEnd();
00300             }
00301     }
00302         } finally       {
00303                 synchronized(this){
00304                         this.synchroPending = false;
00305                         this.notifyAll();
00306             LogManager.traceDebug(0, "OpenMSPSynchroManager doSynchro END");
00307                 }
00308         }
00309   }
00310 
00314   public void registerSynchroListenerAddNotifier(SynchroListenerAddNotifier listener) {
00315     addlistener = listener;
00316   }
00317 
00329   public void addListener(OpenMSPSyncListener listener, String[] depends) {
00330    // LogManager.traceDebug(0, "OpenMSPSynchroManager add listener  :"+listener.getSyncName());
00331         // init listener.
00332         try     {
00333                 listener.initListener();
00334         }catch  (OpenMSPException ex)   {
00335                 LogManager.traceError(0, ex);
00336                 return;
00337         }
00338 
00339     if (addlistener != null) {
00340       addlistener.notifyAddListener(listener, depends);
00341       if (!addlistener.isBlocking())    {
00342         listenerOrdonancer.addListener(listener, depends);
00343       }
00344     } else  {
00345       listenerOrdonancer.addListener(listener, depends);
00346     }
00347   }
00348 
00349 
00350 
00360   public void addModuleListener(OpenMSPSyncListener listener, String[] depends) {
00361     moduleOrdonancer.addListener(listener, depends);
00362   }
00363 
00364   private void notifyFailureToListeners(Array listenerList) {
00365     for (int i=0; i<listenerList.size(); i++) {
00366       OpenMSPSyncListener listener = (OpenMSPSyncListener)listenerList.get(i);
00367       listener.notifySynchroFailure();
00368       listenerOrdonancer.notifySynchroError(listener.getSyncName());
00369       moduleOrdonancer.notifySynchroError(listener.getSyncName());
00370     }
00371     this.setGlobalSynchroStatut(Status.STATUS_FAILED);
00372   }
00373 
00374   private byte[] compressAndEncodeRequest(String request) throws IOException {
00375     // compresse data
00376     byte[] compressedData = null;
00377     ByteArrayOutputStream byteStream = new ByteArrayOutputStream(512);
00378     GZIPOutputStream zipStream = new GZIPOutputStream(byteStream);
00379     try {
00380       zipStream.write(request.getBytes());
00381     } finally  {
00382       zipStream.close();
00383     }
00384     compressedData = byteStream.toByteArray();
00385 
00386     // encode compressed data
00387     byte[] returnData = GeneralCoder.encodeBase64(compressedData);
00388     return returnData;
00389   }
00390 
00391   public String getLastSynchroLogin() {
00392     if (this.lastSynchroLogin == null){
00393       this.lastSynchroLogin = PersistentPropertiesManager.getManager().getProperty("OpenMSPSynchroManager", "login");
00394 
00395     }
00396     return this.lastSynchroLogin;
00397   }
00398 
00407   public String getSynchroUserAgent(SynchroDescriptor descriptor) {
00408     String usera = PropertiesManager.getManager().getProperty("org.openmobileis.synchro.direct.useragent");
00409     if (usera == null)  {
00410       Plateform plateform = ApplicationContextManager.getManager().getApplicationContext().getPlateform();
00411       StringBuffer useragent = new StringBuffer("OpenMSPPlug-");
00412       useragent.append(plateform.getOpenMobileISMajorVersion()).append('.').append(plateform.getOpenMobileISMinorVersion()).append('-');
00413       useragent.append(plateform.getOS()).append('[').append(plateform.getOSVersion()).append("]-");
00414       String language = IntlResourceManager.getManager().getManagerLocaleString();
00415       useragent.append(language);
00416       String synctype = descriptor.getProperty("OpenMSPsynchrotype");
00417       if (synctype != null) {
00418         useragent.append('-').append(synctype);
00419       }
00420       usera = useragent.toString();
00421     }
00422     return usera;
00423   }
00424 
00425   public int getGlobalSynchroStatut() {
00426     return this.perglobalSynchroStatut;
00427   }
00428 
00429   public void setGlobalSynchroStatut(int status) {
00430         PersistentPropertiesManager.getManager().saveProperty(OPENMSPPROCESSORNAME, "globalSynchroStatut", Integer.toString(status));
00431     perglobalSynchroStatut = status;
00432   }
00433 
00434 }

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