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 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
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
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
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
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
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
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 }