001: /* ***** BEGIN LICENSE BLOCK *****
002: * Version: MPL 1.1
003: * The contents of this file are subject to the Mozilla Public License Version
004: * 1.1 (the "License"); you may not use this file except in compliance with
005: * the License. You may obtain a copy of the License at
006: * http://www.mozilla.org/MPL/
007: *
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
010: * for the specific language governing rights and limitations under the
011: * License.
012: *
013: * The Original Code is Riot.
014: *
015: * The Initial Developer of the Original Code is
016: * Neteye GmbH.
017: * Portions created by the Initial Developer are Copyright (C) 2007
018: * the Initial Developer. All Rights Reserved.
019: *
020: * Contributor(s):
021: * Felix Gnass [fgnass at neteye dot de]
022: *
023: * ***** END LICENSE BLOCK ***** */
024: package org.riotfamily.common.web.view;
025:
026: import java.io.IOException;
027: import java.net.URI;
028: import java.net.URISyntaxException;
029: import java.util.ArrayList;
030: import java.util.Collection;
031: import java.util.Iterator;
032: import java.util.List;
033: import java.util.Locale;
034: import java.util.Random;
035: import java.util.regex.Matcher;
036: import java.util.regex.Pattern;
037:
038: import javax.servlet.ServletException;
039: import javax.servlet.http.HttpServletRequest;
040: import javax.servlet.http.HttpServletResponse;
041:
042: import org.apache.commons.logging.Log;
043: import org.apache.commons.logging.LogFactory;
044: import org.riotfamily.common.beans.PropertyUtils;
045: import org.riotfamily.common.util.FormatUtils;
046: import org.riotfamily.common.web.collaboration.SharedProperties;
047: import org.riotfamily.common.web.filter.ResourceStamper;
048: import org.riotfamily.common.web.mapping.HandlerUrlResolver;
049: import org.riotfamily.common.web.mapping.ReverseHandlerMapping;
050: import org.riotfamily.common.web.util.ServletUtils;
051: import org.riotfamily.common.web.util.StringCapturingResponseWrapper;
052: import org.springframework.context.ApplicationContext;
053: import org.springframework.context.MessageSourceResolvable;
054: import org.springframework.util.StringUtils;
055: import org.springframework.web.servlet.support.RequestContextUtils;
056:
057: /**
058: * @author Felix Gnass [fgnass at neteye dot de]
059: * @since 6.5
060: */
061: public class CommonMacroHelper {
062:
063: private static final Log log = LogFactory
064: .getLog(CommonMacroHelper.class);
065:
066: private static final Pattern LINK_PATTERN = Pattern.compile(
067: "(\\s+href\\s*=\\s*\")(.+?)(\")", Pattern.CASE_INSENSITIVE);
068:
069: private static Random random = new Random();
070:
071: private ApplicationContext ctx;
072:
073: private HttpServletRequest request;
074:
075: private HttpServletResponse response;
076:
077: private ResourceStamper stamper;
078:
079: private HandlerUrlResolver handlerUrlResolver;
080:
081: private Locale requestLocale = null;
082:
083: public CommonMacroHelper(ApplicationContext ctx,
084: HttpServletRequest request, HttpServletResponse response,
085: ResourceStamper stamper,
086: HandlerUrlResolver handlerUrlResolver) {
087:
088: this .ctx = ctx;
089: this .request = request;
090: this .response = response;
091: this .stamper = stamper;
092: this .handlerUrlResolver = handlerUrlResolver;
093: }
094:
095: public Random getRandom() {
096: return random;
097: }
098:
099: public Locale getLocale() {
100: if (requestLocale == null) {
101: requestLocale = RequestContextUtils.getLocale(request);
102: }
103: return requestLocale;
104: }
105:
106: public String getMessage(String code, List args,
107: String defaultMessage) {
108: return ctx.getMessage(code, args.toArray(), defaultMessage,
109: getLocale());
110: }
111:
112: public String getMessage(MessageSourceResolvable resolvable) {
113: return ctx.getMessage(resolvable, getLocale());
114: }
115:
116: public String getSharedProperty(String key) {
117: return SharedProperties.getProperty(request, key);
118: }
119:
120: public String setSharedProperty(String key, String value) {
121: SharedProperties.setProperty(request, key, value);
122: return "";
123: }
124:
125: public String resolveAndEncodeUrl(String url) {
126: return ServletUtils.resolveAndEncodeUrl(url, request, response);
127: }
128:
129: public String resolveAndEncodeLinks(String html) {
130: Matcher m = LINK_PATTERN.matcher(html);
131: StringBuffer result = new StringBuffer();
132: while (m.find() && m.groupCount() == 3) {
133: String newLink = ServletUtils.resolveAndEncodeUrl(m
134: .group(2), request, response);
135: log.debug("Replacing link '" + m.group(2) + "' with '"
136: + newLink + "'");
137: m.appendReplacement(result, m.group(1) + newLink
138: + m.group(3));
139: }
140: m.appendTail(result);
141: return result.toString();
142: }
143:
144: public String getAbsoluteUrl(String url) {
145: return ServletUtils.getAbsoluteUrlPrefix(request).append(
146: request.getContextPath()).append(url).toString();
147: }
148:
149: public String getUrlForHandler(String handlerName,
150: Object attributes, String prefix) {
151:
152: return handlerUrlResolver.getUrlForHandler(request,
153: handlerName, attributes, prefix);
154: }
155:
156: public String getOriginatingRequestUri() {
157: String uri = ServletUtils.getOriginatingRequestUri(request);
158: if (StringUtils.hasText(request.getQueryString())) {
159: uri = uri + "?" + request.getQueryString();
160: }
161: return uri;
162: }
163:
164: public String getPathWithinApplication() {
165: return ServletUtils.getPathWithinApplication(request);
166: }
167:
168: public String getTopLevelHandlerName() {
169: return (String) request
170: .getAttribute(ReverseHandlerMapping.TOP_LEVEL_HANDLER_NAME_ATTRIBUTE);
171: }
172:
173: public boolean isExternalUrl(String url) {
174: try {
175: URI uri = new URI(url);
176: if (!uri.isOpaque()) {
177: if (uri.isAbsolute()
178: && !request.getServerName().equals(
179: uri.getHost())) {
180:
181: return true;
182: }
183: }
184: } catch (URISyntaxException e) {
185: log.warn(e.getMessage());
186: }
187: return false;
188: }
189:
190: public String include(String url) throws ServletException,
191: IOException {
192: request.getRequestDispatcher(url).include(request, response);
193: return "";
194: }
195:
196: public String capture(String url) throws ServletException,
197: IOException {
198: StringCapturingResponseWrapper wrapper = new StringCapturingResponseWrapper(
199: response);
200:
201: request.getRequestDispatcher(url).include(request, wrapper);
202: return wrapper.getCapturedData();
203: }
204:
205: public String addTimestamp(String s) {
206: return stamper.stamp(s);
207: }
208:
209: /**
210: * Partitions the given collection by inspecting the specified property
211: * of the contained items.
212: *
213: * @param c The collection to partition
214: * @param titleProperty The property to use for grouping
215: * @return A list of {@link ObjectGroup ObjectGroups}
216: */
217: public static List partition(Collection c, String titleProperty) {
218: ArrayList groups = new ArrayList();
219: Iterator it = c.iterator();
220: ObjectGroup group = null;
221: while (it.hasNext()) {
222: Object item = it.next();
223: Object title = PropertyUtils.getProperty(item,
224: titleProperty);
225: if (group == null
226: || (title != null && !title
227: .equals(group.getTitle()))) {
228:
229: group = new ObjectGroup(title, item);
230: groups.add(group);
231: } else {
232: group.add(item);
233: }
234: }
235: return groups;
236: }
237:
238: public String getFileExtension(String filename,
239: Collection validExtensions, String defaultExtension) {
240:
241: String ext = FormatUtils.getExtension(filename);
242: if (validExtensions.isEmpty() || validExtensions.contains(ext)) {
243: return ext;
244: }
245: return defaultExtension;
246: }
247:
248: public String baseName(String path) {
249: int begin = path.lastIndexOf('/') + 1;
250: int end = path.indexOf(';');
251: if (end == -1) {
252: end = path.indexOf('?');
253: if (end == -1) {
254: end = path.length();
255: }
256: }
257: return path.substring(begin, end);
258: }
259:
260: public String formatByteSize(long bytes) {
261: return FormatUtils.formatByteSize(bytes);
262: }
263:
264: public String formatMillis(long millis) {
265: return FormatUtils.formatMillis(millis);
266: }
267:
268: public String toTitleCase(String s) {
269: return FormatUtils.fileNameToTitleCase(s);
270: }
271:
272: public static class ObjectGroup {
273:
274: private Object title;
275:
276: private List items;
277:
278: private ObjectGroup(Object title, Object item) {
279: this .title = title;
280: this .items = new ArrayList();
281: this .items.add(item);
282: }
283:
284: public void add(Object item) {
285: items.add(item);
286: }
287:
288: public Object getTitle() {
289: return this .title;
290: }
291:
292: public List getItems() {
293: return this.items;
294: }
295:
296: }
297: }
|