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 }