Subversion Repositories aduna

[/] [org.openrdf/] [sesame/] [branches/] [2.3/] [core/] [http/] [workbench/] [src/] [main/] [java/] [org/] [openrdf/] [workbench/] [proxy/] [WorkbenchGateway.java] - Blame information for rev 10943

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7668 james_leigh
/*
2 james_leigh
 * Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
3 james_leigh
 *
4 james_leigh
 * Licensed under the Aduna BSD-style license.
5 james_leigh
 */
6 7575 james_leigh
package org.openrdf.workbench.proxy;
7 james_leigh
 
8 james_leigh
import static java.util.Collections.singletonMap;
9 james_leigh
import static org.openrdf.workbench.proxy.WorkbenchServlet.SERVER_PARAM;
10 james_leigh
 
11 james_leigh
import java.io.BufferedReader;
12 james_leigh
import java.io.File;
13 james_leigh
import java.io.IOException;
14 james_leigh
import java.io.InputStreamReader;
15 james_leigh
import java.io.UnsupportedEncodingException;
16 james_leigh
import java.net.MalformedURLException;
17 james_leigh
import java.net.URL;
18 james_leigh
import java.net.URLDecoder;
19 james_leigh
import java.util.Map;
20 james_leigh
import java.util.concurrent.ConcurrentHashMap;
21 james_leigh
 
22 james_leigh
import javax.servlet.ServletConfig;
23 james_leigh
import javax.servlet.ServletException;
24 james_leigh
import javax.servlet.http.Cookie;
25 james_leigh
import javax.servlet.http.HttpServletRequest;
26 james_leigh
import javax.servlet.http.HttpServletResponse;
27 james_leigh
 
28 james_leigh
import org.openrdf.workbench.base.BaseServlet;
29 james_leigh
import org.openrdf.workbench.exceptions.MissingInitParameterException;
30 james_leigh
import org.openrdf.workbench.util.BasicServletConfig;
31 james_leigh
import org.openrdf.workbench.util.TupleResultBuilder;
32 james_leigh
import org.slf4j.Logger;
33 james_leigh
import org.slf4j.LoggerFactory;
34 james_leigh
 
