| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License") + you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openmeetings.web.app; |
| |
| import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey; |
| import static org.red5.logging.Red5LoggerFactory.getLogger; |
| import static org.springframework.web.context.WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE; |
| import static org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext; |
| |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import javax.servlet.ServletContext; |
| |
| import org.apache.commons.collections.MapIterator; |
| import org.apache.commons.collections.keyvalue.MultiKey; |
| import org.apache.commons.collections.map.MultiKeyMap; |
| import org.apache.openmeetings.db.dao.basic.ConfigurationDao; |
| import org.apache.openmeetings.db.dao.label.LabelDao; |
| import org.apache.openmeetings.db.dao.user.UserDao; |
| import org.apache.openmeetings.util.InitializationContainer; |
| import org.apache.openmeetings.web.pages.ActivatePage; |
| import org.apache.openmeetings.web.pages.MainPage; |
| import org.apache.openmeetings.web.pages.NotInitedPage; |
| import org.apache.openmeetings.web.pages.RecordingPage; |
| import org.apache.openmeetings.web.pages.ResetPage; |
| import org.apache.openmeetings.web.pages.SwfPage; |
| import org.apache.openmeetings.web.pages.auth.SignInPage; |
| import org.apache.openmeetings.web.pages.install.InstallWizardPage; |
| import org.apache.openmeetings.web.user.dashboard.MyRoomsWidgetDescriptor; |
| import org.apache.openmeetings.web.user.dashboard.RssWidgetDescriptor; |
| import org.apache.openmeetings.web.user.dashboard.StartWidgetDescriptor; |
| import org.apache.openmeetings.web.user.dashboard.WelcomeWidgetDescriptor; |
| import org.apache.openmeetings.web.util.AviRecordingResourceReference; |
| import org.apache.openmeetings.web.util.FlvRecordingResourceReference; |
| import org.apache.openmeetings.web.util.JpgRecordingResourceReference; |
| import org.apache.openmeetings.web.util.Mp4RecordingResourceReference; |
| import org.apache.openmeetings.web.util.OggRecordingResourceReference; |
| import org.apache.openmeetings.web.util.UserDashboardPersister; |
| import org.apache.wicket.Localizer; |
| import org.apache.wicket.Page; |
| import org.apache.wicket.RestartResponseException; |
| import org.apache.wicket.RuntimeConfigurationType; |
| import org.apache.wicket.ThreadContext; |
| import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession; |
| import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication; |
| import org.apache.wicket.core.request.handler.BookmarkableListenerInterfaceRequestHandler; |
| import org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler; |
| import org.apache.wicket.core.request.mapper.MountedMapper; |
| import org.apache.wicket.markup.html.WebPage; |
| import org.apache.wicket.protocol.http.WebApplication; |
| import org.apache.wicket.request.IRequestHandler; |
| import org.apache.wicket.request.Url; |
| import org.apache.wicket.request.component.IRequestablePage; |
| import org.apache.wicket.request.mapper.info.PageComponentInfo; |
| import org.apache.wicket.request.mapper.parameter.PageParametersEncoder; |
| import org.apache.wicket.util.tester.WicketTester; |
| import org.slf4j.Logger; |
| import org.springframework.web.context.WebApplicationContext; |
| import org.springframework.web.context.support.XmlWebApplicationContext; |
| import org.wicketstuff.select2.ApplicationSettings; |
| |
| import ro.fortsoft.wicket.dashboard.WidgetRegistry; |
| import ro.fortsoft.wicket.dashboard.web.DashboardContext; |
| import ro.fortsoft.wicket.dashboard.web.DashboardContextInjector; |
| import ro.fortsoft.wicket.dashboard.web.DashboardSettings; |
| |
| public class Application extends AuthenticatedWebApplication { |
| private static final Logger log = getLogger(Application.class, webAppRootKey); |
| private static boolean isInstalled; |
| private static MultiKeyMap ONLINE_USERS = new MultiKeyMap(); |
| private static Map<String, WebClient> INVALID_SESSIONS = new ConcurrentHashMap<String, WebClient>(); |
| private DashboardContext dashboardContext; |
| private static Set<Long> STRINGS_WITH_APP = new HashSet<Long>(); //FIXME need to be removed |
| private static String appName; |
| static { |
| STRINGS_WITH_APP.addAll(Arrays.asList(499L, 500L, 506L, 511L, 512L, 513L, 517L, 532L, 622L, 804L |
| , 909L, 952L, 978L, 981L, 984L, 989L, 990L, 999L, 1151L, 1155L, 1157L, 1158L, 1194L)); |
| } |
| |
| @Override |
| protected void init() { |
| appName = super.getName(); |
| getSecuritySettings().setAuthenticationStrategy(new OmAuthenticationStrategy()); |
| |
| //Add custom resource loader at the beginning, so it will be checked first in the |
| //chain of Resource Loaders, if not found it will search in Wicket's internal |
| //Resource Loader for a the property key |
| getResourceSettings().getStringResourceLoaders().add(0, new LabelResourceLoader()); |
| |
| ApplicationSettings.get().setIncludeJqueryUI(false); |
| super.init(); |
| |
| // register some widgets |
| dashboardContext = new DashboardContext(); |
| dashboardContext.setDashboardPersister(new UserDashboardPersister()); |
| WidgetRegistry widgetRegistry = dashboardContext.getWidgetRegistry(); |
| widgetRegistry.registerWidget(new MyRoomsWidgetDescriptor()); |
| widgetRegistry.registerWidget(new WelcomeWidgetDescriptor()); |
| widgetRegistry.registerWidget(new StartWidgetDescriptor()); |
| widgetRegistry.registerWidget(new RssWidgetDescriptor()); |
| // add dashboard context injector |
| getComponentInstantiationListeners().add(new DashboardContextInjector(dashboardContext)); |
| DashboardSettings dashboardSettings = DashboardSettings.get(); |
| dashboardSettings.setIncludeJQuery(false); |
| dashboardSettings.setIncludeJQueryUI(false); |
| |
| getRootRequestMapperAsCompound().add(new NoVersionMapper(getHomePage())); |
| getRootRequestMapperAsCompound().add(new NoVersionMapper("notinited", NotInitedPage.class)); |
| getRootRequestMapperAsCompound().add(new NoVersionMapper("swf", SwfPage.class)); |
| getRootRequestMapperAsCompound().add(new NoVersionMapper("signin", getSignInPageClass())); |
| mountPage("install", InstallWizardPage.class); |
| mountPage("activate", ActivatePage.class); |
| mountPage("reset", ResetPage.class); |
| mountPage("/recording/${hash}", RecordingPage.class); |
| mountResource("/recordings/avi/${id}", new AviRecordingResourceReference()); |
| mountResource("/recordings/flv/${id}", new FlvRecordingResourceReference()); |
| mountResource("/recordings/mp4/${id}", new Mp4RecordingResourceReference()); |
| mountResource("/recordings/ogg/${id}", new OggRecordingResourceReference()); |
| mountResource("/recordings/jpg/${id}", new JpgRecordingResourceReference()); //should be in sync with VideoPlayer |
| } |
| |
| private static class NoVersionMapper extends MountedMapper { |
| public NoVersionMapper(final Class<? extends IRequestablePage> pageClass) { |
| this("/", pageClass); |
| } |
| |
| public NoVersionMapper(String mountPath, final Class<? extends IRequestablePage> pageClass) { |
| super(mountPath, pageClass, new PageParametersEncoder()); |
| } |
| |
| @Override |
| protected void encodePageComponentInfo(Url url, PageComponentInfo info) { |
| //Does nothing |
| } |
| |
| @Override |
| public Url mapHandler(IRequestHandler requestHandler) { |
| if (requestHandler instanceof ListenerInterfaceRequestHandler || requestHandler instanceof BookmarkableListenerInterfaceRequestHandler) { |
| return null; |
| } else { |
| return super.mapHandler(requestHandler); |
| } |
| } |
| } |
| |
| public static OmAuthenticationStrategy getAuthenticationStrategy() { |
| return (OmAuthenticationStrategy)get().getSecuritySettings().getAuthenticationStrategy(); |
| } |
| |
| @Override |
| public Class<? extends Page> getHomePage() { |
| return MainPage.class; |
| } |
| |
| @Override |
| protected Class<? extends AbstractAuthenticatedWebSession> getWebSessionClass() { |
| return WebSession.class; |
| } |
| |
| @Override |
| public Class<? extends WebPage> getSignInPageClass() { |
| return SignInPage.class; |
| } |
| |
| public static Application get() { |
| return (Application) WebApplication.get(); |
| } |
| |
| public static DashboardContext getDashboardContext() { |
| return get().dashboardContext; |
| } |
| |
| public synchronized static void addOnlineUser(WebClient client) { |
| try { |
| ONLINE_USERS.put(client.getUserId(), client.getSessionId(), client); |
| } catch (Exception err) { |
| log.error("[addOnlineUser]", err); |
| } |
| } |
| |
| public synchronized static void removeOnlineUser(WebClient c) { |
| try { |
| if (c != null) { |
| ONLINE_USERS.remove(c.getUserId(), c.getSessionId()); |
| } |
| } catch (Exception err) { |
| log.error("[removeOnlineUser]", err); |
| } |
| } |
| |
| public static boolean isUserOnline(Long userId) { |
| MapIterator it = ONLINE_USERS.mapIterator(); |
| boolean isUserOnline = false; |
| while (it.hasNext()) { |
| MultiKey multi = (MultiKey) it.next(); |
| if (multi.size() > 0 && userId.equals(multi.getKey(0))){ |
| isUserOnline = true; |
| break; |
| } |
| } |
| return isUserOnline; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public static List<WebClient> getClients() { |
| return new ArrayList<WebClient>(ONLINE_USERS.values()); |
| } |
| |
| public static int getClientsSize() { |
| return ONLINE_USERS.size(); |
| } |
| |
| public static WebClient getClientByKeys(Long userId, String sessionId) { |
| return (WebClient) ONLINE_USERS.get(userId, sessionId); |
| } |
| |
| public static void invalidateClient(WebClient client) { |
| if (!INVALID_SESSIONS.containsKey(client.getSessionId())) { |
| INVALID_SESSIONS.put(client.getSessionId(), client); |
| removeOnlineUser(client); |
| } |
| } |
| |
| public static boolean isInvaldSession(String sessionId) { |
| return sessionId == null ? false : INVALID_SESSIONS.containsKey(sessionId); |
| } |
| |
| public static void removeInvalidSession(String sessionId) { |
| if (INVALID_SESSIONS.containsKey(sessionId)){ |
| INVALID_SESSIONS.remove(sessionId); |
| } |
| } |
| |
| //TODO need more safe way FIXME |
| public <T> T _getBean(Class<T> clazz) { |
| WebApplicationContext wac = getWebApplicationContext(getServletContext()); |
| return wac == null ? null : wac.getBean(clazz); |
| } |
| |
| public static String getString(long id) { |
| return getString(id, WebSession.getLanguage()); |
| } |
| |
| public static String getString(long id, final long languageId) { |
| Locale loc = LabelDao.languages.get(languageId); |
| if (loc == null) { |
| loc = WebSession.exists() ? WebSession.get().getLocale() : Locale.ENGLISH; |
| } |
| return getString(id, loc); |
| } |
| |
| public static String getString(long id, final Locale loc) { |
| return getString(id, loc, false); |
| } |
| |
| public static String getString(long id, final Locale loc, boolean noReplace) { |
| if (!exists()) { |
| ThreadContext.setApplication(Application.get(appName)); |
| } |
| Localizer l = get().getResourceSettings().getLocalizer(); |
| String value = l.getStringIgnoreSettings("" + id, null, null, loc, null, "[Missing]"); |
| if (!noReplace && STRINGS_WITH_APP.contains(id)) { |
| final MessageFormat format = new MessageFormat(value, loc); |
| value = format.format(new Object[]{getBean(ConfigurationDao.class).getAppName()}); |
| } |
| if (!noReplace && RuntimeConfigurationType.DEVELOPMENT == get().getConfigurationType()) { |
| value += String.format(" [%s]", id); |
| } |
| return value; |
| } |
| |
| public static boolean isInstalled() { |
| boolean result = isInstalled; |
| if (!isInstalled) { |
| if (InitializationContainer.initComplete) { |
| //TODO can also check crypt class here |
| isInstalled = result = get()._getBean(UserDao.class).count() > 0; |
| } |
| } |
| return result; |
| } |
| |
| public static <T> T getBean(Class<T> clazz) { |
| if (InitializationContainer.initComplete) { |
| if (!isInstalled()) { |
| throw new RestartResponseException(InstallWizardPage.class); |
| } |
| return get()._getBean(clazz); |
| } else { |
| throw new RestartResponseException(NotInitedPage.class); |
| } |
| } |
| |
| public static WicketTester getWicketTester() { |
| return getWicketTester(-1); |
| } |
| |
| public static WicketTester getWicketTester(long langId) { |
| Application app = new Application(); |
| |
| WicketTester tester = new WicketTester(app); |
| ServletContext sc = app.getServletContext(); |
| XmlWebApplicationContext xmlContext = new XmlWebApplicationContext(); |
| xmlContext.setConfigLocation("classpath:openmeetings-applicationContext.xml"); |
| xmlContext.setServletContext(sc); |
| xmlContext.refresh(); |
| sc.setAttribute(ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, xmlContext); |
| if (langId > 0) { |
| WebSession.get().setLanguage(langId); |
| } |
| InitializationContainer.initComplete = true; |
| return tester; |
| } |
| |
| public static void destroy(WicketTester tester) { |
| if (tester != null) { |
| ServletContext sc = tester.getServletContext(); |
| try { |
| ((XmlWebApplicationContext)sc.getAttribute(ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)).close(); |
| } catch (Exception e) { |
| log.error("Unexpected error while destroying XmlWebApplicationContext", e); |
| } |
| tester.destroy(); |
| } |
| } |
| |
| public static String getAppName() { |
| return appName; |
| } |
| } |