All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.red5.server.util.ScopeUtils Maven / Gradle / Ivy

/*
 * RED5 Open Source Media Server - https://github.com/Red5/
 * 
 * Copyright 2006-2016 by respective authors (see below). All rights reserved.
 * 
 * Licensed 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.red5.server.util;

import java.lang.reflect.Field;
import java.util.Arrays;

import org.red5.server.api.IContext;
import org.red5.server.api.persistence.IPersistable;
import org.red5.server.api.scope.IBasicScope;
import org.red5.server.api.scope.IScope;
import org.red5.server.api.scope.IScopeHandler;
import org.red5.server.api.scope.IScopeService;
import org.red5.server.api.scope.ScopeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

/**
 * Collection of utilities for working with scopes
 */
public class ScopeUtils {

    private static final Logger log = LoggerFactory.getLogger(ScopeUtils.class);

    private static final String SERVICE_CACHE_PREFIX = "__service_cache:";

    /**
     * Constant for slash symbol
     */
    private static final String SLASH = "/";

    /**
     * Resolves scope for specified scope and path.
     *
     * @param from
     *            Scope to use as context (to start from)
     * @param path
     *            Path to resolve
     * @return Resolved scope
     */
    public static IScope resolveScope(IScope from, String path) {
        log.debug("resolveScope from: {} path: {}", from.getName(), path);
        IScope current = from;
        if (path.startsWith(SLASH)) {
            current = ScopeUtils.findRoot(current);
            path = path.substring(1, path.length());
        }
        if (path.endsWith(SLASH)) {
            path = path.substring(0, path.length() - 1);
        }
        log.trace("Current: {}", current);
        String[] parts = path.split(SLASH);
        if (log.isTraceEnabled()) {
            log.trace("Parts: {}", Arrays.toString(parts));
        }
        for (String part : parts) {
            log.trace("Part: {}", part);
            if (part.equals(".")) {
                continue;
            }
            if (part.equals("..")) {
                if (!current.hasParent()) {
                    return null;
                }
                current = current.getParent();
                continue;
            }
            if (!current.hasChildScope(part)) {
                return null;
            }
            current = current.getScope(part);
            log.trace("Current: {}", current);
        }
        return current;
    }

    /**
     * Finds root scope for specified scope object. Root scope is the top level scope among scope's parents.
     *
     * @param from
     *            Scope to find root for
     * @return Root scope object
     */
    public static IScope findRoot(IScope from) {
        IScope current = from;
        while (current.hasParent()) {
            current = current.getParent();
        }
        return current;
    }

