Main Page | Packages | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

OpenMSPService.java

00001 /*
00002  * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM)
00003  * Copyright (C) 2004-2005 Philippe Delrieu
00004  * All rights reserved.
00005  * Contact: openmobileis@e-care.fr
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  *  Modifications :
00025  *  2004 Creation P.Delrieu
00026  * 
00027  */
00028 
00029 package org.openmobileis.synchro.openmsp.server;
00030 
00031 
00032 import org.openmobileis.common.user.User;
00033 import org.openmobileis.common.user.UserManager;
00034 import org.openmobileis.common.user.UserNotFoundException;
00035 import org.openmobileis.common.user.profil.Profil;
00036 import org.openmobileis.common.user.profil.ProfilDataManager;
00037 import org.openmobileis.common.user.profil.ProfilNotFoundException;
00038 import org.openmobileis.common.util.PropertiesManager;
00039 import org.openmobileis.common.util.codec.GeneralCoder;
00040 import org.openmobileis.common.context.*;
00041 import org.openmobileis.common.util.exception.*;
00042 import org.openmobileis.common.util.log.*;
00043 import org.openmobileis.services.Service;
00044 import org.openmobileis.synchro.openmsp.OpenMSPException;
00045 import org.openmobileis.synchro.openmsp.client.core.OpenMSPSyncMessageFactory;
00046 import org.openmobileis.synchro.openmsp.protocol.AbstractCommand;
00047 import org.openmobileis.synchro.openmsp.protocol.Command;
00048 import org.openmobileis.synchro.openmsp.protocol.ContainerMessage;
00049 import org.openmobileis.synchro.openmsp.protocol.Element;
00050 import org.openmobileis.synchro.openmsp.protocol.Header;
00051 import org.openmobileis.synchro.openmsp.protocol.Message;
00052 import org.openmobileis.synchro.openmsp.protocol.MessageFactory;
00053 import org.openmobileis.synchro.openmsp.protocol.RequestCommand;
00054 import org.openmobileis.synchro.openmsp.protocol.Result;
00055 import org.openmobileis.synchro.openmsp.protocol.Status;
00056 import org.openmobileis.synchro.openmsp.server.synctarget.SynchroTargerManager;
00057 import org.openmobileis.synchro.openmsp.server.synctarget.proxy.ProxySyncroTarget;
00058 import org.openmobileis.synchro.openmsp.server.util.FileSystem;
00059 import org.openmobileis.synchro.openmsp.server.util.FileSystemObjectPool;
00060 import org.openmobileis.synchro.openmsp.server.util.FileSystemObjectPoolSelecter;
00061 import org.openmobileis.synchro.openmsp.server.util.MemoryFile;
00062 import org.openmobileis.synchro.openmsp.server.util.SynchroFileGenerator;
00063 import org.openmobileis.synchro.openmsp.server.util.SynchroFileGeneratorManager;
00064 import org.openmobileis.synchro.security.auth.Credential;
00065 import org.openmobileis.synchro.security.auth.CredentialCodec;
00066 
00067 import java.io.IOException;
00068 import java.io.ByteArrayInputStream;
00069 import java.io.ByteArrayOutputStream;
00070 import java.util.zip.*;
00071 
00072 import javax.servlet.ServletException;
00073 import javax.servlet.http.HttpServletRequest;
00074 import javax.servlet.http.HttpServletResponse;
00075 
00083 public class OpenMSPService extends Service{
00084 
00085   public OpenMSPService() {
00086     String synchrologfile =  PropertiesManager.getManager().getProperty("org.openmobileis.synchro.openmsp.server.log.filename");
00087     if (synchrologfile != null)  {
00088       java.util.Properties props = new java.util.Properties();
00089       props.put("LOGFILE", synchrologfile);
00090       OpenMSPServiceTracer tracer = new OpenMSPServiceTracer();
00091       tracer.setLogTracerProperties(props);
00092       LogManager.attachLogTracerToPriority(LogPriorities.USERSYNCHRO, tracer);
00093     }
00094   }
00095   
00096   public void run(HttpServletRequest request, HttpServletResponse res) throws ServletException, IOException  {
00097     // validate client
00098     User user = null;
00099     String group = request.getParameter("openMISGroup");
00100     if (group == null)  {
00101       LogManager.traceError(0, "OpenMSPService bad request no openMISGroup parameter.");
00102       res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00103       return;
00104     }
00105 
00106 
00107 
00108     try {
00109       // get cyberML message
00110       String openMSPString = request.getParameter("openMISData");
00111       try {
00112         openMSPString = new String(uncompressAndDecodeRequest(openMSPString.getBytes()));
00113       } catch (Throwable ex)  {
00114         // not encoded or compressed data.
00115         LogManager.traceError(0, ex);
00116         res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
00117         return;
00118       }
00119 
00120 
00121       Message openMLMessage =  MessageFactory.getFactory().getMessage(openMSPString);
00122       
00123       Header header = openMLMessage.getHeader();
00124 
00125       // validate user auth.
00126       String[] credential = header.getCredential();
00127       Credential cred = null;
00128       if (credential != null) {
00129         cred = CredentialCodec.getOpenMSPCredential(credential);
00130         String userId = UserManager.getManager().authenticateUser(group, cred.getPrincipal(), cred.getPassword());
00131         user = UserManager.getManager().getUser(group,userId);
00132       } else  {
00133         LogManager.traceError(0, "OpenMSPService no credential in OpenMSP request.");
00134         res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
00135         return;
00136       }
00137       Profil profil = ProfilDataManager.getManager().getProfil(group, user.getProfil());
00138       SessionContext context = SessionContextManager.getManager().getSessionContext();
00139       UserTerminal terminal = (UserTerminal)context.getTerminal();
00140       if (terminal == null) {
00141         String useragent = UserTerminal.getUserAgentFromRequest(request);
00142         terminal = new UserTerminal(useragent);
00143         context.setTerminal(terminal);
00144       } 
00145       
00146       if (!terminal.isOPenMISClient())  {
00147         LogManager.traceError(0, "Synchro terminal is not supported for user:"+user.getLogin());
00148         res.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
00149         return;
00150       }
00151       context.setUserId(user.getId());
00152       context.setUserGroup(group);
00153 
00154       // log new synchro
00155       LogManager.traceUserSynchro(LogServices.SYNCHROSERVICE, request.getRemoteAddr()+"#"+user.getId()+"#"+group+"#"+terminal.getClientPlateformType()+"#"+terminal.getSynchroType());
00156 
00157       long sessionNumber = header.getSessionID();
00158  /*     SynchroNumber currentSynchroNumber = null;
00159       try {
00160         currentSynchroNumber = SyncNumberManager.getManager().getSynchroNumber(sessionNumber);
00161       } catch (SyncNumberNotFoundException ex) {
00162         LogManager.trace(ex);
00163         currentSynchroNumber = new SynchroNumber(0,0);
00164       } */
00165       String target = header.getTarget();
00166       String source = header.getSource();
00167       if (target.indexOf(OpenMSPSyncMessageFactory.OpenMSPTARGET) == -1) {
00168         res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
00169       }
00170 
00171       // init client file management
00172       FileSystemObjectPool pool = FileSystemObjectPoolSelecter.getPool(terminal);
00173       FileSystem  fileSystem = pool.getFileSystem();
00174 
00175       try {
00176 //        SynchroNumber newSynchroNumber = SyncNumberManager.getManager().getNextSynchroNumber();
00177 
00178         // create answer message
00179         Message CMLAnswer = MessageFactory.getFactory().createMessage(new Header(sessionNumber+1, target, source , null, null));
00180 
00181         openMLMessage.resetCursor();
00182         // dispatcher commande ( Get | Map | Results | Sequence | Status | Sync)+, Final?)
00183         while (openMLMessage.hasMoreMessage()) {
00184           ContainerMessage CMLRequest = openMLMessage.nextMessage();
00185           this.dispatchElement(cred, group, CMLRequest, CMLAnswer, terminal, profil, fileSystem);
00186         }
00187 
00188         // end SyncML code management
00189 
00190         // save CyberML file
00191         ByteArrayInputStream input = new ByteArrayInputStream(CMLAnswer.encode().getBytes());
00192         fileSystem.addFile(new MemoryFile("/cyberML.xml", input));
00193         //generate synchro file
00194         SynchroFileGenerator fileGenerator = SynchroFileGeneratorManager.getManager().getFileGenerator(terminal);
00195         fileGenerator.generateSynchroFile(terminal, profil, request, res, fileSystem, Long.toString(sessionNumber+1));
00196 
00197         res.setStatus(HttpServletResponse.SC_OK);
00198       } finally {
00199         pool.disposeObject(fileSystem);
00200       }
00201     } catch (OpenMSPException ex) {
00202       res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
00203       LogManager.trace(new SynchroException(ex));
00204     } catch (UserNotFoundException ex) {
00205       res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00206     } catch(ProfilNotFoundException ex)  {
00207       LogManager.traceError(0, "OpenMSPService no Profil for user login :"+user.getLogin());
00208       res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00209     } catch (Throwable ex) {
00210       res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
00211       LogManager.trace(new SynchroException(ex));
00212     }
00213   }
00214 
00215   private final void dispatchElement(Credential cred, String group, ContainerMessage message, Message answer, UserTerminal terminal, Profil profil, FileSystem  fileSystem) {
00216     Element element = message.getElement();
00217     try {
00218       if (element.getElementType() == Element.RESULT)  {
00219         String serviceName = ((Result)element).getSourceRef();
00220         String version = null;
00221         this.callService(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00222       } else if (element.getElementType() == Element.STATUS)  {// not supported
00223         Status status = new  Status (((Status)element).getCmdId(), Status.STATUS_COMMAND_NOT_IMPLEMENTED) ;
00224         answer.add(status);
00225       } else if ((element.getElementType() == Element.SYNC)
00226             || (element.getElementType() == Element.MAP)
00227             ){
00228         String serviceName = ((Command)element).getTarget();
00229         String version = null;
00230         this.callService(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00231       } else if (element.getElementType() == Element.SEQUENCE) {
00232         while (message.hasMoreMessage())  {
00233           ContainerMessage commandContainer = message.nextMessage();
00234           this.dispatchElement(cred, group, commandContainer, answer, terminal, profil, fileSystem);
00235         }
00236       } else if (element.getElementType() == Element.FINAL) {
00237       } else  {
00238         Status status = new  Status (((RequestCommand)element).getCmdId(), Status.STATUS_WRONG_FORMAT) ;
00239         answer.add(status);
00240       }
00241     } catch (Exception ex)  {
00242       try {
00243         LogManager.trace(new SynchroException(ex));
00244         Status status = new  Status (((RequestCommand)element).getCmdId(), Status.STATUS_FAILED) ;
00245         answer.add(status);
00246       } catch (Exception e)  {
00247         LogManager.trace(new SynchroException(e));
00248       }
00249     }
00250   }
00251 
00252   private final void callService(Credential cred, String serviceName, ContainerMessage message, Message answer, UserTerminal terminal, String version,  Profil profil, FileSystem  fileSystem) throws OpenMSPException {
00253     try {
00254       ProxySyncroTarget proxy = SynchroTargerManager.getManager().getProxySynchroTargetForTerminal(terminal);
00255       if (proxy != null)  {
00256         proxy.executeOpenMSPCommande(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00257       } else  {
00258         Status status = new  Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_NOT_FOUND) ;
00259         answer.add(status);
00260         LogManager.traceInfo(LogServices.SYNCHROSERVICE, "Service "+serviceName+" ask by CyberML commande and not available");
00261       }
00262     } catch (Throwable e)  {
00263       LogManager.trace(new SynchroException(e));
00264       Status status = new  Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_FAILED) ;
00265       answer.add(status);
00266     }
00267   }
00268 
00269   public String getName() {
00270     return "OpenMSPService";
00271   }
00272 
00273   public byte[] uncompressAndDecodeRequest(byte[] request) throws IOException {
00274     // decode compressed data
00275     byte[] decodedData = GeneralCoder.decodeBase64(request);
00276 
00277     // uncompresse data
00278     ByteArrayOutputStream byteStream = new ByteArrayOutputStream(1024);
00279     ByteArrayInputStream inStream = new ByteArrayInputStream(decodedData);
00280     GZIPInputStream zipStream = new GZIPInputStream(inStream);
00281     try {
00282       byte[] buff = new byte[1024];
00283       int length;
00284       while ((length = zipStream.read(buff)) != -1) {
00285         byteStream.write(buff, 0, length);
00286       }
00287     } finally  {
00288       zipStream.close();
00289       byteStream.close();
00290     }
00291     return byteStream.toByteArray();
00292   }
00293 }

Generated on Wed Dec 14 21:05:34 2005 for OpenMobileIS by  doxygen 1.4.4