001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.webbeans.context;
031:
032: import com.caucho.util.*;
033: import com.caucho.webbeans.component.*;
034: import com.caucho.server.dispatch.ServletInvocation;
035:
036: import java.util.*;
037:
038: import javax.faces.*;
039: import javax.faces.context.*;
040: import javax.faces.component.*;
041: import javax.servlet.*;
042: import javax.servlet.http.*;
043: import javax.webbeans.*;
044:
045: /**
046: * The conversation scope value
047: */
048: public class ConversationScope extends ScopeContext implements
049: Conversation, java.io.Serializable {
050: private static final L10N L = new L10N(ConversationScope.class);
051:
052: public ConversationScope() {
053: }
054:
055: /**
056: * Returns the current value of the component in the conversation scope.
057: */
058: public <T> T get(ComponentFactory<T> component, boolean create) {
059: FacesContext facesContext = FacesContext.getCurrentInstance();
060:
061: if (facesContext == null)
062: throw new IllegalStateException(
063: L
064: .l("@ConversationScoped is not available because JSF is not active"));
065:
066: ExternalContext extContext = facesContext.getExternalContext();
067: Map<String, Object> sessionMap = extContext.getSessionMap();
068:
069: Scope scope = (Scope) sessionMap.get("caucho.conversation");
070:
071: // XXX: create
072: if (scope == null)
073: return null;
074:
075: UIViewRoot root = facesContext.getViewRoot();
076: String id = root.getViewId();
077:
078: HashMap map = scope._conversationMap.get(id);
079:
080: if (map == null) {
081: map = scope._extendedConversation;
082:
083: if (map != null)
084: scope._conversationMap.put(id, map);
085: }
086:
087: if (map != null)
088: return (T) map
089: .get(((ComponentImpl) component).getScopeId());
090: else
091: return null;
092: }
093:
094: /**
095: * Sets the current value of the component in the conversation scope.
096: */
097: public <T> void put(ComponentFactory<T> component, T value) {
098: FacesContext facesContext = FacesContext.getCurrentInstance();
099:
100: if (facesContext == null)
101: throw new IllegalStateException(
102: L
103: .l("@ConversationScoped is not available because JSF is not active"));
104:
105: ExternalContext extContext = facesContext.getExternalContext();
106: Map<String, Object> sessionMap = extContext.getSessionMap();
107:
108: Scope scope = (Scope) sessionMap.get("caucho.conversation");
109:
110: if (scope == null) {
111: scope = new Scope();
112: sessionMap.put("caucho.conversation", scope);
113: }
114:
115: UIViewRoot root = facesContext.getViewRoot();
116: String id = root.getViewId();
117:
118: HashMap map = scope._conversationMap.get(id);
119:
120: if (map == null) {
121: if (scope._extendedConversation != null)
122: map = scope._extendedConversation;
123: else
124: map = new HashMap(8);
125:
126: scope._conversationMap.put(id, map);
127: }
128:
129: map.put(((ComponentImpl) component).getScopeId(), value);
130: }
131:
132: /**
133: * Removes the current value of the component in the conversation scope.
134: */
135: public <T> void remove(ComponentFactory<T> component) {
136: FacesContext facesContext = FacesContext.getCurrentInstance();
137:
138: if (facesContext == null)
139: throw new IllegalStateException(
140: L
141: .l("@ConversationScoped is not available because JSF is not active"));
142:
143: ExternalContext extContext = facesContext.getExternalContext();
144: Map<String, Object> sessionMap = extContext.getSessionMap();
145:
146: Scope scope = (Scope) sessionMap.get("caucho.conversation");
147:
148: if (scope == null)
149: return;
150:
151: UIViewRoot root = facesContext.getViewRoot();
152: String id = root.getViewId();
153:
154: HashMap map = scope._conversationMap.get(id);
155:
156: if (map != null)
157: map.remove(((ComponentImpl) component).getScopeId());
158: }
159:
160: /**
161: * returns true if the argument scope can be safely injected in a
162: * scope-instance.
163: */
164: @Override
165: public boolean canInject(ScopeContext scope) {
166: return (scope instanceof SingletonScope
167: || scope instanceof ApplicationScope
168: || scope instanceof SessionScope || scope instanceof ConversationScope);
169: }
170:
171: //
172: // Conversation API
173: //
174:
175: /**
176: * Begins an extended conversation
177: */
178: public void begin() {
179: FacesContext facesContext = FacesContext.getCurrentInstance();
180:
181: if (facesContext == null)
182: throw new IllegalStateException(
183: L
184: .l("@ConversationScoped is not available because JSF is not active"));
185:
186: ExternalContext extContext = facesContext.getExternalContext();
187: Map<String, Object> sessionMap = extContext.getSessionMap();
188:
189: Scope scope = (Scope) sessionMap.get("caucho.conversation");
190:
191: if (scope == null) {
192: scope = new Scope();
193: sessionMap.put("caucho.conversation", scope);
194: }
195:
196: UIViewRoot root = facesContext.getViewRoot();
197: String id = root.getViewId();
198:
199: HashMap map = scope._conversationMap.get(id);
200:
201: if (map == null) {
202: map = new HashMap(8);
203: scope._conversationMap.put(id, map);
204: }
205:
206: scope._extendedConversation = map;
207: }
208:
209: /**
210: * Ends an extended conversation
211: */
212: public void end() {
213: FacesContext facesContext = FacesContext.getCurrentInstance();
214:
215: if (facesContext == null)
216: throw new IllegalStateException(
217: L
218: .l("@ConversationScoped is not available because JSF is not active"));
219:
220: ExternalContext extContext = facesContext.getExternalContext();
221: Map<String, Object> sessionMap = extContext.getSessionMap();
222:
223: Scope scope = (Scope) sessionMap.get("caucho.conversation");
224:
225: if (scope == null)
226: return;
227:
228: scope._extendedConversation = null;
229: }
230:
231: static class Scope implements java.io.Serializable {
232: final HashMap<String, HashMap> _conversationMap = new HashMap<String, HashMap>();
233:
234: HashMap _extendedConversation;
235: }
236: }
|