001: /*
002: * Title: AbstractPage
003: * Description:
004: *
005: * This software is published under the terms of the OpenSymphony Software
006: * License version 1.1, of which a copy has been included with this
007: * distribution in the LICENSE.txt file.
008: */
009:
010: package com.opensymphony.module.sitemesh.parser;
011:
012: import com.opensymphony.module.sitemesh.Page;
013:
014: import javax.servlet.http.HttpServletRequest;
015: import javax.servlet.http.HttpServletRequestWrapper;
016: import java.io.*;
017: import java.util.HashMap;
018: import java.util.Map;
019: import java.util.Set;
020:
021: /**
022: * Abstract implementation of {@link com.opensymphony.module.sitemesh.Page} .
023: *
024: * <p>Contains base methods for storing and accessing page properties.
025: * Also stores {@link #pageData} as byte[] and implements write???()
026: * methods.</p>
027: *
028: * <p>Concrete implementations need only set the {@link #pageData} and
029: * call {@link #addProperty(java.lang.String,java.lang.String)} to
030: * add all the required information.</p>
031: *
032: * @author <a href="joe@truemesh.com">Joe Walnes</a>
033: * @version $Revision: 1.6 $
034: *
035: * @see com.opensymphony.module.sitemesh.Page
036: */
037: public abstract class AbstractPage implements Page {
038: /**
039: * Map of all properties.
040: * Key is String. Value is java.util.List of multiple String values.
041: */
042: private final Map properties = new HashMap();
043:
044: /** Date of page contents. */
045: protected char[] pageData = new char[0];
046:
047: /** RequestURI of original Page. */
048: private HttpServletRequest request;
049:
050: public void writePage(Writer out) throws IOException {
051: out.write(pageData);
052: }
053:
054: public String getPage() {
055: try {
056: StringWriter writer = new StringWriter();
057: writePage(writer);
058: return writer.toString();
059: } catch (IOException e) {
060: throw new IllegalStateException("Could not get page "
061: + e.getMessage());
062: }
063: }
064:
065: /**
066: * Write data of html <code><body></code> tag.
067: *
068: * <p>Must be implemented. Data written should not actually contain the
069: * body tags, but all the data in between.
070: */
071: public abstract void writeBody(Writer out) throws IOException;
072:
073: public String getBody() {
074: try {
075: StringWriter writer = new StringWriter();
076: writeBody(writer);
077: return writer.toString();
078: } catch (IOException e) {
079: throw new IllegalStateException("Could not get body "
080: + e.getMessage());
081: }
082: }
083:
084: /** Return title of from "title" property. Never returns null. */
085: public String getTitle() {
086: return noNull(getProperty("title"));
087: }
088:
089: public int getContentLength() {
090: try {
091: //todo - this needs to be fixed properly (SIM-196)
092: return new String(pageData).getBytes("UTF-8").length; // we cannot just measure pageData.length, due to i18n issues (SIM-157)
093: } catch (UnsupportedEncodingException e) {
094: return new String(pageData).getBytes().length;
095: }
096: }
097:
098: public String getProperty(String name) {
099: if (!isPropertySet(name))
100: return null;
101: return (String) properties.get(name);
102: }
103:
104: public int getIntProperty(String name) {
105: try {
106: return Integer.parseInt(noNull(getProperty(name)));
107: } catch (NumberFormatException e) {
108: return 0;
109: }
110: }
111:
112: public long getLongProperty(String name) {
113: try {
114: return Long.parseLong(noNull(getProperty(name)));
115: } catch (NumberFormatException e) {
116: return 0;
117: }
118: }
119:
120: public boolean getBooleanProperty(String name) {
121: String property = getProperty(name);
122: if (property == null || property.trim().length() == 0)
123: return false;
124: switch (property.charAt(0)) {
125: case '1':
126: case 't':
127: case 'T':
128: case 'y':
129: case 'Y':
130: return true;
131: default:
132: return false;
133: }
134: }
135:
136: public boolean isPropertySet(String name) {
137: return properties.containsKey(name);
138: }
139:
140: public String[] getPropertyKeys() {
141: synchronized (properties) {
142: Set keys = properties.keySet();
143: return (String[]) keys.toArray(new String[keys.size()]);
144: }
145: }
146:
147: public Map getProperties() {
148: return properties;
149: }
150:
151: /** @see com.opensymphony.module.sitemesh.Page#getRequest() */
152: public HttpServletRequest getRequest() {
153: return request;
154: }
155:
156: /**
157: * Create snapshot of Request.
158: *
159: * @see com.opensymphony.module.sitemesh.Page#getRequest()
160: */
161: public void setRequest(HttpServletRequest request) {
162: this .request = new PageRequest(request);
163: }
164:
165: /**
166: * Add a property to the properties list.
167: *
168: * @param name Name of property
169: * @param value Value of property
170: */
171: public void addProperty(String name, String value) {
172: properties.put(name, value);
173: }
174:
175: /** Return String as is, or "" if null. (Prevents NullPointerExceptions) */
176: protected static String noNull(String in) {
177: return in == null ? "" : in;
178: }
179: }
180:
181: class PageRequest extends HttpServletRequestWrapper {
182:
183: private String requestURI, method, pathInfo, pathTranslated,
184: queryString, servletPath;
185:
186: public PageRequest(HttpServletRequest request) {
187: super (request);
188: requestURI = request.getRequestURI();
189: method = request.getMethod();
190: pathInfo = request.getPathInfo();
191: pathTranslated = request.getPathTranslated();
192: queryString = request.getQueryString();
193: servletPath = request.getServletPath();
194: }
195:
196: public String getRequestURI() {
197: return requestURI;
198: }
199:
200: public String getMethod() {
201: return method;
202: }
203:
204: public String getPathInfo() {
205: return pathInfo;
206: }
207:
208: public String getPathTranslated() {
209: return pathTranslated;
210: }
211:
212: public String getQueryString() {
213: return queryString;
214: }
215:
216: public String getServletPath() {
217: return servletPath;
218: }
219: }
|