⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genericmediaservice.java

📁 jtapi for telephone
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package net.sourceforge.gjtapi.media;

/*
	Copyright (c) 2002 8x8 Inc. (www.8x8.com) 

	All rights reserved. 

	Permission is hereby granted, free of charge, to any person obtaining a 
	copy of this software and associated documentation files (the 
	"Software"), to deal in the Software without restriction, including 
	without limitation the rights to use, copy, modify, merge, publish, 
	distribute, and/or sell copies of the Software, and to permit persons 
	to whom the Software is furnished to do so, provided that the above 
	copyright notice(s) and this permission notice appear in all copies of 
	the Software and that both the above copyright notice(s) and this 
	permission notice appear in supporting documentation. 

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 
	OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
	HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 
	INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING 
	FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 
	NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
	WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 

	Except as contained in this notice, the name of a copyright holder 
	shall not be used in advertising or otherwise to promote the sale, use 
	or other dealings in this Software without prior written authorization 
	of the copyright holder.
*/
import javax.telephony.callcontrol.*;
import javax.telephony.*;
import javax.telephony.media.*;
import java.util.*;
import net.sourceforge.gjtapi.*;

/**
 * Implements MediaService and the basic Resource interfaces.
 * Resource methods are delegated to the bound MediaGroup.
 * <p>
 * This class understands about binding and configuration,
 * and knows how to delegate resource methods to whatever
 * object or objects are bound to this one. And conversely
 * understand how to register Listeners for each resource,
 * and dispatch events from any of the resources 
 * to all of the ResourceListeners.
 * <p>
 * The Resource methods in BasicMediaService are documented
 * in the associated Resource interface definition.
 */
