001: /*
002: * URLRewriteServlet.java
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.servlet;
010:
011: import java.io.IOException;
012: import java.net.URL;
013: import java.util.ArrayList;
014: import java.util.List;
015: import java.util.regex.Matcher;
016: import java.util.regex.Pattern;
017: import javax.servlet.ServletConfig;
018: import javax.servlet.ServletException;
019: import javax.servlet.http.HttpServlet;
020: import javax.servlet.http.HttpServletRequest;
021: import javax.servlet.http.HttpServletResponse;
022: import javax.xml.parsers.DocumentBuilder;
023: import javax.xml.parsers.DocumentBuilderFactory;
024: import org.w3c.dom.Document;
025: import org.w3c.dom.Element;
026: import org.w3c.dom.Node;
027: import org.w3c.dom.NodeList;
028: import org.xml.sax.ErrorHandler;
029: import org.xml.sax.InputSource;
030: import org.xml.sax.SAXException;
031: import org.xml.sax.SAXParseException;
032:
033: public class URLRewriteServlet extends HttpServlet {
034: private final static boolean DEBUG = false;
035: private final static String DEFAULT_CONFIGURATION = "url_rewrite.conf";
036:
037: private String pattern;
038: private String replacement;
039: private List rewriteRule;
040: private List excludedPatterns;
041: private boolean verbose;
042: private boolean validating;
043:
044: public void init() throws ServletException {
045: ServletConfig conf = getServletConfig();
046: String file = conf.getInitParameter("configuration");
047: if (file == null) {
048: file = DEFAULT_CONFIGURATION;
049: }
050: String verbose = conf.getInitParameter("verbose");
051: if (verbose != null && "true".equals(verbose.toLowerCase())) {
052: this .verbose = true;
053: }
054: String validating = conf.getInitParameter("validating");
055: if (validating != null
056: && "true".equals(validating.toLowerCase())) {
057: this .validating = true;
058: }
059: readConfiguration(file);
060: }
061:
062: protected void service(HttpServletRequest request,
063: HttpServletResponse response) throws ServletException,
064: IOException {
065: String queryString = request.getQueryString();
066: String uri = request.getRequestURI();
067: String contextPath = request.getContextPath();
068: if (uri.startsWith(contextPath)) {
069: uri = uri.substring(contextPath.length());
070: }
071: if (queryString != null && queryString.length() > 0) {
072: uri = uri + "?" + queryString;
073: }
074: String newURI = rewriteURL(uri);
075: request.getRequestDispatcher(newURI).forward(request, response);
076: }
077:
078: void readConfiguration(String configFile) {
079: ClassLoader cl = Thread.currentThread().getContextClassLoader();
080: URL url = cl.getResource(configFile);
081: readConfiguration(url);
082: }
083:
084: void readConfiguration(URL url) {
085: try {
086: this .rewriteRule = new ArrayList();
087: this .excludedPatterns = new ArrayList();
088: DocumentBuilderFactory factory = DocumentBuilderFactory
089: .newInstance();
090: factory.setValidating(this .validating);
091: DocumentBuilder builder = factory.newDocumentBuilder();
092: builder.setErrorHandler(new ErrorHandler() {
093: public void warning(SAXParseException exception)
094: throws SAXException {
095: System.err.println(exception);
096: }
097:
098: public void error(SAXParseException exception)
099: throws SAXException {
100: System.err.println(exception);
101: }
102:
103: public void fatalError(SAXParseException exception)
104: throws SAXException {
105: System.err.println(exception);
106: }
107: });
108: Document doc = builder
109: .parse(new InputSource(url.toString()));
110: Element elem = doc.getDocumentElement();
111: NodeList rules = elem.getElementsByTagName("rewrite-rule");
112: int n = rules.getLength();
113: for (int i = 0; i < n; i++) {
114: Element rule = (Element) rules.item(i);
115: NodeList pattern = rule.getElementsByTagName("pattern");
116: NodeList replacement = rule
117: .getElementsByTagName("replacement");
118:
119: String patternString = null;
120: for (int j = 0; j < pattern.getLength(); j++) {
121: Node patternNode = pattern.item(j);
122: if (patternNode.getNodeType() == Node.ELEMENT_NODE) {
123: NodeList nodes = patternNode.getChildNodes();
124: for (int k = 0; k < nodes.getLength(); k++) {
125: Node t = nodes.item(k);
126: if (t.getNodeType() == Node.TEXT_NODE) {
127: patternString = t.getNodeValue();
128: }
129: }
130: }
131: }
132:
133: String replacementString = null;
134: for (int j = 0; j < replacement.getLength(); j++) {
135: Node replacementNode = replacement.item(j);
136: if (replacementNode.getNodeType() == Node.ELEMENT_NODE) {
137: NodeList nodes = replacementNode
138: .getChildNodes();
139: for (int k = 0; k < nodes.getLength(); k++) {
140: Node t = nodes.item(k);
141: if (t.getNodeType() == Node.TEXT_NODE) {
142: replacementString = t.getNodeValue();
143: }
144: }
145: }
146: }
147: if (patternString != null && replacementString != null) {
148: addRule(patternString, replacementString);
149: }
150: }
151: NodeList patterns = elem
152: .getElementsByTagName("exclude-pattern");
153: n = patterns.getLength();
154: for (int i = 0; i < n; i++) {
155: Node node = patterns.item(i);
156: if (node.getNodeType() == Node.ELEMENT_NODE) {
157: NodeList nodes = node.getChildNodes();
158: for (int k = 0; k < nodes.getLength(); k++) {
159: Node t = nodes.item(k);
160: if (t.getNodeType() == Node.TEXT_NODE) {
161: String pattern = t.getNodeValue();
162: if (pattern != null) {
163: pattern = pattern.trim();
164: if (pattern.length() > 0) {
165: addExcludedPattern(pattern);
166: }
167: }
168: }
169: }
170: }
171: }
172: } catch (Exception e) {
173: e.printStackTrace();
174: }
175: }
176:
177: void addRule(String pattern, String replacement) {
178: if (DEBUG) {
179: System.err.println("addRule " + pattern + " ==> "
180: + replacement);
181: }
182: this .rewriteRule.add(new RewriteRule(Pattern.compile(pattern),
183: replacement));
184: }
185:
186: void addExcludedPattern(String pattern) {
187: if (DEBUG) {
188: System.err.println("addExcludedPattern " + pattern);
189: }
190: this .excludedPatterns.add(Pattern.compile(pattern));
191: }
192:
193: String rewriteURL(String url) {
194: int n = excludedPatterns.size();
195: for (int i = 0; i < n; i++) {
196: Pattern pattern = (Pattern) excludedPatterns.get(i);
197: Matcher m = pattern.matcher(url);
198: if (m.find()) {
199: return url;
200: }
201: }
202: n = rewriteRule.size();
203: for (int i = 0; i < n; i++) {
204: RewriteRule rule = (RewriteRule) rewriteRule.get(i);
205: Pattern pattern = rule.pattern;
206: String replacement = rule.replacement;
207: String newURL = rewriteURL(url, pattern, replacement);
208: if (newURL != null) {
209: if (verbose) {
210: System.err.println(url + " => " + newURL);
211: }
212: return newURL;
213: }
214: }
215: return url;
216: }
217:
218: String rewriteURL(String url, Pattern pattern, String replacement) {
219: Matcher m = pattern.matcher(url);
220: if (m.find()) {
221: return m.replaceFirst(replacement);
222: } else {
223: return null;
224: }
225: }
226:
227: static class RewriteRule {
228: Pattern pattern;
229: String replacement;
230:
231: RewriteRule(Pattern pattern, String replacement) {
232: this.pattern = pattern;
233: this.replacement = replacement;
234: }
235: }
236: }
|