「逆引きリファレンス」カテゴリーアーカイブ

ログ出力とログ・ローテーション

ログ出力

Log4jやcommons loggingのようなロギング機能です

initialize-logプロシージャで、ロギング機能の設定をセットします。そのあと、以下のように利用します。

def logger = {LogFactory.get-log}

{logger.fatal “致命的エラーです。”}
{logger.error “エラーです。”}
{logger.warn “ワーニングです。”}
{logger.info “情報です。”}
{logger.debug “デバッグです。”}
{logger.trace “トレースです。”}

ログ・ローテーション

rotate-logプロシージャを利用して、Apache LogRotateのように、ローテーションができます。

詳細については、Curlドキュメンテーションを参照ください。

パッケージ名:COM.CURLAP.LIB.LOGGING

envrironment-switchで実行モードの切り替え

environment-switch

これは、開発時、テスト時、本番時ごとに処理を変えたい場合に、切り替えることのできるマクロです。

例えば下記の例は、”development”, “test”, “production”という環境ごとにincludeするファイルを変更したい場合に以下のようにコーディングできます。 

{environment-switch
    case “development” do
      {include “foo-dev.scurl”}
    case “test” do
      {include “foo-test.scurl”}
    case “production” do
      {include “foo.scurl”}
    else
}

全体の設定として、”development”, “test”, “production”を指定するには、manifest.mcurlファイルにx-environmentというキーワードを記述します。

{curl 6.0 manifest}
{manifest TESTS,
    x-environment = “development”
}

この例ですと、”development”というモードで稼動しますので、environment-switchの”development”が実行され、”foo-dev.scurl”がincludeされます。

ちなみに、”development”, “test”, “production”などは、任意の文字列が指定できます。

パッケージ名:COM.CURLAP.LIB.ENVIRONMENT

 

データ・キャッシング

キャッシング機能

javaで有名なJCacheやEHCacheなどのように、クライアントでのキャッシングができます。これらは、例えばほとんど変わらないマスタデータを毎回サーバに取得するのではなく、一定期間、メモリもしくはディスクにキャッシングしておき、サーバ負荷を軽減するために利用できます。

まずは、キャッシュという1つの塊をCacheManager.create-cacheメソッドにて作成します。このとき、キャッシュ内の各オブジェクトの生存期限、キャッシュの最大数などを指定できます。最大数を越えた場合は、一番アクセスされていないオブジェクトを破棄します。 

        || キャッシュの作成
        def cm = {CacheManager.get-instance}
        def cache1 = {cm.create-cache
                         “cache1”,
                         max-elements-in-cache = 3,
                         expire-idle-time = 1s
                     }
        || キャッシュ”cache1”にオブジェクト登録
        {cache1.set “k1”, {Array}}
        {cache1.set “k2”, {HashTable}}
        {cache1.set “k3”, 10}

        || キャッシュからオブジェクト取得
        def v = cache1[“k1”]

メモリ上にあるキャッシュをディスクへ書き出すには、キャッシュ作成時にpersistent-disk引数にURLを指定しておくと、flushメソッドを実行した場合にディスクへ書き出します。 

        def cm = {CacheManager.get-instance}
        def cache =
            {cm.create-cache “disk-cache”, persistent-disk = {url “file/disk.cache”}}
        set cache[“k1”] = “val1”
        set cache[“k2”] = “val2”
        {cache.flush} || persistent disk

もうちょっと簡単にキャッシュを利用するために、with-cacheマクロが利用できます。このマクロは、もしキャッシュ内にオブジェクトがなければ、with-cacheの中身が実行され、結果がキャッシュへ格納され、戻り値を返します。キャッシュ内にオブジェクトがある場合、キャッシュから取得した値を戻します。

        def v1 =
            {with-cache “k1” of “cache1” do
                def v = “test”
                v
            }

パッケージ名:COM.CURLAP.LIB.CACHING

メッセージ・リソースファイル

ほとんどのアプリケーションで利用されるメッセージ・リソースファイルのためのAPIです。

このAPIでは、メッセージを管理し、アプリケーション内からメッセージを取得することができます。以下にメッセージAPI(MessageList)のサンプルを掲載しておきます。

|| メッセージ定義(通常はメッセージファイルとして管理)
def messages = {MessageList
                           “MSG01”, “あいうえお”,
                           “MSG02”, “Hello %s!”
                       }

|| “あいうえお”が取得できます。
{messages[“MSG01”].create-message}

