001: /*
002: * Copyright 2000-2001,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: /*
018:
019: */
020:
021: package org.apache.wsrp4j.consumer.driver;
022:
023: import java.net.URLDecoder;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.Map;
027: import java.util.Set;
028:
029: import org.apache.wsrp4j.consumer.URLGenerator;
030: import org.apache.wsrp4j.consumer.URLRewriter;
031: import org.apache.wsrp4j.log.LogManager;
032: import org.apache.wsrp4j.log.Logger;
033: import org.apache.wsrp4j.util.Constants;
034:
035: import com.liferay.util.SystemProperties;
036:
037: /**
038: * This class implements the URLRewriter-interface providing a method
039: * to rewrite urls (Consumer URL Rewriting).
040: *
041: * @author <a href="mailto:stefan.behl@de.ibm.com">Stefan Behl</a>
042: * @author Richard Jacob
043: */
044: public class URLRewriterImpl implements URLRewriter {
045:
046: private static URLRewriter instance = null;
047:
048: private URLGenerator urlGenerator = null;
049:
050: // log and trace support
051: private Logger logger = LogManager.getLogManager().getLogger(
052: this .getClass());
053:
054: public static URLRewriter getInstance() {
055: if (instance == null) {
056: instance = new URLRewriterImpl();
057: }
058:
059: return instance;
060: }
061:
062: private URLRewriterImpl() {
063: }
064:
065: /**
066: * Sets the url generator. This is required to enable url rewriting.
067: */
068: public void setURLGenerator(URLGenerator urlGenerator) {
069:
070: String MN = "setURLGenerator";
071: if (logger.isLogging(Logger.TRACE_HIGH)) {
072: logger.entry(Logger.TRACE_HIGH, MN);
073: }
074:
075: this .urlGenerator = urlGenerator;
076:
077: if (logger.isLogging(Logger.TRACE_HIGH)) {
078: logger.exit(Logger.TRACE_HIGH, MN);
079: }
080:
081: }
082:
083: /**
084: * Parses markup and performs URL rewriting.
085: *
086: * Principle:
087: * - Iterate over markup-string once and copy processed markup to result
088: * buffer (StringBuffer)
089: * - If url to be rewritten found (during markup iteration),
090: * ... append markup before url to result buffer,
091: * ... perform rewriting (call URLGenerator) and append rewritten url to result buffer.
092: *
093: * Incomplete rewrite-pairs (e.g. a rewrite-begin-token not followed by a
094: * rewrite-end-token) are considered as 'normal' markup.
095: *
096: * @param markup String representing the markup to be processed.
097: *
098: * @return String representing the processed markup.
099: */
100: /**
101: * Rewriting: get url from URLGenerator and append it
102: */
103: private void rewrite(StringBuffer markup, String rewriteURL) {
104: String MN = "rewrite";
105: if (this .urlGenerator != null) {
106: if (rewriteURL.startsWith(Constants.REWRITE_START
107: + Constants.PARAMS_START)) {
108: // handle URL rewriting
109: Map params = createParameterMap(rewriteURL);
110:
111: // What kind of link has to be rewritten?
112: if (rewriteURL
113: .indexOf(Constants.URL_TYPE_BLOCKINGACTION) != -1) {
114: markup.append(urlGenerator
115: .getBlockingActionURL(params));
116: } else if (rewriteURL
117: .indexOf(Constants.URL_TYPE_RENDER) != -1) {
118: markup.append(urlGenerator.getRenderURL(params));
119: } else if (rewriteURL
120: .indexOf(Constants.URL_TYPE_RESOURCE) != -1) {
121: markup.append(urlGenerator.getResourceURL(params));
122: }
123: } else if (rewriteURL.startsWith(Constants.REWRITE_START
124: + Constants.NAMESPACE_START)) {
125: // handle namespace rewriting
126: markup.append(urlGenerator.getNamespacedToken(""));
127: } else {
128: if (logger.isLogging(Logger.ERROR)) {
129: logger.text(Logger.ERROR, MN,
130: "no valid rewrite expression found in: "
131: + rewriteURL);
132: }
133: }
134:
135: } else {
136:
137: if (logger.isLogging(Logger.ERROR)) {
138: String message = "URLGenerator has not been set for class URLRewriterImpl. URL-Rewriting not possible.";
139: logger.text(Logger.ERROR, MN, message);
140: }
141:
142: }
143:
144: }
145:
146: /**
147: * Extracts parameters from url to be rewritten copies them into a map.
148: * Returns this map.
149: */
150: private Map createParameterMap(String rewriteURL) {
151:
152: Map params = new HashMap();
153:
154: if (rewriteURL.indexOf(Constants.URL_TYPE_BLOCKINGACTION) != -1) {
155:
156: params.put(Constants.URL_TYPE,
157: Constants.URL_TYPE_BLOCKINGACTION);
158:
159: } else if (rewriteURL.indexOf(Constants.URL_TYPE_RENDER) != -1) {
160:
161: params.put(Constants.URL_TYPE, Constants.URL_TYPE_RENDER);
162:
163: } else if (rewriteURL.indexOf(Constants.URL_TYPE_RESOURCE) != -1) {
164:
165: params.put(Constants.URL_TYPE, Constants.URL_TYPE_RESOURCE);
166:
167: } else {
168: // TODO: throw exception...
169: }
170:
171: // begin parsing
172: int equals = 0;
173: int next = 0;
174: int end = rewriteURL.indexOf(Constants.REWRITE_END);
175: int index = rewriteURL.indexOf(Constants.NEXT_PARAM);
176: int lengthNext = 0;
177: String subNext = null;
178:
179: while (index != -1) {
180:
181: // support "&" as parameter seperator
182: // see if & was used
183: subNext = rewriteURL.substring(index, index
184: + Constants.NEXT_PARAM_AMP.length());
185: if (subNext.equals(Constants.NEXT_PARAM_AMP)) {
186: lengthNext = Constants.NEXT_PARAM_AMP.length();
187: } else {
188: lengthNext = Constants.NEXT_PARAM.length();
189: }
190:
191: equals = rewriteURL.indexOf(Constants.EQUALS, index
192: + lengthNext);
193: next = rewriteURL.indexOf(Constants.NEXT_PARAM, equals);
194:
195: if (equals != -1) {
196:
197: if (next != -1) {
198: params.put(rewriteURL.substring(index + lengthNext,
199: equals), rewriteURL.substring(equals + 1,
200: next));
201: } else {
202: params.put(rewriteURL.substring(index + lengthNext,
203: equals), rewriteURL.substring(equals + 1,
204: end));
205: }
206:
207: }
208:
209: index = next;
210: }
211:
212: Set keys = params.keySet();
213: String encoding = SystemProperties.get("file.encoding");
214:
215: for (Iterator i = keys.iterator(); i.hasNext();) {
216: Object key = i.next();
217: String value = (String) params.get(key);
218: try {
219: params.put(key, URLDecoder.decode(value, encoding));
220: } catch (Exception e) {
221: }
222: }
223:
224: return params;
225:
226: }
227:
228: /**
229: * @param markup
230: * @return
231: */
232: public String rewriteURLs(String markup) {
233: final String MN = "rewriteURLs";
234: if (logger.isLogging(Logger.TRACE_HIGH)) {
235: logger.entry(Logger.TRACE_HIGH, MN);
236: }
237:
238: if (this .urlGenerator == null) {
239: if (logger.isLogging(Logger.ERROR)) {
240: String message = "URLGenerator has not been set for class URLRewriterImpl. URL-Rewriting not possible.";
241: logger.text(Logger.ERROR, MN, message);
242: }
243: return markup;
244: }
245:
246: StringBuffer resultMarkup = new StringBuffer("");
247: int markupIndex = 0;
248: int rewriteStartPos = -1;
249: int rewriteEndPos = -1;
250: int currentPos = 0;
251: String exprType = null;
252:
253: // loop through the markup, find rewrite expressions, rewrite them
254: while (markupIndex < markup.length()) {
255:
256: rewriteStartPos = -1;
257: rewriteEndPos = -1;
258:
259: // get fist occurance of wsrp rewrite expression
260: rewriteStartPos = markup.indexOf(Constants.REWRITE_START,
261: markupIndex);
262:
263: if (!(rewriteStartPos == -1 || (rewriteStartPos
264: + Constants.REWRITE_START.length() - 1) > (markup
265: .length() - 2))) {
266: // found a rewrite start token, and token is not at the end of markup so we can
267: // determine the rewrite type, i.e. there is at least 1 char after the rewrite start token
268:
269: // namespace or URL? The single char string after the token decides
270: exprType = markup.substring(rewriteStartPos
271: + Constants.REWRITE_START.length() - 1 + 1,
272: rewriteStartPos
273: + Constants.REWRITE_START.length() - 1
274: + 2);
275:
276: if (exprType.equals(Constants.NAMESPACE_START)) {
277: // ok, we have a namespace rewrite here
278: rewriteEndPos = rewriteStartPos
279: + Constants.REWRITE_START.length()
280: + Constants.NAMESPACE_START.length() - 1;
281: } else if (exprType.equals(Constants.PARAMS_START)) {
282: // ok, we have a URL rewrite here
283: // get the position of the end token
284: rewriteEndPos = markup.indexOf(
285: Constants.REWRITE_END, markupIndex);
286: if (rewriteEndPos != -1) {
287: // now let's see if we find a rewrite start token nearer to the end token
288: currentPos = rewriteStartPos;
289:
290: while ((currentPos != -1)
291: && (currentPos < rewriteEndPos)) {
292: // update rewriteStartPos with position of found rewrite begin token being 'nearer'
293: rewriteStartPos = currentPos;
294: // look for next URL rewrite start expression
295: currentPos = markup.indexOf(
296: Constants.REWRITE_START
297: + Constants.PARAMS_START,
298: rewriteStartPos
299: + Constants.REWRITE_START
300: .length()
301: + Constants.PARAMS_START
302: .length());
303: }
304: rewriteEndPos = rewriteEndPos
305: + Constants.REWRITE_END.length() - 1;
306: }
307: }
308: }
309:
310: if ((rewriteStartPos != -1) && (rewriteEndPos != -1)) {
311: // append markup before rewrite expression
312: resultMarkup.append(markup.substring(markupIndex,
313: rewriteStartPos));
314: // append rewritten expression
315: rewrite(resultMarkup, markup.substring(rewriteStartPos,
316: rewriteEndPos + 1));
317: // set markup index after the last char of the rewriteExpression
318: markupIndex = rewriteEndPos + 1;
319: } else {
320: // append rest of markup
321: resultMarkup.append(markup.substring(markupIndex,
322: markup.length()));
323: markupIndex = markup.length();
324: }
325: }
326:
327: if (logger.isLogging(Logger.TRACE_HIGH)) {
328: logger.exit(Logger.TRACE_HIGH, MN);
329: }
330:
331: return resultMarkup.toString();
332: }
333:
334: }
|