001/*
002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu
016 */
017package org.nuxeo.ecm.webengine.gwt;
018
019import java.io.File;
020import java.io.FileInputStream;
021import java.io.FileNotFoundException;
022import java.io.IOException;
023import java.net.MalformedURLException;
024import java.net.URL;
025import java.text.ParseException;
026
027import javax.servlet.ServletConfig;
028import javax.servlet.ServletException;
029import javax.servlet.http.HttpServletRequest;
030
031import org.apache.commons.logging.Log;
032import org.apache.commons.logging.LogFactory;
033import org.nuxeo.ecm.core.api.NuxeoException;
034import org.nuxeo.runtime.api.Framework;
035
036import com.google.gwt.user.server.rpc.RemoteServiceServlet;
037import com.google.gwt.user.server.rpc.SerializationPolicy;
038import com.google.gwt.user.server.rpc.SerializationPolicyLoader;
039
040/**
041 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
042 */
043public class WebEngineGwtServlet extends RemoteServiceServlet {
044
045    private static final long serialVersionUID = 1L;
046
047    private static Log log = LogFactory.getLog(WebEngineGwtServlet.class);
048
049
050    @Override
051    public void init(ServletConfig config) throws ServletException {
052        super.init(config);
053    }
054
055    /**
056     * When in hosted mode the default mechanism is used. In production mode the last path element from the request URL
057     * is considered as the GWT module identifier and the GWT application root will be resolved to
058     * <code>${nxserver}/web/root.war/gwt/gwtModuleId</code>
059     * <p>
060     * The GWT web application will be copied there at startup time by using the extension to
061     * {@link InstallGwtAppComponent} extension point <code>install</code>. in your GWT bundle.
062     *
063     * @see {@link #_doGetSerializationPolicy(HttpServletRequest, String, String)}
064     */
065    @Override
066    protected SerializationPolicy doGetSerializationPolicy(HttpServletRequest request, String moduleBaseURL,
067            String strongName) {
068        try {
069            return _doGetSerializationPolicy(request, moduleBaseURL, strongName);
070        } catch (FileNotFoundException cause) {
071            throw new NuxeoException("Cannot find serialization policy for " + moduleBaseURL, cause);
072        }
073    }
074
075    protected SerializationPolicy _doGetSerializationPolicy(HttpServletRequest request, String moduleBaseURL,
076            String strongName) throws FileNotFoundException  {
077
078        String modulePath = null;
079        if (moduleBaseURL != null) {
080            try {
081                modulePath = new URL(moduleBaseURL).getPath();
082            } catch (MalformedURLException ex) {
083                // log the information, we will default
084                log.warn("Malformed moduleBaseURL: " + moduleBaseURL, ex);
085                return super.doGetSerializationPolicy(request, moduleBaseURL, strongName);
086            }
087        }
088        String moduleId = new File(modulePath).getName();
089        if (moduleId.length() == 0) {
090            moduleId = "root";
091        }
092        String filename = SerializationPolicyLoader.getSerializationPolicyFileName(strongName);
093        File policyFile = Framework.getService(GwtResolver.class).resolve(moduleId+"/"+filename);
094        if (policyFile == null || !policyFile.isFile()) {
095            log.warn("Could not find gwt serialization policy file for module " + moduleId + " [ " + filename + " ]");
096            return super.doGetSerializationPolicy(request, moduleBaseURL, strongName);
097        }
098        log.debug("Found gwt serialization policy file: " + policyFile);
099        FileInputStream in = null;
100        try {
101            in = new FileInputStream(policyFile);
102            return SerializationPolicyLoader.loadFromStream(in, null);
103        } catch (IOException e) {
104            log.error("Failed to read gwt serialization policy file for module " + moduleId + " [ " + filename + " ]", e);
105            return super.doGetSerializationPolicy(request, moduleBaseURL, strongName);
106        } catch (ParseException e) {
107            log.error("Failed to parse the policy file '" + policyFile + "'", e);
108            return super.doGetSerializationPolicy(request, moduleBaseURL, strongName);
109        } finally {
110            if (in != null) {
111                try {
112                    in.close();
113                } catch (IOException e) {
114                    log.error(e);
115                }
116            }
117        }
118    }
119
120}