|| Hello Curl!が取得できます。
{messages[“MSG02”].create-message “Curl”}

詳細は、COM.CURLAP.LIB.MESSAGESパッケージを参照してください。

コンテナからコントロールの検索

コンテナからコントロールの検索

あるコンテナ上からその下にあるコントロール(TextField, TextArea, ComboBoxなど)やコンテナ(Frame, Canvas, VBox, HBoxなど)を検索することができます。

 

       def root =
            {Frame
                {VBox
                    {TextField name=”name1″, value=”value1″},
                    {TextField name=”name2″, value=”value2″},
                    {Frame
                        {VBox
                            {TextField name=”name3″},
                            {TextArea name=”name4″, value=”value4″},
                            {TextField value=”value5″}
                        }
                    }
                }
            }

        {walk-graphics
 
           || 第1引数: 検索対象のコンテナ
            root,
            || 第2引数: Graphic(コンテナやコントロール)ごとに、以下のプロシージャが実行される
            ||        以下のサンプルでは、GraphicがValueControlの場合に、valueをコンソールに表示している例
            {fn g =>
                {if g isa ValueControl then
                    def v = g asa ValueControl
                    {dump v.name, v.value-as-any}
                }
            }
        }

 

データクラスとコントロール間での値セット

データクラスから各コントロールに一度に値をセットすることができます。これにはset-values-to-contorlsプロシージャを利用します。下記の例では、Fooクラスから、フィールド名がコントロールのnameが一致するものへ値をセットしています。

set-values-to-controlsのset-value-proc引数は、nameが一致しない場合や、コントロールのvalueとデータクラスのフィールドの型が一致しない場合に、変換ロジックを記載できるものです。

        def tf1 = {TextField name=”tf-1″}
        def tf2 = {TextField name=”tf-2″}
        def tf3 = {TextField name=”tf-3″}
        def tf4 = {TextField}
        def tf5 = {TextField name=”no-name”}
        def tf6 = {TextField name=”tf-1″}

        def td = {TextDisplay name=”td”}
        def df = {DateField name=”df”}
        def cb = {CommandButton name=”cb”}
       
        def root-graphic =
            {VBox
                {HBox tf1, tf2, tf3}, {HBox td, tf4, tf5, tf6}, df, cb
            }
        || set values of graphic
        {set-values-to-controls
            {Foo},
            root-graphic,
            set-value-proc =
                {fn v, p, c =>
                    {if p.name == c.name then
                        {if-non-null value = {p.get-value v} then
                            set c.value-as-any =
                                {if p.type == int and c.value-type == String then
                                    (value * 3) & “”
                                 else
                                    value
                                }
                        }
                    }
                }
        }

逆に、Fooオブジェクトからコントロールへ値をセットするには、set-values-from-controlsを使用します。

パッケージ名:COM.CURLAP.LIB.UI

数学関数

数学関数のAPIです

以下は最大公約数、最小公倍数のサンプルです。

        def (a,b,c) = (3,12,24)
        {gcd a,b,c} == 3

        def (a,b,c) = (2,3,12)
        {lcm a,b,c} == 12

パッケージ名:COM.CURLAP.LIB.MATH

都道府県ユーティリティ

都道府県ユーティリティ

都道府県の操作ができるユーティリティです。以下はサンプルとなります。

 

{get-japanese-prefecture-from-prefecture-code “40”}.name || “福岡県”

{get-japanese-prefecture-from-prefecture-code “40”}.capital-city || “福岡市”

{get-japanese-name-from-prefecture-code “40”} || “福岡県”

{get-japanese-prefectures-from-area “九州”}.size || 8

 

パッケージ名:COM.CURLAP.LIB.JAPAN

 

郵便番号ユーティリティ

郵便番号を操作するユーティリティ

これを利用するには、日本郵便のページから郵便番号CSVをダウンロードして利用します。from-csvでダウンロードしたCSVデータを取り込みます。

 

def pcs = {PostalCodes.from-csv
                     {url “file/postal-data/13TOKYO.CSV”},
                     {url “file/postal-data/09TOCHIG.CSV”}
              }
|| 検索
pc = {pcs.search-by-postal-code “1000004”}

 

パッケージ名:COM.CURLAP.LIB.JAPAN

オブジェクトの保存・読み込み

オブジェクトの保存・読み込み

