はじめに
前回はサンプルコードを用いて、Curl ORBの動きを説明していきました。今回は、実際にコードを記述して、開発する手順を説明していきたいと思います。
Javaコードの作成(1)
前回説明したEclipseプロジェクトに新規サービスを追加していきます。まずはサービスクラスとデータクラスを作成します。サービスクラスは実際にCurlから呼び出すクラスとなり、データクラスはそのやりとりをするデータのクラスとなります。具体的には、メソッドの引数や戻り値となるクラスです。引数や戻り値にサポートしている型(プリミティブ、String、配列、List、Map、BigInteger、BigDecimal、Date、Timestamp、RecordSetなど)を定義する場合は、データクラスを作らなくてもよいです(Curl ORBでサポートされる方はこちらを参照ください)。
ここではまず、demoパッケージを作成し、その配下にデータクラスProductを作ります。EclipseのProject Explorerからcurl-orb-serverを選択し、New→Packageを選択し、demoパッケージを作成します。新しいパッケージをSpringで管理できるように、以下のように<context:component-scan base-package="demo"/>を1行追加します。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:component-scan base-package="sample"/>
<context:component-scan base-package="demo"/>
</beans>
次に、demoパッケージを右クリックし、New→Classを選択します。

上記画面で、NameにProductを入力し、Interfaceにjava.io.Serializableを選択すると空のProductクラスが作成されますので、以下のようにフィールドとgetter/setterを追加します。
package demo;
import java.io.Serializable;
public class Product implements Serializable {
private static final long serialVersionUID = 7071029986547765264L;
private String id;
private String name;
private int price;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
Javaコードの作成(2)
今回はデータベースの代わりにProductデータを保存するクラスを作成します。EclipseのProject Explorerからdemoパッケージを右クリックし、New→Classを選択します。

New Java Class画面で、NameにProductStoreを入力し、Superclassにjava.util.ArrayList<Product>を入力して、Finishボタンを押下します。
作成されたファイルProductStoreを以下のように修正します。@Componentを付与し、Spring上でBean id:storeとして管理されるようにします。
package demo;
import java.util.ArrayList;
import org.springframework.stereotype.Component;
@Component("store")
public class ProductStore extends ArrayList<Product> {
private static final long serialVersionUID = -2656699492233321360L;
}
サービスクラスとして、インターフェースProductServiceと実装クラスProductServiceImplを作成します。EclipseのProject Explorerからdemoパッケージを右クリックし、New→Interfaceを選択します。

nameをProductServiceにしてFinishを押下すると、ProductService.javaファイルが作成されますので、以下のように編集します。
package demo;
public interface ProductService {
/* Product登録メソッド */
public void regiseterProduct(Product product);
/* Product取得メソッド */
public Product[] getProducts();
}
次に、ProductServiceの実装クラスであるProductServiceImplを作成します。EclipseのProject Explorerからdemoパッケージを右クリックし、New→Classを選択します。

nameをProductServiceImplにしてFinishを押下すると、ProductServiceImpl.javaファイルが作成されますので、以下のように編集します(Springに自動的に登録させるため、@Serviceアノテーションを付与します。また、@RemoteServiceアノテーションはCurl ORBのセキュリティ制御のために付与します)。
package demo;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.curlap.orb.security.RemoteService;
@RemoteService /* Curl ORBアクセス制御アノテーション */
@Service("productService") /* Springサービスアノテーション */
public class ProductServiceImpl implements ProductService {
/* ProductStoreをインジェクト */
@Resource
private ProductStore store;
public void regiseterProduct(Product product) {
store.add(product);
}
public Product[] getProducts() {
return store.toArray(new Product[]{});
}
}
これで、外部に公開するサービス:ProductService(実装クラス:ProductServiceImpl)とデータクラス:Product、仮データベース:ProdctStoreが作成されました。この時点でTomcatサーバを起動します。

上記画面で、Tomcatサーバを起動します。
ここまでの説明ではJavaが主体でしたので、まだCurlは関係ありません。次ページ以降でCurl部分について実装していきます。
Curlコードの生成(1)
Javaのサービスができたら、次にCurlのコードを生成します。ちなみに実際の開発では、コード生成時点でJavaのメソッドをすべて実装しておく必要はありません。クラスやメソッドの名称や引数・戻り値さえ変わらなければ、Curlコードを再度生成しなおさなくてかまいません。
まずは、curl/code-generator.dcurlをダブルクリックし、コード生成ツールを立ち上げます(コードを生成するには、サーバを起動しておく必要があります)。

Configurationを選択します。ここではBase save directoryに任意の保存先ディレクトリを選択し、saveボタンを押下します。

元の画面に戻り、Data Classを選択し、Nextボタンを押下します。

Browseボタンを押下しますと下記ポップアップ画面が表示されます。

ここで、データクラスであるProduct - demo -を選択します。

上記のようにdemo.ProductがClass nameにセットされます。これは、手動で入力してもよいです。Nextボタンを押下します。

データクラスのフィールド名やメソッド名などの詳細が表示されます。名称や、非同期メソッドの追加などが行えます。Generatorボタンを押下すると、Configuration画面のBase save directoryにセットしたディレクトリに以下のように出力されます(パッケージ名/クラス名.scurlとパッケージ名/load.scurl)。
|||
||| Curl ORB for java (version 0.6)
||| This code was generated by the Curl code generator automatically.
||| package name : DEMO
||| generated date : 2009-04-07 11:59:29.314000
|||
{define-class public serializable Product
field private _id:#String
field private _name:#String
field private _price:int
{getter public {price}:int
{return self._price asa int}
}
{getter public {name}:#String
{return self._name asa #String}
}
{getter public {id}:#String
{return self._id asa #String}
}
{setter public {id v:String}:void
set self._id = v
}
{setter public {price v:int}:void
set self._price = v
}
{setter public {name v:String}:void
set self._name = v
}
}
Curlコードの生成(2)
次にサービスクラスを生成します。curl/code-generator.dcurlをダブルクリックし、起動します。

Service Class(DI)を選択し、Nextボタンを押下します。

Browseボタンを押下します。

ProductServiceImplクラスに指定した@ServiceアノテーションのproductServiceを選択します。

productServiceがセットされますので、Nextボタンを押下します。

当画面でもNextを押下します。

クラスの詳細画面が表示されるので、Generatorボタンを押下します。これで、curl/ProductService.scurlも以下のように生成されました。
|||
||| Curl ORB for java (version 0.6)
||| This code was generated by the Curl code generator automatically.
||| package name : DEMO
||| generated date : 2009-04-07 12:05:34.835000
|||
{import * from COM.CURLAP.ORB}
{define-class public ProductService {inherits ApplicationContextClient}
{constructor public {default server-url:#Url = null}
{construct-super.ApplicationContextClient "productService", server-url = server-url}
}
{method public {regiseter-product v0:Product}:void
{self.invoke "regiseterProduct", arguments = {FastArray v0}}
}
{method public {get-products}:#{FastArray-of #Product}
{return {self.invoke "getProducts"} asa #{FastArray-of #Product}}
}
}
コード生成ツールの詳細な説明は「コード生成ツール・マニュアル」を参照ください。
CurlからJavaのサービスを呼ぶ
curl/project.cprjをダブルクリックし、Curl IDEでプロジェクトを開きます。
メニューから、プロジェクト→プロジェクトの追加を選択し、curl/DEMO/load.scurlを選択すると、DEMOパッケージがロードされます。

テスト用のCurlファイルを作成するため、Curl IDEのメニューからファイル→新規を選択します。

ファイル名にtest.curlを選択し、OKボタンを押下します。そして、以下のようにサービス呼び出しのコードを追加します。
{curl 6.0 applet}
{curl-file-attributes character-encoding = "shift-jis"}
{applet manifest = "manifest.mcurl",
{compiler-directives careful? = true}
}
{import * from DEMO}
{do
|| データクラスProduct作成
def p1 = {Product}
set p1.id = "0001"
set p1.name = "abc"
set p1.price = 5000
|| データクラスProduct作成
def p2 = {Product}
set p2.id = "0002"
set p2.name = "xyz"
set p2.price = 3000
|| サービスクラスのインスタンス生成
def service = {ProductService}
{service.regiseter-product p1} || registerProductメソッド呼び出し
{service.regiseter-product p2} || registerProductメソッド呼び出し
{if-non-null products = {service.get-products} then || getProductsメソッド呼び出し
{for p in products do
|| コンソールにサーバから取得したProductを出力
{dump p.id, p.name, p.price}
}
}
}
これで、test.curlをダブルクリックし実行すると、上記コードが実行され、Curlコンソールにサーバに保存されているProductがすべて出力されます。
このようにCurl ORBを使えば、CurlとJavaの通信を容易に実現することが可能です。後は、サーバから取得したデータを画面の各項目にセットしたり、画面の各項目の値をサーバに送信したりすることで、リッチクライアントな画面を開発することができます。


