/*
* RED5 Open Source Flash Server - http://code.google.com/p/red5/
*
* Copyright 2006-2012 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.api;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import javax.management.openmbean.CompositeData;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.scope.IScope;
import org.slf4j.Logger;
/**
* Utility class for accessing Red5 API objects.
*
* This class uses a thread local, and will be setup by the service invoker.
*
* The code below shows various uses.
* <br />
* <pre>
* IConnection conn = Red5.getConnectionLocal();
* Red5 r5 = new Red5();
* IScope scope = r5.getScope();
* conn = r5.getConnection();
* r5 = new Red5(conn);
* IClient client = r5.getClient();
* </pre>
*
* @author The Red5 Project
* @author Luke Hubbard (luke@codegent.com)
* @author Paul Gregoire (mondain@gmail.com)
* @author Tiago Daniel Jacobs (os@tdj.cc)
*/
public final class Red5 {
private static Logger log = Red5LoggerFactory.getLogger(Red5.class);
/**
* Connection associated with the current thread. Each connection runs in a separate thread.
*/
private static final ThreadLocal<WeakReference<IConnection>> connThreadLocal = new ThreadLocal<WeakReference<IConnection>>();
/**
* Connection local to the current thread
*/
public IConnection conn;
/**
* Current server version with revision
*/
public static final String VERSION = "Red5 Server 1.0.4-SNAPSHOT";
/**
* Current server version for fmsVer requests
*/
public static final String FMS_VERSION = "RED5/1,0,3,0";
/**
* Data version for NetStatusEvents
*/
@SuppressWarnings("serial")
public static final Map<String, Object> DATA_VERSION = new HashMap<String, Object>(2) {
{
put("version", "4,0,0,1121");
put("type", "red5");
}
};
/**
* Server start time
*/
private static final long START_TIME = System.currentTimeMillis();
/**
* Detection of debug mode
*/
private static boolean debug = java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toString().indexOf("jdwp") >= 0;
/**
* Create a new Red5 object using given connection.
*
* @param conn Connection object.
*/
public Red5(IConnection conn) {
this.conn = conn;
}
/**
* Create a new Red5 object using the connection local to the current thread
* A bit of magic that lets you access the red5 scope from anywhere
*/
public Red5() {
conn = Red5.getConnectionLocal();
}
/**
* Setter for connection
*
* @param connection Thread local connection
*/
public static void setConnectionLocal(IConnection connection) {
log.debug("Set connection: {} with thread: {}", (connection != null ? connection.getSessionId() : null), Thread.currentThread().getName());
if (connection != null) {
connThreadLocal.set(new WeakReference<IConnection>(connection));
IScope scope = connection.getScope();
if (scope != null) {
Thread.currentThread().setContextClassLoader(scope.getClassLoader());
}
} else {
// use null to clear the value
connThreadLocal.remove();
}
}
/**
* Get the connection associated with the current thread. This method allows
* you to get connection object local to current thread. When you need to
* get a connection associated with event handler and so forth, this method
* provides you with it.
*
* @return Connection object
*/
public static IConnection getConnectionLocal() {
log.debug("Get connection on thread: {}", Thread.currentThread().getName());
WeakReference<IConnection> ref = connThreadLocal.get();
if (ref != null) {
return ref.get();
} else {
return null;
}
}
/**
* Get the connection object.
*
* @return Connection object
*/
public IConnection getConnection() {
return conn;
}
/**
* Get the scope
*
* @return Scope object
*/
public IScope getScope() {
return conn.getScope();
}
/**
* Get the client
*
* @return Client object
*/
public IClient getClient() {
return conn.getClient();
}
/**
* Get the spring application context
*
* @return Application context
*/
public IContext getContext() {
return conn.getScope().getContext();
}
/**
* Returns the current version with revision number
*
* @return String version
*/
public static String getVersion() {
return VERSION;
}
/**
* Returns the current version for fmsVer requests
*
* @return String fms version
*/
public static String getFMSVersion() {
return FMS_VERSION;
}
public static Object getDataVersion() {
return DATA_VERSION;
}
/**
* Returns true if java debugging was detected.
*
* @return true if debugging, false otherwise
*/
public static boolean isDebug() {
return debug;
}
/**
* Returns server uptime in milliseconds.
*
* @return String version
*/
public static long getUpTime() {
return System.currentTimeMillis() - START_TIME;
}
/**
* Allows for reconstruction via CompositeData.
*
* @param cd composite data
* @return Red5 class instance
*/
public static Red5 from(CompositeData cd) {
Red5 instance = null;
if (cd.containsKey("connection")) {
Object cn = cd.get("connection");
if (cn != null && cn instanceof IConnection) {
instance = new Red5((IConnection) cn);
} else {
instance = new Red5();
}
} else {
instance = new Red5();
}
return instance;
}
}