alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

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.

Java - Scala tags/keywords

channel, channelexception, class, classloader, classloader, float, int, io, ioexception, ioexception, net, network, socket, string, string, t, t

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:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.