35 james_leigh
public class WorkbenchGateway extends BaseServlet {
36 10938 arjohn
 
37 7668 james_leigh
    private static final String COOKIE_AGE_PARAM = "cookie-max-age";
38 10938 arjohn
 
39 7575 james_leigh
    private static final String DEFAULT_SERVER_PARAM = "default-server";
40 10938 arjohn
 
41 7575 james_leigh
    private static final String ACCEPTED_SERVER_PARAM = "accepted-server-prefixes";
42 10938 arjohn
 
43 7575 james_leigh
    private static final String CHANGE_SERVER_PARAM = "change-server-path";
44 10938 arjohn
 
45 7575 james_leigh
    private static final String SERVER_COOKIE = "workbench-server";
46 10938 arjohn
 
47 7575 james_leigh
    private static final String TRANSFORMATIONS_PARAM = "transformations";
48 james_leigh
 
49 10938 arjohn
    private final Logger logger = LoggerFactory.getLogger(getClass());
50 arjohn
 
51 arjohn
    private final Map<String, WorkbenchServlet> servlets = new ConcurrentHashMap<String, WorkbenchServlet>();
52 arjohn
 
53 7575 james_leigh
    @Override
54 10938 arjohn
    public void init(ServletConfig config)
55 arjohn
        throws ServletException
56 arjohn
    {
57 7575 james_leigh
        super.init(config);
58 james_leigh
        if (getDefaultServerPath() == null)
59 james_leigh
            throw new MissingInitParameterException(DEFAULT_SERVER_PARAM);
60 james_leigh
        if (config.getInitParameter(TRANSFORMATIONS_PARAM) == null)
61 james_leigh
            throw new MissingInitParameterException(TRANSFORMATIONS_PARAM);
62 james_leigh
    }
63 james_leigh
 
64 james_leigh
    @Override
65 james_leigh
    public void destroy() {
66 james_leigh
        for (WorkbenchServlet servlet : servlets.values()) {
67 james_leigh
            servlet.destroy();
68 james_leigh
        }
69 james_leigh
    }
70 james_leigh
 
71 james_leigh
    public String getAcceptServerPrefixes() {
72 james_leigh
        return config.getInitParameter(ACCEPTED_SERVER_PARAM);
73 james_leigh
    }
74 james_leigh
 
75 james_leigh
    public String getChangeServerPath() {
76 james_leigh
        return config.getInitParameter(CHANGE_SERVER_PARAM);
77 james_leigh
    }
78 james_leigh
 
79 james_leigh
    public String getDefaultServerPath() {
80 james_leigh
        return config.getInitParameter(DEFAULT_SERVER_PARAM);
81 james_leigh
    }
82 james_leigh
 
83 james_leigh
    public String getMaxAgeOfCookie() {
84 james_leigh
        return config.getInitParameter(COOKIE_AGE_PARAM);
85 james_leigh
    }
86 james_leigh
 
87 james_leigh
    public boolean isServerFixed() {
88 james_leigh
        return getChangeServerPath() == null;
89 james_leigh
    }
90 james_leigh
 
91 james_leigh
    @Override
92 james_leigh
    public void service(HttpServletRequest req, HttpServletResponse resp)
93 10938 arjohn
        throws ServletException, IOException
94 arjohn
    {
95 7575 james_leigh
        String change = getChangeServerPath();
96 james_leigh
        if (change != null && change.equals(req.getPathInfo())) {
97 james_leigh
            changeServer(req, resp);
98 10938 arjohn
        }
99 arjohn
        else {
100 7575 james_leigh
            WorkbenchServlet servlet = findWorkbenchServlet(req, resp);
101 james_leigh
            if (servlet == null) {
102 james_leigh
                String uri = req.getRequestURI();
103 james_leigh
                if (req.getPathInfo() != null) {
104 10938 arjohn
                    uri = uri.substring(0, uri.length() - req.getPathInfo().length());
105 7575 james_leigh
                }
106 james_leigh
                resp.sendRedirect(uri + getChangeServerPath());
107 10938 arjohn
            }
108 arjohn
            else {
109 7575 james_leigh
                servlet.service(req, resp);
110 james_leigh
            }
111 james_leigh
        }
112 james_leigh
    }
113 james_leigh
 
114 7582 james_leigh
    private void resetCache() {
115 james_leigh
        for (WorkbenchServlet servlet : servlets.values()) {
116 james_leigh
            // inform browser that server changed and cache is invalid
117 james_leigh
            servlet.resetCache();
118 james_leigh
        }
119 james_leigh
    }
120 james_leigh
 
121 10938 arjohn
    private File asLocalFile(URL rdf)
122 arjohn
        throws UnsupportedEncodingException
123 arjohn
    {
124 7575 james_leigh
        return new File(URLDecoder.decode(rdf.getFile(), "UTF-8"));
125 james_leigh
    }
126 james_leigh
 
127 james_leigh
    private boolean canConnect(String server) {
128 james_leigh
        try {
129 james_leigh
            URL url = new URL(server + "/protocol");
130 james_leigh
            InputStreamReader in = new InputStreamReader(url.openStream());
131 james_leigh
            BufferedReader reader = new BufferedReader(in);
132 james_leigh
            try {
133 james_leigh
                Integer.parseInt(reader.readLine());
134 james_leigh
                return true;
135 10938 arjohn
            }
136 arjohn
            finally {
137 7575 james_leigh
                reader.close();
138 james_leigh
            }
139 10938 arjohn
        }
140 arjohn
        catch (MalformedURLException e) {
141 7575 james_leigh
            logger.warn(e.toString(), e);
142 james_leigh
            return false;
143 10938 arjohn
        }
144 arjohn
        catch (IOException e) {
145 7575 james_leigh
            logger.warn(e.toString(), e);
146 james_leigh
            return false;
147 james_leigh
        }
148 james_leigh
    }
149 james_leigh
 
150 james_leigh
    private void changeServer(HttpServletRequest req, HttpServletResponse resp)
151 10938 arjohn
        throws IOException
152 arjohn
    {
153 7575 james_leigh
        String server = req.getParameter(SERVER_COOKIE);
154 james_leigh
        if (server == null) {
155 james_leigh
            resp.setContentType("application/xml");
156 10938 arjohn
            TupleResultBuilder builder = new TupleResultBuilder(resp.getWriter());
157 7575 james_leigh
            builder.transform(getTransformationUrl(req), "server.xsl");
158 james_leigh
            builder.start();
159 james_leigh
            builder.end();
160 10938 arjohn
        }
161 arjohn
        else if (isValidServer(server)) {
162 7575 james_leigh
            Cookie cookie = new Cookie(SERVER_COOKIE, server);
163 james_leigh
            initCookie(cookie, req);
164 james_leigh
            resp.addCookie(cookie);
165 james_leigh
            String uri = req.getRequestURI();
166 james_leigh
            uri = uri.substring(0, uri.length() - req.getPathInfo().length());
167 7582 james_leigh
            resetCache();
168 7575 james_leigh
            resp.sendRedirect(uri);
169 10938 arjohn
        }
170 arjohn
        else {
171 7575 james_leigh
            resp.setContentType("application/xml");
172 10938 arjohn
            TupleResultBuilder builder = new TupleResultBuilder(resp.getWriter());
173 7575 james_leigh
            builder.transform(getTransformationUrl(req), "server.xsl");
174 james_leigh
            builder.start("error-message");
175 james_leigh
            builder.result("Invalid Server URL");
176 james_leigh
            builder.end();
177 james_leigh
        }
178 james_leigh
    }
179 james_leigh
 
180 james_leigh
    private boolean checkServerPrefixes(String server) {
181 james_leigh
        String prefixes = getAcceptServerPrefixes();
182 james_leigh
        if (prefixes == null)
183 james_leigh
            return true;
184 james_leigh
        for (String prefix : prefixes.split(" ")) {
185 james_leigh
            if (server.startsWith(prefix))
186 james_leigh
                return true;
187 james_leigh
        }
188 10938 arjohn
        logger.warn("server URL {} does not have a prefix {}", server, prefixes);
189 7575 james_leigh
        return false;
190 james_leigh
    }
191 james_leigh
 
192 james_leigh
    private String findServer(HttpServletRequest req, HttpServletResponse resp) {
193 james_leigh
        if (isServerFixed())
194 james_leigh
            return getDefaultServer(req);
195 james_leigh
        String value = getServerCookie(req, resp);
196 james_leigh
        if (value == null)
197 james_leigh
            return getDefaultServer(req);
198 james_leigh
        if (isValidServer(value))
199 james_leigh
            return value;
200 james_leigh
        return getDefaultServer(req);
201 james_leigh
    }
202 james_leigh
 
203 10938 arjohn
    private WorkbenchServlet findWorkbenchServlet(HttpServletRequest req, HttpServletResponse resp)
204 arjohn
        throws ServletException, IOException
205 arjohn
    {
206 7575 james_leigh
        String server = findServer(req, resp);
207 james_leigh
        if (servlets.containsKey(server))
208 james_leigh
            return servlets.get(server);
209 james_leigh
        if (isServerFixed() || isValidServer(server)) {
210 james_leigh
            Map<String, String> params = singletonMap(SERVER_PARAM, server);
211 james_leigh
            ServletConfig cfg = new BasicServletConfig(server, config, params);
212 james_leigh
            WorkbenchServlet servlet = new WorkbenchServlet();
213 james_leigh
            servlet.init(cfg);
214 james_leigh
            synchronized (servlets) {
215 james_leigh
                if (servlets.containsKey(server))
216 james_leigh
                    return servlets.get(server);
217 james_leigh
                servlets.put(server, servlet);
218 james_leigh
                return servlet;
219 james_leigh
            }
220 10938 arjohn
        }
221 arjohn
        else {
222 7575 james_leigh
            return null;
223 james_leigh
        }
224 james_leigh
    }
225 james_leigh
 
226 james_leigh
    private String getDefaultServer(HttpServletRequest req) {
227 james_leigh
        String server = getDefaultServerPath();
228 james_leigh
        if (server.startsWith("/")) {
229 james_leigh
            StringBuffer url = req.getRequestURL();
230 james_leigh
            StringBuilder path = getServerPath(req);
231 james_leigh
            url.setLength(url.indexOf(path.toString()));
232 james_leigh
            server = url.append(server).toString();
233 james_leigh
        }
234 james_leigh
        return server;
235 james_leigh
    }
236 james_leigh
 
237 10938 arjohn
    private String getServerCookie(HttpServletRequest req, HttpServletResponse resp) {
238 7575 james_leigh
        Cookie[] cookies = req.getCookies();
239 james_leigh
        if (cookies == null)
240 james_leigh
            return null;
241 james_leigh
        for (Cookie cookie : cookies) {
242 james_leigh
            if (SERVER_COOKIE.equals(cookie.getName())) {
243 7668 james_leigh
                resp.addHeader("Vary", "Cookie");
244 7575 james_leigh
                initCookie(cookie, req);
245 james_leigh
                resp.addCookie(cookie);
246 james_leigh
                return cookie.getValue();
247 james_leigh
            }
248 james_leigh
        }
249 james_leigh
        return null;
250 james_leigh
    }
251 james_leigh
 
252 james_leigh
    private StringBuilder getServerPath(HttpServletRequest req) {
253 james_leigh
        StringBuilder path = new StringBuilder();
254 james_leigh
        if (req.getContextPath() != null) {
255 james_leigh
            path.append(req.getContextPath());
256 james_leigh
        }
257 james_leigh
        if (req.getServletPath() != null) {
258 james_leigh
            path.append(req.getServletPath());
259 james_leigh
        }
260 james_leigh
        if (req.getPathInfo() != null) {
261 james_leigh
            path.append(req.getPathInfo());
262 james_leigh
        }
263 james_leigh
        return path;
264 james_leigh
    }
265 james_leigh
 
266 james_leigh
    private String getTransformationUrl(HttpServletRequest req) {
267 james_leigh
        String contextPath = req.getContextPath();
268 james_leigh
        return contextPath + config.getInitParameter(TRANSFORMATIONS_PARAM);
269 james_leigh
    }
270 james_leigh
 
271 james_leigh
    private void initCookie(Cookie cookie, HttpServletRequest req) {
272 james_leigh
        if (req.getContextPath() != null) {
273 james_leigh
            cookie.setPath(req.getContextPath());
274 10938 arjohn
        }
275 arjohn
        else {
276 7575 james_leigh
            cookie.setPath("/");
277 james_leigh
        }
278 james_leigh
        String age = getMaxAgeOfCookie();
279 james_leigh
        if (age != null) {
280 james_leigh
            cookie.setMaxAge(Integer.parseInt(age));
281 james_leigh
        }
282 james_leigh
    }
283 james_leigh
 
284 james_leigh
    private boolean isDirectory(String server) {
285 james_leigh
        try {
286 james_leigh
            URL url = new URL(server);
287 james_leigh
            return asLocalFile(url).isDirectory();
288 10938 arjohn
        }
289 arjohn
        catch (MalformedURLException e) {
290 7575 james_leigh
            logger.warn(e.toString(), e);
291 james_leigh
            return false;
292 10938 arjohn
        }
293 arjohn
        catch (IOException e) {
294 7575 james_leigh
            logger.warn(e.toString(), e);
295 james_leigh
            return false;
296 james_leigh
        }
297 james_leigh
    }
298 james_leigh
 
299 james_leigh
    private boolean isValidServer(String server) {
300 james_leigh
        if (!checkServerPrefixes(server))
301 james_leigh
            return false;
302 james_leigh
        if (server.startsWith("http")) {
303 james_leigh
            return canConnect(server);
304 10938 arjohn
        }
305 arjohn
        else if (server.startsWith("file:")) {
306 7575 james_leigh
            return isDirectory(server);
307 james_leigh
        }
308 james_leigh
        return true;
309 james_leigh
    }
310 james_leigh
 
311 james_leigh
}