001: package org.wings;
002:
003: import java.io.IOException;
004: import java.io.UnsupportedEncodingException;
005: import java.net.URLEncoder;
006:
007: import org.apache.commons.logging.Log;
008: import org.apache.commons.logging.LogFactory;
009: import org.wings.io.Device;
010: import org.wings.portlet.Const;
011: import org.wings.session.Session;
012: import org.wings.session.SessionManager;
013: import org.wings.util.SStringBuilder;
014:
015: /**
016: *
017: * This class extends the RequestURL to make it possible the the actionURL from
018: * the portlet can be written out without any additional parameters or sites.
019: * The write method from the RequestURL is changed and the Clone Method.
020: *
021: * @author <a href="mailto:marc.musch@mercatis.com">Marc Musch</a>
022: */
023: public class PortletRequestURL extends RequestURL {
024:
025: private final transient static Log log = LogFactory
026: .getLog(PortletRequestURL.class);
027:
028: private static final String DEFAULT_RESOURCE_NAME = "_";
029:
030: /**
031: * Current session encoding used for URLEncoder.
032: */
033: private final String characterEncoding;
034:
035: private String baseParameters;
036:
037: private boolean hasQuestMark;
038:
039: private String eventEpoch;
040:
041: private String resource;
042:
043: private SStringBuilder parameters = null;
044:
045: public PortletRequestURL() {
046: super ();
047: this .characterEncoding = determineCharacterEncoding();
048: }
049:
050: public PortletRequestURL(String baseURL, String encodedBaseURL) {
051: super (baseURL, encodedBaseURL);
052: this .characterEncoding = determineCharacterEncoding();
053: }
054:
055: /**
056: * copy constructor.
057: */
058: private PortletRequestURL(PortletRequestURL other) {
059: this .characterEncoding = determineCharacterEncoding();
060: this .baseURL = other.baseURL;
061: this .baseParameters = other.baseParameters;
062: this .hasQuestMark = other.hasQuestMark;
063: this .eventEpoch = other.eventEpoch;
064: this .resource = other.resource;
065: SStringBuilder params = other.parameters;
066: parameters = (params == null) ? null : new SStringBuilder(
067: params.toString());
068: }
069:
070: /*
071: * (non-Javadoc)
072: *
073: * @see org.wings.RequestURL#write(org.wings.io.Device) The
074: * PortletRequestWrite Method only writes the portletURL
075: */
076: @Override
077: public void write(Device d) throws IOException {
078:
079: boolean printed = false;
080: String epoResString = "";
081:
082: if (resource != null && eventEpoch != null) {
083: epoResString = eventEpoch + SConstants.UID_DIVIDER;
084: }
085:
086: if (resource != null) {
087: if (resource.endsWith("xml") || resource.endsWith("html")) {
088: addParameter(Const.REQUEST_PARAM_RESOURCE_AS_PARAM,
089: epoResString + resource);
090: } else if (resource.startsWith("-")) {
091: d.print(resource);
092: printed = true;
093: }
094:
095: } else {
096: addParameter(Const.REQUEST_PARAM_RESOURCE_AS_PARAM,
097: DEFAULT_RESOURCE_NAME);
098: }
099:
100: if (baseURL != null && !printed) {
101: d.print(baseURL);
102: }
103:
104: // if (resource != null && epoch != null) {
105: // d.print(epoch);
106: // d.print(SConstants.UID_DIVIDER);
107: // }
108: //
109: // if (resource != null) {
110: // d.print(resource);
111: // } else {
112: // /*
113: // * The default resource name. Work around a bug in some
114: // * browsers that fail to assemble URLs.
115: // * (TODO: verify and give better explanation here).
116: // */
117: // d.print(DEFAULT_RESOURCE_NAME);
118: // }
119:
120: if (baseParameters != null) {
121: d.print(baseParameters);
122: }
123:
124: if (parameters != null && parameters.length() > 0) {
125: d.print(hasQuestMark ? "&" : "?");
126: d.print(parameters.toString());
127: }
128: }
129:
130: @Override
131: public void setBaseURL(String b, String encoded) {
132: baseURL = b;
133:
134: baseParameters = encoded.substring(b.length());
135: if (baseParameters.length() == 0)
136: baseParameters = null;
137:
138: if (baseParameters != null)
139: hasQuestMark = baseParameters.indexOf('?') >= 0;
140: else
141: hasQuestMark = false;
142: }
143:
144: @Override
145: public void setEventEpoch(String e) {
146: eventEpoch = e;
147: }
148:
149: @Override
150: public String getEventEpoch() {
151: return eventEpoch;
152: }
153:
154: @Override
155: public String getResource() {
156: return resource;
157: }
158:
159: @Override
160: public void setResource(String r) {
161: resource = r;
162: }
163:
164: @Override
165: public PortletRequestURL addParameter(String parameter) {
166: if (parameter != null) {
167: if (parameters == null)
168: parameters = new SStringBuilder();
169: else
170: parameters.append("&");
171: parameters.append(recode(parameter));
172: }
173: return this ;
174: }
175:
176: @Override
177: public PortletRequestURL addParameter(String name, String value) {
178: addParameter(name);
179: parameters.append("=").append(recode(value));
180: return this ;
181: }
182:
183: @Override
184: public PortletRequestURL addParameter(LowLevelEventListener comp,
185: String value) {
186: addParameter(comp.getLowLevelEventId(), value);
187: return this ;
188: }
189:
190: @Override
191: public PortletRequestURL addParameter(String name, int value) {
192: addParameter(name);
193: parameters.append("=").append(value);
194: return this ;
195: }
196:
197: @Override
198: public void clear() {
199: if (parameters != null) {
200: parameters.setLength(0);
201: }
202: setEventEpoch(null);
203: setResource(null);
204: }
205:
206: @Override
207: public Object clone() {
208: return new PortletRequestURL(this );
209: }
210:
211: /**
212: * Determine the current character encoding.
213: *
214: * @return Character encoding string or <code>null</code>
215: */
216: private String determineCharacterEncoding() {
217: String characterEncoding = null;
218: final Session session = SessionManager.getSession();
219: if (session != null) {
220: characterEncoding = session.getCharacterEncoding();
221: }
222: return characterEncoding;
223: }
224:
225: /**
226: * Recoded passes string to URL with current encoding.
227: *
228: * @param parameter
229: * String to recode
230: * @return Encoded parameter or same if an error occured
231: */
232: private String recode(String parameter) {
233: try {
234: return URLEncoder.encode(parameter, characterEncoding);
235: } catch (UnsupportedEncodingException e) {
236: log.warn("Unknown character encoding?! "
237: + characterEncoding, e);
238: return parameter;
239: }
240: }
241:
242: private final boolean eq(Object a, Object b) {
243: return (a == b) || (a != null && a.equals(b));
244: }
245:
246: @Override
247: public boolean equals(Object o) {
248: if (o == null)
249: return false;
250: if (!super .equals(o))
251: return false;
252: PortletRequestURL other = (PortletRequestURL) o;
253: return (hasQuestMark == other.hasQuestMark
254: && eq(baseParameters, other.baseParameters)
255: && eq(eventEpoch, other.eventEpoch)
256: && eq(resource, other.resource) && eq(parameters,
257: other.parameters));
258: }
259:
260: @Override
261: public int hashCode() {
262: return baseURL != null ? baseURL.hashCode() : 0;
263: }
264:
265: @Override
266: public String toString() {
267: SStringBuilder erg = new SStringBuilder();
268:
269: boolean printed = false;
270: String epoResString = "";
271:
272: if (resource != null && eventEpoch != null) {
273: epoResString = eventEpoch + SConstants.UID_DIVIDER;
274: }
275:
276: if (resource != null) {
277: if (resource.endsWith("xml") || resource.endsWith("html")) {
278: addParameter(Const.REQUEST_PARAM_RESOURCE_AS_PARAM,
279: epoResString + resource);
280: } else if (resource.startsWith("-")) {
281: erg.append(resource);
282: printed = true;
283: }
284:
285: } else {
286: addParameter(Const.REQUEST_PARAM_RESOURCE_AS_PARAM,
287: DEFAULT_RESOURCE_NAME);
288: }
289:
290: if (baseURL != null && !printed) {
291: erg.append(baseURL);
292: }
293:
294: // if (resource != null && epoch != null) {
295: // erg.append(epoch);
296: // erg.append(SConstants.UID_DIVIDER);
297: // }
298:
299: // if (resource != null) {
300: // erg.append(resource);
301: // } else {
302: // erg.append(DEFAULT_RESOURCE_NAME);
303: // }
304:
305: if (baseParameters != null) {
306: erg.append(baseParameters);
307: }
308:
309: if (parameters != null && parameters.length() > 0) {
310: erg.append(hasQuestMark ? "&" : "?");
311: erg.append(parameters.toString());
312: }
313:
314: return erg.toString();
315: }
316:
317: }
|