001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.framework.basic;
011:
012: import org.mmbase.framework.*;
013: import java.util.*;
014: import org.mmbase.util.*;
015: import java.io.*;
016: import javax.servlet.http.HttpServletRequest;
017: import org.mmbase.util.functions.*;
018: import org.mmbase.util.transformers.Url;
019: import org.mmbase.util.transformers.CharTransformer;
020: import org.mmbase.util.logging.Logger;
021: import org.mmbase.util.logging.Logging;
022:
023: /**
024: * Basic implementation of UrlConverter. Essential, should typically be
025: * chained last in ChainedUrlConverter by the framework.
026: *
027: *
028: * @author Michiel Meeuwissen
029: * @version $Id: BasicUrlConverter.java,v 1.9 2008/02/23 14:36:30 michiel Exp $
030: * @since MMBase-1.9
031: */
032: public final class BasicUrlConverter implements UrlConverter {
033: private static final Logger log = Logging
034: .getLoggerInstance(BasicUrlConverter.class);
035:
036: private static final CharTransformer paramEscaper = new Url(
037: Url.ESCAPE);
038:
039: /**
040: * General utility function to create an Url
041: *
042: * @param page servletPath
043: * @param params The query to be added
044: * @param req A request object is needed to determin context-paths and so on.
045: * @param writeamp Wheter amperstands must be XML-escaped. Typically needed if the URL is used
046: * in (X)HTML.
047: */
048: public static String getUrl(String page,
049: Map<String, Object> params, HttpServletRequest req,
050: boolean escapeamp) {
051: if (log.isDebugEnabled()) {
052: log.debug("(static) constructing " + page + params);
053: }
054: StringBuilder show = new StringBuilder();
055: if (escapeamp && page != null) {
056: page = page.replaceAll("&", "&");
057: }
058: if (page == null || page.equals("")) { // means _this_ page
059: page = FrameworkFilter.getPath(req); //No good, it will produce something which starts
060: //with /, which at least is not what mm:url wants in this case.
061:
062: log.debug("page not given, -> supposing it " + page
063: + " determined");
064: }
065: show.append(page);
066:
067: if (params != null && !params.isEmpty()) {
068: // url is now complete up to query string, which we are to construct now
069: String amp = (escapeamp ? "&" : "&");
070: String connector = (show.indexOf("?") == -1 ? "?" : amp);
071:
072: Writer w = new StringBuilderWriter(show);
073: for (Map.Entry<String, ? extends Object> entry : params
074: .entrySet()) {
075: Object value = entry.getValue();
076: if (value != null
077: && Casting.isStringRepresentable(value
078: .getClass())) { // if not string representable, that suppose it was an 'automatic' parameter which does need presenting on url
079: if (value instanceof Iterable) {
080: for (Object v : (Iterable<?>) value) {
081: show.append(connector).append(
082: entry.getKey()).append("=");
083: paramEscaper.transform(new StringReader(
084: Casting.toString(v)), w);
085: connector = amp;
086: }
087: } else {
088: show.append(connector).append(entry.getKey())
089: .append("=");
090: paramEscaper.transform(new StringReader(Casting
091: .toString(value)), w);
092: connector = amp;
093: }
094: }
095: }
096: }
097: return show.toString();
098: }
099:
100: private final BasicFramework framework;
101:
102: public BasicUrlConverter(BasicFramework fw) {
103: framework = fw;
104:
105: }
106:
107: /**
108: * @todo Actually these paremters are only added here, because this urlconverter is always in
109: * BasicFramework. Actually BasicFramework should add them itself.
110: */
111: public Parameter[] getParameterDefinition() {
112: return new Parameter[] { Parameter.REQUEST };
113: }
114:
115: protected String getUrl(String path,
116: Map<String, Object> parameters,
117: Parameters frameworkParameters, boolean escapeAmps,
118: boolean action) {
119: HttpServletRequest request = frameworkParameters
120: .get(Parameter.REQUEST);
121: State state = State.getState(request);
122: Map<String, Object> map = new TreeMap<String, Object>();
123: if (log.isDebugEnabled()) {
124: log.debug("path '" + path + "' " + parameters + " "
125: + frameworkParameters);
126: }
127: for (Map.Entry<String, Object> e : parameters.entrySet()) {
128: map.put(e.getKey(), e.getValue());
129: }
130: if (state.isRendering()) {
131: map = new TreeMap<String, Object>(framework.prefix(state,
132: map));
133: for (Object e : request.getParameterMap().entrySet()) {
134: Map.Entry<String, String[]> entry = (Map.Entry<String, String[]>) e;
135:
136: String k = entry.getKey();
137: if (k.startsWith(framework.getPrefix(state))) {
138: // for this block, don't add that,
139: // because should be in parameters then
140: continue;
141: }
142: if (!map.containsKey(k)) {
143: map.put(k, entry.getValue()[0]);
144: }
145: }
146: Block block = state.getBlock();
147: if (log.isDebugEnabled()) {
148: log.debug("current block " + block);
149: }
150: Block toBlock = block.getComponent().getBlock(path);
151: if (toBlock != null) {
152: path = null;
153: if (!toBlock.equals(block)) {
154: log.debug("New block " + toBlock);
155: state.setBlock(map, toBlock);
156: } else {
157: log.debug("staying at " + block);
158: }
159: } else {
160: log.debug("No block '" + path + "' found");
161: }
162: }
163: log.debug("constructing '" + path + "'" + map);
164: return BasicUrlConverter.getUrl(path, map, request, escapeAmps);
165: }
166:
167: public String getUrl(String path, Map<String, Object> parameters,
168: Parameters frameworkParameters, boolean escapeAmps) {
169: return getUrl(path, parameters, frameworkParameters,
170: escapeAmps, false);
171: }
172:
173: public String getProcessUrl(String path,
174: Map<String, Object> parameters,
175: Parameters frameworkParameters, boolean escapeAmps) {
176: return getUrl(path, parameters, frameworkParameters,
177: escapeAmps, true);
178: }
179:
180: public String getInternalUrl(String page,
181: Map<String, Object> params, Parameters frameworkParameters) {
182: HttpServletRequest request = frameworkParameters
183: .get(Parameter.REQUEST);
184: return BasicUrlConverter.getUrl(page, params, request, false);
185: }
186:
187: public boolean equals(Object o) {
188: return o instanceof BasicUrlConverter
189: && ((BasicUrlConverter) o).framework.equals(framework);
190: }
191:
192: public String toString() {
193: return "COPY";
194: }
195:
196: }
|