KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > portal > generic > context > ConnectionContext


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
51 package com.caucho.portal.generic.context;
52
53 import com.caucho.portal.generic.*;
54
55 import javax.portlet.*;
56 import java.io.BufferedReader JavaDoc;
57 import java.io.IOException JavaDoc;
58 import java.io.InputStream JavaDoc;
59 import java.io.OutputStream JavaDoc;
60 import java.io.PrintWriter JavaDoc;
61 import java.io.UnsupportedEncodingException JavaDoc;
62 import java.util.*;
63 import java.util.logging.Level JavaDoc;
64 import java.util.logging.Logger JavaDoc;
65
66
67 /**
68  * ConnectionContext tracks the state of a PortletConnection and provides
69  * methods for all operations that affect the connection.
70  *
71  * InterfaceImpl classes implement interfaces and delegate all operations to
72  * the ConnectionContext.
73  *
74  * <ul>
75  * <li>{@link com.caucho.portal.generic.context.ActionImpl}
76  * <li>{@link com.caucho.portal.generic.context.RenderImpl}
77  * <li>{@link com.caucho.portal.generic.context.PortalRequestImpl}
78  * <li>{@link com.caucho.portal.generic.context.PortalResponseImpl}
79  * </ul>
80  *
81  * <ul>
82  * <li>{@link com.caucho.portal.generic.context.PortletRequestImpl}
83  * <li>{@link com.caucho.portal.generic.context.PortletResponseImpl}
84  * <li>{@link com.caucho.portal.generic.context.ActionRequestImpl}
85  * <li>{@link com.caucho.portal.generic.context.ActionResponseImpl}
86  * <li>{@link com.caucho.portal.generic.context.RenderRequestImpl}
87  * <li>{@link com.caucho.portal.generic.context.RenderResponseImpl}
88  * </ul>
89  *
90  * Some of the state of the connection depends on the "current window". The
91  * ConnectionContext maintains a stack of {@link WindowContext}.
92  */