    /**
     * Returns the application scope for specified scope. Application scope has depth of 1 and has no parent.
     *
     * See
     * 
     * 
     * isApp
     * 
* * method for details. * * @param from * Scope to find application for * @return Application scope. */ public static IScope findApplication(IScope from) { IScope current = from; while (current.hasParent() && !current.getType().equals(ScopeType.APPLICATION)) { current = current.getParent(); } return current; } /** * Check whether one scope is an ancestor of another * * @param from * Scope * @param ancestor * Scope to check * @return
     * true
     * 
* * if ancestor scope is really an ancestor of scope passed as from parameter, * *
     * false
     * 
* * otherwise. */ public static boolean isAncestor(IBasicScope from, IBasicScope ancestor) { IBasicScope current = from; while (current.hasParent()) { current = current.getParent(); if (current.equals(ancestor)) { return true; } } return false; } /** * Checks whether scope is root or not * * @param scope * Scope to check * @return
     * true
     * 
* * if scope is root scope (top level scope), * *
     * false
     * 
* * otherwise. */ public static boolean isRoot(IBasicScope scope) { return !scope.hasParent(); } /** * Check whether scope is the global scope (level 0 leaf in scope tree) or not * * When user connects the following URL: rtmp://localhost/myapp/foo/bar then / is the global level scope, myapp is app level, foo is room level and bar is room level as well (but with higher depth level) * * @param scope * Scope to check * @return
     * true
     * 
* * if scope is the global scope, * *
     * false
     * 
* * otherwise. */ public static boolean isGlobal(IBasicScope scope) { return scope.getType().equals(ScopeType.GLOBAL); } /** * Check whether scope is an application scope (level 1 leaf in scope tree) or not * * @param scope * Scope to check * @return
     * true
     * 
* * if scope is an application scope, * *
     * false
     * 
* * otherwise. */ public static boolean isApp(IBasicScope scope) { return scope.getType().equals(ScopeType.APPLICATION); } /** * Check whether scope is a room scope (level 2 leaf in scope tree or lower, e.g. 3, 4, ...) or not * * @param scope * Scope to check * @return
     * true
     * 
* * if scope is a room scope, * *
     * false
     * 
* * otherwise. */ public static boolean isRoom(IBasicScope scope) { return scope.getType().equals(ScopeType.ROOM); } /** * Returns scope service by bean name. See overloaded method for details. * * @param scope * scope * @param name * name * @return object */ protected static Object getScopeService(IScope scope, String name) { return getScopeService(scope, name, null); } /** * Returns scope services (e.g. SharedObject, etc) for the scope. Method uses either bean name passes as a string or class object. * * @param scope * The scope service belongs to * @param name * Bean name * @param defaultClass * Class of service * @return Service object */ protected static Object getScopeService(IScope scope, String name, Class defaultClass) { if (scope != null) { final IContext context = scope.getContext(); ApplicationContext appCtx = context.getApplicationContext(); Object result; if (!appCtx.containsBean(name)) { if (defaultClass == null) { return null; } try { result = defaultClass.newInstance(); } catch (Exception e) { log.error("{}", e); return null; } } else { result = appCtx.getBean(name); } return result; } return null; } /** * Returns scope service that implements a given interface. * * @param scope * The scope service belongs to * @param intf * The interface the service must implement * @return Service object */ public static Object getScopeService(IScope scope, Class intf) { return getScopeService(scope, intf, null); } public static Object getScopeService(IScope scope, Class intf, boolean checkHandler) { return getScopeService(scope, intf, null, checkHandler); } /** * Returns scope service that implements a given interface. * * @param scope * The scope service belongs to * @param intf * The interface the service must implement * @param defaultClass * Class that should be used to create a new service if no service was found. * @return Service object */ public static Object getScopeService(IScope scope, Class intf, Class defaultClass) { return getScopeService(scope, intf, defaultClass, true); } public static Object getScopeService(IScope scope, Class intf, Class defaultClass, boolean checkHandler) { if (scope == null || intf == null) { return null; } // We expect an interface assert intf.isInterface(); String attr = String.format("%s%s%s", IPersistable.TRANSIENT_PREFIX, SERVICE_CACHE_PREFIX, intf.getCanonicalName()); if (scope.hasAttribute(attr)) { // return cached service return scope.getAttribute(attr); } Object handler = null; if (checkHandler) { IScope current = scope; while (current != null) { IScopeHandler scopeHandler = current.getHandler(); if (intf.isInstance(scopeHandler)) { handler = scopeHandler; break; } if (!current.hasParent()) { break; } current = current.getParent(); } } if (handler == null && IScopeService.class.isAssignableFrom(intf)) { // we've got an IScopeService, try to lookup bean Field key = null; Object serviceName = null; try { key = intf.getField("BEAN_NAME"); serviceName = key.get(null); //log.debug("serviceName {}", serviceName); handler = getScopeService(scope, serviceName.toString(), defaultClass); } catch (Exception e) { if (log.isDebugEnabled()) { if (key == null) { log.debug("No string field 'BEAN_NAME' in interface {}", intf.getName()); } else { log.warn("Exception getting scope service using {}", intf.getName(), e); } } } } if (handler == null && defaultClass != null) { try { handler = defaultClass.newInstance(); } catch (Exception e) { log.error("", e); } } // cache service scope.setAttribute(attr, handler); return handler; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy