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.profile.Profile;
00036 import org.openmobileis.common.user.profile.ProfileDataManager;
00037 import org.openmobileis.common.user.profile.ProfileNotFoundException;
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       Profile profil = ProfileDataManager.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(ProfileNotFoundException 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, Profile 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           || (element.getElementType() == Element.GET)
00229             ){
00230         String serviceName = ((Command)element).getTarget();
00231         String version = null;
00232         this.callService(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00233       } else if (element.getElementType() == Element.SEQUENCE) {
00234         while (message.hasMoreMessage())  {
00235           ContainerMessage commandContainer = message.nextMessage();
00236           this.dispatchElement(cred, group, commandContainer, answer, terminal, profil, fileSystem);
00237         }
00238       } else if (element.getElementType() == Element.FINAL) {
00239       } else  {
00240         Status status = new  Status (((RequestCommand)element).getCmdId(), Status.STATUS_WRONG_FORMAT) ;
00241         answer.add(status);
00242       }
00243     } catch (Exception ex)  {
00244       try {
00245         LogManager.trace(new SynchroException(ex));
00246         Status status = new  Status (((RequestCommand)element).getCmdId(), Status.STATUS_FAILED) ;
00247         answer.add(status);
00248       } catch (Exception e)  {
00249         LogManager.trace(new SynchroException(e));
00250       }
00251     }
00252   }
00253 
00254   private final void callService(Credential cred, String serviceName, ContainerMessage message, Message answer, UserTerminal terminal, String version,  Profile profil, FileSystem  fileSystem) throws OpenMSPException {
00255     try {
00256       ProxySyncroTarget proxy = SynchroTargerManager.getManager().getProxySynchroTargetForTerminal(terminal);
00257       if (proxy != null)  {
00258         proxy.executeOpenMSPCommande(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00259       } else  {
00260         Status status = new  Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_NOT_FOUND) ;
00261         answer.add(status);
00262         LogManager.traceInfo(LogServices.SYNCHROSERVICE, "Service "+serviceName+" ask by CyberML commande and not available");
00263       }
00264     } catch (Throwable e)  {
00265       LogManager.trace(new SynchroException(e));
00266       Status status = new  Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_FAILED) ;
00267       answer.add(status);
00268     }
00269   }
00270 
00271   public String getServiceUri() {
00272     return ServiceManager.getManager().getServiceBaseURI()+"/openmspservice";
00273   }
00274 
00275   public byte[] uncompressAndDecodeRequest(byte[] request) throws IOException {
00276     // decode compressed data
00277     byte[] decodedData = GeneralCoder.decodeBase64(request);
00278 
00279     // uncompresse data
00280     ByteArrayOutputStream byteStream = new ByteArrayOutputStream(1024);
00281     ByteArrayInputStream inStream = new ByteArrayInputStream(decodedData);
00282     GZIPInputStream zipStream = new GZIPInputStream(inStream);
00283     try {
00284       byte[] buff = new byte[1024];
00285       int length;
00286       while ((length = zipStream.read(buff)) != -1) {
00287         byteStream.write(buff, 0, length);
00288       }
00289     } finally  {
00290       zipStream.close();
00291       byteStream.close();
00292     }
00293     return byteStream.toByteArray();
00294   }
00295 }

Generated on Mon Dec 4 11:03:28 2006 for OpenMobileIS by  doxygen 1.5.1-p1