001: package org.gridsphere.portlet.impl;
002:
003: import javax.portlet.PortletContext;
004: import javax.portlet.PortletRequestDispatcher;
005: import javax.servlet.RequestDispatcher;
006: import javax.servlet.ServletContext;
007: import java.net.MalformedURLException;
008:
009: /**
010: * The <CODE>PortletContext</CODE> interface defines a portlet view
011: * of the portlet container.
012: * The <CODE>PortletContext</CODE> also makes resources available
013: * to the portlet. Using the context, a portlet can access
014: * the portlet log, and obtain URL references to resources.
015: * <p/>
016: * <p>There is one context per "portlet application" per Java Virtual Machine. (A
017: * "portlet application" is a collection of portlets, servlets, and content installed
018: * under a specific subset of the server URL namespace, such as <code>/catalog</code>.
019: * They are possibly installed via a <code>.war</code> file.)
020: * As a web application, a portlet application also has a servlet context.
021: * The portlet context leverages most of its functionality from the
022: * servlet context of the portlet application.
023: * <p/>
024: * Attibutes stored in the context are global for <I>all</I> users and <I>all</I>
025: * components in the portlet application.
026: * <p/>
027: * In the case of a web
028: * application marked "distributed" in its deployment descriptor, there will
029: * be one context instance for each virtual machine. In this situation, the
030: * context cannot be used as a location to share global information (because
031: * the information is not truly global). Use an external resource, such as
032: * a database to achieve sharing on a global scope.
033: */
034: public class PortletContextImpl implements PortletContext {
035:
036: private ServletContext context = null;
037:
038: /**
039: * Cannot instantiate uninitialized SportletContext
040: */
041: private PortletContextImpl() {
042: }
043:
044: /**
045: * Constructs an instance of SportletContext from a <code>ServletConfig</code>
046: */
047: public PortletContextImpl(ServletContext context) {
048: this .context = context;
049: }
050:
051: public ServletContext getServletContext() {
052: return context;
053: }
054:
055: /**
056: * Returns the name and version of the portlet container in which the
057: * portlet is running.
058: * <p/>
059: * <P>
060: * The form of the returned string is <code>containername/versionnumber</code>.
061: *
062: * @return the string containing at least name and version number
063: */
064:
065: public String getServerInfo() {
066: return SportletProperties.getInstance().getProperty(
067: "gridsphere.release");
068: }
069:
070: /**
071: * Returns a {@link PortletRequestDispatcher} object that acts
072: * as a wrapper for the resource located at the given path.
073: * A <code>PortletRequestDispatcher</code> object can be used include the
074: * resource in a response. The resource can be dynamic or static.
075: * <p/>
076: * <p>The pathname must begin with a slash (<code> / </code>) and is interpreted as relative
077: * to the current context root.
078: * <p/>
079: * <p>This method returns <code>null</code> if the <code>PortletContext</code>
080: * cannot return a <code>PortletRequestDispatcher</code>
081: * for any reason.
082: *
083: * @param path a <code>String</code> specifying the pathname
084: * to the resource
085: * @return a <code>PortletRequestDispatcher</code> object
086: * that acts as a wrapper for the resource
087: * at the specified path.
088: * @see PortletRequestDispatcher
089: */
090: public PortletRequestDispatcher getRequestDispatcher(String path) {
091: RequestDispatcher rd = context.getRequestDispatcher(path);
092: return new PortletRequestDispatcherImpl(rd, path);
093: }
094:
095: /**
096: * Returns a {@link PortletRequestDispatcher} object that acts
097: * as a wrapper for the named servlet.
098: * <p/>
099: * <p>Servlets (and also JSP pages) may be given names via server
100: * administration or via a web application deployment descriptor.
101: * <p/>
102: * <p>This method returns <code>null</code> if the
103: * <code>PortletContext</code> cannot return a
104: * <code>PortletRequestDispatcher</code> for any reason.
105: *
106: * @param name a <code>String</code> specifying the name
107: * of a servlet to be wrapped
108: * @return a <code>PortletRequestDispatcher</code> object
109: * that acts as a wrapper for the named servlet
110: * @see PortletRequestDispatcher
111: */
112: public PortletRequestDispatcher getNamedDispatcher(String name) {
113: RequestDispatcher rd = context.getNamedDispatcher(name);
114: if (rd != null) {
115: return new PortletRequestDispatcherImpl(rd);
116: }
117: return null;
118: }
119:
120: /**
121: * Returns the resource located at the given path as an InputStream object.
122: * The data in the InputStream can be of any type or length. The method returns
123: * null if no resource exists at the given path.
124: * <p/>
125: * In order to access protected resources the path has to be prefixed with
126: * <code>/WEB-INF/</code> (for example <code>/WEB-INF/myportlet/myportlet.jsp</code>).
127: * Otherwise, the direct path is used
128: * (for example <code>/myportlet/myportlet.jsp</code>).
129: *
130: * @param path the path to the resource
131: * @return the input stream
132: */
133: public java.io.InputStream getResourceAsStream(String path) {
134: return context.getResourceAsStream(path);
135: }
136:
137: /**
138: * Returns the major version of the Portlet API that this portlet
139: * container supports.
140: *
141: * @return the major version
142: * @see #getMinorVersion()
143: */
144: public int getMajorVersion() {
145: return Integer.valueOf(
146: SportletProperties.getInstance().getProperty(
147: "portletapi.majorversion")).intValue();
148: }
149:
150: /**
151: * Returns the minor version of the Portlet API that this portlet
152: * container supports.
153: *
154: * @return the minor version
155: * @see #getMajorVersion()
156: */
157: public int getMinorVersion() {
158: return Integer.valueOf(
159: SportletProperties.getInstance().getProperty(
160: "portletapi.minorversion")).intValue();
161: }
162:
163: /**
164: * Returns the MIME type of the specified file, or <code>null</code> if
165: * the MIME type is not known. The MIME type is determined
166: * by the configuration of the portlet container and may be specified
167: * in a web application deployment descriptor. Common MIME
168: * types are <code>text/html</code> and <code>image/gif</code>.
169: *
170: * @param file a <code>String</code> specifying the name
171: * of a file
172: * @return a <code>String</code> specifying the MIME type of the file
173: */
174: public String getMimeType(String file) {
175: return context.getMimeType(file);
176: }
177:
178: /**
179: * Returns a <code>String</code> containing the real path
180: * for a given virtual path. For example, the path <code>/index.html</code>
181: * returns the absolute file path of the portlet container file system.
182: * <p/>
183: * <p>The real path returned will be in a form
184: * appropriate to the computer and operating system on
185: * which the portlet container is running, including the
186: * proper path separators. This method returns <code>null</code>
187: * if the portlet container cannot translate the virtual path
188: * to a real path for any reason (such as when the content is
189: * being made available from a <code>.war</code> archive).
190: *
191: * @param path a <code>String</code> specifying a virtual path
192: * @return a <code>String</code> specifying the real path,
193: * or null if the transformation cannot be performed.
194: */
195: public String getRealPath(String path) {
196: return context.getRealPath(path);
197: }
198:
199: /**
200: * Returns a directory-like listing of all the paths to resources within
201: * the web application longest sub-path of which
202: * matches the supplied path argument. Paths indicating subdirectory paths
203: * end with a slash (<code>/</code>). The returned paths are all
204: * relative to the root of the web application and have a leading slash.
205: * For example, for a web application
206: * containing<br><br>
207: * <code>
208: * /welcome.html<br>
209: * /catalog/index.html<br>
210: * /catalog/products.html<br>
211: * /catalog/offers/books.html<br>
212: * /catalog/offers/music.html<br>
213: * /customer/login.jsp<br>
214: * /WEB-INF/web.xml<br>
215: * /WEB-INF/classes/com.acme.OrderPortlet.class,<br><br>
216: * </code>
217: * <p/>
218: * <code>getResourcePaths("/")</code> returns
219: * <code>{"/welcome.html", "/catalog/", "/customer/", "/WEB-INF/"}</code><br>
220: * <code>getResourcePaths("/catalog/")</code> returns
221: * <code>{"/catalog/index.html", "/catalog/products.html", "/catalog/offers/"}</code>.<br>
222: *
223: * @param path the partial path used to match the resources, which must start with a slash
224: * @return a Set containing the directory listing, or <code>null</code> if there
225: * are no resources in the web application of which the path
226: * begins with the supplied path.
227: */
228: public java.util.Set getResourcePaths(String path) {
229: return context.getResourcePaths(path);
230: }
231:
232: /**
233: * Returns a URL to the resource that is mapped to a specified
234: * path. The path must begin with a slash (<code>/</code>) and is interpreted
235: * as relative to the current context root.
236: * <p/>
237: * <p>This method allows the portlet container to make a resource
238: * available to portlets from any source. Resources
239: * can be located on a local or remote
240: * file system, in a database, or in a <code>.war</code> file.
241: * <p/>
242: * <p>The portlet container must implement the URL handlers
243: * and <code>URLConnection</code> objects that are necessary
244: * to access the resource.
245: * <p/>
246: * <p>This method returns <code>null</code>
247: * if no resource is mapped to the pathname.
248: * <p/>
249: * <p>Some containers may allow writing to the URL returned by
250: * this method using the methods of the URL class.
251: * <p/>
252: * <p>The resource content is returned directly, so be aware that
253: * requesting a <code>.jsp</code> page returns the JSP source code.
254: * Use a <code>RequestDispatcher</code> instead to include results of
255: * an execution.
256: * <p/>
257: * <p>This method has a different purpose than
258: * <code>java.lang.Class.getResource</code>,
259: * which looks up resources based on a class loader. This
260: * method does not use class loaders.
261: *
262: * @param path a <code>String</code> specifying
263: * the path to the resource
264: * @return the resource located at the named path,
265: * or <code>null</code> if there is no resource
266: * at that path
267: * @throws java.net.MalformedURLException if the pathname is not given in
268: * the correct form
269: */
270: public java.net.URL getResource(String path)
271: throws java.net.MalformedURLException {
272: if (path == null || !path.startsWith("/")) {
273: throw new MalformedURLException(
274: "path must start with a '/'");
275: }
276: return context.getResource(path);
277: }
278:
279: /**
280: * Returns the portlet container attribute with the given name,
281: * or null if there is no attribute by that name.
282: * An attribute allows a portlet container to give the
283: * portlet additional information not
284: * already provided by this interface.
285: * A list of supported attributes can be retrieved using
286: * <code>getAttributeNames</code>.
287: * <p/>
288: * <p>The attribute is returned as a <code>java.lang.Object</code>
289: * or some subclass.
290: * Attribute names should follow the same convention as package
291: * names. The Java Portlet API specification reserves names
292: * matching <code>java.*</code>, <code>javax.*</code>,
293: * and <code>sun.*</code>.
294: *
295: * @param name a <code>String</code> specifying the name
296: * of the attribute
297: * @return an <code>Object</code> containing the value
298: * of the attribute, or <code>null</code>
299: * if no attribute exists matching the given
300: * name
301: * @exception IllegalArgumentException if name is <code>null</code>.
302: * @see #getAttributeNames
303: */
304: public Object getAttribute(String name) {
305: if (name == null)
306: throw new IllegalArgumentException("name is NULL");
307: return context.getAttribute(name);
308: }
309:
310: /**
311: * Returns an <code>Enumeration</code> containing the attribute names
312: * available within this portlet context, or an emtpy
313: * <code>Enumeration</code> if no attributes are available. Use the
314: * {@link #getAttribute} method with an attribute name
315: * to get the value of an attribute.
316: *
317: * @return an <code>Enumeration</code> of attribute names
318: * @see #getAttribute
319: */
320: public java.util.Enumeration getAttributeNames() {
321: return context.getAttributeNames();
322: }
323:
324: /**
325: * Returns a String containing the value of the named context-wide
326: * initialization parameter, or <code>null</code> if the parameter does not exist.
327: * This method provides configuration information which may be useful for
328: * an entire "portlet application".
329: *
330: * @return a <code>String</code> containing the value
331: * of the initialization parameter, or
332: * <code>null</code> if the parameter does not exist.
333: * @param name a <code>String</code> containing the name of the
334: * requested parameter
335: * @exception IllegalArgumentException if name is <code>null</code>.
336: * @see #getInitParameterNames
337: */
338: public String getInitParameter(String name) {
339: if (name == null)
340: throw new IllegalArgumentException("name is NULL!");
341: return context.getInitParameter(name);
342: }
343:
344: /**
345: * Returns the names of the context initialization parameters as an
346: * <code>Enumeration</code> of String objects, or an empty Enumeration if the context
347: * has no initialization parameters.
348: *
349: * @return an <code>Enumeration</code> of <code>String</code>
350: * objects containing the names of the context
351: * initialization parameters
352: * @see #getInitParameter
353: */
354:
355: public java.util.Enumeration getInitParameterNames() {
356: return context.getInitParameterNames();
357: }
358:
359: /**
360: * Writes the specified message to a portlet log file, usually an event log.
361: * The name and type of the portlet log file is specific to the portlet container.
362: * <p/>
363: * This method mapps to the <code>ServletContext.log</code> method.
364: * The portlet container may in addition log this message in a
365: * portlet container specific log file.
366: *
367: * @param msg a <code>String</code> specifying the
368: * message to be written to the log file
369: */
370:
371: public void log(String msg) {
372: context.log(msg);
373: }
374:
375: /**
376: * Writes an explanatory message and a stack trace for a given
377: * Throwable exception to the portlet log file.
378: * The name and type of the portlet log file is specific to the
379: * portlet container, usually an event log.
380: * <p/>
381: * This method is mapped to the <code>ServletContext.log</code> method.
382: * The portlet container may in addition log this message in a
383: * portlet container specific log file.
384: *
385: * @param message a <code>String</code> that
386: * describes the error or exception
387: * @param throwable the <code>Throwable</code> error
388: * or exception
389: */
390:
391: public void log(String message, Throwable throwable) {
392: context.log(message, throwable);
393: }
394:
395: /**
396: * Removes the attribute with the given name from the portlet context.
397: * After removal, subsequent calls to
398: * {@link #getAttribute} to retrieve the attribute's value
399: * will return <code>null</code>.
400: *
401: * @param name a <code>String</code> specifying the name
402: * of the attribute to be removed
403: * @exception IllegalArgumentException if name is <code>null</code>.
404: */
405:
406: public void removeAttribute(String name) {
407: if (name == null)
408: throw new IllegalArgumentException("name is NULL");
409: context.removeAttribute(name);
410: }
411:
412: /**
413: * Binds an object to a given attribute name in this portlet context.
414: * If the name specified is already used for an attribute, this method
415: * removes the old attribute and binds the name to the new attribute.
416: * <p/>
417: * If a null value is passed, the effect is the same as calling
418: * <code>removeAttribute()</code>.
419: * <p/>
420: * <p>Attribute names should follow the same convention as package
421: * names. The Java Portlet API specification reserves names
422: * matching <code>java.*</code>, <code>javax.*</code>, and
423: * <code>sun.*</code>.
424: *
425: * @param name a <code>String</code> specifying the name
426: * of the attribute
427: * @param object an <code>Object</code> representing the
428: * attribute to be bound
429: * @exception IllegalArgumentException if name is <code>null</code>.
430: */
431:
432: public void setAttribute(String name, Object object) {
433: if (name == null)
434: throw new IllegalArgumentException("name is NULL");
435: context.setAttribute(name, object);
436: }
437:
438: /**
439: * Returns the name of this portlet application correponding to this PortletContext as specified
440: * in the <code>web.xml</code> deployment descriptor for this web application by the
441: * <code>display-name</code> element.
442: *
443: * @return The name of the web application or null if no name has been declared in the deployment descriptor.
444: */
445:
446: public String getPortletContextName() {
447: return context.getServletContextName();
448: }
449:
450: }
|