Java tutorial
/** * 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) frentix GmbH<br> * http://www.frentix.com<br> * <p> */ package org.olat.core.commons.contextHelp; import java.util.Locale; import org.apache.commons.lang.ArrayUtils; import org.olat.core.commons.chiefcontrollers.LanguageChangedEvent; import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; import org.olat.core.defaults.dispatcher.StaticMediaDispatcher; import org.olat.core.dispatcher.DispatcherAction; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; import org.olat.core.gui.control.generic.breadcrumb.BreadCrumbController; import org.olat.core.gui.control.generic.dtabs.Activateable; import org.olat.core.logging.activity.CoreLoggingResourceable; import org.olat.core.logging.activity.OlatLoggingAction; import org.olat.core.logging.activity.StringResourceableType; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.event.EventBus; import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; /** * <h3>Description:</h3> This controller serves as the main entry point of the context help display controller. The workflow is intended to run in a separate window. * <p> * The controller can be triggered in two modes: * <ul> * <li>/help/de/org.olat.core/mychelp_page.html : the new, preferred style</li> * <li>/help/de/mychelp_page.html : legacy mode to support old external links. Don't use this when creating new pages!</li> </li> Those are only the entry URL's. As soon * as the window is build up, everything works via the framework. * <p> * To be delievered context help files must be in a _chelp directory in the classpath. Links to the page are made using the velocity helper method * $r.contextHelp("org.olat.core", "mychelp_page.html", "help to mypage") * <p> * Each context help page must provide a translated title in the same package as the page is located using the syntax 'chelp.PAGENAME.title': Example: <br> * <code>page: my.package._chelp.my_help.html </code><br> * <code>chelp.my_help.title translated in my.package._i18n</code> * <p> * Context help files can reference static resources, e.g. images. Those images must be in the _static directory within the _chelp directory:<br> * <code>resource: my.package._chelp._static.myimage_de.png</code> <br> * The resource must be in the static directory for each locale. A fallback mechanism checks if the resource exists and uses the fallback image when no image is found. <br> * In the html template the resource must be addressed without the locale, e.g: <code><img src='chelpStaticDirUrl/myimage.png' ></code> <br> * This will load the resource from my.package._chelp._static.myimage_de.png * <p> * The controller listens to LanguageChangedEvent and changes the locale for is children when such an event occures (fired by ContextHelpTopNavController) * <p> * The workflow features a table of contents and a page details view. The navigation is implemented using a bread crumb controller. Sub-pages are also supported. Links to * those sub-pages must be made with<br> * <code>$r.contextHelpRelativeLink("my-pagename.html")</code> * <h3>Events thrown by this controller:</h3> * <ul> * <li>none</li> * </ul> * <p> * Initial Date: 04.11.2008 <br> * * @author Florian Gnaegi, frentix GmbH, http://www.frentix.com */ class ContextHelpMainController extends MainLayoutBasicController implements GenericEventListener { private LayoutMain3ColsController mainLayoutCtr; private BreadCrumbController breadCrumbLayoutCtr; private ContextHelpTOCCrumbController startCtr; private EventBus eventBus; /** * Constructor for the context help display. * * @param ureq * @param control */ public ContextHelpMainController(UserRequest ureq, WindowControl control) { super(ureq, control); String[] uriParts = ureq.getNonParsedUri().split("/"); String lang = null; // get lang and set locale for help page accordingly lang = uriParts[0]; Locale newLocale = I18nManager.getInstance().getLocaleOrNull(lang); if (newLocale == null || !I18nModule.getEnabledLanguageKeys().contains(newLocale.toString())) { newLocale = I18nModule.getDefaultLocale(); } if (!getLocale().toString().equals(newLocale.toString())) { setLocale(newLocale, true); } // Create bread crumb navigation breadCrumbLayoutCtr = new BreadCrumbController(ureq, control); listenTo(breadCrumbLayoutCtr); // Add translation tool start controller to bread crumb startCtr = new ContextHelpTOCCrumbController(ureq, control, newLocale); listenTo(startCtr); breadCrumbLayoutCtr.activateFirstCrumbController(startCtr); // Our view is generated by the main and the bread crumb layouer mainLayoutCtr = new LayoutMain3ColsController(ureq, getWindowControl(), null, null, breadCrumbLayoutCtr.getInitialComponent(), null); listenTo(mainLayoutCtr); putInitialPanel(mainLayoutCtr.getInitialComponent()); activatePageFromURL(uriParts, ureq, startCtr); // Register for events on this user session. Identity is set to null, but // event bus is still user-session only eventBus = ureq.getUserSession().getSingleUserEventCenter(); eventBus.registerFor(this, ureq.getIdentity(), ContextHelpTopNavController.CHANGE_LANG_RESOURCE); // do logging if (ureq.getUserSession().getSessionInfo() != null) { // context help can be called in dmz zone as well - in that case don't call log() - only call log() for logged-in users ThreadLocalUserActivityLogger.log(OlatLoggingAction.CS_HELP, getClass(), CoreLoggingResourceable .wrapNonOlatResource(StringResourceableType.csHelp, "-1", ArrayUtils.toString(uriParts))); } } /** * Internal helper to parse the URL for an entry point to a specific help page * * @param uriParts * @param ureq * @param activateableController */ private void activatePageFromURL(String[] uriParts, UserRequest ureq, Activateable activateableController) { // Initialize active page // add context help page // Try to extract requested help page from URI String page = null, bundleName = null; if (uriParts.length == 2) { // 1) Legacy context help URL : lookup from map and if not found // redirect to static dispatcher to load old static help file page = uriParts[1]; bundleName = ContextHelpModule.getContextHelpPagesLegacyLookupIndex().get(page); if (bundleName == null) { // Help page not found, try it with static legacy help files String legacyHelpUrl = StaticMediaDispatcher.createStaticURIFor("help/" + ureq.getNonParsedUri()); DispatcherAction.redirectTo(ureq.getHttpResp(), legacyHelpUrl); return; } } else if (uriParts.length == 3) { // 2) Normal case: get page bundle and name bundleName = uriParts[1]; page = uriParts[2]; } if (page != null || bundleName != null) { activateableController.activate(ureq, bundleName + ":" + page); } } /** * @see org.olat.core.util.event.GenericEventListener#event(org.olat.core.gui.control.Event) */ @Override public void event(Event event) { if (event instanceof LanguageChangedEvent) { LanguageChangedEvent langEvent = (LanguageChangedEvent) event; Locale newLocale = langEvent.getNewLocale(); setLocale(newLocale, true); // Set new locale on bread crumb chain startCtr.setLocale(newLocale, langEvent.getCurrentUreq()); // Reset all text lables on bread crumb breadCrumbLayoutCtr.resetCrumbTexts(); } } /* * (non-Javadoc) * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) */ @Override protected void event(UserRequest ureq, Component source, Event event) { // no events to catch } /* * (non-Javadoc) * @see org.olat.core.gui.control.DefaultController#doDispose() */ @Override protected void doDispose() { // Controllers autodisposed by BasicController eventBus.deregisterFor(this, ContextHelpTopNavController.CHANGE_LANG_RESOURCE); eventBus = null; } }