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.cocoon.components.deli;
018:
019: import java.io.BufferedReader;
020: import java.io.IOException;
021: import java.net.MalformedURLException;
022: import java.security.Principal;
023: import java.util.Enumeration;
024: import java.util.Iterator;
025: import java.util.Locale;
026: import java.util.Map;
027: import java.util.Set;
028: import java.util.Vector;
029:
030: import javax.servlet.RequestDispatcher;
031: import javax.servlet.Servlet;
032: import javax.servlet.ServletContext;
033: import javax.servlet.ServletException;
034: import javax.servlet.ServletInputStream;
035: import javax.servlet.http.Cookie;
036: import javax.servlet.http.HttpServletRequest;
037: import javax.servlet.http.HttpSession;
038:
039: import org.apache.avalon.framework.activity.Disposable;
040: import org.apache.avalon.framework.activity.Initializable;
041: import org.apache.avalon.framework.context.Context;
042: import org.apache.avalon.framework.context.ContextException;
043: import org.apache.avalon.framework.context.Contextualizable;
044: import org.apache.avalon.framework.logger.AbstractLogEnabled;
045: import org.apache.avalon.framework.parameters.Parameterizable;
046: import org.apache.avalon.framework.parameters.Parameters;
047: import org.apache.avalon.framework.service.ServiceException;
048: import org.apache.avalon.framework.service.ServiceManager;
049: import org.apache.avalon.framework.service.Serviceable;
050: import org.apache.avalon.framework.thread.ThreadSafe;
051: import org.apache.cocoon.Constants;
052: import org.apache.cocoon.environment.Request;
053: import org.apache.excalibur.xml.dom.DOMParser;
054: import org.w3c.dom.Document;
055: import org.w3c.dom.Element;
056: import org.w3c.dom.Text;
057:
058: import com.hp.hpl.deli.Profile;
059: import com.hp.hpl.deli.ProfileAttribute;
060: import com.hp.hpl.deli.Workspace;
061:
062: /**
063: * Allows the use of <a href="http://www-uk.hpl.hp.com/people/marbut/">DELI</a>
064: * to provide <a href="http://www.w3.org/Mobile/CCPP/">CC/PP</a> or
065: * <a href="http://www1.wapforum.org/tech/terms.asp?doc=WAP-248-UAProf-20010530-p.pdf">UAProf</a>
066: * support. For more details of DELI see the Technical Report
067: * <a href="http://www-uk.hpl.hp.com/people/marbut/DeliUserGuideWEB.htm">DELI:
068: * A Delivery Context Library for CC/PP and UAProf</a>.
069: *
070: * @author <a href="mailto:marbut@hplb.hpl.hp.com">Mark H. Butler</a>
071: * @version CVS $Id: DeliImpl.java 433543 2006-08-22 06:22:54Z crossley $
072: */
073: public final class DeliImpl extends AbstractLogEnabled implements
074: Parameterizable, Deli, Serviceable, Disposable, Initializable,
075: ThreadSafe, Contextualizable {
076:
077: /** The name of the main DELI configuration file */
078: private String deliConfig = "deli/config/deliConfig.xml";
079:
080: /** The service manager */
081: protected ServiceManager manager = null;
082:
083: /** Parser used to construct the DOM tree to import the profile to a stylesheet */
084: protected DOMParser parser;
085:
086: /** A context, used to retrieve the path to the configuration file */
087: protected CocoonServletContext servletContext;
088:
089: /** Contextualize this class */
090: public void contextualize(Context context) throws ContextException {
091: org.apache.cocoon.environment.Context ctx = (org.apache.cocoon.environment.Context) context
092: .get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
093: this .servletContext = new CocoonServletContext(ctx);
094: }
095:
096: /** Service this class */
097: public void service(ServiceManager manager) throws ServiceException {
098: this .manager = manager;
099: try {
100: this .parser = (DOMParser) this .manager
101: .lookup(DOMParser.ROLE);
102: } catch (ServiceException e) {
103: getLogger().error("DELI Exception while creating parser: ",
104: e);
105: throw e;
106: }
107: }
108:
109: /** Configure this class */
110: public void parameterize(Parameters params) {
111: this .deliConfig = params.getParameter("deli-config-file",
112: this .deliConfig);
113: }
114:
115: /**
116: * Initialize
117: */
118: public void initialize() throws Exception {
119: try {
120: Workspace.getInstance().configure(this .servletContext,
121: this .deliConfig);
122: } catch (Exception e) {
123: getLogger().error(
124: "DELI Exception while creating workspace: ", e);
125: throw e;
126: }
127: }
128:
129: /** Dispose of this class */
130: public void dispose() {
131: if (parser != null) {
132: this .manager.release(parser);
133: }
134: this .parser = null;
135: }
136:
137: /** Process a HttpServletRequest and either extract
138: * CC/PP or UAProf information from it and use this information
139: * to resolve a profile or examine the user agent string, match
140: * this using the DELI legacy device database, and use this
141: * information to retrieve the appropriate CC/PP profile.
142: *
143: * @param theRequest The Request.
144: * @return The profile as a vector of profile attributes.
145: * @throws IOException
146: * @throws ServletException
147: * @throws Exception
148: */
149: public Profile getProfile(Request theRequest) throws IOException,
150: ServletException, Exception {
151: Profile theProfile = null;
152: try {
153: CocoonServletRequest servletRequest = new CocoonServletRequest(
154: theRequest);
155: theProfile = new Profile(servletRequest);
156: } catch (Exception e) {
157: getLogger().error(
158: "DELI Exception while retrieving profile: ", e);
159: throw e;
160: }
161: return theProfile;
162: }
163:
164: /** Convert a profile stored as a vector of profile attributes
165: * to a DOM tree.
166: *
167: * @param theProfile The profile as a vector of profile attributes.
168: * @return The DOM tree.
169: */
170: public Document getUACapabilities(Profile theProfile)
171: throws Exception {
172: Document document = null;
173: try {
174: Element rootElement;
175: Element attributeNode;
176: Element complexAttributeNode;
177: Text text;
178:
179: document = parser.createDocument();
180: rootElement = document.createElementNS(null, "browser");
181: document.appendChild(rootElement);
182:
183: Iterator profileIter = theProfile.iterator();
184: while (profileIter.hasNext()) {
185: ProfileAttribute p = (ProfileAttribute) profileIter
186: .next();
187: attributeNode = document.createElementNS(null, p
188: .getAttribute());
189: rootElement.appendChild(attributeNode);
190: Vector attributeValue = p.get();
191: if (attributeValue != null) {
192: Iterator complexValueIter = attributeValue
193: .iterator();
194: if (p.getCollectionType().equals("Simple")) {
195: // Simple attribute
196: String value = (String) complexValueIter.next();
197: text = document.createTextNode(value);
198: attributeNode.appendChild(text);
199: } else {
200: // Complex attribute e.g. Seq or Bag
201: while (complexValueIter.hasNext()) {
202: String value = (String) complexValueIter
203: .next();
204: complexAttributeNode = document
205: .createElementNS(null, "li");
206: attributeNode
207: .appendChild(complexAttributeNode);
208: text = document.createTextNode(value);
209: complexAttributeNode.appendChild(text);
210: }
211: }
212: }
213: }
214: } catch (Exception e) {
215: getLogger()
216: .error(
217: "DELI Exception while converting profile to DOM fragment: ",
218: e);
219: throw e;
220: }
221: return document;
222: }
223:
224: public Document getUACapabilities(Request theRequest)
225: throws IOException, Exception {
226: return this .getUACapabilities(this .getProfile(theRequest));
227: }
228:
229: /**
230: * Stub implementation of Servlet Context
231: */
232: public static class CocoonServletContext implements ServletContext {
233:
234: org.apache.cocoon.environment.Context envContext;
235:
236: public CocoonServletContext(
237: org.apache.cocoon.environment.Context context) {
238: this .envContext = context;
239: }
240:
241: public Object getAttribute(String name) {
242: return envContext.getAttribute(name);
243: }
244:
245: public void setAttribute(String name, Object value) {
246: envContext.setAttribute(name, value);
247: }
248:
249: public Enumeration getAttributeNames() {
250: return envContext.getAttributeNames();
251: }
252:
253: public java.net.URL getResource(String path)
254: throws MalformedURLException {
255: return envContext.getResource(path);
256: }
257:
258: public String getRealPath(String path) {
259: return envContext.getRealPath(path);
260: }
261:
262: public String getMimeType(String file) {
263: return envContext.getMimeType(file);
264: }
265:
266: public String getInitParameter(String name) {
267: return envContext.getInitParameter(name);
268: }
269:
270: public java.io.InputStream getResourceAsStream(String path) {
271: return envContext.getResourceAsStream(path);
272: }
273:
274: public ServletContext getContext(String uripath) {
275: return (null);
276: }
277:
278: public Enumeration getInitParameterNames() {
279: return (null);
280: }
281:
282: public int getMajorVersion() {
283: return (2);
284: }
285:
286: public int getMinorVersion() {
287: return (3);
288: }
289:
290: public RequestDispatcher getNamedDispatcher(String name) {
291: return (null);
292: }
293:
294: public RequestDispatcher getRequestDispatcher(String path) {
295: return (null);
296: }
297:
298: public Set getResourcePaths(String path) {
299: return null;
300: }
301:
302: public String getServerInfo() {
303: return (null);
304: }
305:
306: /**
307: * @deprecated The method DeliImpl.CocoonServletContext.getServlet(String)
308: * overrides a deprecated method from ServletContext.
309: * @see <a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletContext.html#getServlet(java.lang.String)">ServletContext#getServlet(java.lang.String)</a>
310: */
311: public Servlet getServlet(String name) throws ServletException {
312: return (null);
313: }
314:
315: public String getServletContextName() {
316: return (null);
317: }
318:
319: /**
320: * @deprecated The method DeliImpl.CocoonServletContext.getServletNames()
321: * overrides a deprecated method from ServletContext.
322: * @see <a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletContext.html#getServletNames()">ServletContext#getServletNames()</a>
323: */
324: public Enumeration getServletNames() {
325: return (null);
326: }
327:
328: /**
329: * @deprecated The method DeliImpl.CocoonServletContext.getServlets()
330: * overrides a deprecated method from ServletContext.
331: * @see <a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletContext.html#getServlets()">ServletContext#getServlets()</a>
332: */
333: public Enumeration getServlets() {
334: return (null);
335: }
336:
337: public void log(String message) {
338: }
339:
340: /** @deprecated use {@link #log(String message, Throwable throwable)} instead. */
341: public void log(Exception exception, String message) {
342: }
343:
344: public void log(String message, Throwable throwable) {
345: }
346:
347: public void removeAttribute(String name) {
348: }
349: }
350:
351: /**
352: * Stub implementation of HttpServletRequest
353: */
354: public static class CocoonServletRequest implements
355: HttpServletRequest {
356: Request request;
357:
358: public CocoonServletRequest(Request request) {
359: this .request = request;
360: }
361:
362: public String getAuthType() {
363: return request.getAuthType();
364: }
365:
366: public long getDateHeader(String s) {
367: return request.getDateHeader(s);
368: }
369:
370: public String getHeader(String s) {
371: return request.getHeader(s);
372: }
373:
374: public Enumeration getHeaders(String s) {
375: return request.getHeaders(s);
376: }
377:
378: public Enumeration getHeaderNames() {
379: return request.getHeaderNames();
380: }
381:
382: public String getMethod() {
383: return request.getMethod();
384: }
385:
386: public String getPathInfo() {
387: return request.getPathInfo();
388: }
389:
390: public String getPathTranslated() {
391: return request.getPathTranslated();
392: }
393:
394: public String getContextPath() {
395: return request.getContextPath();
396: }
397:
398: public String getQueryString() {
399: return request.getQueryString();
400: }
401:
402: public String getRemoteUser() {
403: return request.getRemoteUser();
404: }
405:
406: public boolean isUserInRole(String s) {
407: return request.isUserInRole(s);
408: }
409:
410: public String getRequestedSessionId() {
411: return request.getRequestedSessionId();
412: }
413:
414: public String getRequestURI() {
415: return request.getRequestURI();
416: }
417:
418: public String getServletPath() {
419: return request.getServletPath();
420: }
421:
422: public boolean isRequestedSessionIdValid() {
423: return request.isRequestedSessionIdValid();
424: }
425:
426: public boolean isRequestedSessionIdFromCookie() {
427: return request.isRequestedSessionIdFromCookie();
428: }
429:
430: public Object getAttribute(String s) {
431: return request.getAttribute(s);
432: }
433:
434: public Enumeration getAttributeNames() {
435: return request.getAttributeNames();
436: }
437:
438: public String getCharacterEncoding() {
439: return request.getCharacterEncoding();
440: }
441:
442: public int getContentLength() {
443: return request.getContentLength();
444: }
445:
446: public String getContentType() {
447: return request.getContentType();
448: }
449:
450: public String getParameter(String s) {
451: return request.getParameter(s);
452: }
453:
454: public Enumeration getParameterNames() {
455: return request.getParameterNames();
456: }
457:
458: public String[] getParameterValues(String s) {
459: return request.getParameterValues(s);
460: }
461:
462: public String getProtocol() {
463: return request.getProtocol();
464: }
465:
466: public String getScheme() {
467: return request.getScheme();
468: }
469:
470: public String getServerName() {
471: return request.getServerName();
472: }
473:
474: public int getServerPort() {
475: return request.getServerPort();
476: }
477:
478: public String getRemoteAddr() {
479: return request.getRemoteAddr();
480: }
481:
482: public String getRemoteHost() {
483: return request.getRemoteHost();
484: }
485:
486: public void setAttribute(String s, Object obj) {
487: request.setAttribute(s, obj);
488: }
489:
490: public void removeAttribute(String s) {
491: request.removeAttribute(s);
492: }
493:
494: public boolean isSecure() {
495: return request.isSecure();
496: }
497:
498: public StringBuffer getRequestURL() {
499: return null;
500: }
501:
502: public Map getParameterMap() {
503: return null;
504: }
505:
506: public void setCharacterEncoding(String s) {
507: }
508:
509: public Principal getUserPrincipal() {
510: return request.getUserPrincipal();
511: }
512:
513: public Locale getLocale() {
514: return request.getLocale();
515: }
516:
517: public Enumeration getLocales() {
518: return request.getLocales();
519: }
520:
521: /** @deprecated use {@link org.apache.cocoon.components.deli.DeliImpl.CocoonServletContext#getRealPath(java.lang.String)} instead. */
522: public String getRealPath(String s) {
523: return null;
524: }
525:
526: public Cookie[] getCookies() {
527: return null;
528: }
529:
530: public RequestDispatcher getRequestDispatcher(String s) {
531: return null;
532: }
533:
534: public BufferedReader getReader() throws IOException {
535: return null;
536: }
537:
538: public ServletInputStream getInputStream() throws IOException {
539: return null;
540: }
541:
542: public HttpSession getSession(boolean flag) {
543: return null;
544: }
545:
546: public HttpSession getSession() {
547: return null;
548: }
549:
550: public boolean isRequestedSessionIdFromURL() {
551: return false;
552: }
553:
554: /** @deprecated use {@link #isRequestedSessionIdFromURL()} instead */
555: public boolean isRequestedSessionIdFromUrl() {
556: return false;
557: }
558:
559: public int getIntHeader(String s) {
560: return 0;
561: }
562: }
563:
564: }
|