001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.container.url.impl;
018:
019: import java.io.UnsupportedEncodingException;
020: import java.util.Map;
021:
022: import javax.portlet.PortletMode;
023: import javax.portlet.WindowState;
024: import javax.servlet.http.HttpServletRequest;
025:
026: import org.apache.jetspeed.PortalContext;
027: import org.apache.jetspeed.container.ContainerConstants;
028: import org.apache.jetspeed.container.state.NavigationalState;
029: import org.apache.jetspeed.container.url.BasePortalURL;
030: import org.apache.jetspeed.container.url.PortalURL;
031: import org.apache.jetspeed.util.ArgUtil;
032: import org.apache.pluto.om.window.PortletWindow;
033:
034: /**
035: * AbstractPortalURL delivers the base implemention for parsing Jetspeed Portal URLs and creating new Portlet URLs.
036: * Not implemented is the encoding and decoding of the NavigationState parameter in the URL, allowing concrete
037: * implementations to supply different algorithms for it like encoding it as pathInfo or as query string parameter.
038: *
039: * @author <a href="mailto:ate@apache.org">Ate Douma</a>
040: * @version $Id: AbstractPortalURL.java 605989 2007-12-20 18:26:54Z ate $
041: */
042: public abstract class AbstractPortalURL implements PortalURL {
043: public static final String DEFAULT_NAV_STATE_PARAMETER = "_ns";
044:
045: protected static String navStateParameter;
046:
047: protected NavigationalState navState;
048: protected BasePortalURL base = null;
049:
050: protected static Boolean relativeOnly;
051: protected String contextPath;
052: protected String basePath;
053: protected String path;
054: protected String encodedNavState;
055: protected String secureBaseURL;
056: protected String nonSecureBaseURL;
057: protected String characterEncoding = "UTF-8";
058:
059: public AbstractPortalURL(NavigationalState navState,
060: PortalContext portalContext, BasePortalURL base) {
061: this (navState, portalContext);
062: this .base = base;
063: }
064:
065: public AbstractPortalURL(NavigationalState navState,
066: PortalContext portalContext) {
067: if (navStateParameter == null) {
068: navStateParameter = portalContext.getConfigurationProperty(
069: "portalurl.navigationalstate.parameter.name",
070: DEFAULT_NAV_STATE_PARAMETER);
071: }
072: this .navState = navState;
073: if (relativeOnly == null) {
074: relativeOnly = new Boolean(portalContext.getConfiguration()
075: .getBoolean("portalurl.relative.only", false));
076: }
077: }
078:
079: public AbstractPortalURL(String characterEncoding,
080: NavigationalState navState, PortalContext portalContext) {
081: this (navState, portalContext);
082: this .characterEncoding = characterEncoding;
083: }
084:
085: public AbstractPortalURL(HttpServletRequest request,
086: String characterEncoding, NavigationalState navState,
087: PortalContext portalContext) {
088: this (characterEncoding, navState, portalContext);
089: setRequest(request);
090: }
091:
092: public boolean isRelativeOnly() {
093: return relativeOnly.booleanValue();
094: }
095:
096: public static String getNavigationalStateParameterName() {
097: return navStateParameter;
098: }
099:
100: public String createNavigationalEncoding(PortletWindow window,
101: Map parameters, PortletMode mode, WindowState state,
102: boolean action) {
103: try {
104: return getNavigationalStateParameterName()
105: + ":"
106: + getNavigationalState().encode(window, parameters,
107: mode, state, action);
108: } catch (UnsupportedEncodingException e) {
109: e.printStackTrace();
110: return "";
111: }
112: }
113:
114: public String createNavigationalEncoding(PortletWindow window,
115: PortletMode mode, WindowState state) {
116: try {
117: return getNavigationalStateParameterName()
118: + ":"
119: + getNavigationalState()
120: .encode(window, mode, state);
121: } catch (UnsupportedEncodingException e) {
122: e.printStackTrace();
123: return "";
124: }
125: }
126:
127: protected void decodeBaseURL(HttpServletRequest request) {
128: if (base == null) {
129: base = new BasePortalURLImpl();
130: base.setServerScheme(request.getScheme());
131: base.setServerName(request.getServerName());
132: base.setServerPort(request.getServerPort());
133: base.setSecure(request.isSecure());
134: }
135: if (relativeOnly.booleanValue()) {
136: this .secureBaseURL = this .nonSecureBaseURL = "";
137: } else {
138: StringBuffer buffer;
139:
140: buffer = new StringBuffer(HTTPS);
141: buffer.append("://").append(base.getServerName());
142: if (base.getServerPort() != 443
143: && base.getServerPort() != 80) {
144: buffer.append(":").append(base.getServerPort());
145: }
146: this .secureBaseURL = buffer.toString();
147:
148: buffer = new StringBuffer(HTTP);
149: buffer.append("://").append(base.getServerName());
150: if (base.getServerPort() != 443
151: && base.getServerPort() != 80) {
152: buffer.append(":").append(base.getServerPort());
153: }
154: this .nonSecureBaseURL = buffer.toString();
155: }
156: }
157:
158: protected void decodeBasePath(HttpServletRequest request) {
159: this .contextPath = (String) request
160: .getAttribute(ContainerConstants.PORTAL_CONTEXT);
161: if (contextPath == null) {
162: contextPath = request.getContextPath();
163: }
164: if (contextPath == null) {
165: contextPath = "";
166: }
167: String servletPath = request.getServletPath();
168: if (servletPath == null) {
169: servletPath = "";
170: }
171: this .basePath = contextPath + servletPath;
172: }
173:
174: protected void setEncodedNavigationalState(
175: String encodedNavigationalState) {
176: this .encodedNavState = encodedNavigationalState;
177: try {
178: navState.init(encodedNavState, characterEncoding);
179: } catch (UnsupportedEncodingException e) {
180: IllegalStateException ise = new IllegalStateException(
181: "An unsupported encoding was defined for this NavigationalState.");
182: ise.initCause(e);
183: throw ise;
184: }
185: }
186:
187: protected void setPath(String path) {
188: this .path = path;
189: }
190:
191: public String getBaseURL() {
192: return getBaseURL(base.isSecure());
193: }
194:
195: public String getBaseURL(boolean secure) {
196: // TODO: delivering both secure and non-secure baseURL for PLT.7.1.2
197: // currently only the baseURL as decoded (secure or non-secure) is returned
198: // and the secure parameter is ignored
199: return secure ? secureBaseURL : nonSecureBaseURL;
200: }
201:
202: public String getBasePath() {
203: return basePath;
204: }
205:
206: public String getPath() {
207: return path;
208: }
209:
210: public String getPageBasePath() {
211: if (null == path
212: || (1 == path.length() && '/' == path.charAt(0))) {
213: return basePath;
214: } else if (-1 != path.indexOf('/') && !path.endsWith("/")) {
215: return basePath + path.substring(0, path.lastIndexOf('/'));
216: } else {
217: return basePath + path;
218: }
219: }
220:
221: public boolean isSecure() {
222: return base.isSecure();
223: }
224:
225: public NavigationalState getNavigationalState() {
226: return navState;
227: }
228:
229: public String createPortletURL(PortletWindow window,
230: Map parameters, PortletMode mode, WindowState state,
231: boolean action, boolean secure) {
232: try {
233: return createPortletURL(navState.encode(window, parameters,
234: mode, state, action), secure);
235: } catch (UnsupportedEncodingException e) {
236: // should never happen
237: e.printStackTrace();
238: // to keep the compiler happy
239: return null;
240: }
241: }
242:
243: public String createPortletURL(PortletWindow window,
244: PortletMode mode, WindowState state, boolean secure) {
245: try {
246: return createPortletURL(navState
247: .encode(window, mode, state), secure);
248: } catch (UnsupportedEncodingException e) {
249: // should never happen
250: e.printStackTrace();
251: // to keep the compiler happy
252: return null;
253: }
254: }
255:
256: protected abstract void decodePathAndNavigationalState(
257: HttpServletRequest request);
258:
259: protected abstract String createPortletURL(String encodedNavState,
260: boolean secure);
261:
262: public void setRequest(HttpServletRequest request) {
263: ArgUtil.assertNotNull(HttpServletRequest.class, request, this ,
264: "setRequest");
265: decodeBaseURL(request);
266: decodeBasePath(request);
267: decodePathAndNavigationalState(request);
268: }
269:
270: public void setCharacterEncoding(String characterEncoding) {
271: this .characterEncoding = characterEncoding;
272: }
273:
274: public String getPortalURL() {
275: try {
276: return createPortletURL(navState.encode(), isSecure());
277: } catch (UnsupportedEncodingException e) {
278: // should never happen
279: e.printStackTrace();
280: // to keep the compiler happy
281: return null;
282: }
283: }
284:
285: public boolean hasEncodedNavState() {
286: return encodedNavState != null;
287: }
288:
289: public boolean isPathInfoEncodingNavState() {
290: return false;
291: }
292: }
|