オブジェクトをファイルに保存することができます。また、もとに戻すこともできます。

 

        let src:#HashTable = {HashTable “key1”, 10, “key2”, 20, “key3”, {DateTime}}
        def obj-url = {url “file/obj.bin”}

        || 保存
        {save-object-to-url obj-url, src}

        || 読み込み
        def dst = {read-object-from-url obj-url} asa HashTable

 

パッケージ名:COM.CURLAP.LIB.IO

 

RecordSetのファイル保存・読み込み

RecordSetのファイル保存・読み込み

RecordSetをファイルに保存、また、そのデータを読み込みすることができます。

        def record = {RecordSet
                         {RecordFields
                             {RecordField “c1”, domain = int, index-type = RecordFieldIndexType.unique},
                             {RecordField “c2”, domain = String},
                             {RecordField “c3”, domain = DateTime}
                         },
                         {RecordData c1 = 1, c2 = “v1”, c3 = {DateTime}},
                         {RecordData c1 = 2, c2 = “v2”, c3 = {DateTime}},
                         {RecordData c1 = 3, c2 = “v3”, c3 = {DateTime}},
                         {RecordData c1 = 4, c2 = “v4”, c3 = {DateTime}},
                         {RecordData c1 = 5, c2 = “v5”, c3 = {DateTime}}
                     }
        def path = “file/record.bin”
        {save-record-set-to-url {url path}, record}
        def restore = {read-record-set-from-url {url path}}

パッケージ名:COM.CURLAP.LIB.IO

 

 

ディレクトリ・ファイル検索ユーティリティ

DirectoryUtil

ディレクトリやファイルの検索を簡単にできる便利ツールです。

        || search by name
        def r1 =
            {DirectoryUtil.search-by-name
                {url “file”}, || directory
                “a-1.txt”,
                recurse? = true
            }
        
        || search by proc
        def r2 =
            {DirectoryUtil.search
                {url “file”}, || directory
                {proc {u:Url}:bool
                    def name = u.filename
                    {return name == “c-1.txt” or name == “test1”}
                },
                recurse? = true
            }

 

パッケージ名:COM.CURLAP.LIB.IO

簡単RecordSet定義

create-tableマクロ

CurlのRecordSetを定義するには、長いコードを記述しなければなりません。そこで、簡単に、かつSQLのCREATE TABLE文に似た構文でRecordSetを定義することができるマクロを用意しています。

    def rs = {create-table
                     col1 String   not null,
                     col2 int,
                     col3 DateTime NOT NULL,
                     col4 {StandardStringDomain},
                     col5 ,        || any
                     col6 not null || any
                 }

これは以下のものに相当します。

        def rs = {RecordSet
                        {RecordFields
                             {RecordField “col1” domain = String, nullable? = false},
                             {RecordField “col2” domain = int},
                             {RecordField “col3”, domain = DateTime, nullable? = false},
                             {RecordField “col4”, domain = {StandardStringDomain},
                             {RecordField “col5”},        || any
                             {RecordField “col6”, nullable? = false} || any
                        }
                 }

パッケージ名:COM.CURLAP.LIB.DATA-ACCESS

暗号・複合化ユーティリティ

メッセージダイジェスト

メッセージダイジェスト(SHA-1, MD5)を利用できます。以下のようにsha-1もしくはmd5プロシージャを実行することで、暗号化された文字列を取得できます。

def str = {sha-1 “abcd1234”}
def str = {md5 “abcd1234”}

またバージョン0.7から、SHA-1については、HMACにも対応しています。これにはhmac-sha-1プロシージャを利用してください。

将来的に、SHA-256,SHA-512などにも対応していく予定です。

秘密鍵暗号

秘密鍵暗号(トリプルDES、RC2、RC4)を利用できます。encrypt-with-common-keyで暗号化でき、decrypt-with-common-keyで複合化できます。

|| 暗号化
{encrypt-with-common-key
   
 ”key1234″, || かぎ
      “this is a text.”, || メッセージ
       {write-open-byte {url secret-file}} || OutputStream(書き出し先)
}   

|| 複合化
def result =
    {decrypt-with-common-key
       “key1234”, || かぎ
      {read-open-byte {url secret-file}} || InputStream 読み込み元
    }

パッケージ名:COM.CURLAP.LIB.CRYPTO

 

 

 

 

 

16進数ユーティリティ

hex-encode / hex-decode

これは、16進数のバイト列から文字列へエンコード、文字列から16進数のバイト列にデコードするユーティリティです。 

        {hex-encode {ByteVec 11, 7, 10}}   || == “0b070a”
        {hex-encode {ByteVec 255, 7, 10}} || == “ff070a”
        
        def b = {hex-decode “0b070a”}
        || b[0] == 11
        || b[1] == 7
        || b[2] == 10

パッケージ名:COM.CURLAP.LIB.CODEC

 

ボタンの2度押し防止

with-busy-viewマクロ

CommandButtonの2度押し防止をするためのマクロです。以下のサンプルのようにvというView内で、with-busy-view内に記述された処理が実行されている間は、CommandButtonがdisableとなり、押下することができません。

let v:View = …..
{with-busy-view v do
    {for i:int = 0 below 100000 do
        {output “押せない!!”}
    }
}

 パッケージ名:COM.CURLAP.LIB.UI

 

 

 

プロパティ(properties)ファイルの利用

Propertiesクラス

javaのpropertiesファイル形式を取り扱うためのクラスです。

hello.english=abcde
hello.test1=
hello.test2=jdbc.abc%s %d
hello.test3=jdbc.abc%s %d

 

def props = {Properties}
{props.load {read-open {url “file/properties/resource_ja.properties”}}}
props.size ||== 4
props[“hello.english”] ||== “abcde”

パッケージ名:COM.CURLAP.LIB.UTIL

経過時間の計測

stop-watchマクロ

stop-watchマクロを利用することで、stop-watchマクロ内のブロックのある処理からある処理までの実行速度を計測することができます。

           {stop-watch
                finish-proc =
                    {proc {elapsed-time:Time}:void
                        {output “elapsed time=” & elapsed-time}
                    }
             do
                {for i = 0 below 100000 do
                    {output “i = ” & i}
                }
            }

            || もしくはfinish-procを省略
            {stop-watch do
                {for i = 0 below 100000 do
                    {output “i = ” & i}
                }
            }
        }

