/*
* Mobicents, Communications Middleware
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party
* contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program 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 distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
*
* Boston, MA 02110-1301 USA
*/
package org.mobicents.media.server.resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.mobicents.media.Component;
import org.mobicents.media.ComponentFactory;
import org.mobicents.media.Inlet;
import org.mobicents.media.MediaSink;
import org.mobicents.media.MediaSource;
import org.mobicents.media.Outlet;
import org.mobicents.media.server.spi.Endpoint;
import org.mobicents.media.server.spi.ResourceUnavailableException;
/**
* Factory class for creating channels.
*
* @author kulikov
*/
public class ChannelFactory {
private List<PipeFactory> pipes;
private List<ComponentFactory> factories;
private ArrayList<Channel> channels = new ArrayList();
private int maxSize = 50;
private int coreSize = 10;
private volatile boolean started = false;
private static final Logger logger = Logger.getLogger(ChannelFactory.class);
/**
* Returns new channel.
*
* if there is unused channels in the cache the existing channels will be
* returned and new instance other wise.
*
* @return
* @throws org.mobicents.media.server.resource.UnknownComponentException
*/
public Channel newInstance(Endpoint endpoint) throws ResourceUnavailableException {
if (!started) {
throw new IllegalStateException("Factory is not started");
}
if (!channels.isEmpty()) {
return channels.remove(0);
} else {
return createNewChannel(endpoint);
}
}
/**
* Constructs new channel instance.
*
* @return channel instance.
* @throws org.mobicents.media.server.resource.UnknownComponentException
*/
private Channel createNewChannel(Endpoint endpoint) throws ResourceUnavailableException {
//creating components
HashMap<String, MediaSource> sources = new HashMap<String, MediaSource>();
HashMap<String, MediaSink> sinks = new HashMap<String, MediaSink>();
HashMap<String, Inlet> inlets = new HashMap<String, Inlet>();
HashMap<String, Outlet> outlets = new HashMap<String, Outlet>();
for (ComponentFactory factory: factories) {
Component component = factory.newInstance(endpoint);
if (component instanceof MediaSink) {
sinks.put(component.getName(), (MediaSink)component);
}
if (component instanceof MediaSource) {
sources.put(component.getName(),(MediaSource)component);
}
if (component instanceof Inlet) {
sinks.put(component.getName(), ((Inlet)component).getInput());
inlets.put(component.getName(), (Inlet)component);
}
if (component instanceof Outlet) {
sources.put(component.getName(), ((Outlet)component).getOutput());
outlets.put(component.getName(), (Outlet)component);
}
}
Channel channel = new Channel(sources, sinks, inlets, outlets);
//creating pipes
for (PipeFactory pipeFactory : pipes) {
try {
pipeFactory.openPipe(channel);
} catch (UnknownComponentException e) {
throw new ResourceUnavailableException(e);
}
}
return channel;
}
/**
* Get amount of prestarted channels.
*
* @return the amount of prestarted channels.
*/
public int getCoreSize() {
return coreSize;
}
/**
* Get maximum size of prestarted channels.
*
* @return pool's max size.
*/
public int getMaxSize() {
return maxSize;
}
/**
* Define amount of initialy prestarted channels.
*
* @param coreSize the number of prestarted channels.
*/
public void setCoreSize(int coreSize) {
this.coreSize = coreSize;
}
/**
* Define max pools size;
*
* @param maxSize the maximum size of pool.
*/
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
/**
* Modify pipe list.
*
* @param pipes the list of pipes beans defining media flow path
*/
public void setPipes(List<PipeFactory> pipes) {
this.pipes = pipes;
}
/**
* Gets the existing list of pipes.
*
* @return the list of pipes.
*/
public List getPipes() {
return this.pipes;
}
/**
* Gets the list of components which will be placed into the new channel.
*
* @return the list of media component.
*/
public List getComponents() {
return factories;
}
/**
* Sets the list of components which will be placed into the new channel.
*
* @return the list of media component.
*/
public void setComponents(List components) {
this.factories = components;
}
/**
* Informs factory that specified channel not longer used.
*
* @param channel the reference to unused channel.
*/
public void release(Channel channel) {
if (started && channels.size() < maxSize) {
channel.stop();
channels.add(channel);
}
}
/**
* Starts this factory.
*
*/
public void start() throws Exception {
started = true;
if (factories == null) {
factories = new ArrayList();
}
if (pipes == null) {
pipes = new ArrayList();
}
logger.info("Started, core size = " + coreSize);
}
/**
* Stop this factory.
*/
public void stop() {
started = false;
for (int i = 0; i < channels.size(); i++) {
Channel channel = channels.remove(i);
channel.close();
}
}
}