package org.red5.server.so;
/*
* RED5 Open Source Flash Server - http://www.osflash.org/red5
*
* Copyright (c) 2006-2009 by respective authors (see below). All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any later
* version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import static org.red5.server.api.so.ISharedObject.TYPE;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.red5.server.api.IBasicScope;
import org.red5.server.api.IScope;
import org.red5.server.api.persistence.IPersistable;
import org.red5.server.api.persistence.IPersistenceStore;
import org.red5.server.api.persistence.PersistenceUtils;
import org.red5.server.api.so.ISharedObject;
import org.red5.server.api.so.ISharedObjectService;
import org.red5.server.persistence.RamPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Shared object service
*/
public class SharedObjectService implements ISharedObjectService {
/**
* Logger
*/
private Logger log = LoggerFactory.getLogger(SharedObjectService.class);
/**
* Persistence store prefix
*/
private static final String SO_PERSISTENCE_STORE = IPersistable.TRANSIENT_PREFIX
+ "_SO_PERSISTENCE_STORE_";
/**
* Transient store prefix
*/
private static final String SO_TRANSIENT_STORE = IPersistable.TRANSIENT_PREFIX
+ "_SO_TRANSIENT_STORE_";
/**
* Persistence class name
*/
private String persistenceClassName = "org.red5.server.persistence.RamPersistence";
/**
* Setter for persistence class name.
*
* @param name Setter for persistence class name
*/
public void setPersistenceClassName(String name) {
persistenceClassName = name;
}
/**
* Return scope store
*
* @param scope Scope
* @param persistent Persistent store or not?
* @return Scope's store
*/
private IPersistenceStore getStore(IScope scope, boolean persistent) {
IPersistenceStore store;
if (!persistent) {
// Use special store for non-persistent shared objects
if (!scope.hasAttribute(SO_TRANSIENT_STORE)) {
store = new RamPersistence(scope);
scope.setAttribute(SO_TRANSIENT_STORE, store);
return store;
}
return (IPersistenceStore) scope.getAttribute(SO_TRANSIENT_STORE);
}
// Evaluate configuration for persistent shared objects
if (!scope.hasAttribute(SO_PERSISTENCE_STORE)) {
try {
store = PersistenceUtils.getPersistenceStore(scope,
persistenceClassName);
log.info("Created persistence store {} for shared objects.", store);
} catch (Exception err) {
log.error("Could not create persistence store for shared objects, falling back to Ram persistence.",
err);
store = new RamPersistence(scope);
}
scope.setAttribute(SO_PERSISTENCE_STORE, store);
return store;
}
return (IPersistenceStore) scope.getAttribute(SO_PERSISTENCE_STORE);
}
/** {@inheritDoc} */
public boolean createSharedObject(IScope scope, String name,
boolean persistent) {
if (hasSharedObject(scope, name)) {
// The shared object already exists.
return true;
}
synchronized (scope) {
final IBasicScope soScope = new SharedObjectScope(scope, name,
persistent, getStore(scope, persistent));
return scope.addChildScope(soScope);
}
}
/** {@inheritDoc} */
public ISharedObject getSharedObject(IScope scope, String name) {
return (ISharedObject) scope.getBasicScope(TYPE, name);
}
/** {@inheritDoc} */
public ISharedObject getSharedObject(IScope scope, String name,
boolean persistent) {
synchronized (scope) {
if (!hasSharedObject(scope, name)) {
createSharedObject(scope, name, persistent);
}
return getSharedObject(scope, name);
}
}
/** {@inheritDoc} */
public Set<String> getSharedObjectNames(IScope scope) {
Set<String> result = new HashSet<String>();
Iterator<String> iter = scope.getBasicScopeNames(TYPE);
while (iter.hasNext()) {
result.add(iter.next());
}
return result;
}
/** {@inheritDoc} */
public boolean hasSharedObject(IScope scope, String name) {
return scope.hasChildScope(TYPE, name);
}
/** {@inheritDoc} */
public boolean clearSharedObjects(IScope scope, String name) {
boolean result = false;
synchronized (scope) {
if (hasSharedObject(scope, name)) {
// '/' clears all local and persistent shared objects associated
// with the instance
// if (name.equals('/')) {
// /foo/bar clears the shared object /foo/bar; if bar is a
// directory name, no shared objects are deleted.
// if (name.equals('/')) {
// /foo/bar/* clears all shared objects stored under the
// instance directory /foo/bar. The bar directory is also deleted if no
// persistent shared objects are in use within this namespace.
// if (name.equals('/')) {
// /foo/bar/XX?? clears all shared objects that begin with XX,
// followed by any two characters. If a directory name matches
// this specification, all the shared objects within this directory
// are cleared.
// if (name.equals('/')) {
// }
result = ((ISharedObject) scope.getBasicScope(TYPE, name))
.clear();
}
}
return result;
}
}