001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * 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. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018:
019: package org.apache.roller.ui.rendering.util;
020:
021: import java.util.Locale;
022: import javax.servlet.http.HttpServletRequest;
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.apache.roller.RollerException;
026: import org.apache.roller.business.RollerFactory;
027: import org.apache.roller.business.UserManager;
028: import org.apache.roller.pojos.WebsiteData;
029:
030: /**
031: * Represents a request to a weblog.
032: *
033: * This is a fairly generic parsed request which is only trying to figure out
034: * the elements of a weblog request which apply to all weblogs. We try to
035: * determine the weblogHandle, if a locale was specified, and then what extra
036: * path info remains. The basic format is like this ...
037: *
038: * /<weblogHandle>[/locale][/extra/path/info]
039: *
040: * All weblog urls require a weblogHandle, so we ensure that part of the url is
041: * properly specified. locale is always optional, so we do our best to see
042: * if a locale is specified. and path info is always optional.
043: *
044: * NOTE: this class purposely exposes a getPathInfo() method which provides the
045: * path info specified by the request that has not been parsed by this
046: * particular class. this makes it relatively easy for subclasses to extend
047: * this class and simply pick up where it left off in the parsing process.
048: */
049: public class WeblogRequest extends ParsedRequest {
050:
051: private static Log log = LogFactory.getLog(WeblogRequest.class);
052:
053: // lightweight attributes
054: private String weblogHandle = null;
055: private String locale = null;
056: private String pathInfo = null;
057:
058: // heavyweight attributes
059: private WebsiteData weblog = null;
060: private Locale localeInstance = null;
061:
062: public WeblogRequest() {
063: }
064:
065: public WeblogRequest(HttpServletRequest request)
066: throws InvalidRequestException {
067:
068: // let our parent take care of their business first
069: super (request);
070:
071: String path = request.getPathInfo();
072:
073: log.debug("parsing path " + path);
074:
075: // first, cleanup extra slashes and extract the weblog weblogHandle
076: if (path != null && path.trim().length() > 1) {
077:
078: // strip off the leading slash
079: path = path.substring(1);
080:
081: // strip off trailing slash if needed
082: if (path.endsWith("/")) {
083: path = path.substring(0, path.length() - 1);
084: }
085:
086: String[] pathElements = path.split("/", 2);
087: if (pathElements[0].trim().length() > 0) {
088: this .weblogHandle = pathElements[0];
089: } else {
090: // no weblogHandle in path info
091: throw new InvalidRequestException(
092: "not a weblog request, "
093: + request.getRequestURL());
094: }
095:
096: // if there is more left of the path info then hold onto it
097: if (pathElements.length == 2) {
098: path = pathElements[1];
099: } else {
100: path = null;
101: }
102: }
103:
104: // second, check if we have a locale, everything else is extra path info
105: if (path != null && path.trim().length() > 0) {
106:
107: String[] pathElements = path.split("/", 2);
108: if (this .isLocale(pathElements[0])) {
109: this .locale = pathElements[0];
110:
111: // everything else is path info
112: if (pathElements.length == 2) {
113: this .pathInfo = pathElements[1];
114: }
115: } else {
116: // no locale, just extra path info
117: this .pathInfo = path;
118: }
119: }
120:
121: if (log.isDebugEnabled()) {
122: log.debug("handle = " + this .weblogHandle);
123: log.debug("locale = " + this .locale);
124: log.debug("pathInfo = " + this .pathInfo);
125: }
126: }
127:
128: /**
129: * Convenience method which determines if the given string is a valid
130: * locale string.
131: */
132: protected boolean isLocale(String potentialLocale) {
133:
134: boolean isLocale = false;
135:
136: // we only support 2 or 5 character locale strings, so check that first
137: if (potentialLocale != null
138: && (potentialLocale.length() == 2 || potentialLocale
139: .length() == 5)) {
140:
141: // now make sure that the format is proper ... e.g. "en_US"
142: // we are not going to be picky about capitalization
143: String[] langCountry = potentialLocale.split("_");
144: if (langCountry.length == 1 && langCountry[0] != null
145: && langCountry[0].length() == 2) {
146: isLocale = true;
147:
148: } else if (langCountry.length == 2
149: && langCountry[0] != null
150: && langCountry[0].length() == 2
151: && langCountry[1] != null
152: && langCountry[1].length() == 2) {
153:
154: isLocale = true;
155: }
156: }
157:
158: return isLocale;
159: }
160:
161: public String getWeblogHandle() {
162: return weblogHandle;
163: }
164:
165: public void setWeblogHandle(String weblogHandle) {
166: this .weblogHandle = weblogHandle;
167: }
168:
169: public String getLocale() {
170: return locale;
171: }
172:
173: public void setLocale(String locale) {
174: this .locale = locale;
175: }
176:
177: public String getPathInfo() {
178: return pathInfo;
179: }
180:
181: public void setPathInfo(String pathInfo) {
182: this .pathInfo = pathInfo;
183: }
184:
185: public WebsiteData getWeblog() {
186:
187: if (weblog == null && weblogHandle != null) {
188: try {
189: UserManager umgr = RollerFactory.getRoller()
190: .getUserManager();
191: weblog = umgr.getWebsiteByHandle(weblogHandle,
192: Boolean.TRUE);
193: } catch (RollerException ex) {
194: log
195: .error("Error looking up weblog "
196: + weblogHandle, ex);
197: }
198: }
199:
200: return weblog;
201: }
202:
203: public void setWeblog(WebsiteData weblog) {
204: this .weblog = weblog;
205: }
206:
207: /**
208: * Get the Locale instance to be used for this request.
209: *
210: * The Locale is determined via these rules ...
211: * 1. if a locale is explicitly specified, then it is used
212: * 2. if no locale is specified, then use the weblog default locale
213: */
214: public Locale getLocaleInstance() {
215:
216: if (localeInstance == null && locale != null) {
217: String[] langCountry = locale.split("_");
218: if (langCountry.length == 1) {
219: localeInstance = new Locale(langCountry[0]);
220: } else if (langCountry.length == 2) {
221: localeInstance = new Locale(langCountry[0],
222: langCountry[1]);
223: }
224: } else if (localeInstance == null) {
225: localeInstance = getWeblog().getLocaleInstance();
226: }
227:
228: return localeInstance;
229: }
230:
231: public void setLocaleInstance(Locale localeInstance) {
232: this.localeInstance = localeInstance;
233: }
234:
235: }
|