public class GenericMediaService implements MediaService, MediaServiceListener, Player, PlayerListener, Recorder, RecorderListener, SignalDetector, SignalDetectorListener, SignalGenerator, MediaServiceHolder {
	/** The Provider and media service manager to work with */
	private GenericProvider provider = null;
	private MediaMgr mgr = null;
	/** Vector of MediaListeners (MediaServiceListener, 
			ResourceListener (PlayerListener, RecorderListener, SignalDetectorListener)) */
	protected static Vector theListeners = new Vector();
	private GenericMediaGroup mediaGroup = null;
/**
 * Create an unbound MediaService,
 * using the installation default MediaProvider.
 */
public GenericMediaService() throws JtapiPeerUnavailableException, ProviderUnavailableException {
	super();
	Provider prov = JtapiPeerFactory.getJtapiPeer(null).getProvider(null);
	if (prov instanceof MediaProvider)
		this.initMediaService((MediaProvider) prov);
	else
		throw new ProviderUnavailableException("Default Provider not a MediaProvider");
}
	/**
	 * Create an unbound MediaService, using services identified
	 * by the two String arguments.
	 * 
	 * @param peerName the name of a Class that implements JtapiPeer.
	 * @param providerString a "login" string for that JtapiPeer.
	 *
	 * @throws ClassNotFoundException if JtapiPeer class is not found
	 * @throws IllegalAccessException if JtapiPeer class is not accessible
	 * @throws InstantiationException if JtapiPeer class does not instantiate
	 * @throws ProviderUnavailableException if Provider is not available
	 * @throws ClassCastException if Provider instance is not a MediaProvider
	 */
	public GenericMediaService(String peerName, String providerString) 
	throws ClassNotFoundException, 
		InstantiationException, // hope to remove in Jtapi-2.0
		IllegalAccessException,	// hope to remove in Jtapi-2.0
		ProviderUnavailableException {
	    initMediaService(findMediaProvider(peerName, providerString));
	}
	/*
	 * Create an unbound MediaService, using services associated
	 * with the given MediaProvider object.
	 * The MediaProvider object may be a JTAPI Provider,
	 * or may be some other object obtained by other vendor-specific means.
	 *
	 * @param provider a MediaProvider instance
	 */
	public GenericMediaService(MediaProvider provider) {
	initMediaService(provider);
	}
	/** 
	 * Add a MediaListener to this MediaService.
	 * <p>
	 * Events generated by this MediaService are dispatched to the
	 * given listener if it implements the appropriate Listener interface.
	 * @@param listener an object that implements 
	 * one or more of the ResourceListener interfaces and/or 
	 * the MediaServiceListener interface.
	 */
	public void addMediaListener(MediaListener listener) {
	 theListeners.add(listener);
	}
	/*
	 * bind to an new outbound call.
	 * @exception MediaBindException one of AlreadyBoundException, BindCancelledException.
	 * @exception MediaConfigException if MediaGroup can not be configured as requested.
	 * @exception MediaCallException encapsulates any call processing exceptions
	 * generated while trying to establish the new Call and Connections.
	 */
	synchronized
	public void bindAndConnect(ConfigSpec configSpec, 
				     String origAddr, 
				     String dialDigits)
	throws MediaBindException, MediaConfigException, MediaCallException {
	    if(this.getMediaGroup() != null) throw new AlreadyBoundException();

	    	// find a media terminal
	    GenericProvider gp = this.getProvider();
	    Address addr = null;
	    try {
		    addr = gp.getAddress(origAddr);
	    } catch (InvalidArgumentException iae) {
		    throw new MediaCallException("Originating Address unknown");
	    }
			    
		Terminal[] terms = addr.getTerminals();
	    MediaTerminal term = null;
	    for (int i = 0; i < terms.length && term == null; i++) {
		    if (terms[i] instanceof MediaTerminal) {
		    	term = (MediaTerminal)terms[i];
		    	break;
		    }
	    }
	    if (term == null) {		// no media terminals
		    throw new MediaCallException("No media terminal for address " + origAddr);
	    }

	    	// bind to the terminal
	    this.bindToTerminal(configSpec, term);

	    	// make the call and connect it
	    try {
		    gp.createCall().connect(term, addr, dialDigits);
	    } catch (Exception e) {
	    	// release the MediaService, since the call failed
	    	this.releaseAndFree();

		    throw new MediaCallException("Error making call: " + e.toString());
	    }
	}
	/* 
	 * Bind this MediaService to a MediaGroup connected to an existing Call.
	 * This will typically create a new Connection to the Call.
	 * <p>
	 * @param configSpec declares configuration requirments for the MediaGroup.
	 * @param call a JTAPI Call object
	 *
	 * @exception MediaBindException one of AlreadyBoundException, BindCancelledException.
	 * @exception MediaConfigException if MediaGroup can not be configured as requested.
	 * @exception MediaCallException encapsulates any call processing exceptions
	 * generated while trying to establish the new Connections.
	 * @return the Connection between the bound Terminal and the given Call.
	 */
	synchronized
	public Connection bindToCall(ConfigSpec configSpec,
			   Call call)
	throws MediaBindException, MediaConfigException, MediaCallException {
	if (this.getMediaGroup() != null)
		throw new AlreadyBoundException();
	if (call == null)
		throw new MediaCallException("Null Call");
	MediaTerminal mt = null;
	CallControlTerminalConnection tc = null;	// for later, if we need it in adding in a new media terminal
	// first check if any of the current terminals support media
	Connection[] conns = call.getConnections();
	Connection mediaConn = null;
	for (int i = 0; i < conns.length; i++) {
		TerminalConnection[] tcs = conns[i].getTerminalConnections();
		if (tcs != null) {
			for (int j = 0; j < tcs.length; j++) {
				if (tc == null && tcs[j] instanceof CallControlTerminalConnection)
					tc = (CallControlTerminalConnection)tcs[j];
				if (tcs[j].getTerminal() instanceof MediaTerminal) {
					mt = (MediaTerminal)tcs[j].getTerminal();
					mediaConn = conns[i];
					break;
				}
			}
		}
	}
	if (mt == null) { // create a new media terminal connection to the call
		if (!(call instanceof CallControlCall))
			throw new MediaCallException("Call does not support conferencing in new Media Terminals");
		if (tc == null)
			throw new MediaCallException("No TerminalConnection to make conference from");
		CallControlCall ccc = (CallControlCall)call;

			// ask the provider for the first known available media terminal
		mt = this.getProvider().getAvailableMediaTerminal();

		// check if any MediaTerminals found
		if (mt == null)
			throw new MediaCallException("No available media terminals known");

		Connection[] consultCons = null;
		try {
			// connect to the active call by conferencing the media terminal in
			consultCons = ccc.consult(tc, mt.getAddresses()[0].getName());

			// answer the other end
			boolean answered = false;
			TerminalConnection[] newTcs = mt.getTerminalConnections();
			for (int i = 0; i < newTcs.length; i++) {
				if (newTcs[i].getState() == TerminalConnection.RINGING) {
					((CallControlTerminalConnection)newTcs[i]).answer();
					// mediaConn = newTcs[i].getConnection(); -- but the conference will break this
					answered = true;
					break;
				}
			}
			if (!answered) {
				for (int i = 0; i < consultCons.length; i++)
					consultCons[i].disconnect();
				throw new MediaCallException("Could not answer consultation call");
			}

			// now join things up
			ccc.conference(consultCons[0].getCall());
		} catch (Exception e) {
			if (e instanceof MediaCallException)
				throw (MediaCallException)e;
			else
				throw new MediaCallException("Error making consultation call");
		}
	}

	// now assign the media service to the connected media terminal
	this.bindToTerminal(configSpec, mt);

	// return the connection between the call and the terminal
	if (mediaConn == null) {
		conns = call.getConnections();
		int sz = conns.length;
		for (int i = 0; i < sz; i++) {
			TerminalConnection[] tcs = conns[i].getTerminalConnections();
			int tcSize = tcs.length;
			for (int j = 0; j < tcSize; j++) {
				if (tcs[j].getTerminal().equals(mt)) {
					mediaConn = conns[i];
					break;
				}
			}
		}
	}
	return mediaConn;
}
/* 
 * Bind this MediaService with a particular MediaGroup.
 * <p>This may be performed by another object in the same package.
 *
 * @param group The MediaGroup to hook into this MediaService
 *
 * @exception AlreadyBoundException
 */
synchronized void bindToGroup(GenericMediaGroup group) throws AlreadyBoundException {
	if (this.isBound())
		throw new AlreadyBoundException();
	this.setMediaGroup(group);
	this.getMgr().bind(group.getTerminal().getName(), this);
	
	// notify any thread that is waiting for this service to be bound
	synchronized(this) {
		this.notify();
	}
}
	/*
	 * This MediaService is ready for a MediaGroup.
	 * Waits for a Call to be delivered to this service name.
	 * <p>
	 * On return, this MediaService is bound to a MediaGroup,
	 * and that MediaGroup is configured to configSpec.
	 * <p>
	 * if cancelBindRequest() terminates this method,
	 * this method unblocks, throwing a BindCancelledException.
	 * <p>
	 * @param configSpec configure MediaGroup to configspec before binding.
	 * @param serviceName name under which this MediaService is to be registered.
	 * @exception MediaBindException one of AlreadyBoundException, BindCancelledException.
	 */
	// Does not throw MediaConfigException: that exception goes to releaseToService().
	
	/* The logical equivalent of S.100:RequestGroup() */
	synchronized
	public void bindToServiceName(ConfigSpec configSpec,
				  String serviceName)
	throws MediaBindException {
	    if(this.getMediaGroup() != null)
	    	throw new AlreadyBoundException();
	    // place in MediaMgr
	    this.getMgr().register(serviceName, this);

	    // wait for service to be invoked
	    synchronized (this) {
		    try {
			    this.wait();
		    } catch (InterruptedException ie) {
			    throw new BindCancelledException("Bind Thread Interrupted");
		    }
		    // test if the bind was cancelled

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -