org.apache.openmeetings.web.app.Application.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.openmeetings.web.app.Application.java

Source

/*
 * 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.apache.openmeetings.util.OpenmeetingsVariables.wicketApplicationName;
import static org.apache.openmeetings.web.pages.HashPage.INVITATION_HASH;
import static org.apache.openmeetings.web.user.rooms.RoomEnterBehavior.getRoomUrlFragment;
import static org.apache.openmeetings.web.util.OmUrlFragment.PROFILE_MESSAGES;
import static org.red5.logging.Red5LoggerFactory.getLogger;
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.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.collections4.MapIterator;
import org.apache.commons.collections4.keyvalue.MultiKey;
import org.apache.commons.collections4.map.MultiKeyMap;
import org.apache.openmeetings.IApplication;
import org.apache.openmeetings.core.remote.MainService;
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.db.entity.record.Recording;
import org.apache.openmeetings.db.entity.room.Invitation;
import org.apache.openmeetings.db.entity.room.Room;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.db.entity.user.User.Type;
import org.apache.openmeetings.util.InitializationContainer;
import org.apache.openmeetings.web.pages.AccessDeniedPage;
import org.apache.openmeetings.web.pages.ActivatePage;
import org.apache.openmeetings.web.pages.HashPage;
import org.apache.openmeetings.web.pages.MainPage;
import org.apache.openmeetings.web.pages.NotInitedPage;
import org.apache.openmeetings.web.pages.ResetPage;
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.user.dashboard.admin.AdminWidgetDescriptor;
import org.apache.openmeetings.web.user.record.AviRecordingResourceReference;
import org.apache.openmeetings.web.user.record.FlvRecordingResourceReference;
import org.apache.openmeetings.web.user.record.JpgRecordingResourceReference;
import org.apache.openmeetings.web.user.record.Mp4RecordingResourceReference;
import org.apache.openmeetings.web.user.record.OggRecordingResourceReference;
import org.apache.openmeetings.web.util.ProfileImageResourceReference;
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.cycle.RequestCycle;
import org.apache.wicket.request.mapper.info.PageComponentInfo;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
import org.apache.wicket.util.collections.ConcurrentHashSet;
import org.slf4j.Logger;
import org.springframework.web.context.WebApplicationContext;
import org.wicketstuff.dashboard.WidgetRegistry;
import org.wicketstuff.dashboard.web.DashboardContext;
import org.wicketstuff.dashboard.web.DashboardContextInjector;
import org.wicketstuff.dashboard.web.DashboardSettings;

public class Application extends AuthenticatedWebApplication implements IApplication {
    private static final Logger log = getLogger(Application.class, webAppRootKey);
    private static boolean isInstalled;
    private static MultiKeyMap<String, org.apache.openmeetings.web.app.Client> ONLINE_USERS = new MultiKeyMap<>();
    private static Map<String, org.apache.openmeetings.web.app.Client> INVALID_SESSIONS = new ConcurrentHashMap<String, org.apache.openmeetings.web.app.Client>();
    private static Map<Long, Set<Client>> ROOMS = new ConcurrentHashMap<Long, Set<Client>>();
    //additional maps for faster searching should be created
    private DashboardContext dashboardContext;
    private static Set<String> STRINGS_WITH_APP = new HashSet<>(); //FIXME need to be removed
    private static String appName;
    static {
        STRINGS_WITH_APP.addAll(Arrays.asList("499", "500", "506", "511", "512", "513", "517", "532", "622", "804",
                "909", "952", "978", "981", "984", "989", "990", "999", "1151", "1155", "1157", "1158", "1194"));
    }

    @Override
    protected void init() {
        wicketApplicationName = super.getName();
        getSecuritySettings().setAuthenticationStrategy(new OmAuthenticationStrategy());
        getApplicationSettings().setAccessDeniedPage(AccessDeniedPage.class);

        //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());

        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());
        widgetRegistry.registerWidget(new AdminWidgetDescriptor());
        // 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", HashPage.class));
        //getRootRequestMapperAsCompound().add(new NoVersionMapper("/hash", HashPage.class));
        getRootRequestMapperAsCompound().add(new NoVersionMapper("/recording/${hash}", HashPage.class));
        getRootRequestMapperAsCompound().add(new NoVersionMapper("signin", getSignInPageClass()));
        mountPage("install", InstallWizardPage.class);
        mountPage("activate", ActivatePage.class);
        mountPage("reset", ResetPage.class);
        mountPage("/hash", HashPage.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
        mountResource("/profile/${id}", new ProfileImageResourceReference());
    }

    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(org.apache.openmeetings.web.app.Client client) {
        try {
            ONLINE_USERS.put("" + client.getUserId(), client.getSessionId(), client);
        } catch (Exception err) {
            log.error("[addOnlineUser]", err);
        }
    }

    public synchronized static void removeOnlineUser(org.apache.openmeetings.web.app.Client c) {
        try {
            if (c != null) {
                ONLINE_USERS.removeAll("" + c.getUserId(), c.getSessionId());
            }
        } catch (Exception err) {
            log.error("[removeOnlineUser]", err);
        }
    }

    public static boolean isUserOnline(Long userId) {
        MapIterator<MultiKey<? extends String>, org.apache.openmeetings.web.app.Client> it = ONLINE_USERS
                .mapIterator();
        boolean isUserOnline = false;
        while (it.hasNext()) {
            MultiKey<? extends String> multi = it.next();
            if (multi.size() > 0 && userId.equals(multi.getKey(0))) {
                isUserOnline = true;
                break;
            }
        }
        return isUserOnline;
    }

    public static List<org.apache.openmeetings.web.app.Client> getClients() {
        return new ArrayList<org.apache.openmeetings.web.app.Client>(ONLINE_USERS.values());
    }

    public static List<org.apache.openmeetings.web.app.Client> getClients(Long userId) {
        List<org.apache.openmeetings.web.app.Client> result = new ArrayList<org.apache.openmeetings.web.app.Client>();
        MapIterator<MultiKey<? extends String>, org.apache.openmeetings.web.app.Client> it = ONLINE_USERS
                .mapIterator();
        while (it.hasNext()) {
            MultiKey<? extends String> multi = it.next();
            if (multi.size() > 1 && userId.equals(multi.getKey(0))) {
                result.add(getClientByKeys(userId, (String) (multi.getKey(1))));
                break;
            }
        }
        return result;
    }

    public static int getClientsSize() {
        return ONLINE_USERS.size();
    }

    public static org.apache.openmeetings.web.app.Client getClientByKeys(Long userId, String sessionId) {
        return (org.apache.openmeetings.web.app.Client) ONLINE_USERS.get(userId, sessionId);
    }

    @Override
    public void invalidateClient(Long userId, String sessionId) {
        org.apache.openmeetings.web.app.Client client = getClientByKeys(userId, sessionId);
        if (client != null) {
            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);
        }
    }

    public static Client addUserToRoom(long roomId, int pageId) {
        if (!ROOMS.containsKey(roomId)) {
            ROOMS.put(roomId, new ConcurrentHashSet<Client>());
        }
        Client c = new Client(WebSession.get().getId(), pageId, WebSession.getUserId());
        c.setUid(UUID.randomUUID().toString());
        ROOMS.get(roomId).add(c);
        return c;
    }

    public static void removeUserFromRoom(long roomId, int pageId) {
        removeUserFromRoom(roomId, new Client(WebSession.get().getId(), pageId, WebSession.getUserId()));
    }

    public static Client removeUserFromRoom(long roomId, Client _c) {
        if (ROOMS.containsKey(roomId)) {
            Set<Client> clients = ROOMS.get(roomId);
            for (Client c : clients) {
                if (c.equals(_c)) {
                    clients.remove(c);
                    return c;
                }
            }
            if (clients.isEmpty()) {
                ROOMS.remove(roomId);
            }
        }
        return _c;
    }

    public static long getRoom(Client c) {
        for (Entry<Long, Set<Client>> me : ROOMS.entrySet()) {
            Set<Client> clients = me.getValue();
            if (clients.contains(c)) {
                return me.getKey();
            }
        }
        return -1;
    }

    public static Set<Client> getRoomUsers(long roomId) {
        return ROOMS.containsKey(roomId) ? ROOMS.get(roomId) : new HashSet<Client>();
    }

    public static Set<Long> getUserRooms(long userId) {
        Set<Long> result = new HashSet<Long>();
        for (Entry<Long, Set<Client>> me : ROOMS.entrySet()) {
            for (Client c : me.getValue()) {
                if (c.getUserId() == userId) {
                    result.add(me.getKey());
                }
            }
        }
        return result;
    }

    public static boolean isUserInRoom(long roomId, long userId) {
        if (ROOMS.containsKey(roomId)) {
            Set<Client> clients = ROOMS.get(roomId);
            for (Client c : clients) {
                if (c.getUserId() == userId) {
                    return true;
                }
            }
        }
        return false;
    }

    //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(String id) {
        return getString(id, WebSession.getLanguage());
    }

    public static Locale getLocale(final long languageId) {
        Locale loc = LabelDao.languages.get(languageId);
        if (loc == null) {
            loc = WebSession.exists() ? WebSession.get().getLocale() : Locale.ENGLISH;
        }
        return loc;
    }

    public static String getString(String key, final long languageId) {
        return getString(key, getLocale(languageId), false);
    }

    public static String getString(long id, final long languageId) {
        return getString(id, getLocale(languageId));
    }

    public static String getString(long id, final Locale loc) {
        return getString("" + id, loc, false);
    }

    public static String getString(String key, final Locale loc, boolean noReplace) {
        if (!exists()) {
            ThreadContext.setApplication(Application.get(appName));
        }
        Localizer l = get().getResourceSettings().getLocalizer();
        String value = l.getStringIgnoreSettings(key, null, null, loc, null, "[Missing]");
        if (!noReplace && STRINGS_WITH_APP.contains(key)) {
            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]", key);
        }
        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);
        }
    }

    @Override
    public <T> T getOmBean(Class<T> clazz) { //FIXME hack for email templates support (should be in separate module for now
        return Application.getBean(clazz);
    }

    public static String getContactsLink() {
        return PROFILE_MESSAGES.getLink();
    }

    @Override
    public String getOmContactsLink() { //FIXME hack for email templates support (should be in separate module for now
        return getContactsLink();
    }

    public static String getInvitationLink(Invitation i) {
        String link = "";
        Room r = i.getRoom();
        User u = i.getInvitee();
        if (r != null) {
            boolean allowed = u.getType() != Type.contact;
            if (allowed) {
                allowed = getBean(MainService.class).isRoomAllowedToUser(r, u);
            }
            if (!allowed) {
                PageParameters pp = new PageParameters();
                pp.add(INVITATION_HASH, i.getHash());
                if (u.getLanguageId() > 0) {
                    pp.add("language", u.getLanguageId());
                }
                link = urlForPage(HashPage.class, pp);
            } else {
                link = getRoomUrlFragment(r.getId()).getLink();
            }
        }
        Recording rec = i.getRecording();
        if (rec != null) {
            link = urlForPage(HashPage.class, new PageParameters().add(INVITATION_HASH, i.getHash()));
        }
        return link;
    }

    @Override
    public String getOmInvitationLink(Invitation i) { //FIXME hack for email templates support (should be in separate module for now
        return getInvitationLink(i);
    }

    public static String urlForPage(Class<? extends Page> clazz, PageParameters pp) {
        RequestCycle rc = RequestCycle.get();
        return rc.getUrlRenderer()
                .renderFullUrl(Url.parse(getBean(ConfigurationDao.class).getBaseUrl() + rc.urlFor(clazz, pp)));
    }

    @Override
    public String urlForActivatePage(PageParameters pp) { //FIXME hack for email templates support (should be in separate module for now
        return urlForPage(ActivatePage.class, pp);
    }

    @Override
    public String getOmString(long id) {
        return getString(id);
    }

    @Override
    public String getOmString(long id, long languageId) {
        return getString(id, languageId);
    }

    @Override
    public String getOmString(String key, long languageId) {
        return getString(key, languageId);
    }
}