/*
* Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.wsrp4j.commons.consumer.driver;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wsrp4j.commons.consumer.interfaces.urlgenerator.URLGenerator;
import org.apache.wsrp4j.commons.consumer.interfaces.urlgenerator.URLRewriter;
import org.apache.wsrp4j.commons.util.Constants;
import org.apache.wsrp4j.commons.util.Utility;
/**
* This class implements the URLRewriter-interface providing a method
* to rewrite urls (Consumer URL Rewriting).
*
* @version $Id: URLRewriterImpl.java 405796 2006-05-10 16:48:00Z dlouzan $
*/
public class URLRewriterImpl implements URLRewriter {
private final static Log log = LogFactory.getLog(URLRewriterImpl.class);
private static URLRewriter instance;
private URLGenerator urlGenerator;
public static URLRewriter getInstance() {
if (instance == null) {
instance = new URLRewriterImpl();
}
return instance;
}
private URLRewriterImpl() {
}
/**
* Sets the url generator. This is required to enable url rewriting.
*/
public void setURLGenerator(URLGenerator urlGenerator) {
String MN = "setURLGenerator";
if (log.isDebugEnabled()) {
log.debug(Utility.strEnter(MN));
}
this.urlGenerator = urlGenerator;
if (log.isDebugEnabled()) {
log.debug(Utility.strExit(MN));
}
}
/**
* Parses markup and performs URL rewriting.
*
* Principle:
* - Iterate over markup-string once and copy processed markup to result
* buffer (StringBuffer)
* - If url to be rewritten found (during markup iteration),
* ... append markup before url to result buffer,
* ... perform rewriting (call URLGenerator) and append rewritten url
* to result buffer.
*
* Incomplete rewrite-pairs (e.g. a rewrite-begin-token not followed by a
* rewrite-end-token) are considered as 'normal' markup.
*
* @param markup String representing the markup to be processed.
*
* @return String representing the processed markup.
*/
/**
* Rewriting: get url from URLGenerator and append it
*/
private void rewrite(StringBuffer markup, String rewriteURL) {
String MN = "rewrite";
if (this.urlGenerator != null) {
if ( rewriteURL.startsWith(Constants.REWRITE_START +
Constants.PARAMS_START) ) {
// handle URL rewriting
Map params = createParameterMap(rewriteURL);
// What kind of link has to be rewritten?
if (rewriteURL.indexOf(Constants.URL_TYPE_BLOCKINGACTION) !=
-1) {
markup.append(urlGenerator.getBlockingActionURL(params));
} else if (rewriteURL.indexOf(
Constants.URL_TYPE_RENDER) != -1) {
markup.append(urlGenerator.getRenderURL(params));
} else if (rewriteURL.indexOf(Constants.URL_TYPE_RESOURCE) !=
-1) {
markup.append(urlGenerator.getResourceURL(params));
}
} else if (rewriteURL.startsWith(
Constants.REWRITE_START + Constants.NAMESPACE_START) ) {
// handle namespace rewriting
markup.append(urlGenerator.getNamespacedToken(""));
} else {
if (log.isErrorEnabled()) {
log.error("No valid rewrite expression found in: " +
rewriteURL);
}
}
} else {
if (log.isErrorEnabled()) {
log.error("URLGenerator has not been set for class " +
"URLRewriterImpl. URL-Rewriting not possible.");
}
}
}
/**
* Extracts parameters from url to be rewritten copies them into a map.
* Returns this map.
*/
private Map createParameterMap(String rewriteURL) {
Map params = new HashMap();
if (rewriteURL.indexOf(Constants.URL_TYPE_BLOCKINGACTION) != -1) {
params.put(Constants.URL_TYPE, Constants.URL_TYPE_BLOCKINGACTION);
} else if (rewriteURL.indexOf(Constants.URL_TYPE_RENDER) != -1) {
params.put(Constants.URL_TYPE, Constants.URL_TYPE_RENDER);
} else if (rewriteURL.indexOf(Constants.URL_TYPE_RESOURCE) != -1) {
params.put(Constants.URL_TYPE, Constants.URL_TYPE_RESOURCE);
} else {
// TODO: throw exception...
}
// begin parsing
int equals = 0;
int next = 0;
int end = rewriteURL.indexOf(Constants.REWRITE_END);
int index = rewriteURL.indexOf(Constants.NEXT_PARAM);
int lengthNext = 0;
String subNext = null;
while (index != -1) {
// support "&" as parameter seperator
// see if & was used
subNext = rewriteURL.substring(
index, index + Constants.NEXT_PARAM_AMP.length());
if (subNext.equals(Constants.NEXT_PARAM_AMP)) {
lengthNext = Constants.NEXT_PARAM_AMP.length();
} else {
lengthNext = Constants.NEXT_PARAM.length();
}
equals = rewriteURL.indexOf(Constants.EQUALS, index + lengthNext);
next = rewriteURL.indexOf(Constants.NEXT_PARAM, equals);
if (equals != -1) {
if (next != -1) {
params.put(rewriteURL.substring(index + lengthNext, equals),
rewriteURL.substring(equals + 1, next));
} else {
params.put(rewriteURL.substring(index + lengthNext, equals),
rewriteURL.substring(equals + 1, end));
}
}
index = next;
}
return params;
}
/**
* @param markup
* @return The rewritten markup
*/
public String rewriteURLs(String markup) {
final String MN = "rewriteURLs";
if (log.isDebugEnabled()) {
log.debug(Utility.strEnter(MN));
}
if (this.urlGenerator == null) {
if (log.isErrorEnabled()) {
log.error("URLGenerator has not been set for class " +
"URLRewriterImpl. URL-Rewriting not possible.");
}
return markup;
}
StringBuffer resultMarkup = new StringBuffer("");
int markupIndex = 0;
int rewriteStartPos = -1;
int rewriteEndPos = -1;
int currentPos = 0;
String exprType = null;
// loop through the markup, find rewrite expressions, rewrite them
while ( markupIndex < markup.length() ) {
rewriteStartPos = -1;
rewriteEndPos = -1;
// get fist occurance of wsrp rewrite expression
rewriteStartPos = markup.indexOf(
Constants.REWRITE_START,markupIndex);
if (! ( rewriteStartPos == -1 ||
( rewriteStartPos + Constants.REWRITE_START.length() - 1 ) >
( markup.length() - 2 ) ) ) {
// found a rewrite start token, and token is not at the end of
// markup so we can determine the rewrite type, i.e. there is
// at least 1 char after the rewrite start token
// namespace or URL? The single char string after the token
// decides
exprType = markup.substring(
rewriteStartPos+Constants.REWRITE_START.length()-1+1,
rewriteStartPos+Constants.REWRITE_START.length()-1+2);
if ( exprType.equals(Constants.NAMESPACE_START)) {
// ok, we have a namespace rewrite here
rewriteEndPos = rewriteStartPos +
Constants.REWRITE_START.length() +
Constants.NAMESPACE_START.length() - 1;
} else if ( exprType.equals(Constants.PARAMS_START) ) {
// ok, we have a URL rewrite here
// get the position of the end token
rewriteEndPos = markup.indexOf(
Constants.REWRITE_END, markupIndex);
if (rewriteEndPos != -1) {
// now let's see if we find a rewrite start token nearer
// to the end token
currentPos = rewriteStartPos;
while ((currentPos != -1) &&
(currentPos < rewriteEndPos)) {
// update rewriteStartPos with position of found
// rewrite begin token being 'nearer'
rewriteStartPos = currentPos;
// look for next URL rewrite start expression
currentPos = markup.indexOf(
Constants.REWRITE_START +
Constants.PARAMS_START,
rewriteStartPos +
Constants.REWRITE_START.length() +
Constants.PARAMS_START.length());
}
rewriteEndPos = rewriteEndPos +
Constants.REWRITE_END.length() - 1;
}
}
}
if ( (rewriteStartPos != -1) && (rewriteEndPos != -1) ) {
// append markup before rewrite expression
resultMarkup.append(
markup.substring(markupIndex,rewriteStartPos));
// append rewritten expression
rewrite(resultMarkup,
markup.substring(rewriteStartPos,rewriteEndPos+1));
// set markup index after the last char of the rewriteExpression
markupIndex = rewriteEndPos + 1;
} else {
// append rest of markup
resultMarkup.append(
markup.substring(markupIndex,markup.length()));
markupIndex = markup.length();
}
}
if (log.isDebugEnabled()) {
log.debug(Utility.strExit(MN));
}
return resultMarkup.toString();
}
}