なんとな~くしあわせ?の日記

「そしてそれゆえ、知識そのものが力である」 (Nam et ipsa scientia potestas est.) 〜 フランシス・ベーコン

ScalaでOSGi

私も昔はプログラマーだったんだが、JavaC++のせいで腕が筋肉痛になってしまってな…(流行に乗れていない)


StackOverflowにOSGiのソースコードをScalaで書くやり方が載っていたので、ちょっちScalaを書いてみる。


環境としては以下のOSGi基本jarを起動させておく
・org.eclipse.osgi
・org.eclipse.osgi.services

もひとつscala用ライブラリを起動させておく
・org.scala-ide.scala.library


以下は起動例

osgi> ss

Framework is launched.

id	State       Bundle
0	ACTIVE      org.eclipse.osgi_3.7.2.v20120110-1415
1	ACTIVE      org.eclipse.osgi.services_3.3.0.v20110513
2	ACTIVE      org.eclipse.osgi.util_3.2.200.v20110110
3	ACTIVE      org.scala-ide.scala.library_2.9.2.v20120330-163119-949a4804e4
5	ACTIVE      OSGiByScala_1.0.0.qualifier

osgi> 


嬉しいことにscala-libraryはOSGi対応らしい(スカラスゴイ、ヤッター)
心配する人もいるかも知れないがScalaJVMで動いてるので、書いたソースを適切にコンパイルすれば、きちんとOSGi上で動くjarファイルとなる。

SimpleActivator.scala

package jp.gr.java_conf.nagata

import java.lang.System
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

/**
 * Bundleのライフサイクルを決めるActivator
 * 
 * I refer "http://stackoverflow.com/questions/5052706/scala-in-osgi-container" thanks!
 */
class SimpleActivator extends BundleActivator {
  
  def start(bundleContext: BundleContext) {
    System.out.println("Hello OSGi from Scala!!!");
    
    // プロパティファイルを読み込んで初期化する
    SimpleProp.init()
    System.out.println(SimpleProp.getProperty("http_proxy.host"))
    
    // WEBから情報を取得する
    SimpleHttpClient.getHttpData()
  }

  def stop(bundleContext: BundleContext) {
    System.out.println("Good Bye OSGi from Scala!!!")
  }
}

SimpleHttpClient.scala

package jp.gr.java_conf.nagata

import scala.io.Source
import scala.xml.XML
import scala.xml.parsing.ConstructingParser

object SimpleHttpClient {
  
  def getHttpData() {
    
    // めんどくさいからSystemでproxy設定とか
    //System.setProperty("proxyHost", SimpleProp.getProperty("http_proxy.host"))
    //System.setProperty("proxyPort", SimpleProp.getProperty("http_proxy.port"))
    
    // APIをたたいてXMLを取得する
    val src = Source.fromURL(SimpleProp.getProperty("i_wanna_webcontent"), "utf8")
    // SourceからStringに
    val xml = XML.loadString( src.getLines.mkString )
    src.close()
    System.out.println(xml)
    
    // ScalaのXML型に変換
    val src2 = Source.fromURL(SimpleProp.getProperty("i_wanna_webcontent"), "utf8")
    val cpa = ConstructingParser.fromSource(src2, false)
    src2.close()
    val doc = cpa.document()
    System.out.println(doc)
  }
}

SimpleProp.scala

package jp.gr.java_conf.nagata

import java.util.HashMap
import java.util.ResourceBundle

object SimpleProp {

  // プロパティファイル名
  val propName = "simple"
  // プロパティファイルの内容が入るハッシュマップ
  var propMap: HashMap[String, String] = _

  /**
   * ハッシュにプロパティファイルの内容を詰める
   */
  def init() {
    propMap = new HashMap[String, String]()
    val bundle = ResourceBundle.getBundle("simple")
    val e = bundle.getKeys()

    while (e.hasMoreElements()) {
      val key = e.nextElement()
      val value = bundle.getString(key)
      propMap.put(key, value)
    }
  }

  /**
   * キーに対する値を返す
   * @param  key
   * @return value
   */
  def getProperty(key: String): String = {
    val v = try {
      propMap.get(key)
    } catch {
      case _: NoSuchElementException => null
    }
    return v
  }
}

simple.properties

http_proxy.host=proxy.gw.sample.co.jp
http_proxy.port=8080
i_wanna_webcontent=http://www.drk7.jp/weather/xml/pollen/23.xml

思ったこと

・素晴らしいのはscala.xml.XMLで、今までJDOMとかSAXとか使ってやっていたことが馬鹿らしくなる感じ(Javaを窓から投げ捨てろ(AA略))
・コードが短いゾ
・なんかXMLリテラルとかいうのもあって、コードの地の文にXMLを書けるらしい
・例外処理とかロガーの使い方がわからんので調べないとなあ