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

Generated on Mon Jul 10 10:29:31 2006 for OpenMobileIS by  doxygen 1.4.4