001: /**
002: * Copyright 2006 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.uilib.core;
016:
017: import java.util.HashMap;
018: import java.util.Map;
019: import org.apache.commons.lang.RandomStringUtils;
020: import org.araneaframework.Environment;
021: import org.araneaframework.EnvironmentAwareCallback;
022: import org.araneaframework.OutputData;
023: import org.araneaframework.Widget;
024: import org.araneaframework.core.ApplicationWidget;
025: import org.araneaframework.core.BaseApplicationWidget;
026: import org.araneaframework.core.StandardEnvironment;
027: import org.araneaframework.core.util.ExceptionUtil;
028: import org.araneaframework.framework.FlowContext;
029: import org.araneaframework.framework.FlowContextWidget;
030: import org.araneaframework.framework.ThreadContext;
031: import org.araneaframework.framework.TopServiceContext;
032: import org.araneaframework.framework.TransactionContext;
033: import org.araneaframework.http.HttpInputData;
034: import org.araneaframework.http.HttpOutputData;
035: import org.araneaframework.http.PopupWindowContext;
036: import org.araneaframework.http.service.WindowClosingService;
037: import org.araneaframework.http.util.EnvironmentUtil;
038: import org.araneaframework.http.util.URLUtil;
039:
040: /**
041: * Wrapper around the flow that is started from new session-thread. It pretends
042: * to be {@link org.araneaframework.framework.FlowContext} for wrapped flows and proxies
043: * method calls to current <emphasis>real</emphasis> {@link org.araneaframework.framework.FlowContext}
044: * and/or to {@link org.araneaframework.framework.FlowContext} from which wrapped flow was started.
045: *
046: * @author Taimo Peelo (taimo@araneaframework.org)
047: */
048: public class PopupFlowWrapperWidget extends BaseApplicationWidget
049: implements FlowContextWidget {
050: protected Widget child;
051:
052: public PopupFlowWrapperWidget(Widget child) {
053: this .child = child;
054: }
055:
056: protected Environment getChildWidgetEnvironment() {
057: return new StandardEnvironment(getEnvironment(),
058: FlowContext.class, this );
059: }
060:
061: protected void init() throws Exception {
062: super .init();
063: addWidget("child", child);
064: }
065:
066: public void start(Widget flow, Handler handler) {
067: start(flow, null, handler);
068: }
069:
070: public void start(Widget flow) {
071: start(flow, null, null);
072: }
073:
074: public void start(Widget flow, Configurator configurator,
075: Handler handler) {
076: getLocalFlowContext().start(flow, configurator, handler);
077: }
078:
079: public void replace(Widget flow) {
080: replace(flow, null);
081: }
082:
083: public void replace(Widget flow, Configurator configurator) {
084: // XXX: does not work when this is only widget on call stack
085: getLocalFlowContext().replace(flow, configurator);
086: }
087:
088: public void finish(Object result) {
089: ThreadContext threadCtx = (ThreadContext) getEnvironment()
090: .getEntry(ThreadContext.class);
091: getOpenerFlowContext().finish(result);
092:
093: try {
094: // close the session-thread of popupflow
095: Object currentThreadId = threadCtx.getCurrentId();
096: getOpenerPopupContext().close(currentThreadId.toString());
097:
098: Object servingThreadId = getInputData().getGlobalData()
099: .get(ThreadContext.THREAD_SERVICE_KEY);
100:
101: // if request for closing popup came from the popup window itself
102: if (currentThreadId.equals(servingThreadId)) {
103: String rndThreadId = RandomStringUtils
104: .randomAlphanumeric(12);
105: //popup window is closed with redirect to a page that closes current window and reloads parent.
106: threadCtx.addService(rndThreadId,
107: new WindowClosingService(getEnvironment()));
108: ((HttpOutputData) getOutputData())
109: .sendRedirect(getResponseURL(
110: getRequestURL(),
111: (String) EnvironmentUtil
112: .requireTopServiceId(getEnvironment()),
113: rndThreadId));
114: }
115: } catch (Exception e) {
116: ExceptionUtil.uncheckException(e);
117: }
118: }
119:
120: public void cancel() {
121: // XXX: may not just call openerflowcontext if more than one flow has been started from here
122: getOpenerFlowContext().cancel();
123: }
124:
125: public boolean isNested() {
126: // XXX: should hold that information itself?
127: return getLocalFlowContext().isNested();
128: }
129:
130: public void reset(EnvironmentAwareCallback callback) {
131: getLocalFlowContext().reset(callback);
132: // XXX: and now what?
133: }
134:
135: public FlowReference getCurrentReference() {
136: return getLocalFlowContext().getCurrentReference();
137: }
138:
139: public void addNestedEnvironmentEntry(ApplicationWidget scope,
140: Object entryId, Object envEntry) {
141: getLocalFlowContext().addNestedEnvironmentEntry(scope, entryId,
142: envEntry);
143: }
144:
145: protected void render(OutputData output) throws Exception {
146: child._getWidget().render(output);
147: }
148:
149: private FlowContext getLocalFlowContext() {
150: return (FlowContext) getEnvironment().getEntry(
151: FlowContext.class);
152: }
153:
154: protected String getRequestURL() {
155: return ((HttpInputData) getInputData()).getContainerURL();
156: }
157:
158: protected String getResponseURL(String url, String topServiceId,
159: String threadServiceId) {
160: Map m = new HashMap();
161: m.put(TopServiceContext.TOP_SERVICE_KEY, topServiceId);
162: m.put(ThreadContext.THREAD_SERVICE_KEY, threadServiceId);
163: m.put(TransactionContext.TRANSACTION_ID_KEY,
164: TransactionContext.OVERRIDE_KEY);
165: return ((HttpOutputData) getOutputData()).encodeURL(URLUtil
166: .parametrizeURI(url, m));
167: }
168:
169: private FlowContext getOpenerFlowContext() {
170: PopupWindowContext popupCtx = (PopupWindowContext) getEnvironment()
171: .getEntry(PopupWindowContext.class);
172: // XXX
173: return (FlowContext) ((ApplicationWidget) popupCtx.getOpener())
174: .getChildEnvironment().getEntry(FlowContext.class);
175: }
176:
177: protected PopupWindowContext getPopupContext() {
178: return (PopupWindowContext) getEnvironment().getEntry(
179: PopupWindowContext.class);
180: }
181:
182: protected PopupWindowContext getOpenerPopupContext() {
183: return (PopupWindowContext) ((ApplicationWidget) getPopupContext()
184: .getOpener()).getChildEnvironment().getEntry(
185: PopupWindowContext.class);
186: }
187:
188: public void setTransitionHandler(TransitionHandler handler) {
189: getLocalFlowContext().setTransitionHandler(handler);
190: }
191:
192: public TransitionHandler getTransitionHandler() {
193: return getLocalFlowContext().getTransitionHandler();
194: }
195: }
|