00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
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
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
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
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
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
00331
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
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
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 }