/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <hr>
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* This file has been modified by the OpenOLAT community. Changes are licensed
* under the Apache 2.0 license as the original file.
* <p>
*/
package org.olat.core.gui.control.winmgr;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.olat.core.gui.GlobalSettings;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.WindowManager;
import org.olat.core.gui.WindowSettings;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.ComponentRenderer;
import org.olat.core.gui.components.Window;
import org.olat.core.gui.control.ChiefController;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.JSAndCSSAdderImpl;
import org.olat.core.gui.control.WindowBackOffice;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.guistack.GuiStack;
import org.olat.core.gui.control.guistack.GuiStackNiceImpl;
import org.olat.core.gui.control.pushpoll.WindowCommand;
import org.olat.core.gui.control.util.ZIndexWrapper;
import org.olat.core.gui.dev.controller.DevelopmentController;
import org.olat.core.gui.media.MediaResource;
import org.olat.core.gui.media.ServletUtil;
import org.olat.core.gui.render.intercept.InterceptHandler;
import org.olat.core.gui.render.intercept.InterceptHandlerInstance;
import org.olat.core.gui.render.intercept.debug.GuiDebugDispatcherController;
import org.olat.core.helpers.Settings;
import org.olat.core.logging.AssertException;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.event.GenericEventListener;
import org.olat.core.util.i18n.I18nManager;
import org.olat.core.util.i18n.ui.I18nUIFactory;
import org.olat.core.util.i18n.ui.InlineTranslationInterceptHandlerController;
/**
* Description:<br>
* impl of windowbackoffice - responsible for several activities around a (browser)window
*
* <P>
* Initial Date: 10.02.2007 <br>
* @author Felix Jost, http://www.goodsolutions.ch
*/
public class WindowBackOfficeImpl implements WindowBackOffice {
private static final OLog log = Tracing.createLoggerFor(WindowBackOfficeImpl.class);
private final WindowManagerImpl winmgrImpl;
private final Window window;
private WindowSettings settings;
private final ChiefController windowOwner;
private InterceptHandler linkedInterceptHandler;
private InterceptHandler debug_interceptHandler;
private InterceptHandler inlineTranslation_interceptHandler;
private AjaxController ajaxC;
private GuiDebugDispatcherController guidebugC;
private InlineTranslationInterceptHandlerController inlineTranslationC;
private List<ZIndexWrapper> guiMessages = new ArrayList<>(); // request-transient render-related data
private transient List<GenericEventListener> cycleListeners = new CopyOnWriteArrayList<>();
WindowBackOfficeImpl(final WindowManagerImpl winmgrImpl, String windowName, ChiefController windowOwner, WindowSettings settings) {
this.winmgrImpl = winmgrImpl;
this.windowOwner = windowOwner;
window = new Window(windowName, this);
this.settings = settings;
linkedInterceptHandler = new InterceptHandler() {
@Override
public InterceptHandlerInstance createInterceptHandlerInstance() {
InterceptHandler debugH = debug_interceptHandler;
InterceptHandler inlineTranslationH = inlineTranslation_interceptHandler;
final InterceptHandlerInstance debugI = debugH == null? null: debugH.createInterceptHandlerInstance();
final InterceptHandlerInstance inlineTranslationI = (inlineTranslationH == null ? null : inlineTranslationH.createInterceptHandlerInstance());
return new InterceptHandlerInstance() {
@Override
public ComponentRenderer createInterceptComponentRenderer(ComponentRenderer originalRenderer) {
ComponentRenderer toUse = originalRenderer;
if (winmgrImpl.isShowDebugInfo() && debugI != null) {
toUse = debugI.createInterceptComponentRenderer(toUse);
}
if (I18nManager.getInstance().isCurrentThreadMarkLocalizedStringsEnabled() && inlineTranslationI != null) {
toUse = inlineTranslationI.createInterceptComponentRenderer(toUse);
}
return toUse;
}};
}};
}
/* (non-Javadoc)
* @see org.olat.core.gui.control.WindowBackOffice#getWindow()
*/
@Override
public Window getWindow() {
return window;
}
@Override
public ChiefController getChiefController() {
return windowOwner;
}
/* (non-Javadoc)
* @see org.olat.core.gui.control.WindowBackOffice#createDevelopmentController(org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl)
*/
@Override
public Controller createDevelopmentController(UserRequest ureq, WindowControl windowControl) {
return new DevelopmentController(ureq, windowControl,this);
}
/* (non-Javadoc)
* @see org.olat.core.gui.control.WindowBackOffice#getGlobalSettings()
*/
@Override
public GlobalSettings getGlobalSettings() {
return winmgrImpl.getGlobalSettings();
}
@Override
public WindowSettings getWindowSettings() {
if(settings == null) {
settings = new WindowSettings();
}
return settings;
}
@Override
public void setWindowSettings(WindowSettings settings) {
this.settings = settings;
}
/**
* @return
*/
public JSAndCSSAdderImpl createJSAndCSSAdder() {
JSAndCSSAdderImpl jcImpl = new JSAndCSSAdderImpl(this);
return jcImpl;
}
/**
* @see org.olat.core.gui.control.WindowBackOffice#sendCommandTo(org.olat.core.gui.control.winmgr.Command)
*/
@Override
public void sendCommandTo(Command wco) {
if (ajaxC != null) ajaxC.sendCommandTo(new WindowCommand(this,wco));
}
public void pushCommands(UserRequest ureq, HttpServletRequest request, HttpServletResponse response) {
try {
boolean acceptJson = ServletUtil.acceptJson(request);
//first set the headers with the content-type
//and after get the writer with the encoding
//fixed by the content-type
if(acceptJson) {
ServletUtil.setJSONResourceHeaders(response);
Writer w = response.getWriter();
ajaxC.pushJSONAndClear(ureq, w);
} else {
ServletUtil.setStringResourceHeaders(response);
Writer w = response.getWriter();
ajaxC.pushResource(ureq, w, true);
}
} catch (IOException e) {
log.error("Error pushing commans to the AJAX canal.", e);
}
}
/**
* @param wrapHTML
* @return
*/
public MediaResource extractCommands(HttpServletRequest request) {
boolean acceptJson = ServletUtil.acceptJson(request);
return ajaxC.extractMediaResource(!acceptJson);
}
/**
* @return
*/
public InterceptHandler getInterceptHandler() {
return linkedInterceptHandler;
}
/**
* @param ureq
* @param windowControl
* @return the debug controller (not visible on screen, only in debug mode it wraps around each component for dispatching of gui debug info)
*/
public Controller createDebugDispatcherController(UserRequest ureq, WindowControl windowControl) {
guidebugC = new GuiDebugDispatcherController(ureq, windowControl);
this.debug_interceptHandler = guidebugC;
return guidebugC;
}
/**
* Factory method to create the inline translation tool dispatcher controller.
* This implicitly sets the translation controller on the window back office
*
* @param ureq
* @param windowControl
* @return
*/
@Override
public Controller createInlineTranslationDispatcherController(UserRequest ureq, WindowControl windowControl) {
if (inlineTranslationC != null) throw new AssertException("Can't set the inline translation dispatcher twice!", null);
inlineTranslationC = I18nUIFactory.createInlineTranslationIntercepHandlerController(ureq, windowControl);
this.inlineTranslation_interceptHandler = inlineTranslationC;
return inlineTranslationC;
}
@Override
public Controller createAJAXController(UserRequest ureq) {
boolean ajaxEnabled = winmgrImpl.isAjaxEnabled();
ajaxC = new AjaxController(ureq, this, ajaxEnabled);
return ajaxC;
}
/* (non-Javadoc)
* @see org.olat.core.gui.control.WindowBackOffice#isDebuging()
*/
@Override
public boolean isDebuging() {
return Settings.isDebuging();
}
public WindowManagerImpl getWinmgrImpl() {
return winmgrImpl;
}
@Override
public void dispose() {
windowOwner.dispose();
}
/**
* @param enabled
*/
public void setAjaxEnabled(boolean enabled) {
if (ajaxC != null) ajaxC.setAjaxEnabled(enabled);
}
/**
* @param refreshInterval
*/
public void setRequiredRefreshInterval(int refreshInterval) {
if (ajaxC != null) ajaxC.setPollPeriod(refreshInterval);
}
/**
* @param showDebugInfo
*/
public void setShowDebugInfo(boolean showDebugInfo) {
if (guidebugC != null) {
guidebugC.setShowDebugInfo(showDebugInfo);
}
}
/* (non-Javadoc)
* @see org.olat.core.gui.control.WindowBackOffice#getWindowManager()
*/
@Override
public WindowManager getWindowManager() {
return winmgrImpl;
}
/* (non-Javadoc)
* @see org.olat.core.gui.control.WindowBackOffice#createGuiStack(org.olat.core.gui.components.Component)
*/
@Override
public GuiStack createGuiStack(Component initialComponent) {
return new GuiStackNiceImpl(this, initialComponent);
}
public void fireCycleEvent(Event cycleEvent) {
for (GenericEventListener gel : cycleListeners) {
gel.event(cycleEvent);
}
if (cycleEvent == Window.AFTER_VALIDATING) {
// clear the added data for this cycle
guiMessages.clear();
}
}
@Override
public void addCycleListener(GenericEventListener gel) {
cycleListeners.add(gel);
}
@Override
public void removeCycleListener(GenericEventListener gel) {
// Since we use a CopyOnWriteArrayList it is save to remove an event
// listener even when we are in the fireCycleEvent() method at the same time
cycleListeners.remove(gel);
}
@Override
public List<ZIndexWrapper> getGuiMessages() {
return guiMessages;
}
}