KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > portal > generic > PortletConnection


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution, if
19  * any, must include the following acknowlegement:
20  * "This product includes software developed by the
21  * Caucho Technology (http://www.caucho.com/)."
22  * Alternately, this acknowlegement may appear in the software itself,
23  * if and wherever such third-party acknowlegements normally appear.
24  *
25  * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * info@caucho.com.
29  *
30  * 5. Products derived from this software may not be called "Resin"
31  * nor may "Resin" appear in their names without prior written
32  * permission of Caucho Technology.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37  * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  * @author Sam
47  */

48
49
50 package com.caucho.portal.generic;
51
52 import com.caucho.portal.generic.context.ConnectionContext;
53
54 import javax.portlet.PortletException;
55 import javax.portlet.PortletRequest;
56 import javax.portlet.PortletSecurityException;
57 import javax.portlet.PortletSession;
58 import java.io.BufferedReader JavaDoc;
59 import java.io.IOException JavaDoc;
60 import java.io.InputStream JavaDoc;
61 import java.io.OutputStream JavaDoc;
62 import java.io.PrintWriter JavaDoc;
63 import java.io.UnsupportedEncodingException JavaDoc;
64 import java.security.Principal JavaDoc;
65 import java.util.Enumeration JavaDoc;
66 import java.util.Locale JavaDoc;
67 import java.util.Set JavaDoc;
68 import java.util.logging.Level JavaDoc;
69 import java.util.logging.Logger JavaDoc;
70
71
72 /**
73  * A PortletConnection is used to obtain {@link Action} and {@link Render}
74  * objects.
75  *
76  * For implementations that support only one portlet for each connection,
77  * the pattern of use is:
78  *
79  * <pre>
80  * Window window = ...;
81  * Portlet portlet = ...;
82  *
83  * Action action = connection.getAction(window);
84  *
85  * if (action != null) {
86  * try {
87  * if (action.isTarget())
88  * action.processAction(portlet);
89  * }
90  * finally {
91  * action.finish();
92  * }
93  * }
94  *
95  * Render render = connection.getRender(window);
96  *
97  * if (render != null) {
98  * try {
99  * render.render(portlet);
100  * }
101  * finally {
102  * render.finish();
103  * }
104  * }
105  *
106  * </pre>
107  *
108  * For implementations that support more than one portlet for each connection,
109  * each portlet is identified with a namespace. An optional Renderer is
110  * specified, it is used to obtain a Writer or OutputStream when the portlet
111  * requests it.
112  *
113  * <pre>
114  * Window window = ...;
115  * Portlet portlet = ...;
116  * String namespace = "...";
117  *
118  * Action action = connection.getAction(window, namespace);
119  *
120  * if (action != null) {
121  * try {
122  * if (action.isTarget())
123  * action.processAction(portlet);
124  * }
125  * finally {
126  * action.finish();
127  * }
128  * }
129  *
130  * Render render = connection.getRender(window, namespace);
131  *
132  * if (render != null) {
133  * try {
134  * render.render(portlet);
135  * }
136  * finally {
137  * render.finish();
138  * }
139  * }
140  *
141  * </pre>
142  *
143  * @see PortletConnection#getAction
144  * @see PortletConnection#getRender
145  * @see Action
146  * @see Render
147  *
148  */

149 abstract public class PortletConnection
150 {
151   /**
152    * Name of the request attribute that stores the connection
153    */

154   public static final String JavaDoc PORTLET_CONNECTION
155     = "com.caucho.portal.generic.PortletConnection";
156
157   /**
158    * Return the connection that corresponds to the PortletRequest
159    */

160   public static PortletConnection getConnection(PortletRequest portletRequest)
161   {
162     return (PortletConnection) portletRequest.getAttribute(PORTLET_CONNECTION);
163   }
164
165   /**
166    * Return the Portal that corresponds to the PortletRequest, or null
167    * if there is not a current Portal or Connection.
168    */

169   public static Portal getPortal(PortletRequest portletRequest)
170   {
171     PortletConnection connection = getConnection(portletRequest);
172
173     if (connection == null)
174       return null;
175     else
176       return connection.getPortal();
177   }
178
179   /**
180    * Return the Action that corresponds to the PortletRequest, or null
181    * if there is not a current Action or Connection.
182    */

183   public static Action getAction(PortletRequest portletRequest)
184   {
185     PortletConnection connection = getConnection(portletRequest);
186
187     if (connection == null)
188       return null;
189     else
190       return connection.getCurrentAction();
191   }
192
193   /**
194    * Return the Render that corresponds to the PortletRequest, or null
195    * if there is not a current Render or Connection.
196    */

197   public static Render getRender(PortletRequest portletRequest)
198   {
199     PortletConnection connection = getConnection(portletRequest);
200
201     if (connection == null)
202       return null;
203     else
204       return connection.getCurrentRender();
205   }
206
207   // --
208

209   static final public Logger JavaDoc log =
210     Logger.getLogger(PortletConnection.class.getName());
211
212   private static int _connectionCount = 10;
213
214   private ConnectionContext _context;
215
216   private String JavaDoc _connectionId;
217
218   private Portal _portal;
219
220   private boolean _connectionFailed;
221   private Exception JavaDoc _connectionFailedCause;
222
223   protected PortletConnection()
224   {
225     int id = _connectionCount++;
226     _connectionId = Integer.toString(id, Character.MAX_RADIX);
227     _context = new ConnectionContext(this);
228   }
229
230   /**
231    * A unique identifier for this connection object, used for debugging
232    */

233   public String JavaDoc getId()
234   {
235     return _connectionId;
236   }
237
238   public void start(Portal portal, InvocationFactory invocationFactory)
239   {
240     if (_portal != null)
241       throw new IllegalStateException JavaDoc("missing finish()?");
242
243     _portal = portal;
244
245     _context.start(invocationFactory);
246   }
247
248   public void finish()
249   {
250     _context.finish();
251     _portal = null;
252     _connectionFailedCause = null;
253     _connectionFailed = false;
254   }
255
256   public Portal getPortal()
257   {
258     return _portal;
259   }
260
261   /**
262    * Used to indicate that the connection has failed. A connection fails if an
263    * unrecoverable error occurs.
264    */

265   public void setConnectionFailed()
266   {
267     if (!_connectionFailed) {
268       PortletException ex = new PortletException("connection failed");
269       setConnectionFailed(ex);
270     }
271   }
272
273   /**
274    * Used to indicate that the connection has failed. A connection fails if an
275    * unrecoverable error occurs.
276    */

277   public void setConnectionFailed(Exception JavaDoc ex)
278   {
279     if (!_connectionFailed) {
280       _connectionFailed = true;
281       _connectionFailedCause = ex;
282
283       log.log(Level.FINE, ex.toString(), ex);
284     }
285   }
286
287   /**
288    * A connection fails if an unrecoverable error occurs.
289    */

290   public boolean isConnectionFailed()
291   {
292     return _connectionFailed;
293   }
294
295   /**
296    * Handle a constraint failure by sending some response to the client.
297    *
298    * @return false if the connection cannot handle the constraint failure.
299    */

300   abstract public boolean handleConstraintFailure( Constraint constraint,
301                                                    int failureCode )
302     throws IOException JavaDoc;
303
304   /**
305    * Handle an exception by sending some response to the client.
306    *
307    * @return false if the connection cannot handle the constraint failure.
308    */

309   abstract public boolean handleException(Exception JavaDoc exception);
310
311   /**
312    * Return true if the connection can guarantee integrity
313    * (preventing data tampering in the communication process).
314    */

315   abstract public boolean canGuaranteeIntegrity();
316
317   /**
318    * Return true if the connection can guarantee confidentiality (preventing
319    * reading while in transit).
320    */

321   abstract public boolean canGuaranteeConfidentiality();
322
323   /**
324    * Set an attribute for the current connection. Attributes are name/value
325    * pairs that are valid for the duration of one connection.
326    */

327   abstract public void setAttribute(String JavaDoc name, Object JavaDoc o);
328
329   /**
330    * Get an attribute for the current connection. Attributes are name/value
331    * pairs that are valid for the duration of one connection.
332    */

333   abstract public Object JavaDoc getAttribute(String JavaDoc name);
334
335   /**
336    * Remove an attribute for the current connection. Attributes are name/value
337    * pairs that are valid for the duration of one connection.
338    */

339   abstract public void removeAttribute(String JavaDoc name);
340
341   /**
342    * Get a list of all attributes for the current connection. Attributes are
343    * name/value pairs that are valid for the duration of one connection.
344    *
345    * @return an Enumeration of String
346    */

347   abstract public Enumeration JavaDoc getAttributeNames();
348
349   /**
350    * Return a {@link PortletSession} for the current client, or null if one is
351    * not available.
352    *
353    * A PortletSession once established will be consistently returned for a
354    * client on subsequent requests. Different clients will never have the same
355    * PortletSession.
356    *
357    * @param create, if true create a new session if one does not already exist
358    * for the client.
359    */

360   abstract public PortletSession getPortletSession(boolean create);
361
362   /**
363    * Return the scheme portion of the url that was used to make the request.
364    *
365    * @see javax.portlet.PortletRequest#getScheme
366    */

367   abstract public String JavaDoc getScheme();
368
369   /**
370    * Return the host name portion of the url that was used to make the request.
371    *
372    * @see javax.portlet.PortletRequest#getServerName
373    */

374   abstract public String JavaDoc getServerName();
375
376   /**
377    * Return the port portion of the url that was used to make the request.
378    *
379    * @see javax.portlet.PortletRequest#getServerPort
380    */

381   abstract public int getServerPort();
382
383   /**
384    * Return the path to the portal portion of the url that was used to make the
385    * request.
386    *
387    * @see javax.portlet.PortletRequest#getContextPath
388    */

389   abstract public String JavaDoc getContextPath();
390
391   /**
392    * Return the authentication scheme used for the current request.
393    *
394    * @return PortletRequest.BASIC_AUTH, PortletRequest.CLIENT_CERT_AUTH,
395    * PortletRequest.DIGEST_AUTH, PortletRequest.FORM_AUTH, or a custom method.
396    *
397    * @see javax.portlet.PortletRequest#getAuthType
398    */

399   abstract public String JavaDoc getAuthType();
400
401   /**
402    * Return true if the connection for the current request is secure, for
403    * example it uses HTTPS.
404    *
405    * @see javax.portlet.PortletRequest#isSecure
406    */

407   abstract public boolean isSecure();
408
409   /**
410    * Return the session id that was supplied by the client for the current
411    * request.
412    *
413    * @see javax.portlet.PortletRequest#getRequestedSessionId
414    */

415   abstract public String JavaDoc getRequestedSessionId();
416
417   /**
418    * Return true the session id that was supplied by the client for the current
419    * request is valid.
420    *
421    * @see javax.portlet.PortletRequest#isRequestedSessionIdValid
422    */

423   abstract public boolean isRequestedSessionIdValid();
424
425   /**
426    * Return the identity of the remote user, null if the identity has not been
427    * established.
428    *
429    * @see javax.portlet.PortletRequest#getRemoteUser
430    */

431   abstract public String JavaDoc getRemoteUser();
432
433   /**
434    * Return a {@link java.security.Principal} that contains the identity of
435    * the remote user, null if the identity has not been established.
436    *
437    * @see javax.portlet.PortletRequest#getUserPrincipal
438    */

439   abstract public Principal JavaDoc getUserPrincipal();
440
441   /**
442    * Return true if the identity of remote user has been established and the
443    * user has been assigned the role.
444    *
445    * @see javax.portlet.PortletRequest#isUserInRole
446    */

447   abstract public boolean isUserInRole(String JavaDoc role);
448
449   /**
450    * Return the value of the specified connection property as a String, null
451    * if the property was not provided by the request from the client.
452    *
453    * "properties" correspond to HTTP headers in the request for HTTP
454    * connections.
455    *
456    * @see javax.portlet.PortletRequest#getProperty
457    */

458   abstract public String JavaDoc getProperty(String JavaDoc propertyName);
459
460   /**
461    * Return the values of the specified connection property as an array of
462    * Strings, null if the property was not provided by the request from the
463    * client.
464    *
465    * "properties" correspond to HTTP headers in the request for HTTP
466    * connections.
467    *
468    * @return an Enumeration of String
469    *
470    * @see javax.portlet.PortletRequest#getProperties
471    */

472   abstract public Enumeration JavaDoc getProperties(String JavaDoc propertyName);
473
474   /**
475    * Return the names of available properties for the connection.
476    *
477    * "properties" correspond to HTTP headers in the request for HTTP
478    * connections.
479    *
480    * @return an Enumeration of String
481    *
482    * @see javax.portlet.PortletRequest#getPropertyNames
483    */

484   abstract public Enumeration JavaDoc getPropertyNames();
485
486   /**
487    * Get the content types acceptable to the client. The returned Set
488    * is ordered, the most preferrable content types appear before the least
489    * preferred.
490    *
491    * A return of null or an empty Set indicates that the client content types
492    * cannot be determiend, and is treated as an indication that any locale is
493    * acceptable.
494    */

495   abstract public Set JavaDoc<String JavaDoc> getClientContentTypes();
496
497   /**
498    * Get the locales acceptable to the client. The returned Set is ordered,
499    * the most preferrable locale appears before the least preferred. If the
500    * client supports all locales, then a Locale("","","") will be present in
501    * the returned Set.
502    *
503    * A return of null or an empty Set indicates that the client locales cannot
504    * be determiend, and is treated as an indication that any locale is
505    * acceptable.
506    */

507   abstract public Set JavaDoc<Locale JavaDoc> getClientLocales();
508
509   /**
510    * Get the character encodings acceptable to the client. The returned Set is
511    * order, the most preferrable character encoding appears before the least
512    * preferred.
513    *
514    * A return of null or an empty Set indicates that the client character
515    * encodings cannot be determiend, and is treated as an indication that any
516    * locale is
517    * acceptable.
518    */

519   abstract public Set JavaDoc<String JavaDoc> getClientCharacterEncodings();
520
521   /**
522    * Return the MIME type of the data supplied as the "body" of the request,
523    * null if not known.
524    *
525    * @see javax.portlet.ActionRequest#getContentType
526    */

527   abstract public String JavaDoc getSubmitContentType();
528
529   /**
530    * Return the length of of the data supplied as the "body" of the request,
531    * -1 if not known.
532    *
533    * @see javax.portlet.ActionRequest#getContentLength
534    */

535   abstract public int getSubmitContentLength();
536
537   /**
538    * Return the binary body of the current request.
539    *
540    * @throws IllegalStateException if getReader() has already been
541    * called for this connection.
542    *
543    * @throws IOException
544    *
545    * @see javax.portlet.ActionRequest#getPortletInputStream
546    */

547   abstract public InputStream JavaDoc getSubmitInputStream()
548     throws IOException JavaDoc, IllegalStateException JavaDoc;
549
550   /**
551    * Override the character encoding used by the Reader obtained
552    * using {@link #getReader}. This method must be called prior to reading
553    * input using {@link #getReader} or {@link #getPortletInputStream}.
554    *
555    * @throws UnsupportedEncodingException
556    *
557    * @throws IllegalStateException if getReader() has already been called for
558    * this connection.
559    *
560    * @see javax.portlet.ActionRequest#setCharacterEncoding
561    */

562   abstract public void setSubmitCharacterEncoding(String JavaDoc enc)
563     throws UnsupportedEncodingException JavaDoc, IllegalStateException JavaDoc;
564
565   /**
566    * Return the name of the character encoding that will be used by the Reader
567    * obtained using {@link #getReader}, null if none.
568    *
569    * @see javax.portlet.ActionRequest#getCharacterEncoding
570    */

571   abstract public String JavaDoc getSubmitCharacterEncoding();
572
573   abstract public BufferedReader JavaDoc getSubmitReader()
574     throws UnsupportedEncodingException JavaDoc, IOException JavaDoc;
575
576   /**
577    * Encode a url with any special encoding needed by the protocol,
578    * for example by adding a sesison id.
579    */

580   abstract public String JavaDoc encodeURL(String JavaDoc path);
581
582   /**
583    * Resolve a url so that it makes a request to the portal
584    */

585   abstract public String JavaDoc resolveURL(String JavaDoc partialUrl);
586
587   /**
588    * Resolve a url so that it makes a request to the portal with
589    * the specified level of security.
590    */

591   abstract public String JavaDoc resolveURL(String JavaDoc partialUrl, boolean isSecure)
592     throws PortletSecurityException;
593
594
595   abstract public void sendRedirect(String JavaDoc location)
596     throws IllegalStateException JavaDoc, IOException JavaDoc;
597
598   /**
599    * Set a property to be returned to the client.
600    *
601    * "properties" correspond to HTTP headers in the response for HTTP
602    * connections.
603    *
604    * @see javax.portlet.PortletResponse#setProperty
605    */

606   abstract public void setProperty(String JavaDoc name, String JavaDoc value);
607
608   /**
609    * Add a value to a property to be returned to the client.
610    *
611    * "properties" correspond to HTTP headers in the response for HTTP
612    * connections.
613    *
614    * @see javax.portlet.PortletResponse#addProperty
615    */

616   abstract public void addProperty(String JavaDoc name, String JavaDoc value);
617
618   
619   /**
620    * Set the content type to use for the response.
621    */

622   abstract public void setContentType(String JavaDoc contentType);
623
624   /**
625    * Return the content type established with setContentType(), or null if
626    * setContentType() has not been called.
627    */

628   abstract public String JavaDoc getContentType();
629
630   /**
631    * Set the locale to use for the response.
632    */

633   abstract public void setLocale(Locale JavaDoc locale);
634
635   /**
636    * Return the Locale established with setLocale(), or null if setLocale()
637    * has not been called.
638    */

639   abstract public Locale JavaDoc getLocale();
640
641   abstract public void setBufferSize(int size);
642
643   abstract public int getBufferSize();
644
645   abstract public void flushBuffer()
646     throws IOException JavaDoc;
647
648   abstract public void resetBuffer();
649
650   abstract public void reset();
651
652   abstract public boolean isCommitted();
653
654   /**
655    * @throws IllegalStatementException if the content type has not been set
656    * with setContentType.
657    */

658   abstract public OutputStream JavaDoc getOutputStream()
659     throws IOException JavaDoc;
660
661   abstract public String JavaDoc getCharacterEncoding();
662
663   abstract public void setCharacterEncoding(String JavaDoc enc)
664     throws UnsupportedEncodingException JavaDoc;
665
666   /**
667     * @throws IllegalStatementException if the content type has not been set
668     * with setContentType.
669     */

670   abstract public PrintWriter JavaDoc getWriter()
671     throws IOException JavaDoc;
672
673
674   /**
675    * Get an Action for a namespace.
676    * Return null if the action stage for the request is complete
677    * or there is some other reason that the window and it's children
678    * should not proceed further in the action stage.
679    *
680    * @throws PortletException if the namespace has already been seen in the
681    * actionstagephase of this connection
682    */

683   public Action getAction( Window window, String JavaDoc namespace )
684     throws PortletException, IOException JavaDoc
685   {
686     return _context.getAction(window, namespace);
687   }
688
689   /**
690    * Get the current Action object, established from a call to getRender().
691    */

692   public Action getCurrentAction()
693   {
694     return _context.getCurrentAction();
695   }
696
697   /**
698    * Get a Render for a namespace.
699    * Return null if there is some reason that the window and it's children
700    * should not be rendered.
701    *
702    * @throws PortletException if the namespace has already been seen in the
703    * render phase of this connection
704    */

705   public Render getRender( Window window, String JavaDoc namespace )
706     throws PortletException, IOException JavaDoc
707   {
708     return _context.getRender(window, namespace);
709   }
710
711   /**
712    * Get the current Render object, established from a call to getRender().
713    */

714   public Render getCurrentRender()
715   {
716     return _context.getCurrentRender();
717   }
718
719
720   /**
721    * Throw an exception if an error was encountered when using this conneciton.
722    */

723   public void checkForFailure()
724     throws PortletException
725   {
726     if (_connectionFailed) {
727       if (_connectionFailedCause == null)
728         throw new PortletException("connection failed");
729       else
730         throw new PortletException(
731             "connection failed: " + _connectionFailedCause.toString(),
732             _connectionFailedCause );
733     }
734   }
735
736   /**
737    * Used in derived classes during finish() to determine if
738    * the response is private
739    */

740   protected boolean isPrivate()
741   {
742     return _context.isConnectionPrivate();
743   }
744
745   /**
746    * Used in derived classes during finish() to determine
747    * the maximum expires time for the connection, derived classes use this
748    * value to send an expires timeout to the client.
749    * -1 means never expire, 0 means expire immediately, otherwise it is a
750    * number in seconds.
751    */

752   protected int getExpirationCache()
753   {
754     return _context.getConnectionExpirationCache();
755   }
756
757 }
758
759
Popular Tags