001    // This file is part of AceWiki.
002    // Copyright 2008-2012, AceWiki developers.
003    //
004    // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
005    // Lesser General Public License as published by the Free Software Foundation, either version 3 of
006    // the License, or (at your option) any later version.
007    //
008    // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009    // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010    // Lesser General Public License for more details.
011    //
012    // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
013    // not, see http://www.gnu.org/licenses/.
014    
015    package ch.uzh.ifi.attempto.acewiki;
016    
017    import java.io.IOException;
018    import java.util.Enumeration;
019    import java.util.HashMap;
020    import java.util.Map;
021    
022    import javax.servlet.ServletException;
023    import javax.servlet.ServletConfig;
024    import javax.servlet.http.HttpServletRequest;
025    import javax.servlet.http.HttpServletResponse;
026    
027    import nextapp.echo.app.ApplicationInstance;
028    import nextapp.echo.webcontainer.WebContainerServlet;
029    import ch.uzh.ifi.attempto.base.Logger;
030    import ch.uzh.ifi.attempto.base.APE;
031    
032    /**
033     * This servlet class is used by the web server to start AceWiki.
034     * In order to run the AceWiki servlet, a web application archive (WAR) file has to be created.
035     * See the <a href="{@docRoot}/README.txt">README file</a> and the
036     * <a href="{@docRoot}/web.xml">web.xml example file</a>.
037     *<p>
038     * An APE should be accessibe for the server, either directly installed on local or using socket
039     * or web service. See the documentation of {@link APE} for more information.
040     *<p>
041     * For larger ontologies it might be necessary to adjust the stack and heap size, for example by
042     * the following Java VM arguments:
043     * <code>-Xmx400m -Xss4m</code>
044     *
045     * @author Tobias Kuhn
046     * @author Yu Changyuan
047     */
048    public class AceWikiServlet extends WebContainerServlet {
049    
050            private static final long serialVersionUID = -7342857942059126499L;
051    
052            private Logger logger;
053        private Backend backend;
054        private Map<String, String> parameters;
055        private String backendName;
056    
057            /**
058             * Creates a new AceWiki servlet object.
059             */
060            public AceWikiServlet() {
061            }
062    
063        /**
064         * Init the AceWiki servlet, get its Backend from ServletContext according
065         * to its config in web.xml or create backend if no 'backend' parameter
066         * exist.
067         *
068         * @param config servlet config.
069         */
070        public void init(ServletConfig config) throws ServletException {
071            parameters = getInitParameters(config);
072    
073            if (logger == null) {
074                logger = new Logger(parameters.get("context:logdir") + "/syst", "syst", 0);
075                    }
076    
077            backendName = config.getInitParameter("backend");
078    
079            if (backendName != null) {
080                logger.log("appl", "application use backend: " + backendName);
081    
082                while (true) {
083                    backend = (Backend) config.getServletContext().getAttribute(backendName);
084    
085                    if (backend != null) break;
086                    try {
087                        Thread.sleep(1000);
088                    }
089                    catch (InterruptedException e) {
090                        break;
091                    }
092                }
093    
094                logger.log("appl", "application get backend: " + backend);
095    
096                // merge backend parameters
097                Map<String, String> p = parameters;
098                parameters = new HashMap<String,String>();
099                parameters.putAll(backend.getParameters());
100                parameters.putAll(p);
101            }
102            else {
103                logger.log("appl", "application create backend.");
104    
105                BackendServlet.setDefaultValues(parameters);
106    
107                APE.setParameters(parameters);
108    
109                backend = new Backend(parameters);
110            }
111    
112            super.init(config);
113        }
114    
115            public ApplicationInstance newApplicationInstance() {
116                    logger.log("appl", "new application instance: " + parameters.get("ontology"));
117    
118                    return new AceWikiApp(backend, parameters);
119            }
120    
121            protected void process(HttpServletRequest request, HttpServletResponse response) throws
122                            IOException, ServletException {
123    
124                    // URLs of the form "...?showpage=ArticleName" can be used to access an article directly.
125                    // For the internal processing "...?page=ArticleName" is used.
126                    String showpageParam = request.getParameter("showpage");
127                    if ("".equals(showpageParam)) showpageParam = null;
128                    String pageParam = request.getParameter("page");
129                    if ("".equals(pageParam)) pageParam = null;
130                    String serviceidParam = request.getParameter("sid");
131                    if ("".equals(serviceidParam)) serviceidParam = null;
132    
133                    if (!request.getSession().isNew() && showpageParam != null) {
134                            response.sendRedirect(
135                                            response.encodeRedirectURL("?sid=ExternalEvent&page=" + showpageParam)
136                                    );
137                    }
138                    if (showpageParam == null && pageParam != null && serviceidParam == null) {
139                            response.sendRedirect(response.encodeRedirectURL("."));
140                    }
141    
142                    try {
143                            super.process(request, response);
144                    } catch (RuntimeException ex) {
145                            logger.log("fail", "fatal error: " + ex);
146                            ex.printStackTrace();
147                            throw ex;
148                    } catch (IOException ex) {
149                            logger.log("fail", "fatal error: " + ex);
150                            ex.printStackTrace();
151                            throw ex;
152                    } catch (ServletException ex) {
153                            logger.log("fail", "fatal error: " + ex);
154                            ex.printStackTrace();
155                            throw ex;
156                    }
157            }
158    
159        @SuppressWarnings("rawtypes")
160        private Map<String, String> getInitParameters(ServletConfig config) {
161    
162            Map<String, String> initParameters = new HashMap<String, String>();
163            Enumeration paramEnum = config.getInitParameterNames();
164            while (paramEnum.hasMoreElements()) {
165                String n = paramEnum.nextElement().toString();
166                initParameters.put(n, config.getInitParameter(n));
167            }
168            Enumeration contextParamEnum = config.getServletContext().getInitParameterNames();
169            while (contextParamEnum.hasMoreElements()) {
170                String n = contextParamEnum.nextElement().toString();
171                initParameters.put("context:" + n, config.getServletContext().getInitParameter(n));
172            }
173            return initParameters;
174        }
175    }