001: package org.wings.adapter;
002:
003: import org.wings.*;
004: import org.wings.resource.DynamicResource;
005: import org.wings.resource.ReloadResource;
006: import org.wings.template.StringTemplateSource;
007: import org.wings.session.SessionManager;
008: import org.wings.header.Link;
009: import org.wings.header.Script;
010: import org.wings.conf.CmsDetail;
011: import org.wings.adapter.CmsAdapter;
012: import org.apache.commons.httpclient.HttpMethod;
013: import org.apache.commons.httpclient.HttpClient;
014: import org.apache.commons.httpclient.HttpStatus;
015: import org.apache.commons.httpclient.util.DateParser;
016: import org.apache.commons.httpclient.methods.GetMethod;
017: import org.apache.commons.httpclient.methods.PostMethod;
018:
019: import java.util.*;
020: import java.text.SimpleDateFormat;
021:
022: import au.id.jericho.lib.html.*;
023:
024: import javax.servlet.http.HttpServletRequest;
025: import javax.servlet.ServletRequest;
026:
027: /**
028: * <code>AbstractCMSAdapter<code>.
029: * <p/>
030: * User: rrd
031: * Date: 08.08.2007
032: * Time: 09:03:52
033: *
034: * @author rrd
035: * @version $Id
036: */
037: public abstract class AbstractCmsAdapter implements CmsAdapter {
038:
039: private SFrame frame;
040: private STemplateLayout layout;
041:
042: private CmsDetail cfg;
043:
044: DynamicResource defaultResource;
045: Map<String, String> contentMap = new HashMap<String, String>();
046: Map<String, Date> obtainedMap = new HashMap<String, Date>();
047: SimpleDateFormat httpdate;
048: private String path;
049:
050: protected Collection<Link> links = new ArrayList<Link>();
051: protected Collection<Script> scripts = new ArrayList<Script>();
052:
053: public AbstractCmsAdapter(SFrame frame, STemplateLayout layout,
054: CmsDetail cfg) {
055: setFrame(frame);
056: setConfiguration(cfg);
057: this .layout = layout;
058: defaultResource = frame
059: .getDynamicResource(ReloadResource.class);
060:
061: // httpdate parses and formats dates in HTTP Date Format (RFC1123)
062: httpdate = new SimpleDateFormat(DateParser.PATTERN_RFC1123,
063: Locale.ENGLISH);
064: httpdate.setTimeZone(TimeZone.getTimeZone("GMT"));
065:
066: navigate(SessionManager.getSession().getServletRequest()
067: .getPathInfo());
068: }
069:
070: public SFrame getFrame() {
071: return frame;
072: }
073:
074: public void setFrame(SFrame frame) {
075: this .frame = frame;
076: }
077:
078: public CmsDetail getConfiguration() {
079: return cfg;
080: }
081:
082: public void setConfiguration(CmsDetail cfg) {
083: this .cfg = cfg;
084: }
085:
086: public Resource mapResource(String url) {
087: navigate(url);
088: return defaultResource;
089: }
090:
091: private void navigate(String url) {
092:
093: HttpServletRequest request = SessionManager.getSession()
094: .getServletRequest();
095:
096: String methodName = request.getMethod();
097: HttpMethod method = null;
098: if ("GET".equals(methodName)) {
099: url += "?";
100:
101: Enumeration enumeration = request.getParameterNames();
102: while (enumeration.hasMoreElements()) {
103: String name = (String) enumeration.nextElement();
104: String value = request.getParameter(name);
105:
106: url += name + "=" + value + "&";
107: }
108: url = url.substring(0, url.length() - 1);
109:
110: method = new GetMethod(cfg.getServerPath() + url);
111: } else if ("POST".equals(methodName)) {
112: method = new PostMethod(cfg.getServerPath() + url);
113:
114: Enumeration enumeration = request.getParameterNames();
115: while (enumeration.hasMoreElements()) {
116: String name = (String) enumeration.nextElement();
117: String value = request.getParameter(name);
118: ((PostMethod) method).addParameter(name, value);
119: }
120: }
121: HttpClient httpclient = new HttpClient();
122: String templateString = null;
123:
124: // Sets the "If-Modified-Since" header to the date in cache
125: if (obtainedMap.containsKey(url)) {
126: method.addRequestHeader("If-Modified-Since", httpdate
127: .format(obtainedMap.get(url)));
128: }
129:
130: try {
131: // Execute http request
132: int httpstatus = httpclient.executeMethod(method);
133:
134: // Invoke handleUnknownResourceRequested
135: if (httpstatus != HttpStatus.SC_OK
136: && httpstatus != HttpStatus.SC_NOT_MODIFIED)
137: return;
138:
139: // If the 'If-Modified-Since' header is sent, the server should set the status to
140: // SC_NOT_MODIFIED (304). Sometimes this does not work. In this case we try to compare the
141: // 'Last-Modified' response header with the date in cache ourselves.
142: boolean cached = true;
143: if (httpstatus == HttpStatus.SC_OK) {
144: try {
145: Date httplastmodified = httpdate.parse(method
146: .getResponseHeader("Last-Modified")
147: .getValue());
148: if (!httplastmodified.before(obtainedMap.get(url)))
149: cached = false;
150: } catch (Exception ex) {
151: // Cannot parse the Last-Modified header or file is not in cache --> Don't use caching
152: cached = false;
153: }
154: }
155:
156: // Load the template from cache or use the response body as new template
157: if (cached) {
158: templateString = contentMap.get(url);
159: } else {
160: templateString = method.getResponseBodyAsString();
161: templateString = process(templateString);
162:
163: // Add template to cache
164: contentMap.put(url, templateString);
165: obtainedMap.put(url, new Date());
166: }
167:
168: method.releaseConnection();
169:
170: layout
171: .setTemplate(new StringTemplateSource(
172: templateString));
173: } catch (Exception ex) {
174: // Http get request failed or can't set template --> Invoke handleUnknownResourceRequested
175: ex.printStackTrace();
176: System.err.println(templateString);
177: }
178: }
179:
180: protected String process(String templateString) {
181:
182: // String wingsServerPath = getPath();
183: // String cmsServerPath = cfg.getServerPath();
184:
185: Source source = new Source(templateString);
186:
187: parseTitle(source);
188: parseLinks(source);
189: parseScripts(source);
190:
191: // Segment content = source.getElementById("body").getContent();
192:
193: Element body = source.findNextElement(0, "body");
194: if (body == null) {
195: return templateString;
196: }
197:
198: Segment content = body.getContent();
199: source = new Source(content.toString());
200:
201: OutputDocument outputDocument = new OutputDocument(source);
202:
203: parseAnchors(source, outputDocument);
204: parseImages(source, outputDocument);
205:
206: templateString = outputDocument.toString();
207: return templateString;
208: }
209:
210: public String getPath() {
211: if (path == null) {
212: //path = SessionManager.getSession().getServletRequest().getContextPath() + SessionManager.getSession().getServletRequest().getServletPath();
213: HttpServletRequest request = SessionManager.getSession()
214: .getServletRequest();
215:
216: String path = request.getRequestURL().toString();
217: String pathInfo = request.getPathInfo();
218: this .path = path.substring(0, path.lastIndexOf(pathInfo));
219: }
220:
221: return path;
222: }
223:
224: protected class Url implements URLResource {
225: private SimpleURL url;
226:
227: public Url(String href) {
228: this .url = new SimpleURL(href);
229: }
230:
231: public SimpleURL getURL() {
232: return url;
233: }
234: }
235: }
|