上記結果は、「elapsed time=10s」のように出力されます。また、finish-procを省略できます。省略した場合は、実行時間のみコンソールに表示されます。

パッケージ名:COM.CURLAP.LIB.UTIL

VLE機能拡張:オートコンプリート

Advanced UIで提供されているオートコンプリートのAPIを利用して、VLEで利用できるようにしました。

まずは以下のファイルをダウンロードしてください。

vle-auto-complete.zip

ファイルを適当な場所に配置して解凍すると、以下のファイルが格納されています。

  •  autocomplete.gif
  •  autocomplete_blue.gif
  •  autocomplete_red.gif
  •  autocomplete_s.gif
  •  autocomplete_s_blue.gif
  •  autocomplete_s_red.gif
  •  AUTOCOMPLETE.scurl
  •  vle-auto-complete.scurl

次にCurl IDEを起動し、「ツール」から「ビジュアル レイアウト エディタ」を選択します。するとVLEが起動しますので、「表示」⇒「パレット機能拡張」を選択してください。すると「パレット機能拡張」というダイアログが表示されますので、『新規』ボタンを押下して、上記のvle-auto-complete.scurlを選択します。選択すると、以下のように一覧にファイルが追加されます。

vle-autocomplete-1.jpg

 

 

 

 

 

 

 

 

 

 

この状態でVLEでファイルの新規作成を行うと、以下のように「Developer Center」のタブが追加され、オートコンプリートの機能を持つ3種類のAPIがアイコンとして表示されます。

vle-autocomplete-2.jpg

 

 

 

 

 

 

 

 

 

 

これらの部品の機能は、以下の通りです。

AutoCompleteTextField

入力補完の機能を持つテキストフィールドです。入力候補となる文字列は自分で指定することが出来ます。

AutoCompleteComboBox

入力補完の機能を持つコンボボックスです。基本的な機能はAutoCompleteTextFieldと同様ですが、右側のプルダウンより入力候補を選択することが出来ます。

ReminderAutoCompleteTextField

入力履歴を記憶し、入力候補として表示するテキストフィールドです。テキストフィールドに名前をつけることにより、入力欄を識別することが可能です。

これらの部品を画面上に配置するとこれらの部品をパッケージに含むAUTOCOMPLETE.scurlがプロジェクトにコピーされ、追加されます。

注意

一度VLEにファイルを追加した後、vle-auto-complete.scurlとAUTOCOMPLETE.scurlのファイルを削除しないでください。また、VLE拡張機能はCurl Pro/IDEでのみ使用することができます。