|
Scala example source code file (Channel.scala)
This example Scala source code file (Channel.scala) is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.
The Scala Channel.scala source code
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2007-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
// $Id: Channel.scala 18365 2009-07-21 11:00:42Z michelou $
package scala.remoting
import java.io._
import java.net._
import java.rmi.server.RMIClassLoader
/** <p>
* The class <code>Channel implements (basic) typed channels
* which use <a href="http://java.sun.com/docs/books/tutorial/networking/sockets/"
* target="_top"/>Java socket</a> communication and Scala type manifests to
* provide type-safe send/receive operations between a localhost and another
* remote machine by specifying some <code>host and port .
* </p>
*
* @author Stephane Micheloud
* @version 1.1
*/
class Channel protected (socket: Socket) {
// Create a socket without a timeout
def this(host: String, port: Int) = this(new Socket(host, port))
// // Create a socket with a timeout
// val sockaddr: SocketAddress = new InetSocketAddress(addr, port)
// val socket = new Socket()
// // If the timeout occurs, SocketTimeoutException is thrown.
// socket.connect(sockaddr, 2000) // 2 seconds
/** Returns the local address of this channel. */
val host = socket.getInetAddress.getHostAddress
/** Returns the port on which this channel is listening. */
val port = socket.getLocalPort
private var cl: ClassLoader =
try {
// requires permission in Java policy file
val codebase = System.getProperty("java.rmi.server.codebase")
if (codebase != null) info("codebase="+codebase)
RMIClassLoader.getClassLoader(codebase)
}
catch {
case e: Exception =>
sys.error("Class loader undefined: " + e.getMessage)
null
}
def classLoader: ClassLoader = cl
def classLoader_=(x: ClassLoader) { cl = x }
info(""+this)
private class CustomObjectInputStream(in: InputStream)
extends ObjectInputStream(in) {
override def resolveClass(desc: ObjectStreamClass): Class[_] =
if (cl eq null)
super.resolveClass(desc)
else
try {
info("resolve class "+desc.getName)
cl loadClass desc.getName
}
catch {
case e: ClassNotFoundException =>
super.resolveClass(desc)
}
}
// lazy modifier is required!
private lazy val in =
try {
new CustomObjectInputStream(socket.getInputStream)
}
catch {
case e: IOException =>
sys.error("Input stream undefined: "+e.getMessage+" ("+this+")")
null
}
private lazy val out =
try {
new ObjectOutputStream(socket.getOutputStream)
}
catch {
case e: IOException =>
sys.error("Output stream undefined: "+e.getMessage+" ("+this+")")
null
}
/** <code>receive<primtype> methods may throw an
* <code>IOException.
*/
def receiveUnit = receive[Unit]
def receiveBoolean = receive[Boolean]
def receiveByte = receive[Byte]
def receiveChar = receive[Char]
def receiveShort = receive[Short]
def receiveInt = receive[Int]
def receiveLong = receive[Long]
def receiveFloat = receive[Float]
def receiveDouble = receive[Double]
def receiveString = receive[String]
/** <code>receive method may throw either an
* <code>ClassNotFoundException or an IOException .
*
* @throw <code>ChannelException if received value has not
* the expected type.
*/
@throws(classOf[ChannelException])
def receive[T](implicit expected: reflect.Manifest[T]): T = {
val found = in.readObject().asInstanceOf[reflect.Manifest[_]]
info("receive: found="+found+", expected="+expected)
import scala.reflect.Manifest
val x = found match {
case Manifest.Unit => ()
case Manifest.Boolean => in.readBoolean()
case Manifest.Byte => in.readByte()
case Manifest.Char => in.readChar()
case Manifest.Short => in.readShort()
case Manifest.Int => in.readInt()
case Manifest.Long => in.readLong()
case Manifest.Float => in.readFloat()
case Manifest.Double => in.readDouble()
case _ => in.readObject()
}
val res = if (found <:< expected)
x.asInstanceOf[T]
else
throw new ChannelException(
"\n\tfound \""+found+"\"\n\texpected \""+expected+"\"")
info("received "+res+" (available="+in.available+")")
res
}
/** <code>? method may throw either an
* <code>ClassNotFoundException or an IOException .
*/
def ?[T](implicit m: reflect.Manifest[T]): T = receive[T](m)
/** <code>send method may throw an IOException .
*/
def send[T](x: T)(implicit m: reflect.Manifest[T]) {
out writeObject m
x match {
case x: Unit => // nop
case x: Boolean => out writeBoolean x
case x: Byte => out writeByte x
case x: Char => out writeChar x
case x: Short => out writeShort x
case x: Int => out writeInt x
case x: Long => out writeLong x
case x: Float => out writeFloat x
case x: Double => out writeDouble x
case x => out writeObject x
}
out.flush()
info("sent "+x)
}
/** <code>! method may throw an IOException .
*/
def ![T](x: T)(implicit m: reflect.Manifest[T]) { send(x)(m) }
def close() {
try { socket.close() }
catch { case e: IOException => }
info(this+" closed")
}
override def toString: String = socket.toString
private def info(msg: String) {
runtime.remoting.Debug.info("[Channel] "+msg)
}
}
/** <code>ChannelException may be thrown by the operation
* <code>receive when the received data has not the expected type.
*/
case class ChannelException(msg: String) extends IOException(msg)
Other Scala examples (source code examples)
Here is a short list of links related to this Scala Channel.scala source code file:
|