/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This 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 software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.restcomm.media.control.mgcp.controller.naming;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import org.restcomm.media.concurrent.ConcurrentCyclicFIFO;
import org.restcomm.media.control.mgcp.controller.MgcpEndpoint;
import org.restcomm.media.control.mgcp.controller.MgcpEndpointStateListener;
import org.restcomm.media.spi.EndpointInstaller;
import org.restcomm.media.spi.utils.Text;
/**
* Storage for endpoints of same type with search and reordering functions.
*
* @author yulian oifa
*/
public class EndpointQueue implements MgcpEndpointStateListener {
//reserved space for endpoint queue
private final static int SIZE = 100;
//wildcards
private final static Text ANY = new Text("$");
private final static Text ALL = new Text("*");
//queue of endpoints
private ArrayList<Holder> completeList=new ArrayList<Holder>(SIZE);
private ConcurrentCyclicFIFO<MgcpEndpoint> queue = new ConcurrentCyclicFIFO<MgcpEndpoint>();
//reference for just found endpoind
//private Holder holder;
//index
private int k;
private EndpointInstaller installer;
public Logger logger = Logger.getLogger(EndpointQueue.class);
public void setInstaller(EndpointInstaller installer)
{
this.installer=installer;
}
/**
* Adds new endpoint to the queue.
*
* @param endpoint the endpoint to be added
*/
public void add(MgcpEndpoint endpoint) {
Holder holder=new Holder(endpoint);
endpoint.setMgcpEndpointStateListener(this);
completeList.add(holder);
queue.offer(endpoint);
}
/**
* Removes endpoint from the queue.
*
* @param endpoint the endpoint to be removed.
*/
/*public void remove(MgcpEndpoint endpoint) {
for(int i=0;i<completeList.size();i++)
if(completeList.get(i).endpoint==endpoint)
{
completeList.remove(i);
break;
}
}*/
/**
* Finds endpoints matching to name pattern.
*
* If "any" endpoint was requested, then first matching endpoint will be locked
* and not available for search in future until this endpoint will be explicitly unlocked.
*
* @param name the name pattern for search
* @param endpoints collection which will be filled by found endpoints
* @return the number of found endpoints.
*/
public int find(Text name, MgcpEndpoint[] endpoints) {
//return all endpoint if all requested
if (name.equals(ALL)) {
k = 0;
for(int i=0;i<completeList.size();i++) {
endpoints[k++] = completeList.get(i).endpoint;
}
return completeList.size();
}
//return first free if ANY endpoint requested
if (name.equals(ANY)) {
MgcpEndpoint endp=queue.poll();
while(endp==null && installer!=null && installer.canExpand())
{
if(logger.isDebugEnabled())
logger.debug("No free endpoints,expanding");
synchronized(installer)
{
installer.newEndpoint();
}
endp=queue.poll();
}
if(endp!=null) {
endp.lock();
endpoints[0] = endp;
if(logger.isDebugEnabled())
{
logger.debug("Endpoint " + endp.getName() + " taken (free="+queue.size()+")");
}
return 1;
}
return 0;
}
int value=name.toInteger();
if(value>0 && value<=completeList.size())
{
endpoints[0] = completeList.get(value-1).endpoint;
return 1;
}
return 0;
}
@Override
public void onFreed(MgcpEndpoint endpoint)
{
queue.offer(endpoint);
if(logger.isDebugEnabled())
{
logger.debug("Endpoint " + endpoint.getName() + " released (free="+queue.size()+")");
}
}
private class Holder {
protected MgcpEndpoint endpoint;
protected Text name;
protected Holder(MgcpEndpoint endpoint) {
this.endpoint = endpoint;
String[] tokens = endpoint.getName().split("/");
this.name = new Text(tokens[tokens.length - 1]);
}
}
}