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 globalSynchroStatut;
00071   private SynchroListenerAddNotifier addlistener;
00072   private OpenMSPSynchroProcessListener processListener;
00073 
00077   private OpenMSPSynchroManager() {
00078     super();
00079     this.listenerOrdonancer = new ListenerOrdonancer();
00080     this.moduleOrdonancer = new ListenerOrdonancer();
00081     this.messageFactory = new OpenMSPSyncMessageFactory();
00082   }
00083 
00084   public static OpenMSPSynchroManager getManager() {
00085     if (manager == null)  {
00086       synchronized (OpenMSPSynchroManager.class) {
00087         if (manager == null)  {
00088           manager = new OpenMSPSynchroManager();
00089           ApplicationContextManager.getManager().addManager(manager);
00090         }
00091       }
00092     }
00093     return manager;
00094   }
00095   
00096   public void setOpenMSPSynchroProcessListener(OpenMSPSynchroProcessListener listener)  {
00097         this.processListener = listener;
00098   }
00099 
00100   public void clearListeners(){
00101           this.listenerOrdonancer.clearListeners();
00102   }
00103 
00104   public String getProcessorName()  {
00105     return OpenMSPSynchroManager.OPENMSPPROCESSORNAME;
00106   }
00107 
00108   public void notifyFailure(String listernerName) {
00109     OpenMSPSyncListener listener = this.getListenerByName(listernerName);
00110     if (listener != null) {
00111       listener.notifySynchroFailure();
00112       listenerOrdonancer.notifySynchroError(listener.getSyncName());
00113       moduleOrdonancer.notifySynchroError(listener.getSyncName());
00114     }
00115     globalSynchroStatut = Status.STATUS_FAILED;
00116   }
00117 
00123   public OpenMSPSyncListener getListenerByName(String listenerName) {
00124     return listenerOrdonancer.getListenerByName(listenerName);
00125   }
00126   
00133   public boolean removeListenerByName(String listenerName) {
00134           return listenerOrdonancer.removeListenerByName(listenerName);
00135   }
00136 
00145   public OpenMSPSyncListener getModuleListenerByName(String listenerName) {
00146     return moduleOrdonancer.getListenerByName(listenerName);
00147   }
00148 
00149   public void doSynchro(Credential cred, SynchroDescriptor descriptor) throws SynchroException {
00150     globalSynchroStatut = Status.STATUS_SYNC_IN_PROGRESS;
00151     if (processListener != null) processListener.notifySynchroStart();
00152     this.lastSynchroLogin = cred.getPrincipal();
00153 
00154     //save login
00155     PersistentPropertiesManager.getManager().saveProperty("OpenMSPSynchroManager", "login", this.lastSynchroLogin);
00156     ListenerOrdonancer currentOrdonnancer = this.listenerOrdonancer;
00157     currentOrdonnancer.beginSynchro();
00158     this.messageFactory.beginSynchro(cred, descriptor);
00159     Array listenerList = currentOrdonnancer.getNextListenerList();
00160     boolean moduleSynchro = false;
00161     if (listenerList.size() == 0)   {
00162       currentOrdonnancer.endSynchro();
00163       currentOrdonnancer = this.moduleOrdonancer;
00164       currentOrdonnancer.beginSynchro();
00165       listenerList = currentOrdonnancer.getNextListenerList();
00166       moduleSynchro = true;
00167     }
00168     try {
00169       while (listenerList.size() != 0)  {
00170         int listsize = listenerList.size();
00171         for (int i=0; i<listsize; i++)  {
00172           OpenMSPSyncListener listener = (OpenMSPSyncListener) listenerList.get(i);
00173           if (processListener != null) processListener.notifyListenerStartSync(listener.getSyncName());
00174           listener.startSync(cred, descriptor);
00175         }
00176         while (true) {
00177          if (processListener != null) processListener.notifyGenerateOpenMSPMessage();
00178          Message message = this.messageFactory.getOpenMSPMessage(listenerList);
00179           if (message.isEmpty()) {
00180             //get next listener phase.
00181             break;
00182           }
00183           String xmlString = message.encode();
00184           ConduitParameter[] parameters = new ConduitParameter[] {new ConduitParameter("openMISGroup", descriptor.getSynchroGroup())};
00185           if (processListener != null) processListener.notifyBeforeSendMessage();
00186           String reqResult = descriptor.getSynchroConduit().sendRequest(parameters, new String(compressAndEncodeRequest(xmlString)), descriptor.getServerURL());
00187           // third step : Process responses
00188           if (processListener != null) processListener.notifyReceiveMessageReturn();
00189           Message receivedMessage = MessageFactory.getFactory().getMessage(reqResult);
00190           String target = receivedMessage.getHeader().getTarget();
00191           if (processListener != null) processListener.notifyBeforeProcessMessageReturn();
00192           if (!target.equals(OpenMSPSyncMessageFactory.OpenMSPSOURCE)) {
00193             throw new OpenMSPException("Bad OpenMSP Sync Source in Server answer message. Synchro Abort.");
00194           } else {
00195             this.messageFactory.receiveOpenMSPMessage(listenerList, receivedMessage);
00196           }
00197           if (processListener != null) processListener.notifyAfterProcessMessageReturn();
00198         }
00199         for (int i=0; i<listsize; i++)  {
00200           OpenMSPSyncListener listener = (OpenMSPSyncListener) listenerList.get(i);
00201           if (processListener != null) processListener.notifyListenerEndSync(listener.getSyncName());
00202           listener.endSync();
00203         }
00204         listenerList = currentOrdonnancer.getNextListenerList();
00205         if (listenerList.size() == 0 && !moduleSynchro)   {
00206           currentOrdonnancer.endSynchro();
00207           currentOrdonnancer = this.moduleOrdonancer;
00208           currentOrdonnancer.beginSynchro();
00209           listenerList = currentOrdonnancer.getNextListenerList();
00210           moduleSynchro = true;
00211         }
00212       }
00213       if (processListener != null) processListener.notifyEndProcessListener();
00214        globalSynchroStatut = Status.STATUS_OK;
00215     } catch (UserNotFoundException ex)  {
00216       notifyFailureToListeners(listenerList);
00217       globalSynchroStatut = Status.STATUS_UNAUTHORIZED;
00218       if (processListener != null) processListener.notifySynchroFailure(Status.STATUS_UNAUTHORIZED);
00219       throw new OpenMSPException(ex);
00220     } catch (Throwable ex)  {
00221       notifyFailureToListeners(listenerList);
00222       if (processListener != null) processListener.notifySynchroFailure(Status.STATUS_FAILED);
00223       throw new OpenMSPException(ex);
00224     } finally {
00225       this.listenerOrdonancer.endSynchro();
00226       this.moduleOrdonancer.endSynchro();
00227       this.messageFactory.endSynchro();
00228       if (processListener != null) processListener.notifySynchroEnd();
00229     }
00230   }
00231 
00235   public void registerSynchroListenerAddNotifier(SynchroListenerAddNotifier listener) {
00236     addlistener = listener;
00237   }
00238 
00250   public void addListener(OpenMSPSyncListener listener, String[] depends) {
00251         // init listener.
00252         try     {
00253                 listener.initListener();
00254         }catch  (OpenMSPException ex)   {
00255                 LogManager.traceError(0, ex);
00256                 return;
00257         }
00258 
00259     if (addlistener != null) {
00260       addlistener.notifyAddListener(listener, depends);
00261       if (!addlistener.isBlocking())    {
00262         listenerOrdonancer.addListener(listener, depends);
00263       }
00264     } else  {
00265       listenerOrdonancer.addListener(listener, depends);
00266     }
00267   }
00268 
00269 
00270 
00280   public void addModuleListener(OpenMSPSyncListener listener, String[] depends) {
00281     moduleOrdonancer.addListener(listener, depends);
00282   }
00283 
00284   private void notifyFailureToListeners(Array listenerList) {
00285     for (int i=0; i<listenerList.size(); i++) {
00286       OpenMSPSyncListener listener = (OpenMSPSyncListener)listenerList.get(i);
00287       listener.notifySynchroFailure();
00288       listenerOrdonancer.notifySynchroError(listener.getSyncName());
00289       moduleOrdonancer.notifySynchroError(listener.getSyncName());
00290     }
00291     globalSynchroStatut = Status.STATUS_FAILED;
00292   }
00293 
00294   private byte[] compressAndEncodeRequest(String request) throws IOException {
00295     // compresse data
00296     byte[] compressedData = null;
00297     ByteArrayOutputStream byteStream = new ByteArrayOutputStream(512);
00298     GZIPOutputStream zipStream = new GZIPOutputStream(byteStream);
00299     try {
00300       zipStream.write(request.getBytes());
00301     } finally  {
00302       zipStream.close();
00303     }
00304     compressedData = byteStream.toByteArray();
00305 
00306     // encode compressed data
00307     byte[] returnData = GeneralCoder.encodeBase64(compressedData);
00308     return returnData;
00309   }
00310 
00311   public String getLastSynchroLogin() {
00312     if (this.lastSynchroLogin == null){
00313       this.lastSynchroLogin = PersistentPropertiesManager.getManager().getProperty("OpenMSPSynchroManager", "login");
00314 
00315     }
00316     return this.lastSynchroLogin;
00317   }
00318 
00327   public String getSynchroUserAgent(SynchroDescriptor descriptor) {
00328     String usera = PropertiesManager.getManager().getProperty("org.openmobileis.synchro.direct.useragent");
00329     if (usera == null)  {
00330       Plateform plateform = ApplicationContextManager.getManager().getApplicationContext().getPlateform();
00331       StringBuffer useragent = new StringBuffer("OpenMSPPlug-");
00332       useragent.append(plateform.getOpenMobileISMajorVersion()).append('.').append(plateform.getOpenMobileISMinorVersion()).append('-');
00333       useragent.append(plateform.getOS()).append('[').append(plateform.getOSVersion()).append("]-");
00334       String language = IntlResourceManager.getManager().getManagerLocaleString();
00335       useragent.append(language);
00336       String synctype = descriptor.getProperty("OpenMSPsynchrotype");
00337       if (synctype != null) {
00338         useragent.append('-').append(synctype);
00339       }
00340       usera = useragent.toString();
00341     }
00342     return usera;
00343   }
00344 
00345   public int getGlobalSynchroStatut() {
00346     return globalSynchroStatut;
00347   }
00348 
00349 }

Generated on Mon Jan 14 17:29:49 2008 for OpenMobileIS by  doxygen 1.5.4