93 public class ConnectionContext {
94   private static final Logger JavaDoc log = PortletConnection.log;
95
96   private static final String JavaDoc EXPIRATION_CACHE
97     = "javax.portlet.expirationCache";
98
99   private static final String JavaDoc RENDER_REQUEST
100     = "javax.portlet.renderRequest";
101
102   private static final String JavaDoc RENDER_RESPONSE
103     = "javax.portlet.renderResponse";
104
105   private static final String JavaDoc PORTLET_CONFIG
106     = "javax.portlet.portletConfig";
107
108   private static final Locale LOCALE_ANY = new Locale("", "", "");
109
110   ActionImpl _action = new ActionImpl(this);
111   RenderImpl _render = new RenderImpl(this);
112   PortalRequestImpl _portalRequest = new PortalRequestImpl(this);
113   PortalResponseImpl _portalResponse = new PortalResponseImpl(this);
114
115   PortletRequestImpl _portletRequest = new PortletRequestImpl(this);
116   PortletResponseImpl _portletResponse = new PortletResponseImpl(this);
117   ActionRequestImpl _actionRequest = new ActionRequestImpl(this);
118   ActionResponseImpl _actionResponse = new ActionResponseImpl(this);
119   RenderRequestImpl _renderRequest = new RenderRequestImpl(this);
120   RenderResponseImpl _renderResponse = new RenderResponseImpl(this);
121
122   final static int STAGE_START = 1;
123   final static int STAGE_ACTION = 2;
124   final static int STAGE_DONEACTION = 3;
125   final static int STAGE_RENDER = 4;
126   final static int STAGE_DONE = 5;
127
128   private PortletConnection _connection;
129
130   private InvocationFactory _invocationFactory;
131   private TopLevelResponseHandler _topLevelResponseHandler;
132
133   int _connectionExpirationCache = -1;
134   boolean _connectionIsPrivate = false;
135   private boolean _forbidRedirect;
136
137   private PreferencesStore _preferencesStore;
138   private UserAttributeStore _userAttributeStore;
139
140   private int _stage = STAGE_START;
141
142   private Map<String JavaDoc, WindowContext> _windowContextMap
143     = new HashMap<String JavaDoc, WindowContext>();
144
145   private ArrayList<WindowContext> _windowContextStack
146     = new ArrayList<WindowContext>();
147
148   private WindowContext _windowContext; // current
149

150   public ConnectionContext(PortletConnection connection)
151   {
152     _connection = connection;
153
154     _topLevelResponseHandler = new TopLevelResponseHandler(connection, this);
155   }
156
157   public void start( InvocationFactory invocationFactory )
158   {
159     log(Level.FINER, "starting connection");
160
161     if (_stage != STAGE_START || _invocationFactory != null)
162       throw new IllegalStateException JavaDoc("missing finish()? " + _stage);
163
164     _invocationFactory = invocationFactory;
165   }
166
167   public void finish()
168   {
169     log(Level.FINEST, "finishing connection");
170
171     try {
172       for (int i = _windowContextStack.size() - 1; i >= 0; i--) {
173         try {
174           WindowContext windowContext = _windowContextStack.get(i);
175
176           if (windowContext != null)
177             finishWindowContext(windowContext);
178         }
179         catch (IOException JavaDoc ex) {
180           log(Level.WARNING, ex.toString(), ex);
181         }
182       }
183     }
184     finally {
185       _windowContextStack.clear();
186     }
187
188     _windowContextMap.clear();
189     _windowContext = null;
190     _stage = STAGE_START;
191     _forbidRedirect = false;
192     _preferencesStore = null;
193     _userAttributeStore = null;
194     _connection = null;
195
196     _invocationFactory = null;
197   }
198
199   /**
200    * finish a WindowContext that is no longer needed for this connection
201    */

202   private void finishWindowContext(WindowContext windowContext)
203     throws IOException JavaDoc
204   {
205     Map<String JavaDoc, String JavaDoc> userAttributeMap = windowContext.getUserAttributeMap();
206     LinkingPortletPreferences pref = windowContext.getPreferences();
207
208     windowContext.finish();
209
210     if (pref != null) {
211       Map<String JavaDoc, String JavaDoc[]> store = pref.getStore();
212       pref.finish();
213       getPreferencesStore().finish(store);
214     }
215
216     if (userAttributeMap != null) {
217       getUserAttributeStore().finish(userAttributeMap);
218     }
219   }
220
221   protected void log(Level JavaDoc level, String JavaDoc message)
222   {
223     if (!log.isLoggable(level))
224       return;
225
226     String JavaDoc namespace = _windowContext == null
227                         ? null
228                         : _windowContext.getNamespace();
229
230     log(namespace, level, message, null);
231   }
232
233   protected void log(Level JavaDoc level, String JavaDoc message, Exception JavaDoc ex)
234   {
235     if (!log.isLoggable(level))
236       return;
237
238     String JavaDoc namespace = _windowContext == null
239                         ? null
240                         : _windowContext.getNamespace();
241
242     log(namespace, level, message, ex);
243   }
244
245   protected void log(String JavaDoc namespace, Level JavaDoc level, String JavaDoc message)
246   {
247     if (!log.isLoggable(level))
248       return;
249
250     log(namespace, level, message, null);
251   }
252
253   protected void log(String JavaDoc namespace, Level JavaDoc level, String JavaDoc message, Exception JavaDoc ex)
254   {
255     if (log.isLoggable(level)) {
256       StringBuffer JavaDoc sb = new StringBuffer JavaDoc(256);
257
258       sb.append('[');
259
260       sb.append(_connection.getId());
261
262       if (namespace != null) {
263         sb.append(' ');
264         sb.append(namespace);
265       }
266
267       sb.append(']');
268
269       if (_stage == STAGE_ACTION)
270         sb.append('a');
271       else if (_stage == STAGE_RENDER)
272         sb.append('r');
273       else
274         sb.append(' ');
275
276       sb.append(' ');
277       sb.append(message);
278
279       if (ex == null)
280         log.log(level, sb.toString());
281       else
282         log.log(level, sb.toString(), ex);
283     }
284   }
285
286   protected PortletConnection getConnection()
287   {
288     return _connection;
289   }
290
291   protected InvocationFactory getInvocationFactory()
292   {
293     return _invocationFactory;
294   }
295
296   protected void setConnectionFailed(Exception JavaDoc ex)
297   {
298     _connection.setConnectionFailed(ex);
299   }
300
301   protected void setConnectionFailed()
302   {
303     _connection.setConnectionFailed();
304   }
305
306   protected boolean isConnectionFailed()
307   {
308     return _connection.isConnectionFailed();
309   }
310
311   public int getConnectionExpirationCache()
312   {
313     return _connectionExpirationCache;
314   }
315
316   protected void updateConnectionExpirationCache(int expirationCache)
317   {
318     if (_connectionExpirationCache != 0
319         && expirationCache >= 0
320         && _connectionExpirationCache < expirationCache)
321     {
322       _connectionExpirationCache = expirationCache;
323     }
324   }
325
326   public boolean isConnectionPrivate()
327   {
328     return _connectionIsPrivate;
329   }
330
331   protected void setConnectionPrivate()
332   {
333     _connectionIsPrivate = true;
334   }
335
336   protected void setForbidRedirect()
337   {
338     _forbidRedirect = true;
339   }
340
341   protected boolean isForbidRedirect()
342   {
343     return _forbidRedirect;
344   }
345
346   public PortalRequest getPortalRequest()
347   {
348     return _portalRequest;
349   }
350
351   public PortalResponse getPortalResponse()
352   {
353     return _portalResponse;
354   }
355
356   public Portal getPortal()
357   {
358     return _connection.getPortal();
359   }
360
361   public PortalContext getPortalContext()
362   {
363     return _connection.getPortal().getPortalContext();
364   }
365
366   protected PreferencesStore getPreferencesStore()
367   {
368     if (_preferencesStore == null)
369       _preferencesStore = getPortal().getPreferencesStore();
370
371     return _preferencesStore;
372   }
373
374   protected UserAttributeStore getUserAttributeStore()
375   {
376     if (_userAttributeStore == null)
377       _userAttributeStore = getPortal().getUserAttributeStore();
378
379     return _userAttributeStore;
380   }
381
382   private void pushStack(WindowContext windowContext)
383   {
384     _windowContextStack.add(_windowContext);
385
386     _windowContext = windowContext;
387   }
388
389   private void popStack()
390   {
391     try {
392       if (_windowContextStack.size() == 0)
393         throw new IllegalStateException JavaDoc(
394             "top of window stack reached, extra finish()?");
395
396       WindowContext windowContext = _windowContext;
397
398       _windowContext = null;
399
400       if (_stage == STAGE_RENDER)
401         finishWindowContext(windowContext);
402
403       _windowContext = _windowContextStack.remove( _windowContextStack.size() - 1 );
404     }
405     catch (Exception JavaDoc ex) {
406       setConnectionFailed(ex);
407     }
408   }
409
410   /**
411    * See if the Window can handle the exception. Return true
412    * if the exception has been handled in some way.
413    *
414    * Side-effect: might set windows.isExcluded to true
415    * might set window.setException to null if it is handled
416    */

417   protected void handleException()
418     throws PortletException, IOException JavaDoc
419   {
420     final Exception JavaDoc exception = _windowContext.getException();
421
422     if (exception == null)
423       return;
424
425     if (log.isLoggable(Level.FINER))
426       log(Level.FINER, "handling exception: " + exception.getClass().getName());
427
428     final WindowContext windowContext = _windowContext;
429
430     ExceptionEvent event = new ExceptionEvent() {
431       public Exception JavaDoc getException()
432       {
433         return exception;
434       }
435
436       public void setHandled(boolean hideWindow)
437       {
438         windowContext.setException(null);
439
440         if (hideWindow)
441           windowContext.setExcluded();
442       }
443
444       public boolean isHandled()
445       {
446         return !windowContext.isException();
447       }
448
449       public boolean isHideWindow()
450       {
451         return windowContext.isExcluded();
452       }
453     };
454
455     Window window = getWindow();
456
457     window.handleException( getRenderRequest(),
458                             getRenderResponse(),
459                             event );
460   }
461
462
463   /**
464    * Check for constraint failures and if any are encountered
465    * set the _windowContext appropriately.
466    */

467   protected void checkConstraints()
468   {
469     ArrayList<Constraint> constraints = getWindow().getConstraints();
470
471     if (constraints == null)
472       return;
473
474     if (log.isLoggable(Level.FINER))
475       log(Level.FINER, "checking constraints");
476
477     int startIndex = _windowContext.getConstraintIndex();
478
479     for (int i = startIndex; i < constraints.size(); i++) {
480       _windowContext.setConstraintIndex(i + 1);
481
482       Constraint constraint = constraints.get(i);
483
484       int result = constraint.check(getPortletRequest(), getPortletResponse());
485
486       if (result == Constraint.SC_PASS) {
487       }
488       else if (result == Constraint.SC_EXCLUDE) {
489         _windowContext.setExcluded();
490         if (log.isLoggable(Level.FINER))
491           log(Level.FINE, "constraint excludes window");
492
493         return;
494       }
495       else {
496         _windowContext.setConstraintFailure(constraint, result);
497
498         if (log.isLoggable(Level.FINER))
499           log(Level.FINE,
500               "constraint failed: " + constraint.getClass().getName());
501
502         return;
503       }
504     }
505   }
506
507   /**
508    * See if the Window can handle the constraint. Return true
509    * if the constraint has been handled in some way.
510    *
511    * Side-effect: might set isExcluded to true
512    */

513   protected boolean handleConstraintFailure()
514     throws PortletException, IOException JavaDoc
515   {
516     final Constraint constraint
517       = _windowContext.getConstraintFailureConstraint();
518
519     if (constraint == null)
520       return true;
521
522     if (log.isLoggable(Level.FINEST))
523       log(Level.FINEST,
524           "handling constraint failure: " + constraint.getClass().getName());
525
526     final WindowContext windowContext = _windowContext;
527
528     final int code = _windowContext.getConstraintFailureCode();
529
530     ConstraintFailureEvent event = new ConstraintFailureEvent() {
531       public Constraint getConstraint()
532       {
533         return constraint;
534       }
535
536       public int getStatusCode()
537       {
538         return code;
539       }
540
541       public void setHandled(boolean hideWindow)
542       {
543         windowContext.setConstraintFailure(null, 0);
544
545         if (hideWindow)
546           windowContext.setExcluded();
547       }
548
549       public boolean isHandled()
550       {
551         return !windowContext.isConstraintFailure();
552       }
553
554       public boolean isHideWindow()
555       {
556         return windowContext.isExcluded();
557       }
558     };
559
560     Window window = getWindow();
561
562     window.handleConstraintFailure( getRenderRequest(),
563                                     getRenderResponse(),
564                                     event );
565
566     return !windowContext.isConstraintFailure();
567   }
568
569   private boolean startActionOrRender( Window window,
570                                        String JavaDoc namespace,
571                                        boolean isActionStage )
572     throws PortletException, IOException JavaDoc
573   {
574     if (log.isLoggable(Level.FINEST)) {
575       log(Level.FINER, "portlet `" +
576           window.getPortletConfig().getPortletName()
577           + "' for namespace `" + namespace + "'");
578     }
579
580     if (_windowContext != null
581         &&
582         (_windowContext.isExcluded()
583          || _windowContext.getException() != null
584          || _windowContext.isConstraintFailure()))
585     {
586       if (log.isLoggable(Level.FINER))
587       {
588         if (_windowContext.isExcluded())
589           log(Level.FINER,
590               "child `" + namespace
591               + "' excluded because parent is excluded");
592         else if (_windowContext.isException())
593           log(Level.FINER,
594               "child `" + namespace
595               + "' excluded because parent has exception");
596         else if (_windowContext.isConstraintFailure())
597           log(Level.FINER,
598               "child `" + namespace
599               + "' excluded because parent has constraint failure");
600       }
601
602       return false;
603     }
604
605     boolean fail = true;
606
607     try {
608       boolean isTopLevel = _windowContextStack.size() == 0;
609
610       // reuse a WindowContext prepared in a previous stage or create a new one
611

612       WindowContext windowContext
613         = namespace == null ? null : _windowContextMap.get(namespace);
614
615       if (windowContext != null) {
616
617         if (isActionStage)
618           throw new PortletException(
619             "duplicate namespace `" + namespace + "'");
620
621         else if (windowContext.getWindow() != window)
622           throw new PortletException(
623                 "cannot have different Window"
624                 + " in render stage for namespace `" + namespace + "'");
625   
626         // check if windowContext was excluded in previous stage
627

628         if (windowContext.isExcluded()) {
629           if (log.isLoggable(Level.FINER))
630           {
631             if (_windowContext.isExcluded())
632               log(Level.FINER,
633                   "child `" + namespace + "' excluded in previous stage");
634           }
635
636           fail = false;
637           return false;
638         }
639       }
640       else {
641         windowContext = new WindowContext();
642
643         windowContext.start(window, namespace);
644
645         if (windowContext.getNamespace() != null) {
646           _windowContextMap.put(windowContext.getNamespace(), windowContext);
647
648           // prepare invocation
649

650           Invocation invocation
651             = getInvocationFactory().getInvocation(namespace);
652
653           windowContext.setInvocation(invocation);
654
655           if (invocation.isActionTarget()) {
656             log(Level.FINER, "action target");
657
658             Map<String JavaDoc, String JavaDoc[]> actionMap
659               = invocation.releaseParameterMap();
660
661             windowContext.setActionMap(actionMap);
662           }
663         }
664       }
665
666       // set the Context to work on the new namespace
667

668       pushStack(windowContext);
669
670       if (_windowContext.getNamespace() == null && log.isLoggable(Level.FINER))
671         log(Level.FINER, "no invocation for null namespace");
672
673       if (isActionStage) {
674         checkConstraints();
675
676         if (_windowContext.isConstraintFailure() || _windowContext.isExcluded())
677         {
678           popStack();
679           fail = false;
680           return false;
681         }
682       }
683
684       fail = false;
685     }
686     catch (PortletException ex) {
687       setConnectionFailed(ex);
688       throw ex;
689     }
690     catch (RuntimeException JavaDoc ex) {
691       setConnectionFailed(ex);
692       throw new PortletException(ex);
693     }
694     finally {
695       if (fail) {
696         setConnectionFailed();
697         return false;
698       }
699     }
700
701     return true;
702   }
703
704   public PortletRequest getPortletRequest()
705   {
706     return _portletRequest;
707   }
708
709   public PortletResponse getPortletResponse()
710   {
711     return _portletResponse;
712   }
713
714   public Action getAction( Window window,
715                            String JavaDoc namespace )
716     throws PortletException, IOException JavaDoc
717   {
718     if (isConnectionFailed())
719       return null;
720
721     if (_stage == STAGE_START) {
722       if (log.isLoggable(Level.FINER))
723         log(Level.FINER, "starting action stage");
724
725       _stage = STAGE_ACTION;
726     }
727     else if (_stage != STAGE_ACTION) {
728       IllegalStateException JavaDoc ex
729         = new IllegalStateException JavaDoc("missing finish()? " + _stage);
730
731       setConnectionFailed(ex);
732
733       throw ex;
734     }
735
736     if (!startActionOrRender(window, namespace, true))
737       return null;
738
739     return getCurrentAction();
740   }
741
742   public Action getCurrentAction()
743   {
744     return _stage == STAGE_ACTION ? _action : null;
745   }
746
747   public boolean isTarget()
748   {
749     return ( _stage == STAGE_ACTION
750              && _windowContext.getActionMap() != null
751              && !_windowContext.isExcluded() );
752
753   }
754
755   public ActionRequest getActionRequest()
756   {
757     if ( _stage != STAGE_ACTION || _windowContext.isExcluded() )
758       return null;
759     else
760       return _actionRequest;
761   }
762
763   public ActionResponse getActionResponse()
764   {
765     if ( _stage != STAGE_ACTION || _windowContext.isExcluded() )
766       return null;
767     else
768       return _actionResponse;
769   }
770
771   public void processAction(Portlet portlet)
772   {
773     if ( _stage != STAGE_ACTION )
774       throw new IllegalStateException JavaDoc("not in action stage");
775
776     if (log.isLoggable(Level.FINEST))
777       log(Level.FINEST, "processAction()");
778
779     try {
780       portlet.processAction(_actionRequest, _actionResponse);
781     }
782     catch (Exception JavaDoc ex) {
783       if (log.isLoggable(Level.FINE))
784         log(Level.FINE, ex.toString(), ex);
785
786       _windowContext.setException(ex);
787     }
788   }
789
790   void finishAction()
791     throws IOException JavaDoc, PortletException
792   {
793     boolean fail = true;
794
795     try {
796       if (_windowContext == null) {
797         throw new IllegalStateException JavaDoc(
798             "cannot finish action, at top of stack");
799       }
800
801       if (_stage != STAGE_ACTION && _stage != STAGE_DONEACTION) {
802         throw new IllegalStateException JavaDoc(
803             "cannot finish action for " + _windowContext.getNamespace()
804             + ", stage is " + _stage);
805       }
806
807       popStack();
808
809       if (_windowContext == null) {
810         _stage = STAGE_DONEACTION;
811
812         if (log.isLoggable(Level.FINER))
813           log(Level.FINER, "finishing action stage");
814       }
815
816       fail = false;
817     }
818     catch (RuntimeException JavaDoc ex) {
819       setConnectionFailed(ex);
820       throw ex;
821     }
822     finally {
823       if (fail)
824         setConnectionFailed();
825     }
826   }
827
828   // XXX: this is bogus, see comments in CacheKey.java
829
// about how the cache key should be built up.
830
// Basically, every WindowContext that has an expirationCache !=0
831
// should have a CacheKey that get's filled with the invocation
832
// for itself _and_ every child WindowContext during the action phase.
833

834   private CacheKey getCacheKey()
835   {
836     CacheKey cacheKey = null;
837
838     if (cacheKey == null)
839       cacheKey = new CacheKey();
840     else
841       cacheKey.reset();
842
843     WindowContext windowContext = _windowContext;
844
845     if (windowContext.getNamespace() == null)
846       return null;
847
848     cacheKey.setNamespace(windowContext.getNamespace());
849     cacheKey.setPortletMode(getPortletMode());
850     cacheKey.setWindowState(getWindowState());
851     cacheKey.setContentType(getResponseContentType());
852     cacheKey.setLocale(getResponseLocale());
853     cacheKey.setPrivate(windowContext.isPrivate());
854     cacheKey.setRequestedSessionId(_connection.getRequestedSessionId());
855
856     return null; // XXX:
857
}
858
859   /**
860    * Reset window specific attributes to null and return a map of the old
861    * values
862    */

863   private Map<String JavaDoc, String JavaDoc> resetWindowRequestAttributes()
864   {
865     Map<String JavaDoc, String JavaDoc> attr = null;
866
867     attr = getAttribute(attr, "javax.portlet.title", true);
868     attr = getAttribute(attr, "javax.portlet.short-title", true);
869     attr = getAttribute(attr, "javax.portlet.keywords", true);
870     attr = getAttribute(attr, "javax.portlet.description", true);
871
872     return attr;
873   }
874
875   /**
876    * Return a map of window specific request attributes, attributes with null
877    * values are not included, the return may be null.
878    */

879   private Map<String JavaDoc, String JavaDoc> getWindowRequestAttributes()
880   {
881     Map<String JavaDoc, String JavaDoc> attr = null;
882
883     attr = getAttribute(attr, "javax.portlet.title", false);
884     getAttribute(attr, "javax.portlet.short-title", false);
885     getAttribute(attr, "javax.portlet.keywords", false);
886     getAttribute(attr, "javax.portlet.description", false);
887
888     return attr;
889   }
890
891   private Map<String JavaDoc, String JavaDoc> getAttribute( Map<String JavaDoc, String JavaDoc> map,
892                                             String JavaDoc name,
893                                             boolean isReset )
894   {
895     String JavaDoc value = (String JavaDoc) _connection.getAttribute(name);
896
897     if (isReset || value != null) {
898       if (map == null)
899         map = new LinkedHashMap<String JavaDoc, String JavaDoc>();
900
901       map.put(name, value);
902
903       if (isReset)
904         _connection.removeAttribute(name);
905     }
906
907     return map;
908   }
909
910   private void restoreWindowRequestAttributes(Map<String JavaDoc, String JavaDoc> map)
911   {
912     if (map != null && !map.isEmpty()) {
913       Iterator<Map.Entry<String JavaDoc, String JavaDoc>> iter = map.entrySet().iterator();
914
915       do {
916         Map.Entry<String JavaDoc, String JavaDoc> entry = iter.next();
917         _connection.setAttribute(entry.getKey(), entry.getValue());
918       } while (iter.hasNext());
919     }
920   }
921
922   public Render getRender( Window window,
923                            String JavaDoc namespace )
924     throws PortletException, IOException JavaDoc
925   {
926     if (isConnectionFailed())
927       return null;
928
929     if (_stage == STAGE_START || _stage == STAGE_DONEACTION) {
930         if (log.isLoggable(Level.FINER))
931           log(Level.FINER, "starting render stage");
932
933       _stage = STAGE_RENDER;
934
935       _connection.setAttribute("javax.portlet.renderRequest", _renderRequest);
936       _connection.setAttribute("javax.portlet.renderResponse", _renderResponse);
937     }
938     else if (_stage != STAGE_RENDER) {
939       IllegalStateException JavaDoc ex
940         = new IllegalStateException JavaDoc("missing finish()? " + _stage);
941
942       setConnectionFailed(ex);
943
944       throw ex;
945     }
946
947     checkAlwaysWriteOrStream();
948
949     ResponseHandler parentResponseHandler
950       = _windowContext == null
951          ? _topLevelResponseHandler
952          : _windowContext.getResponseHandler();
953
954     if (!startActionOrRender(window, namespace, false))
955       return null;
956
957     // discard preferences from action stage
958

959     LinkingPortletPreferences pref = _windowContext.getPreferences();
960     if (pref != null)
961       pref.discard();
962
963
964     // response handler
965

966     _windowContext.setParentResponseHandler(parentResponseHandler);
967
968     ResponseHandler responseHandler = parentResponseHandler;
969
970     Renderer renderer = _windowContext.getWindow().getRenderer();
971
972     if (renderer != null) {
973       BufferFactory bufferFactory = getPortal().getBufferFactory();
974       int rendererBufferSize = renderer.getBufferSize();
975
976       if (bufferFactory != null && rendererBufferSize != 0) {
977
978         responseHandler = new BufferedResponseHandler( responseHandler,
979                                                        bufferFactory,
980                                                        rendererBufferSize );
981       }
982
983       responseHandler = new RendererResponseHandler( this,
984                                                      responseHandler,
985                                                      renderer,
986                                                      getRenderRequest(),
987                                                      getRenderResponse(),
988                                                      namespace );
989     }
990
991     int bufferSize = _windowContext.getWindow().getBufferSize();
992
993     if (bufferSize != 0) {
994       BufferFactory bufferFactory = getPortal().getBufferFactory();
995
996       if (bufferFactory != null) {
997         responseHandler = new BufferedResponseHandler( responseHandler,
998                                                        bufferFactory,
999                                                        bufferSize );
1000      }
1001    }
1002
1003    _windowContext.setResponseHandler(responseHandler);
1004
1005    boolean isPrivate = _windowContext.getWindow().isPrivate();
1006
1007    if (isPrivate) {
1008      _windowContext.setPrivate();
1009      setConnectionPrivate();
1010    }
1011
1012    // set request attributes
1013

1014    _connection.setAttribute( "javax.portlet.portletConfig",
1015                              getWindow().getPortletConfig());
1016
1017    Map<String JavaDoc, String JavaDoc> requestAttributes = resetWindowRequestAttributes();
1018
1019    _windowContext.setWindowRequestAttributes(requestAttributes);
1020
1021    // check for exception failures from previous stage
1022

1023    if (_windowContext.isException()) {
1024      if (log.isLoggable(Level.FINE))
1025        log(Level.FINE, "previous exception");
1026
1027      finishRender();
1028      return null;
1029    }
1030
1031    // constraints
1032

1033    if (!_windowContext.isConstraintFailure())
1034      checkConstraints();
1035
1036    if (_windowContext.isConstraintFailure())
1037    {
1038      if (!handleConstraintFailure()) {
1039        if (log.isLoggable(Level.FINE))
1040          log(Level.FINE,
1041              "constraint failure unhandled, propagating to parent");
1042      }
1043      else {
1044        if (log.isLoggable(Level.FINER)) {
1045          if (_windowContext.isExcluded())
1046            log(Level.FINER, "constraint failure handled, excluding");
1047          else
1048            log(Level.FINER, "constraint failure handled by window");
1049        }
1050      }
1051
1052      finishRender();
1053      return null;
1054    }
1055
1056    // XXX: cache caching
1057

1058    int expirationCache = _windowContext.getExpirationCache();
1059
1060
1061    if (expirationCache != 0
1062        && (!isPrivate || getRequestedSessionId() != null))
1063    {
1064      _windowContext.setExpirationCache(expirationCache);
1065    }
1066
1067    Cache cache = getPortal().getCache();
1068    CacheKey cacheKey = null;
1069        
1070    if (cache != null)
1071      cacheKey = getCacheKey();
1072
1073    if (cacheKey != null)
1074    {
1075      int result = cache.respondFromCache( cacheKey,
1076                                           getRenderRequest(),
1077                                           getRenderResponse() );
1078
1079      if (result != 0)
1080      {
1081        updateConnectionExpirationCache(result);
1082        return null;
1083      }
1084
1085      CachingResponseHandler cacheResponseHandler
1086        = new CachingResponseHandler( _windowContext.getResponseHandler(),
1087                                      cache,
1088                                      _windowContext.getNamespace(),
1089                                      _windowContext.getExpirationCache(),
1090                                      _windowContext.isPrivate() );
1091
1092      _windowContext.setResponseHandler(cacheResponseHandler);
1093    }
1094
1095    return getCurrentRender();
1096  }
1097
1098  public RenderRequest getRenderRequest()
1099  {
1100    if (_stage != STAGE_RENDER || _windowContext.isExcluded() )
1101      return null;
1102    else
1103      return _renderRequest;
1104  }
1105
1106  public RenderResponse getRenderResponse()
1107  {
1108    if (_stage != STAGE_RENDER || _windowContext.isExcluded() )
1109      return null;
1110    else
1111      return _renderResponse;
1112  }
1113
1114  public void render(Portlet portlet)
1115    throws PortletException, IOException JavaDoc
1116  {
1117    if ( _stage != STAGE_RENDER )
1118      throw new IllegalStateException JavaDoc("not in render stage");
1119
1120    if (log.isLoggable(Level.FINEST))
1121      log(Level.FINEST, "render()");
1122
1123    if (_windowContext.getException() == null
1124        && !_windowContext.isExcluded()
1125        && !_windowContext.isConstraintFailure())
1126    {
1127      try {
1128        portlet.render(getRenderRequest(), getRenderResponse());
1129      }
1130      catch (Exception JavaDoc ex) {
1131        if (log.isLoggable(Level.FINE))
1132          log(Level.FINE, ex.toString(), ex);
1133
1134        _windowContext.setException(ex);
1135
1136      }
1137    }
1138  }
1139
1140  public Render getCurrentRender()
1141  {
1142    return _stage == STAGE_RENDER ? _render : null;
1143  }
1144
1145  void finishRender()
1146    throws IOException JavaDoc, PortletException
1147  {
1148    boolean fail = true;
1149
1150    try {
1151      if (_windowContext == null) {
1152        throw new IllegalStateException JavaDoc(
1153            "cannot finish render, at top of stack");
1154      }
1155
1156      Map<String JavaDoc, String JavaDoc> requestAttributes
1157        = _windowContext.getWindowRequestAttributes();
1158
1159      if (_stage != STAGE_RENDER && _stage != STAGE_DONE) {
1160        throw new IllegalStateException JavaDoc(
1161            "cannot finish render for " + _windowContext.getNamespace()
1162            + ", stage is " + _stage);
1163      }
1164
1165      if (_windowContext.isException()) {
1166        try {
1167          reset(false); // do not resetRenderer
1168

1169          handleException();
1170
1171          if (log.isLoggable(Level.FINE)) {
1172            if (_windowContext.isException())
1173                log(Level.FINE, "exception unhandled, propagating to parent");
1174            else if (_windowContext.isExcluded())
1175              log(Level.FINER, "exception handled, excluding");
1176            else
1177              log(Level.FINER, "exception handled by window");
1178          }
1179        }
1180        catch (Exception JavaDoc ex) {
1181          log.log(Level.WARNING, ex.toString(), ex);
1182        }
1183      }
1184
1185      Exception JavaDoc exception = _windowContext.getException();
1186
1187      boolean isException = exception != null;
1188
1189      boolean isConstraintFailure = _windowContext.isConstraintFailure();
1190
1191      Constraint constraintFailureConstraint
1192        = _windowContext.getConstraintFailureConstraint();
1193
1194      int constraintFailureCode
1195        = _windowContext.getConstraintFailureCode();
1196
1197      boolean killResponse = _windowContext.isExcluded()
1198                             || isConstraintFailure
1199                             || isException;
1200
1201      
1202      if (killResponse) {
1203        if (log.isLoggable(Level.FINEST))
1204        {
1205          if (isException)
1206            log(Level.FINEST, "killResponse due to exception");
1207          else if (_windowContext.isConstraintFailure())
1208            log(Level.FINEST, "killResponse due to constraintFailure");
1209          else
1210            log(Level.FINEST, "killResponse");
1211        }
1212
1213        reset(true); // resetRenderer
1214
}
1215
1216      // unwind the write streams and finish() them
1217

1218      ResponseHandler parentResponseHandler
1219        = _windowContext.getParentResponseHandler();
1220
1221      CachingResponseHandler cacheResponseHandler = null;
1222
1223      ResponseHandler next = _windowContext.getResponseHandler();
1224
1225      while ( next != null && next != parentResponseHandler ) {
1226        ResponseHandler responseHandler = next;
1227        next = next.getSuccessor();
1228
1229        try {
1230          if (!killResponse && !isException) {
1231            responseHandler.flushBuffer();
1232          }
1233
1234          if (responseHandler instanceof CachingResponseHandler)
1235            cacheResponseHandler = (CachingResponseHandler) responseHandler;
1236          else
1237            responseHandler.finish();
1238        }
1239        catch (Exception JavaDoc ex) {
1240          if (!isException) {
1241            isException = true;
1242            exception = ex;
1243          }
1244          else {
1245            if (log.isLoggable(Level.FINEST)) {
1246              log(Level.FINEST, "exception while finishing response handlers: " + ex.toString(), ex);
1247            }
1248          }
1249        }
1250      }
1251
1252      String JavaDoc expirationCacheAttribute
1253        = (String JavaDoc) _connection.getAttribute(EXPIRATION_CACHE);
1254
1255      _connection.removeAttribute(EXPIRATION_CACHE);
1256
1257
1258      // caching
1259

1260      if (cacheResponseHandler != null) {
1261        if (killResponse) {
1262          cacheResponseHandler.finish( 0, null, null );
1263        }
1264        else {
1265          try {
1266            int expirationCache = _windowContext.getExpirationCache();
1267            CacheKey cacheKey = null;
1268
1269            if (expirationCache != 0 && expirationCacheAttribute != null)
1270              expirationCache = Integer.parseInt(expirationCacheAttribute);
1271
1272            if (expirationCache != 0)
1273              cacheKey = getCacheKey();
1274
1275            cacheResponseHandler.finish( expirationCache,
1276                                         cacheKey,
1277                                         getWindowRequestAttributes() );
1278                                     
1279          }
1280          catch (Exception JavaDoc ex) {
1281            if (!isException) {
1282              isException = true;
1283              exception = ex;
1284            }
1285          }
1286        }
1287      }
1288
1289      WindowContext windowContext = _windowContext;
1290      String JavaDoc namespace = _windowContext.getNamespace();
1291
1292      try {
1293        popStack();
1294      }
1295      finally {
1296        windowContext.finish();
1297      }
1298
1299      if (isConstraintFailure) {
1300        if (_windowContext != null) {
1301          if (log.isLoggable(Level.FINEST))
1302            log(namespace, Level.FINEST, "propagating constraint failure "
1303                + constraintFailureConstraint.getClass().getName()
1304                + " to parent");
1305
1306          _windowContext.setConstraintFailure( constraintFailureConstraint,
1307                                               constraintFailureCode );
1308        }
1309        else {
1310          if (log.isLoggable(Level.FINEST))
1311            log(namespace, Level.FINEST, "propagating constraint failure "
1312                + constraintFailureConstraint.getClass().getName()
1313                + " to connection");
1314
1315          boolean handled =
1316            _connection.handleConstraintFailure( constraintFailureConstraint,
1317                                                 constraintFailureCode );
1318
1319          if (!handled && !isException) {
1320            isException = true;
1321            exception = new PortletException(
1322                "Constraint failure "
1323                + constraintFailureConstraint.getClass().getName()
1324                + "(" + constraintFailureCode + ")");
1325          }
1326        }
1327      }
1328
1329      if (isException) {
1330        if (_windowContext != null) {
1331          if (log.isLoggable(Level.FINEST))
1332            log(namespace, Level.FINEST, "propagating exception "
1333                + exception.getClass().getName() + " to parent");
1334
1335          _windowContext.setException(exception);
1336        }
1337        else {
1338          if (log.isLoggable(Level.FINEST))
1339            log(namespace, Level.FINEST, "propagating exception "
1340                + exception.getClass().getName() + " to connection");
1341
1342          try {
1343            boolean handled =
1344              _connection.handleException( exception );
1345
1346            if (!handled)
1347              setConnectionFailed(exception);
1348          }
1349          catch (Exception JavaDoc ex) {
1350            setConnectionFailed(exception);
1351            log.log(Level.WARNING, ex.toString(), ex);
1352          }
1353        }
1354      }
1355
1356      if (_windowContext == null) {
1357        if (log.isLoggable(Level.FINER))
1358          log(Level.FINER, "finishing render stage");
1359
1360        _stage = STAGE_DONE;
1361        _connection.setAttribute( "javax.portlet.portletConfig", null );
1362
1363      }
1364      else {
1365        _connection.setAttribute( "javax.portlet.portletConfig",
1366            getWindow().getPortletConfig());
1367      }
1368
1369      restoreWindowRequestAttributes(requestAttributes);
1370
1371      fail = false;
1372    }
1373    catch (RuntimeException JavaDoc ex) {
1374      setConnectionFailed(ex);
1375      throw ex;
1376    }
1377    finally {
1378      if (fail)
1379        setConnectionFailed();
1380    }
1381  }
1382
1383  /**
1384   * @throws IllegalStateException if the window with the namespace
1385   * has already been processed as the target of an action, or already
1386   * renderered.
1387   *
1388   * @throws IllegalArgumentException if the window with the namespace
1389   * is not found
1390   */

1391  protected void checkWindowMutable(String JavaDoc namespace)
1392    throws IllegalStateException JavaDoc, IllegalArgumentException JavaDoc
1393  {
1394    WindowContext windowContext = _windowContextMap.get(namespace);
1395
1396    if (windowContext == null)
1397      throw new IllegalArgumentException JavaDoc(
1398          "namespace `" + namespace + "' not known");
1399
1400    if (windowContext.getActionMap() != null && !namespace.equals(getNamespace()))
1401      throw new IllegalStateException JavaDoc(
1402          "already did processAction() for namespace `" + namespace + "'");
1403
1404    if (windowContext.getNamespace() == null)
1405      throw new IllegalStateException JavaDoc(
1406          "already did render() for namespace `" + namespace + "'");
1407  }
1408
1409  protected Window getWindow()
1410  {
1411    return _windowContext.getWindow();
1412  }
1413
1414  protected Window getWindow(String JavaDoc namespace)
1415  {
1416    WindowContext windowContext = _windowContextMap.get(namespace);
1417    
1418    return windowContext == null ? null : windowContext.getWindow();
1419  }
1420
1421  protected String JavaDoc getNamespace()
1422  {
1423    return _windowContext.getNamespace();
1424  }
1425
1426  protected Renderer getRenderer()
1427  {
1428    return _windowContext.getWindow().getRenderer();
1429  }
1430
1431  protected Renderer getRenderer(String JavaDoc namespace)
1432  {
1433    WindowContext windowContext = _windowContextMap.get(namespace);
1434    
1435    return
1436      windowContext == null
1437      ? null
1438      : windowContext.getWindow().getRenderer();
1439  }
1440
1441  protected Invocation getInvocation()
1442  {
1443    Invocation invocation = _windowContext.getInvocation();
1444
1445    if (invocation == null)
1446      throw new UnsupportedOperationException JavaDoc("operation requires a namespace");
1447    
1448    return invocation;
1449  }
1450
1451  protected Invocation getInvocation(String JavaDoc namespace)
1452  {
1453    return _invocationFactory.getInvocation(namespace);
1454  }
1455
1456  protected void forbidRedirectIfInActionStage()
1457  {
1458    if (_stage == STAGE_ACTION)
1459      setForbidRedirect();
1460  }
1461
1462  // -- Invocation - WindowState/PortletMode
1463

1464  public Set<WindowState> getWindowStatesUsed()
1465  {
1466    return getInvocationFactory().getWindowStatesUsed();
1467  }
1468
1469  public Set<PortletMode> getPortletModesUsed()
1470  {
1471    return getInvocationFactory().getPortletModesUsed();
1472  }
1473
1474  protected boolean isPortletModeAllowed( Window window,
1475                                          PortletMode portletMode)
1476  {
1477    PortletRequest portletRequest = getPortletRequest();
1478
1479
1480    boolean allowed = true;
1481
1482    Renderer renderer = window.getRenderer();
1483
1484    if (renderer != null)
1485      allowed = renderer.isPortletModeAllowed(portletRequest, portletMode);
1486
1487    if (allowed && window != null)
1488      allowed = window.isPortletModeAllowed(portletRequest, portletMode);
1489
1490    if (allowed)
1491      allowed = getPortal().isPortletModeAllowed(portletRequest, portletMode);
1492
1493    return allowed;
1494  }
1495
1496  protected void setPortletMode( Window window,
1497                                 String JavaDoc namespace,
1498                                 Invocation invocation,
1499                                 PortletMode portletMode)
1500    throws PortletModeException
1501  {
1502    if (!isPortletModeAllowed(window, portletMode))
1503      throw new PortletModeException(
1504          "PortletMode `" + portletMode
1505          + "' not allowed for namespace `" + namespace + "'",
1506          portletMode);
1507
1508    forbidRedirectIfInActionStage();
1509
1510    invocation.setPortletMode(portletMode);
1511  }
1512
1513
1514  public boolean isPortletModeAllowed(PortletMode portletMode)
1515  {
1516    return isPortletModeAllowed( getWindow(), getPortletMode());
1517  }
1518
1519  public boolean isPortletModeAllowed( String JavaDoc namespace,
1520                                       PortletMode portletMode)
1521  {
1522    return isPortletModeAllowed( getWindow(namespace),
1523                                 getPortletMode(namespace));
1524  }
1525
1526  public PortletMode getPortletMode()
1527  {
1528    return getInvocation().getPortletMode();
1529  }
1530
1531  public PortletMode getPortletMode(String JavaDoc namespace)
1532  {
1533    return getInvocation(namespace).getPortletMode();
1534  }
1535
1536  public void setPortletMode(PortletMode portletMode)
1537    throws PortletModeException
1538  {
1539    setPortletMode( getWindow(),
1540                    getNamespace(),
1541                    getInvocation(),
1542                    portletMode);
1543  }
1544
1545  public void setPortletMode(String JavaDoc namespace, PortletMode portletMode)
1546    throws PortletModeException
1547  {
1548    checkWindowMutable(namespace);
1549
1550    setPortletMode( getWindow(namespace),
1551                    namespace,
1552                    getInvocation(namespace),
1553                    portletMode);
1554  }
1555
1556  protected boolean isWindowStateAllowed( Window window,
1557                                          WindowState windowState)
1558  {
1559    PortletRequest portletRequest = getPortletRequest();
1560
1561    boolean allowed = true;
1562
1563    Renderer renderer = window.getRenderer();
1564
1565    if (renderer != null)
1566      allowed = renderer.isWindowStateAllowed(portletRequest, windowState);
1567
1568    if (allowed && window != null)
1569      allowed = window.isWindowStateAllowed(portletRequest, windowState);
1570
1571    if (allowed)
1572      allowed = getPortal().isWindowStateAllowed(portletRequest, windowState);
1573
1574    return allowed;
1575  }
1576
1577  protected void setWindowState( Window window,
1578                                 String JavaDoc namespace,
1579                                 Invocation invocation,
1580                                 WindowState windowState )
1581    throws WindowStateException
1582  {
1583    if (!isWindowStateAllowed(window, windowState))
1584      throw new WindowStateException(
1585          "WindowState `" + windowState
1586          + "' not allowed for namespace `" + namespace + "'",
1587          windowState);
1588
1589    forbidRedirectIfInActionStage();
1590
1591    invocation.setWindowState(windowState);
1592  }
1593
1594  public boolean isWindowStateAllowed(WindowState windowState)
1595  {
1596    return isWindowStateAllowed( getWindow(),
1597                                 windowState );
1598  }
1599
1600  public boolean isWindowStateAllowed( String JavaDoc namespace,
1601                                       WindowState windowState)
1602  {
1603    return isWindowStateAllowed( getWindow(namespace),
1604                                 windowState );
1605  }
1606
1607  public WindowState getWindowState()
1608  {
1609    return getInvocation().getWindowState();
1610  }
1611
1612  public WindowState getWindowState(String JavaDoc namespace)
1613  {
1614    return getInvocation(namespace).getWindowState();
1615  }
1616
1617  public void setWindowState(WindowState windowState)
1618    throws WindowStateException
1619  {
1620    setWindowState( getWindow(),
1621                    getNamespace(),
1622                    getInvocation(),
1623                    windowState );
1624  }
1625
1626  public void setWindowState(String JavaDoc namespace, WindowState windowState)
1627    throws WindowStateException
1628  {
1629    checkWindowMutable(namespace);
1630
1631    setWindowState( getWindow(namespace),
1632                    namespace,
1633                    getInvocation(namespace),
1634                    windowState );
1635  }
1636
1637
1638  // -- Invocation - parameters
1639

1640
1641  public Map<String JavaDoc, String JavaDoc[]> getActionParameterMap()
1642  {
1643    Map<String JavaDoc, String JavaDoc[]> actionMap = _windowContext.getActionMap();
1644
1645    if (actionMap == null)
1646      throw new IllegalStateException JavaDoc(
1647          "namespace `" + getNamespace() + "' is not target of action");
1648
1649    return actionMap;
1650  }
1651
1652  public Map<String JavaDoc, String JavaDoc[]> getRenderParameterMap()
1653  {
1654    return getInvocation().getParameterMap();
1655  }
1656
1657  public Map<String JavaDoc, String JavaDoc[]> getRenderParameterMap(String JavaDoc namespace)
1658  {
1659    return getInvocation(namespace).getParameterMap();
1660  }
1661
1662  private void checkNullName(String JavaDoc name)
1663  {
1664    if (name == null)
1665      throw new IllegalArgumentException JavaDoc("parameter name cannot be null");
1666  }
1667
1668  private void checkNullValue(Object JavaDoc value)
1669  {
1670    if (value == null)
1671      throw new IllegalArgumentException JavaDoc("parameter value cannot be null");
1672  }
1673
1674  protected String JavaDoc getParameter(Map<String JavaDoc, String JavaDoc[]> map, String JavaDoc name)
1675  {
1676    checkNullName(name);
1677
1678    String JavaDoc values[] = map.get(name);
1679
1680    return values == null || values.length == 0 ? null : values[0];
1681  }
1682
1683  protected String JavaDoc[] getParameterValues( Map<String JavaDoc, String JavaDoc[]> map,
1684                                         String JavaDoc name)
1685  {
1686    checkNullName(name);
1687    return map.get(name);
1688  }
1689
1690  protected Enumeration getParameterNames(Map<String JavaDoc, String JavaDoc[]> map)
1691  {
1692    return Collections.enumeration(map.keySet());
1693  }
1694
1695  protected void setParameter( Map<String JavaDoc, String JavaDoc[]> map,
1696                               String JavaDoc name,
1697                               String JavaDoc value)
1698  {
1699    checkNullName(name);
1700    checkNullValue(value);
1701
1702    map.put(name, new String JavaDoc[] { value });
1703  }
1704
1705  protected void setParameters( Map<String JavaDoc, String JavaDoc[]> destMap,
1706                                Map<String JavaDoc, String JavaDoc[]> srcMap)
1707  {
1708    checkNullValue(srcMap);
1709    destMap.clear();
1710
1711    Iterator<Map.Entry<String JavaDoc, String JavaDoc[]>> iter
1712      = srcMap.entrySet().iterator();
1713
1714    while (iter.hasNext())
1715    {
1716      Map.Entry<String JavaDoc, String JavaDoc[]> entry = iter.next();
1717
1718      setParameter(destMap, entry.getKey(), entry.getValue());
1719    }
1720  }
1721
1722  protected void setParameter( Map<String JavaDoc, String JavaDoc[]> map,
1723                               String JavaDoc name,
1724                               String JavaDoc[] values)
1725  {
1726    checkNullName(name);
1727    checkNullValue(values);
1728
1729    if (values.length == 0)
1730      map.remove(name);
1731    else
1732      map.put(name, values);
1733  }
1734
1735
1736  public String JavaDoc getActionParameter(String JavaDoc name)
1737  {
1738    return getParameter(getActionParameterMap(), name);
1739  }
1740
1741  public String JavaDoc[] getActionParameterValues(String JavaDoc name)
1742  {
1743    return getParameterValues(getActionParameterMap(), name);
1744  }
1745
1746  public Enumeration getActionParameterNames()
1747  {
1748    return getParameterNames(getActionParameterMap());
1749  }
1750
1751
1752  public String JavaDoc getRenderParameter(String JavaDoc name)
1753  {
1754    return getParameter(getRenderParameterMap(), name);
1755  }
1756
1757  public String JavaDoc[] getRenderParameterValues(String JavaDoc name)
1758  {
1759    return getParameterValues(getRenderParameterMap(), name);
1760  }
1761
1762  public Enumeration getRenderParameterNames()
1763  {
1764    return getParameterNames(getRenderParameterMap());
1765  }
1766
1767  public void setRenderParameters(Map<String JavaDoc, String JavaDoc[]> srcMap)
1768  {
1769    forbidRedirectIfInActionStage();
1770
1771    setParameters(getRenderParameterMap(), srcMap);
1772  }
1773
1774  public void setRenderParameter(String JavaDoc name, String JavaDoc value)
1775  {
1776    forbidRedirectIfInActionStage();
1777
1778    setParameter(getRenderParameterMap(), name, value);
1779  }
1780
1781  public void setRenderParameter(String JavaDoc name, String JavaDoc[] values)
1782  {
1783    forbidRedirectIfInActionStage();
1784
1785    setParameter(getRenderParameterMap(), name, values);
1786  }
1787
1788
1789
1790  public String JavaDoc getRenderParameter(String JavaDoc namespace, String JavaDoc name)
1791  {
1792    return getParameter(getRenderParameterMap(namespace), name);
1793  }
1794
1795  public String JavaDoc[] getRenderParameterValues(String JavaDoc namespace, String JavaDoc name)
1796  {
1797    return getParameterValues(getRenderParameterMap(namespace), name);
1798  }
1799
1800  public Enumeration getRenderParameterNames(String JavaDoc namespace)
1801  {
1802    return getParameterNames(getRenderParameterMap(namespace));
1803  }
1804
1805  public void setRenderParameters(String JavaDoc namespace, Map<String JavaDoc,String JavaDoc[]> srcMap)
1806  {
1807    checkWindowMutable(namespace);
1808
1809    forbidRedirectIfInActionStage();
1810
1811    setParameters(getRenderParameterMap(namespace), srcMap);
1812  }
1813
1814  public void setRenderParameter(String JavaDoc namespace, String JavaDoc name, String JavaDoc value)
1815  {
1816    checkWindowMutable(namespace);
1817
1818    forbidRedirectIfInActionStage();
1819
1820    setParameter(getRenderParameterMap(namespace), name, value);
1821  }
1822
1823  public void setRenderParameter(String JavaDoc namespace, String JavaDoc name, String JavaDoc[] values)
1824  {
1825    checkWindowMutable(namespace);
1826
1827    forbidRedirectIfInActionStage();
1828
1829    setParameter(getRenderParameterMap(namespace), name, values);
1830  }
1831
1832
1833  // -- Invocation - urls
1834

1835  protected PortalURL createURL(InvocationURL url)
1836  {
1837    return new PortalURL(this, url);
1838  }
1839
1840  protected PortalURL createRenderURL( Invocation invocation,
1841                                       boolean keepParameters )
1842  {
1843    PortalURL url = createURL(invocation.createRenderURL());
1844
1845    if (keepParameters)
1846      url.setParameters(invocation.getParameterMap());
1847
1848    return url;
1849  }
1850
1851  protected PortalURL createActionURL( Invocation invocation,
1852                                       boolean keepParameters )
1853  {
1854    PortalURL url = createURL(invocation.createActionURL());
1855
1856    if (keepParameters)
1857      url.setParameters(invocation.getParameterMap());
1858
1859    return url;
1860  }
1861
1862  public PortalURL createRenderURL()
1863  {
1864    return createRenderURL(getInvocation(), false);
1865  }
1866
1867  public PortalURL createActionURL()
1868  {
1869    return createActionURL(getInvocation(), false);
1870  }
1871
1872  public PortalURL createRenderURL(String JavaDoc namespace, boolean keepParameters)
1873  {
1874    return createRenderURL(getInvocation(namespace), keepParameters);
1875  }
1876
1877  public PortalURL createActionURL(String JavaDoc namespace, boolean keepParameters)
1878  {
1879    return createActionURL(getInvocation(namespace), keepParameters);
1880  }
1881
1882  // -- Preferences
1883

1884  public PortletPreferences getPreferences()
1885  {
1886    if (_windowContext.getPreferences() == null) {
1887      PreferencesStore store = getPreferencesStore();
1888
1889      Window window = getWindow();
1890
1891      PortletPreferences defaultPreferences
1892        = window == null
1893          ? null
1894          : window.getDefaultPreferences();
1895
1896      ArrayList<PreferencesValidator> validators
1897        = window == null
1898          ? null
1899          : window.getPreferencesValidators();
1900
1901      try {
1902        Map<String JavaDoc, String JavaDoc[]> storeMap =
1903          store.getPreferencesMap(getPortletRequest(), getNamespace());
1904
1905        // XXX: pool these
1906
LinkingPortletPreferences pref = new LinkingPortletPreferences();
1907        pref.start(defaultPreferences, validators, storeMap);
1908
1909        _windowContext.setPreferences(pref);
1910      }
1911      catch (IOException JavaDoc ex) {
1912        throw new RuntimeException JavaDoc(ex);
1913      }
1914    }
1915
1916    return _windowContext.getPreferences();
1917  }
1918
1919  // -- User Attributes
1920

1921  public Map<String JavaDoc, String JavaDoc> getUserAttributeMap()
1922    throws IOException JavaDoc
1923  {
1924    if (_windowContext.getUserAttributeMap() == null) {
1925      UserAttributeStore store = getUserAttributeStore();
1926
1927      Set<String JavaDoc> names = getPortal().getUserAttributeNames();
1928
1929      Map<String JavaDoc, String JavaDoc> userAttributeMap
1930        = store.getUserAttributeMap(getPortletRequest(), names);
1931
1932      _windowContext.setUserAttributeMap(userAttributeMap);
1933    }
1934
1935    return _windowContext.getUserAttributeMap();
1936  }
1937
1938
1939  // Title
1940

1941  public void setTitle(String JavaDoc title)
1942  {
1943    _connection.setAttribute("javax.portlet.title", title);
1944  }
1945
1946
1947  // -- Client information - character encoding, content type, locales
1948

1949  // if the value has not been set for the connection,
1950
// the possibilities are defined by the client, and in the case
1951
// of locale and content type the capabilities defined by the
1952
// Window.
1953
//
1954
// Once the value is set for the conneciton, it is the only
1955
// possibility.
1956

1957
1958  /**
1959   * Get the locale already established or get the most preferred locale.
1960   */

1961  public Locale getResponseLocale()
1962  {
1963    // getResponseLocalesSet() updates the windowContext.getResponseLocale() with the
1964
// first entry
1965

1966    getResponseLocalesSet();
1967    return _windowContext.getResponseLocale();
1968  }
1969
1970  /**
1971   * True if the set is null or the set contains the locale, or the locale
1972   * without the variant, or the locale without the variant and country, or
1973   * LOCALE_ANY.
1974   */

1975  private boolean containsLocale(Set<Locale> set, Locale locale)
1976  {
1977    if (set == null || set.contains(locale))
1978      return true;
1979    
1980    String JavaDoc language = locale.getLanguage();
1981    String JavaDoc country = locale.getCountry();
1982    String JavaDoc variant = locale.getVariant();
1983
1984    if (variant.length() > 0) {
1985      variant = "";
1986      Locale loc = new Locale(language, country, variant);
1987      if (set.contains(loc))
1988        return true;
1989    }
1990
1991    if (country.length() > 0) {
1992      country = "";
1993      Locale loc = new Locale(language, country, variant);
1994      if (set.contains(loc))
1995        return true;
1996    }
1997
1998    if (language.length() > 0) {
1999      Locale loc = LOCALE_ANY;
2000      if (set.contains(loc))
2001        return true;
2002    }
2003
2004    return false;
2005  }
2006
2007  /**
2008   * Get an ordered set containing all possible locales, the most preferred
2009   * Locale occurring first. If the locale is already established a Set
2010   * containing only the established locale is returned, if the established
2011   * locale is not one of the supported locales specified in the configuration
2012   * an empty set is returned.
2013   */

2014  public Set<Locale> getResponseLocalesSet()
2015  {
2016    Set<Locale> responseLocales = _windowContext.getResponseLocales();
2017
2018    Locale established = _windowContext.getResponseHandler().getLocale();
2019
2020    // if it is established, make sure the set contains only
2021
// the established content type. Otherwise the set will
2022
// need to be rebuilt.
2023

2024    if (established != null
2025        && responseLocales != null
2026        && (responseLocales.size() > 0)
2027        && !responseLocales.contains(established))
2028
2029      responseLocales = null;
2030
2031    if (responseLocales != null)
2032      return responseLocales;
2033
2034    responseLocales = new LinkedHashSet<Locale>();
2035
2036    Locale responseLocale = null; // first one added to Set
2037

2038    Window window = getWindow();
2039
2040    Set<Locale> configLocales = window == null
2041                                ? null
2042                                : window.getSupportedLocales();
2043
2044    Set<Locale> clientLocales = _connection.getClientLocales();
2045
2046    boolean configSupportsAll = configLocales == null
2047                                || configLocales.isEmpty()
2048                                || configLocales.contains(LOCALE_ANY);
2049
2050    boolean clientSupportsAll = clientLocales == null
2051                                || clientLocales.isEmpty()
2052                                || clientLocales.contains(LOCALE_ANY);
2053
2054
2055    if (established != null)
2056    {
2057      boolean configSupports
2058        = configSupportsAll || containsLocale( configLocales, established );
2059
2060      boolean clientSupports
2061        = clientSupportsAll || containsLocale(clientLocales, established);
2062
2063      if (configSupports || clientSupports)
2064      {
2065        responseLocales.add(established);
2066        responseLocale = established;
2067      }
2068    }
2069    else if (configLocales == null) {
2070      Iterator<Locale> iter = clientLocales.iterator();
2071
2072      while (iter.hasNext()) {
2073        Locale clientLocale = iter.next();
2074
2075        if (clientLocale.equals(LOCALE_ANY))
2076          continue;
2077
2078        if (responseLocale == null)
2079          responseLocale = clientLocale;
2080
2081        responseLocales.add(clientLocale);
2082      }
2083    }
2084    else {
2085      Iterator<Locale> iter = configLocales.iterator();
2086
2087      while (iter.hasNext()) {
2088        Locale configLocale = iter.next();
2089
2090        if (configLocale.equals(LOCALE_ANY))
2091          continue;
2092
2093        if (clientSupportsAll || clientLocales.contains(configLocale)) {
2094          responseLocales.add(configLocale);
2095
2096          if (responseLocale == null)
2097            responseLocale = configLocale;
2098        }
2099      }
2100    }
2101
2102    // XXX: default currently is platform default
2103

2104    if (responseLocale == null && established == null) {
2105      responseLocale = Locale.getDefault();
2106      responseLocales.add(responseLocale);
2107    }
2108
2109    _windowContext.setResponseLocale(responseLocale);
2110    _windowContext.setResponseLocales(responseLocales);
2111
2112    return responseLocales;
2113  }
2114  
2115
2116  /**
2117   * Get the character encoding already established or get the most preferred
2118   * character encoding.
2119   */

2120  public String JavaDoc getResponseCharacterEncoding()
2121  {
2122    // getResponseCharacterEncodingsSet() updates the
2123
// windowContext.getResponseCharacterEncoding() with the first entry
2124

2125    getResponseCharacterEncodingsSet();
2126    return _windowContext.getResponseCharacterEncoding();
2127  }
2128
2129  /**
2130   * Get an ordered set containing all possible character encodings, the most
2131   * preferred Locale occurring first. If the character encoding is already
2132   * established a Set containing only the established character encoding is
2133   * returned, if the established character encoding is not one of the
2134   * supported character encodings specified in the configuration an empty set
2135   * is returned.
2136   */

2137  public Set<String JavaDoc> getResponseCharacterEncodingsSet()
2138  {
2139    Set<String JavaDoc> responseEncodings
2140      = _windowContext.getResponseCharacterEncodings();
2141
2142    String JavaDoc establishedEncoding
2143      = _windowContext.getResponseHandler().getCharacterEncoding();
2144
2145    // if it is established, make sure the set contains only
2146
// the established character encoding. Otherwise the set will
2147
// need to be rebuilt.
2148

2149    if (establishedEncoding != null
2150        && responseEncodings != null
2151        && (responseEncodings.size() > 0 )
2152        && !responseEncodings.contains(establishedEncoding))
2153
2154      responseEncodings = null;
2155
2156
2157    if (responseEncodings != null)
2158      return responseEncodings;
2159
2160    responseEncodings = new LinkedHashSet<String JavaDoc>();
2161
2162    String JavaDoc responseEncoding = null; // first one added to Set
2163

2164    Set<String JavaDoc> clientEncodings = _connection.getClientCharacterEncodings();
2165
2166    boolean clientSupportsAll = clientEncodings == null
2167                                || clientEncodings.isEmpty()
2168                                || clientEncodings.contains("*");
2169  
2170  
2171    if (establishedEncoding != null)
2172    {
2173      if (clientSupportsAll || clientEncodings.contains(establishedEncoding))
2174      {
2175        responseEncodings.add(establishedEncoding);
2176        responseEncoding = establishedEncoding;
2177      }
2178    }
2179    else {
2180      Iterator<String JavaDoc> iter = clientEncodings.iterator();
2181
2182      while (iter.hasNext()) {
2183        String JavaDoc clientEncoding = iter.next();
2184
2185        responseEncodings.add(clientEncoding);
2186
2187        if (responseEncoding == null)
2188          responseEncoding = clientEncoding;
2189      }
2190
2191      if (responseEncoding == null) {
2192        // XXX: default is platform default
2193
responseEncoding = System.getProperty("file.encoding");
2194        responseEncodings.add(responseEncoding);
2195      }
2196    }
2197
2198    _windowContext.setResponseCharacterEncoding(responseEncoding);
2199    _windowContext.setResponseCharacterEncodings(responseEncodings);
2200
2201    return responseEncodings;
2202  }
2203  
2204  private String JavaDoc getWildcardContentType(String JavaDoc contentType)
2205  {
2206    // i.e "text/html" becomes "text/*", null if no wildcard possible
2207
// because there is no '/'
2208

2209    int i = contentType.indexOf('/');
2210    if (i < 0)
2211      return null;
2212    else
2213        return contentType.substring(0,i + 1) + "*";
2214  }
2215
2216  public String JavaDoc getResponseContentType()
2217  {
2218    // getResponseContentTypesSet() sets _windowContext.getResponseContentType
2219
// to the value of the first entry it add's to the set
2220
getResponseContentTypesSet();
2221
2222    return _windowContext.getResponseContentType();
2223  }
2224
2225  public Set<String JavaDoc> getResponseContentTypesSet()
2226  {
2227    Set<String JavaDoc> responseTypes = _windowContext.getResponseContentTypes();
2228
2229    String JavaDoc establishedType = _windowContext.getResponseHandler().getContentType();
2230
2231    // if it is established, make sure the set contains only
2232
// the established content type. Otherwise the set will
2233
// need to be rebuilt.
2234

2235    if (establishedType != null
2236        && responseTypes != null
2237        && (responseTypes.size() > 0)
2238        && !responseTypes.contains(establishedType))
2239
2240      responseTypes = null;
2241
2242
2243    if (responseTypes != null)
2244      return responseTypes;
2245
2246    responseTypes = new LinkedHashSet<String JavaDoc>();
2247
2248    String JavaDoc responseType = null; // first one added to Set
2249

2250    Window window = getWindow();
2251
2252    Set<String JavaDoc> configTypes =
2253      window == null
2254      ? null
2255      : window.getSupportedContentTypes(getPortletMode());
2256        
2257    boolean configSupportsAll
2258      = configTypes == null || configTypes.contains("*/*");
2259
2260    Set<String JavaDoc> clientTypes = _connection.getClientContentTypes();
2261
2262    boolean clientSupportsAll = clientTypes == null
2263                                || clientTypes.isEmpty()
2264                                || clientTypes.contains("*/*");
2265
2266
2267    if (establishedType != null)
2268    {
2269      String JavaDoc wildcard = getWildcardContentType(establishedType);
2270
2271      if ((configSupportsAll
2272            || configTypes.contains(establishedType)
2273            || configTypes.contains(wildcard))
2274          &&
2275          (clientSupportsAll
2276            || clientTypes.contains(establishedType)
2277            || clientTypes.contains(wildcard)))
2278      {
2279        responseTypes.add(establishedType);
2280        responseType = establishedType;
2281      }
2282    }
2283    else if (configSupportsAll) {
2284      Iterator<String JavaDoc> iter = clientTypes.iterator();
2285
2286      while (iter.hasNext()) {
2287        String JavaDoc clientType = iter.next();
2288
2289        if (responseType == null)
2290          responseType = clientType;
2291
2292        responseTypes.add(clientType);
2293      }
2294    }
2295    else {
2296
2297      Iterator<String JavaDoc> iter = configTypes.iterator();
2298
2299      // wildcards in the config are added a second time around, so that they
2300
// appear further down the list (they are less desirable as a return
2301
// value)
2302

2303      boolean configHasWildcard = false;
2304
2305      while (iter.hasNext()) {
2306        String JavaDoc configType = iter.next();
2307
2308        boolean isUsableConfigType = false;
2309
2310        if (configType.indexOf('*') > -1) {
2311          configHasWildcard = true;
2312        }
2313        else if (clientSupportsAll || clientTypes.contains(configType)) {
2314          isUsableConfigType = true;
2315        }
2316        else {
2317          String JavaDoc wildcardConfigType = getWildcardContentType(configType);
2318
2319          if (wildcardConfigType != null
2320              && clientTypes.contains(wildcardConfigType))
2321          {
2322            isUsableConfigType = true;
2323          }
2324        }
2325
2326        if (isUsableConfigType) {
2327          responseTypes.add(configType);
2328
2329          if (responseType == null)
2330            responseType = configType;
2331        }
2332      }
2333
2334      if (configHasWildcard) {
2335      
2336        iter = clientTypes.iterator();
2337
2338        while (iter.hasNext()) {
2339          String JavaDoc clientType = iter.next();
2340
2341          boolean isUsableClientType = false;
2342
2343          if (configSupportsAll)
2344            isUsableClientType = true;
2345          else {
2346            String JavaDoc wildcardClientType = clientType.indexOf('*') > -1
2347                                        ? clientType
2348                                        : getWildcardContentType(clientType);
2349
2350            if (wildcardClientType != null
2351              && configTypes.contains(wildcardClientType))
2352            {
2353              isUsableClientType = true;
2354            }
2355          }
2356
2357
2358          if (isUsableClientType) {
2359            responseTypes.add(clientType);
2360
2361            if (responseType == null)
2362              responseType = clientType;
2363          }
2364        }
2365      }
2366    }
2367
2368    _windowContext.setResponseContentType(responseType);
2369    _windowContext.setResponseContentTypes(responseTypes);
2370
2371    return responseTypes;
2372  }
2373
2374  // -- ResponseHandler
2375

2376  public String JavaDoc getContentType()
2377  {
2378    return _windowContext.getResponseHandler().getContentType();
2379  }
2380
2381  public void setContentType(String JavaDoc contentType)
2382  {
2383    if (contentType.equals(_windowContext.getResponseHandler().getContentType()))
2384       return;
2385
2386    // make sure the content type is allowed before
2387
// allowing it to be set
2388

2389    PortletMode currentMode = getPortletMode();
2390
2391    Window window = _windowContext.getWindow();
2392
2393    Set<String JavaDoc> configTypes = null;
2394
2395    if (window != null)
2396        configTypes = window.getSupportedContentTypes(currentMode);
2397
2398    if (configTypes != null && !configTypes.contains(contentType))
2399      throw new IllegalArgumentException JavaDoc(
2400          "portlet with namespace `" + _windowContext.getNamespace ()
2401          + "' does not support content type `" + contentType + "'"
2402          + " when in mode `" + currentMode + "'");
2403
2404    _windowContext.getResponseHandler().setContentType(contentType);
2405  }
2406
2407  public Locale getLocale()
2408  {
2409    return _windowContext.getResponseHandler().getLocale();
2410  }
2411
2412  public void addProperty(String JavaDoc key, String JavaDoc value)
2413  {
2414    _windowContext.getResponseHandler().addProperty(key, value);
2415  }
2416
2417  public void setProperty(String JavaDoc key, String JavaDoc value)
2418  {
2419    _windowContext.getResponseHandler().setProperty(key,value);
2420  }
2421
2422  public String JavaDoc getCharacterEncoding()
2423  {
2424    return _windowContext.getResponseHandler().getCharacterEncoding();
2425  }
2426
2427  public PrintWriter JavaDoc getWriter()
2428    throws IOException JavaDoc
2429  {
2430    return _windowContext.getResponseHandler().getWriter();
2431  }
2432
2433  public void setBufferSize(int size)
2434  {
2435    _windowContext.getResponseHandler().setBufferSize(size);
2436  }
2437
2438  public int getBufferSize()
2439  {
2440    return _windowContext.getResponseHandler().getBufferSize();
2441  }
2442
2443  /**
2444   * @param flushToClient true flush all buffers through to the client.
2445   * If false, flush only the buffers for the current window
2446   */

2447  public void flushBuffer(boolean flushToClient)
2448    throws IOException JavaDoc
2449  {
2450    ResponseHandler parentResponseHandler
2451      = _windowContext.getParentResponseHandler();
2452
2453    ResponseHandler responseHandler
2454      = _windowContext.getResponseHandler();
2455
2456    while (responseHandler != null) {
2457      if (!flushToClient && responseHandler == parentResponseHandler)
2458        break;
2459
2460      responseHandler.flushBuffer();
2461
2462      responseHandler = responseHandler.getSuccessor();
2463    }
2464  }
2465
2466  /**
2467   * @param resetRenderer if true, reset all of the buffers for the current
2468   * window. If false, reset all of the buffers until the
2469   * RendererResponseHandler, reset that too but in such a way
2470   * that it will write the decorations again.
2471   */

2472  public void reset(boolean resetRenderer)
2473  {
2474    ResponseHandler parentResponseHandler
2475      = _windowContext.getParentResponseHandler();
2476
2477    ResponseHandler responseHandler = _windowContext.getResponseHandler();
2478
2479    RendererResponseHandler renderer = null;
2480    boolean isWriter = false;
2481    boolean isOutputStream = false;
2482
2483    while (responseHandler != null) {
2484      if (responseHandler == parentResponseHandler)
2485        break;
2486
2487      if (!resetRenderer && (responseHandler instanceof RendererResponseHandler))
2488      {
2489        renderer = ( (RendererResponseHandler) responseHandler );
2490        isWriter = renderer.isWriter();
2491        isOutputStream = renderer.isOutputStream();
2492      }
2493
2494      responseHandler.reset();
2495
2496      responseHandler = responseHandler.getSuccessor();
2497    }
2498
2499    if (renderer != null) {
2500      if (isWriter) {
2501        try {
2502          renderer.getWriter();
2503        }
2504        catch (IOException JavaDoc ex) {
2505          setConnectionFailed(ex);
2506        }
2507      }
2508
2509      if (isOutputStream) {
2510        try {
2511          renderer.getOutputStream();
2512        }
2513        catch (IOException JavaDoc ex) {
2514          setConnectionFailed(ex);
2515        }
2516      }
2517    }
2518  }
2519
2520  /**
2521   * If the current window has a renderer that is always-write or
2522   * always-stream, call getWriter() or getOutputStream()
2523   */

2524  protected void checkAlwaysWriteOrStream()
2525    throws IOException JavaDoc
2526  {
2527    if (_windowContext == null)
2528      return;
2529
2530    ResponseHandler parentResponseHandler
2531      = _windowContext.getParentResponseHandler();
2532
2533    ResponseHandler responseHandler = _windowContext.getResponseHandler();
2534    ResponseHandler next = responseHandler;
2535
2536    while (next != null && next != parentResponseHandler) {
2537      if (responseHandler instanceof RendererResponseHandler)
2538      {
2539        RendererResponseHandler renderer
2540          = ( (RendererResponseHandler) next );
2541        boolean isWriter = renderer.isWriter();
2542        boolean isOutputStream = renderer.isOutputStream();
2543
2544        if (!isWriter && !isOutputStream) {
2545
2546          if (renderer.isAlwaysWrite()) {
2547            if (getRenderResponse().getContentType() == null) {
2548              String JavaDoc contentType = renderer.getDefaultContentType();
2549              getRenderResponse().setContentType(contentType);
2550            }
2551
2552            responseHandler.getWriter();
2553          }
2554          else if (renderer.isAlwaysStream()) {
2555            if (getRenderResponse().getContentType() == null) {
2556              String JavaDoc contentType = renderer.getDefaultContentType();
2557              getRenderResponse().setContentType(contentType);
2558            }
2559
2560            responseHandler.getOutputStream();
2561          }
2562        }
2563
2564        next = null;
2565      }
2566      else
2567        next = next.getSuccessor();
2568    }
2569  }
2570
2571  public void resetBuffer(boolean resetRenderer)
2572  {
2573    ResponseHandler parentResponseHandler
2574      = _windowContext.getParentResponseHandler();
2575
2576    ResponseHandler responseHandler
2577      = _windowContext.getResponseHandler();
2578
2579    while (responseHandler != null) {
2580
2581      if (responseHandler == parentResponseHandler)
2582        break;
2583
2584      if (!resetRenderer && (responseHandler instanceof RendererResponseHandler))
2585        break;
2586
2587      responseHandler.resetBuffer();
2588
2589      responseHandler = responseHandler.getSuccessor();
2590    }
2591  }
2592
2593  public boolean isCommitted()
2594  {
2595    return _windowContext.getResponseHandler().isCommitted();
2596  }
2597
2598  public OutputStream JavaDoc getPortletOutputStream()
2599    throws IOException JavaDoc
2600  {
2601    return _windowContext.getResponseHandler().getOutputStream();
2602  }
2603
2604  // -- Security and user identity
2605

2606  public boolean isUserInRole(String JavaDoc role)
2607  {
2608    Window window = getWindow();
2609
2610    Map<String JavaDoc, String JavaDoc> roleRefMap
2611      = window == null ? null : window.getRoleRefMap();
2612
2613    if (roleRefMap != null) {
2614      String JavaDoc effectiveRole = roleRefMap.get(role);
2615
2616      if (effectiveRole != null)
2617        role = effectiveRole;
2618    }
2619
2620    return _connection.isUserInRole(role);
2621  }
2622
2623  public String JavaDoc getRemoteUser()
2624  {
2625    return _connection.getRemoteUser();
2626  }
2627
2628  public java.security.Principal JavaDoc getUserPrincipal()
2629  {
2630    return _connection.getUserPrincipal();
2631  }
2632
2633  public String JavaDoc getAuthType()
2634  {
2635    return _connection.getAuthType();
2636  }
2637
2638  public boolean isSecure()
2639  {
2640    return _connection.isSecure();
2641  }
2642
2643  public String JavaDoc getRequestedSessionId()
2644  {
2645    return _connection.getRequestedSessionId();
2646  }
2647
2648  public boolean isRequestedSessionIdValid()
2649  {
2650    return _connection.isRequestedSessionIdValid();
2651  }
2652
2653  public boolean canGuaranteeIntegrity()
2654  {
2655    return _connection.canGuaranteeIntegrity();
2656  }
2657
2658  public boolean canGuaranteeConfidentiality()
2659  {
2660    return _connection.canGuaranteeConfidentiality();
2661  }
2662
2663  // -- Connection - request info
2664

2665
2666  public String JavaDoc getContextPath()
2667  {
2668    return _connection.getContextPath();
2669  }
2670
2671  public String JavaDoc getServerName()
2672  {
2673    return _connection.getServerName();
2674  }
2675
2676  public int getServerPort()
2677  {
2678    return _connection.getServerPort();
2679  }
2680
2681  public String JavaDoc getScheme()
2682  {
2683    return _connection.getScheme();
2684  }
2685
2686
2687  public String JavaDoc getProperty(String JavaDoc name)
2688  {
2689    return _connection.getProperty(name);
2690  }
2691
2692  public Enumeration getProperties(String JavaDoc name)
2693  {
2694    return _connection.getProperties(name);
2695  }
2696
2697  public Enumeration getPropertyNames()
2698  {
2699    return _connection.getPropertyNames();
2700  }
2701
2702
2703
2704  // -- Connection - attributes
2705

2706
2707  public Enumeration getAttributeNames()
2708  {
2709    return _connection.getAttributeNames();
2710  }
2711
2712  public Object JavaDoc getAttribute(String JavaDoc name)
2713  {
2714     if (name.equals(PortletRequest.USER_INFO)) {
2715       try {
2716         return getUserAttributeMap();
2717       }
2718       catch (IOException JavaDoc ex) {
2719         throw new RuntimeException JavaDoc(ex);
2720       }
2721     } else
2722       return _connection.getAttribute(name);
2723  }
2724
2725  public void setAttribute(String JavaDoc name, Object JavaDoc o)
2726  {
2727    _connection.setAttribute(name, o);
2728  }
2729
2730  public void removeAttribute(String JavaDoc name)
2731  {
2732    _connection.removeAttribute(name);
2733  }
2734
2735  public PortletSession getPortletSession()
2736  {
2737    return getPortletSession(false);
2738  }
2739
2740  public PortletSession getPortletSession(boolean create)
2741  {
2742    return _connection.getPortletSession(create);
2743  }
2744
2745  // -- Connection - Submit - Reader/InputStream
2746

2747  public InputStream JavaDoc getSubmitInputStream()
2748    throws IOException JavaDoc
2749  {
2750    return _connection.getSubmitInputStream();
2751  }
2752
2753  public void setSubmitCharacterEncoding(String JavaDoc enc)
2754    throws UnsupportedEncodingException JavaDoc
2755  {
2756    _connection.setSubmitCharacterEncoding(enc);
2757  }
2758
2759  public String JavaDoc getSubmitCharacterEncoding()
2760  {
2761    return _connection.getSubmitCharacterEncoding();
2762  }
2763
2764  public BufferedReader JavaDoc getSubmitReader()
2765    throws UnsupportedEncodingException JavaDoc, IOException JavaDoc
2766  {
2767    return _connection.getSubmitReader();
2768  }
2769
2770  public String JavaDoc getSubmitContentType()
2771  {
2772    return _connection.getSubmitContentType();
2773  }
2774
2775  public int getSubmitContentLength()
2776  {
2777    return _connection.getSubmitContentLength();
2778  }
2779
2780  // Connection - urls and redirect
2781

2782  public String JavaDoc resolveURL(String JavaDoc path)
2783  {
2784    return _connection.resolveURL(path);
2785  }
2786
2787  public String JavaDoc resolveURL(String JavaDoc path, boolean isSecure)
2788    throws PortletSecurityException
2789  {
2790    return _connection.resolveURL(path, isSecure);
2791  }
2792
2793  public String JavaDoc encodeURL(String JavaDoc path)
2794  {
2795    return _connection.encodeURL(path);
2796  }
2797
2798  public void sendRedirect(String JavaDoc location)
2799    throws IOException JavaDoc
2800  {
2801    if (isForbidRedirect())
2802      throw new IllegalStateException JavaDoc(
2803          "sendRedirect() forbidden, portlet mode, window state, "
2804          + " or render parameters were set in action");
2805
2806    _connection.sendRedirect(location);
2807  }
2808}
2809
2810
Popular Tags