clickclient 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/License.txt +57 -0
- data/README.txt +34 -0
- data/example/example_use_localserver.rb +202 -0
- data/lib/clickclient/common.rb +208 -0
- data/lib/clickclient/fx.rb +992 -0
- data/lib/clickclient/version.rb +9 -0
- data/lib/clickclient.rb +4 -0
- data/test/alltests.rb +6 -0
- data/test/connect_test_fx.rb +728 -0
- data/test/test_base.rb +61 -0
- data/test/test_helper.rb +2 -0
- metadata +69 -0
data/History.txt
ADDED
data/License.txt
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the GPL,
|
3
|
+
or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) rename any non-standard executables so the names do not conflict
|
21
|
+
with standard executables, which must also be provided.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or executable
|
26
|
+
form, provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the executables and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard executables non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under this terms.
|
43
|
+
|
44
|
+
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
|
45
|
+
files under the ./missing directory. See each file for the copying
|
46
|
+
condition.
|
47
|
+
|
48
|
+
5. The scripts and library files supplied as input to or produced as
|
49
|
+
output from the software do not automatically fall under the
|
50
|
+
copyright of the software, but belong to whomever generated them,
|
51
|
+
and may be sold commercially, and may be aggregated with this
|
52
|
+
software.
|
53
|
+
|
54
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
55
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
56
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
57
|
+
PURPOSE.
|
data/README.txt
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
= CLICK Client -- CLICK Securities Web Service Client Library for Ruby.
|
2
|
+
|
3
|
+
CLICK Client is a CLICK Securities Web Service Client for Ruby.
|
4
|
+
CLICK Client はクリック証券Webサービスにアクセスするためのクライアントライブラリです。
|
5
|
+
以下の機能を提供します。
|
6
|
+
|
7
|
+
* 外為証拠金取引(FX)取引
|
8
|
+
|
9
|
+
|
10
|
+
== Dounload
|
11
|
+
|
12
|
+
CLICK Clientの最新バージョンは以下のサイトからダウンロードできます。
|
13
|
+
|
14
|
+
* http://rubyforge.org/projects/clickclient
|
15
|
+
|
16
|
+
|
17
|
+
== Installation
|
18
|
+
|
19
|
+
rubygemを使ってインストール可能です。なお、依存もジュールとして「httpclient」も必要となります。
|
20
|
+
以下のコマンドを実行してインストールしてください。
|
21
|
+
|
22
|
+
% [sudo] gem install httpclient --source http://dev.ctor.org/download/
|
23
|
+
% [sudo] gem install clickclient
|
24
|
+
|
25
|
+
|
26
|
+
== License
|
27
|
+
|
28
|
+
Ruby ライセンスに準拠
|
29
|
+
|
30
|
+
|
31
|
+
== Disclaimer
|
32
|
+
* 本ライブラリの利用は自己責任でお願いします。
|
33
|
+
* ライブラリの不備・不具合等によるあらゆる損害について、作成者は責任を負いません。
|
34
|
+
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/clickclient'
|
2
|
+
|
3
|
+
require 'kconv'
|
4
|
+
|
5
|
+
#== 利用サンプル
|
6
|
+
#ローカルサーバーに接続し、結果を表示します。
|
7
|
+
c = ClickClient::Client.new
|
8
|
+
|
9
|
+
# ローカルサーバーへの接続設定
|
10
|
+
c.host_name = "http://localhost:8000"
|
11
|
+
c.fx_path = "/webservice/ws-redirect"
|
12
|
+
c.fx_session( "012345678", "sdfsdf" ) { | fx_session |
|
13
|
+
|
14
|
+
# 通貨ペア一覧取得
|
15
|
+
# 引数で取得する通貨ペアコードを配列で指定
|
16
|
+
# 指定しない場合すべての通貨ペアの情報を取得。
|
17
|
+
puts "\n--- list_currency_pairs"
|
18
|
+
list = fx_session.list_currency_pairs [GMO::FX::USDJPY, GMO::FX::EURJPY]
|
19
|
+
list.each{ |currency_pair_code, value| puts value }
|
20
|
+
|
21
|
+
# レート一覧取得
|
22
|
+
puts "\n--- list_rates"
|
23
|
+
list = fx_session.list_rates
|
24
|
+
list.each{ |currency_pair_code, value| puts value }
|
25
|
+
|
26
|
+
# 成り行き注文
|
27
|
+
puts "\n--- order - buy"
|
28
|
+
puts fx_session.order( GMO::FX::USDJPY, GMO::FX::BUY, 2 )
|
29
|
+
puts "\n--- order - sell"
|
30
|
+
result = fx_session.order( GMO::FX::USDJPY, GMO::FX::SELL, 1, {
|
31
|
+
:slippage=>99,
|
32
|
+
:slippage_base_rate=>list[GMO::FX::USDJPY].bid_rate
|
33
|
+
})
|
34
|
+
puts result
|
35
|
+
|
36
|
+
# 成り行き決済注文
|
37
|
+
puts "\n--- settle"
|
38
|
+
puts fx_session.settle( result.order_no, 1 )
|
39
|
+
puts fx_session.settle( result.order_no, 2, {
|
40
|
+
:slippage=>99,
|
41
|
+
:slippage_base_rate=>list[GMO::FX::USDJPY].bid_rate
|
42
|
+
})
|
43
|
+
|
44
|
+
# 通常注文
|
45
|
+
puts "\n--- order - basic sell"
|
46
|
+
result = fx_session.order( GMO::FX::USDJPY, GMO::FX::SELL, 1, {
|
47
|
+
:rate=>145.19,
|
48
|
+
:execution_expression=>GMO::FX::EXECUTION_EXPRESSION_LIMIT_ORDER,
|
49
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
50
|
+
:expiration_date=>DateTime.new( 2007, 11, 5, 0 )
|
51
|
+
})
|
52
|
+
puts result
|
53
|
+
|
54
|
+
# 注文変更
|
55
|
+
puts "\n--- edit_order"
|
56
|
+
fx_session.edit_order( result.order_no, {
|
57
|
+
:rate=>145.19,
|
58
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_TODAY
|
59
|
+
})
|
60
|
+
|
61
|
+
# 注文取消し
|
62
|
+
puts "\n--- cancel_order"
|
63
|
+
fx_session.cancel_order( result.order_no )
|
64
|
+
|
65
|
+
# 通常決済注文
|
66
|
+
puts "\n--- settle - basic"
|
67
|
+
result = fx_session.order( GMO::FX::USDJPY, GMO::FX::SELL, 2, {
|
68
|
+
:rate=>145.19,
|
69
|
+
:execution_expression=>GMO::FX::EXECUTION_EXPRESSION_LIMIT_ORDER,
|
70
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_TODAY
|
71
|
+
})
|
72
|
+
puts fx_session.settle( result.order_no, 2, {
|
73
|
+
:rate=>146.20,
|
74
|
+
:execution_expression=>GMO::FX::EXECUTION_EXPRESSION_LIMIT_ORDER,
|
75
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
76
|
+
:expiration_date=>DateTime.new( 2007, 11, 5, 0 )
|
77
|
+
})
|
78
|
+
|
79
|
+
# OCO注文
|
80
|
+
puts "\n--- order - oco"
|
81
|
+
result = fx_session.order( GMO::FX::USDJPY, GMO::FX::SELL, 1, {
|
82
|
+
:rate=>145.19,
|
83
|
+
:stop_order_rate=>144.19,
|
84
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
85
|
+
:expiration_date=>DateTime.new( 2007, 11, 5, 0 )
|
86
|
+
})
|
87
|
+
puts result
|
88
|
+
|
89
|
+
# OCO注文変更
|
90
|
+
puts "\n--- edit - oco"
|
91
|
+
fx_session.edit_order( result.limit_order_no, {
|
92
|
+
:stop_order_no=>result.stop_order_no,
|
93
|
+
:rate=>145.29,
|
94
|
+
:stop_order_rate=>144.29,
|
95
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
96
|
+
:expiration_date=>DateTime.new( 2007, 11, 6, 0 )
|
97
|
+
})
|
98
|
+
|
99
|
+
# OCO決済注文
|
100
|
+
puts "\n--- settle - oco"
|
101
|
+
puts fx_session.settle( result.limit_order_no, 2, {
|
102
|
+
:rate=>146.20,
|
103
|
+
:stop_order_rate=>144.19,
|
104
|
+
:execution_expression=>GMO::FX::EXECUTION_EXPRESSION_LIMIT_ORDER,
|
105
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
106
|
+
:expiration_date=>DateTime.new( 2007, 11, 5, 0 )
|
107
|
+
})
|
108
|
+
|
109
|
+
# IFD取引
|
110
|
+
puts "\n--- order - ifd"
|
111
|
+
result = fx_session.order( GMO::FX::USDJPY, GMO::FX::SELL, 1, {
|
112
|
+
:rate=>145.19,
|
113
|
+
:execution_expression=>GMO::FX::EXECUTION_EXPRESSION_LIMIT_ORDER,
|
114
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
115
|
+
:expiration_date=>DateTime.new( 2007, 11, 5, 0 ),
|
116
|
+
:settle=>{
|
117
|
+
:unit=>1,
|
118
|
+
:sell_or_buy=>GMO::FX::BUY,
|
119
|
+
:rate=>145.91,
|
120
|
+
:execution_expression=>GMO::FX::EXECUTION_EXPRESSION_LIMIT_ORDER,
|
121
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
122
|
+
:expiration_date=>DateTime.new( 2007, 11, 5, 0 ),
|
123
|
+
}
|
124
|
+
})
|
125
|
+
puts result
|
126
|
+
|
127
|
+
# IFD注文変更
|
128
|
+
puts "\n--- edit - ifd"
|
129
|
+
fx_session.edit_order( result.order_no, {
|
130
|
+
:rate=>145.29,
|
131
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_TODAY,
|
132
|
+
:settle=>{
|
133
|
+
:order_no=>result.settlement_order_no,
|
134
|
+
:rate=>145.91,
|
135
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
136
|
+
:expiration_date=>DateTime.new( 2007, 11, 6, 0 ),
|
137
|
+
}
|
138
|
+
})
|
139
|
+
|
140
|
+
# IFD-OCO取引
|
141
|
+
puts "\n--- order - ifd-oco"
|
142
|
+
result = fx_session.order( GMO::FX::USDJPY, GMO::FX::SELL, 1, {
|
143
|
+
:rate=>145.19,
|
144
|
+
:execution_expression=>GMO::FX::EXECUTION_EXPRESSION_LIMIT_ORDER,
|
145
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_TODAY,
|
146
|
+
:settle=>{
|
147
|
+
:unit=>1,
|
148
|
+
:sell_or_buy=>GMO::FX::BUY,
|
149
|
+
:rate=>145.91,
|
150
|
+
:stop_order_rate=>144.15,
|
151
|
+
:execution_expression=>GMO::FX::EXECUTION_EXPRESSION_LIMIT_ORDER,
|
152
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
153
|
+
:expiration_date=>DateTime.new( 2007, 11, 5, 0 ),
|
154
|
+
}
|
155
|
+
})
|
156
|
+
puts result
|
157
|
+
|
158
|
+
# IFD-OCO注文変更
|
159
|
+
puts "\n--- edit - ifd-oco"
|
160
|
+
fx_session.edit_order( result.order_no, {
|
161
|
+
:rate=>145.29,
|
162
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
163
|
+
:expiration_date=>DateTime.new( 2007, 11, 6, 0 ),
|
164
|
+
:settle=>{
|
165
|
+
:order_no=>result.kessaiSashineChumonBango,
|
166
|
+
:stop_order_no=>result.kessaiGyakusashiChumonBango,
|
167
|
+
:rate=>145.21,
|
168
|
+
:stop_order_rate=>144.15,
|
169
|
+
:expiration_type=>GMO::FX::EXPIRATION_TYPE_SPECIFIED,
|
170
|
+
:expiration_date=>DateTime.new( 2007, 11, 6, 0 ),
|
171
|
+
}
|
172
|
+
})
|
173
|
+
|
174
|
+
# 注文一覧取得
|
175
|
+
# 引数で、注文状態コード(必須)、通貨ペアコード、注文日期間開始日、注文日期間終了日を指定可能。
|
176
|
+
puts "\n--- list_orders"
|
177
|
+
list = fx_session.list_orders GMO::FX::ORDER_CONDITION_ALL, GMO::FX::EURJPY, Date.new( 2007, 10, 1 ), Date.new( 2007, 11, 1 )
|
178
|
+
list.each{ |item| puts item }
|
179
|
+
|
180
|
+
# 建玉一覧取得
|
181
|
+
# 引数で、通貨ペアコードを指定可能。(省略可)
|
182
|
+
puts "\n--- list_open_interests"
|
183
|
+
list = fx_session.list_open_interests( GMO::FX::EURJPY )
|
184
|
+
list.each{ |item| puts item }
|
185
|
+
|
186
|
+
# 約定一覧取得
|
187
|
+
# 引数で、取得期間(開始日,終了日)(必須)、通貨ペアコード、取引タイプ(新規Or決済)を指定可能。
|
188
|
+
puts "\n--- list_execution_results"
|
189
|
+
list = fx_session.list_execution_results( Date.new( 2007, 10, 1 ), Date.new( 2007, 11, 1 ) )
|
190
|
+
list.each{ |item| puts item }
|
191
|
+
list = fx_session.list_execution_results( Date.new( 2007, 10, 1 ), Date.new( 2007, 11, 1 ), GMO::FX::TRADE_TYPE_NEW, GMO::FX::EURJPY )
|
192
|
+
list.each{ |item| puts item }
|
193
|
+
|
194
|
+
# 余力情報の取得
|
195
|
+
puts "\n--- get_margin"
|
196
|
+
puts fx_session.get_margin
|
197
|
+
|
198
|
+
# お知らせ一覧取得
|
199
|
+
puts "\n--- list_messages"
|
200
|
+
list = fx_session.list_messages
|
201
|
+
list.each{ |item| puts item.to_s.tosjis }
|
202
|
+
}
|
@@ -0,0 +1,208 @@
|
|
1
|
+
begin
|
2
|
+
require 'rubygems'
|
3
|
+
rescue LoadError
|
4
|
+
end
|
5
|
+
require 'httpclient'
|
6
|
+
require 'rexml/document'
|
7
|
+
require 'date'
|
8
|
+
|
9
|
+
#
|
10
|
+
#=== クリック証券アクセスクライアント
|
11
|
+
#
|
12
|
+
#*Version*:: 0.0.1
|
13
|
+
#*License*:: Ruby ライセンスに準拠
|
14
|
+
#
|
15
|
+
#クリック証券Webサービスを利用するためのクライアントライブラリです。以下の機能を提供します。
|
16
|
+
#- 外為証拠金取引(FX)取引
|
17
|
+
#
|
18
|
+
#====依存モジュール
|
19
|
+
#「{httpclient}[http://dev.ctor.org/http-access2]」を利用しています。以下のコマンドを実行してインストールしてください。
|
20
|
+
#
|
21
|
+
# gem install httpclient --source http://dev.ctor.org/download/
|
22
|
+
#
|
23
|
+
#====基本的な使い方
|
24
|
+
#
|
25
|
+
# require 'clickclient'
|
26
|
+
#
|
27
|
+
# c = ClickClient::Client.new
|
28
|
+
# # c = ClickClient::Client.new https://<プロキシホスト>:<プロキシポート> # プロキシを利用する場合
|
29
|
+
# c.fx_session( "<ユーザー名>", "<パスワード>" ) { | fx_session |
|
30
|
+
# # 通貨ペア一覧取得
|
31
|
+
# list = fx_session.list_currency_pairs
|
32
|
+
# puts list
|
33
|
+
# }
|
34
|
+
#なお、ご利用にあたっては「{クリック証券Webサービス利用規約}[https://sec.gmo.jp/corp/guide/regulations/pdf/reg_webservice.pdf]
|
35
|
+
#」(PDF)に同意して頂く必要があります。
|
36
|
+
#
|
37
|
+
#====免責
|
38
|
+
#- 本ライブラリの利用は自己責任でお願いします。
|
39
|
+
#- ライブラリの不備・不具合等によるあらゆる損害について、作成者は責任を負いません。
|
40
|
+
#
|
41
|
+
module ClickClient
|
42
|
+
|
43
|
+
# クライアント
|
44
|
+
class Client
|
45
|
+
|
46
|
+
# ホスト名
|
47
|
+
DEFAULT_HOST_NAME = "https://sec-sso.gmo.jp"
|
48
|
+
|
49
|
+
#
|
50
|
+
#===コンストラクタ
|
51
|
+
#
|
52
|
+
#*proxy*:: プロキシホストを利用する場合、そのホスト名とパスを指定します。
|
53
|
+
# 例) https://proxyhost.com:80
|
54
|
+
#
|
55
|
+
def initialize( proxy=nil )
|
56
|
+
@client = HTTPClient.new( proxy, "ClickClientLib")
|
57
|
+
@client.set_cookie_store("cookie.dat")
|
58
|
+
@host_name = DEFAULT_HOST_NAME
|
59
|
+
end
|
60
|
+
|
61
|
+
#ホスト名
|
62
|
+
attr :host_name, true
|
63
|
+
|
64
|
+
private
|
65
|
+
# ログインしてブロックを実行する。ブロックの実行後ログアウトする。
|
66
|
+
def session( uri, userid, password, &block )
|
67
|
+
|
68
|
+
# sequence 1
|
69
|
+
result = @client.post(uri, "u=" << userid )
|
70
|
+
seq2_uri = result.header["Location"].to_s
|
71
|
+
raise "fail session-1.responce=" << result.content if seq2_uri == nil || seq2_uri.length <= 0
|
72
|
+
|
73
|
+
# sequence 2
|
74
|
+
result = @client.get( seq2_uri )
|
75
|
+
doc = REXML::Document.new(result.content)
|
76
|
+
unless ( doc.text( "./loginResponse/responseStatus" ) =~ /OK/ )
|
77
|
+
raise "fail session-2." << doc.text( "./loginResponse/message" )
|
78
|
+
end
|
79
|
+
|
80
|
+
# sequence 3
|
81
|
+
base_uri = File.dirname( seq2_uri )
|
82
|
+
result = @client.post( base_uri + "/ws-login", "j_username=#{userid}&j_password=#{password}" )
|
83
|
+
seq4_uri = result.header["Location"]
|
84
|
+
if ( seq4_uri == nil || seq4_uri.length <= 0 )
|
85
|
+
doc = REXML::Document.new(result.content)
|
86
|
+
raise "fail session-3." << doc.text( "./loginResponse/message" )
|
87
|
+
end
|
88
|
+
|
89
|
+
# sequence 4
|
90
|
+
# responseStatusがOKになるまでリダイレクトが続く。
|
91
|
+
while ( true )
|
92
|
+
result = @client.get( seq4_uri )
|
93
|
+
doc = REXML::Document.new(result.content)
|
94
|
+
if ( doc.text( "./loginResponse/responseStatus" ) =~ /OK/ )
|
95
|
+
break
|
96
|
+
else
|
97
|
+
seq4_uri = result.header["Location"]
|
98
|
+
raise "fail session-4.responce=" << result.content if seq4_uri == nil || seq4_uri.length <= 0
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
begin
|
103
|
+
block.call( @client, base_uri )
|
104
|
+
ensure
|
105
|
+
# logout
|
106
|
+
result = @client.post( base_uri + "/ws-logout" )
|
107
|
+
doc = REXML::Document.new(result.content)
|
108
|
+
unless ( doc.text( "./logoutResponse/responseStatus" ) =~ /OK/ )
|
109
|
+
raise "fail session-5." << doc.text( "./logoutResponse/message" )
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
#
|
119
|
+
#=== 結果オブジェクトの抽象基底クラス。
|
120
|
+
#
|
121
|
+
class Base #:nodoc:
|
122
|
+
def initialize( item )
|
123
|
+
# 属性と子要素の値を、オブジェクトの属性として格納する。
|
124
|
+
item.attributes.each { |name, value|
|
125
|
+
set_attribute(name.to_s ,value)
|
126
|
+
}
|
127
|
+
item.elements.each { |elm|
|
128
|
+
if ( elm.name != "responseStatus" && elm.name != "message" )
|
129
|
+
set_attribute(elm.name.to_s, elm.text)
|
130
|
+
end
|
131
|
+
}
|
132
|
+
end
|
133
|
+
def to_s
|
134
|
+
str = ""
|
135
|
+
instance_variables.each { |name|
|
136
|
+
str += name + "=" + instance_variable_get(name).to_s + ", "
|
137
|
+
}
|
138
|
+
return str.chop.chop
|
139
|
+
end
|
140
|
+
def method_missing( name, *args )
|
141
|
+
if name.to_s =~ /(.*?)=/
|
142
|
+
name = $1
|
143
|
+
setter = true
|
144
|
+
end
|
145
|
+
|
146
|
+
# 同名の属性があればそれのReaderと見なし、属性値を返す。
|
147
|
+
value = instance_variable_get("@" << name.to_s)
|
148
|
+
unless ( value == nil )
|
149
|
+
if setter
|
150
|
+
instance_variable_set( "@" << name, args[0] )
|
151
|
+
else
|
152
|
+
return value
|
153
|
+
end
|
154
|
+
else
|
155
|
+
super(name)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
def hash
|
159
|
+
hash = 0
|
160
|
+
values.each {|v|
|
161
|
+
hash = v.hash + 31 * hash
|
162
|
+
}
|
163
|
+
return hash
|
164
|
+
end
|
165
|
+
def eql?(other)
|
166
|
+
return false if other == nil
|
167
|
+
return false unless other.is_a?( Base )
|
168
|
+
a = values
|
169
|
+
b = other.values
|
170
|
+
return false if a.length != b.length
|
171
|
+
a.length.times{|i|
|
172
|
+
return false unless a[i].eql? b[i]
|
173
|
+
}
|
174
|
+
return true
|
175
|
+
end
|
176
|
+
protected
|
177
|
+
def values
|
178
|
+
values = []
|
179
|
+
instance_variables.each { |name|
|
180
|
+
values << instance_variable_get(name)
|
181
|
+
}
|
182
|
+
return values
|
183
|
+
end
|
184
|
+
private
|
185
|
+
def set_attribute(name ,value)
|
186
|
+
if ( value =~ /^\d+$/)
|
187
|
+
value = value.to_i
|
188
|
+
elsif ( value =~ /^[\d\.]+$/)
|
189
|
+
value = value.to_f
|
190
|
+
elsif ( value =~ /^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}$/)
|
191
|
+
value = DateTime.strptime( value, "%Y-%m-%d %H:%M:%S")
|
192
|
+
elsif ( value =~ /^\d{4}-\d{2}-\d{2}$/)
|
193
|
+
value = DateTime.strptime( value, "%Y-%m-%d")
|
194
|
+
end
|
195
|
+
instance_variable_set( "@" << name, value )
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# 結果を解析し、エラーであれば例外をスローする。
|
200
|
+
def self.parse( content )
|
201
|
+
doc = REXML::Document.new( content )
|
202
|
+
unless ( doc.text( "./*/responseStatus" ) =~ /OK/ )
|
203
|
+
raise "fail." << doc.text( "./*/message" )
|
204
|
+
end
|
205
|
+
return doc
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|