ironnails 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +21 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/ironnails.gemspec +96 -0
- data/lib/iron_nails.rb +1 -0
- data/lib/ironnails/bin/IronNails.Library.dll +0 -0
- data/lib/ironnails/bin/IronRuby.Libraries.Yaml.dll +0 -0
- data/lib/ironnails/bin/IronRuby.Libraries.dll +0 -0
- data/lib/ironnails/bin/IronRuby.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Dynamic.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Scripting.Core.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Scripting.ExtensionAttribute.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Scripting.dll +0 -0
- data/lib/ironnails/config/configuration.rb +141 -0
- data/lib/ironnails/config/initializer.rb +144 -0
- data/lib/ironnails/controller/base.rb +135 -0
- data/lib/ironnails/controller/view_operations.rb +101 -0
- data/lib/ironnails/controller.rb +2 -0
- data/lib/ironnails/core_ext/array.rb +15 -0
- data/lib/ironnails/core_ext/class/attribute_accessors.rb +57 -0
- data/lib/ironnails/core_ext/class.rb +8 -0
- data/lib/ironnails/core_ext/fixnum.rb +22 -0
- data/lib/ironnails/core_ext/hash.rb +32 -0
- data/lib/ironnails/core_ext/kernel.rb +26 -0
- data/lib/ironnails/core_ext/string.rb +58 -0
- data/lib/ironnails/core_ext/symbol.rb +78 -0
- data/lib/ironnails/core_ext/system/net/web_request.rb +110 -0
- data/lib/ironnails/core_ext/system/security/secure_string.rb +18 -0
- data/lib/ironnails/core_ext/system/windows/markup/xaml_reader.rb +6 -0
- data/lib/ironnails/core_ext/system/windows/ui_element.rb +17 -0
- data/lib/ironnails/core_ext/time.rb +28 -0
- data/lib/ironnails/core_ext.rb +12 -0
- data/lib/ironnails/errors.rb +19 -0
- data/lib/ironnails/iron_xml.rb +83 -0
- data/lib/ironnails/logger.rb +4 -0
- data/lib/ironnails/logging/buffered_logger.rb +137 -0
- data/lib/ironnails/logging/class_logger.rb +29 -0
- data/lib/ironnails/models/base.rb +16 -0
- data/lib/ironnails/models/bindable_collection.rb +15 -0
- data/lib/ironnails/models/model_mixin.rb +69 -0
- data/lib/ironnails/models.rb +3 -0
- data/lib/ironnails/nails_engine.rb +398 -0
- data/lib/ironnails/observable.rb +117 -0
- data/lib/ironnails/security/secure_string.rb +61 -0
- data/lib/ironnails/version.rb +11 -0
- data/lib/ironnails/view/collections.rb +117 -0
- data/lib/ironnails/view/commands/add_sub_view_command.rb +33 -0
- data/lib/ironnails/view/commands/behavior_command.rb +29 -0
- data/lib/ironnails/view/commands/command.rb +208 -0
- data/lib/ironnails/view/commands/event_command.rb +32 -0
- data/lib/ironnails/view/commands/timed_command.rb +40 -0
- data/lib/ironnails/view/commands.rb +5 -0
- data/lib/ironnails/view/view.rb +190 -0
- data/lib/ironnails/view/view_model.rb +45 -0
- data/lib/ironnails/view/xaml_proxy.rb +226 -0
- data/lib/ironnails/view.rb +5 -0
- data/lib/ironnails/wpf.rb +113 -0
- data/lib/ironnails/wpf_application.rb +30 -0
- data/lib/ironnails.rb +68 -0
- metadata +133 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Taken from the Rails codebase. I can't require any gem atm when I can I will use their implementation.
|
|
2
|
+
#
|
|
3
|
+
# Extends the class object with class and instance accessors for class attributes,
|
|
4
|
+
# just like the native attr* accessors for instance attributes.
|
|
5
|
+
#
|
|
6
|
+
# class Person
|
|
7
|
+
# cattr_accessor :hair_colors
|
|
8
|
+
# end
|
|
9
|
+
#
|
|
10
|
+
# Person.hair_colors = [:brown, :black, :blonde, :red]
|
|
11
|
+
class Class
|
|
12
|
+
|
|
13
|
+
def cattr_reader(*syms)
|
|
14
|
+
syms.flatten.each do |sym|
|
|
15
|
+
next if sym.is_a?(Hash)
|
|
16
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
|
17
|
+
unless defined? @@#{sym}
|
|
18
|
+
@@#{sym} = nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.#{sym}
|
|
22
|
+
@@#{sym}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def #{sym}
|
|
26
|
+
@@#{sym}
|
|
27
|
+
end
|
|
28
|
+
EOS
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def cattr_writer(*syms)
|
|
33
|
+
options = syms.extract_options!
|
|
34
|
+
syms.flatten.each do |sym|
|
|
35
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
|
36
|
+
unless defined? @@#{sym}
|
|
37
|
+
@@#{sym} = nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.#{sym}=(obj)
|
|
41
|
+
@@#{sym} = obj
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#{"
|
|
45
|
+
def #{sym}=(obj)
|
|
46
|
+
@@#{sym} = obj
|
|
47
|
+
end
|
|
48
|
+
" unless options[:instance_writer] == false }
|
|
49
|
+
EOS
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def cattr_accessor(*syms)
|
|
54
|
+
cattr_reader(*syms)
|
|
55
|
+
cattr_writer(*syms)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class Fixnum
|
|
2
|
+
|
|
3
|
+
def to_timespan(as=:seconds)
|
|
4
|
+
case as
|
|
5
|
+
when :hours || :hour
|
|
6
|
+
TimeSpan.new(self, 0, 0)
|
|
7
|
+
when :minutes || :minute
|
|
8
|
+
TimeSpan.new(0, self, 0)
|
|
9
|
+
else
|
|
10
|
+
TimeSpan.new(0, 0, self)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def minutes
|
|
15
|
+
self * 60
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def seconds
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class Hash
|
|
2
|
+
|
|
3
|
+
#returns a string of post parameters for http posts, url-encoded
|
|
4
|
+
def to_post_parameters
|
|
5
|
+
params = ""
|
|
6
|
+
|
|
7
|
+
self.each do |k, v|
|
|
8
|
+
params += "&" unless params.empty?
|
|
9
|
+
params += "#{k}=#{HttpUtility.url_encode(v.to_s.to_clr_string)}"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
params
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_s
|
|
16
|
+
res = self.collect do |k, v|
|
|
17
|
+
val = case
|
|
18
|
+
when v.is_a?(String)
|
|
19
|
+
"\"#{v}\""
|
|
20
|
+
when v.is_a?(Symbol)
|
|
21
|
+
":#{v}"
|
|
22
|
+
else
|
|
23
|
+
"#{v}"
|
|
24
|
+
end
|
|
25
|
+
"#{k.is_a?(Symbol) ? ":#{k}" : "#{k}" } => #{val}"
|
|
26
|
+
end
|
|
27
|
+
"{ #{res.join(', ')} }"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
alias_method :to_str, :to_s
|
|
31
|
+
alias_method :inspect, :to_s
|
|
32
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Kernel
|
|
2
|
+
|
|
3
|
+
# Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.
|
|
4
|
+
#
|
|
5
|
+
# silence_warnings do
|
|
6
|
+
# value = noisy_call # no warning voiced
|
|
7
|
+
# end
|
|
8
|
+
#
|
|
9
|
+
# noisy_call # warning voiced
|
|
10
|
+
def silence_warnings
|
|
11
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
|
12
|
+
yield
|
|
13
|
+
ensure
|
|
14
|
+
$VERBOSE = old_verbose
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def using(o=nil)
|
|
18
|
+
begin
|
|
19
|
+
yield if block_given?
|
|
20
|
+
ensure
|
|
21
|
+
o.dispose
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
class String
|
|
2
|
+
|
|
3
|
+
# ensures that our url starts with at least http
|
|
4
|
+
def ensure_http
|
|
5
|
+
return "http://#{self}" unless /^(ht|f)tp:\/\/.*/i.match(self)
|
|
6
|
+
self
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# returns whether this string is a well formed url
|
|
10
|
+
def is_url?
|
|
11
|
+
!!(Uri.is_well_formed_uri_string(self.to_clr_string, UriKind.Absolute) && /^(ht|f)tp/i.match(Uri.new(self).scheme))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def strip_html
|
|
15
|
+
self.gsub(/<(.|\n)*?>/, '')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def camelize(first_letter_in_uppercase = true)
|
|
19
|
+
if first_letter_in_uppercase
|
|
20
|
+
self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
|
21
|
+
else
|
|
22
|
+
self[0...1].downcase + camelize(self)[1..-1]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def underscore
|
|
27
|
+
self.gsub(/::/, '/').
|
|
28
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
|
29
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
|
30
|
+
tr("-", "_").
|
|
31
|
+
downcase
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_clr_char
|
|
35
|
+
self.to_clr_string.to_char_array[0]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def to_secure_string
|
|
39
|
+
IronNails::Security::SecureString.secure_string self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def decrypt
|
|
43
|
+
IronNails::Security::SecureString.decrypt_string self
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def classify
|
|
47
|
+
Kernel.const_get(self.camelize)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def truncate(max=140)
|
|
51
|
+
if self.size > max
|
|
52
|
+
s = self[0...max-5]
|
|
53
|
+
return s.split(' ')[0...s.split(' ').size - 1].join(' ')
|
|
54
|
+
end
|
|
55
|
+
self
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
class Symbol
|
|
2
|
+
|
|
3
|
+
def to_brush
|
|
4
|
+
case self
|
|
5
|
+
when :black
|
|
6
|
+
Brushes.black
|
|
7
|
+
when :white
|
|
8
|
+
Brushes.white
|
|
9
|
+
when :green
|
|
10
|
+
Brushes.green
|
|
11
|
+
when :alice_blue
|
|
12
|
+
Brushes.alice_blue
|
|
13
|
+
when :red
|
|
14
|
+
Brushes.red
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_orientation
|
|
19
|
+
case self
|
|
20
|
+
when :horizontal
|
|
21
|
+
Orientation.horizontal
|
|
22
|
+
when :vertical
|
|
23
|
+
Orientation.vertical
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_visibility
|
|
28
|
+
case self
|
|
29
|
+
when :visible
|
|
30
|
+
Visibility.visible
|
|
31
|
+
when :hidden
|
|
32
|
+
Visibility.hidden
|
|
33
|
+
when :collapsed
|
|
34
|
+
Visibility.collapsed
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def to_vertical_alignment
|
|
39
|
+
case self
|
|
40
|
+
when :center
|
|
41
|
+
VerticalAlignment.center
|
|
42
|
+
when :top
|
|
43
|
+
VerticalAlignment.top
|
|
44
|
+
when :bottom
|
|
45
|
+
VerticalAlignment.bottom
|
|
46
|
+
when :stretch
|
|
47
|
+
VerticalAlignment.strecht
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_horizontal_alignment
|
|
52
|
+
case self
|
|
53
|
+
when :center
|
|
54
|
+
HorizontalAlignment.center
|
|
55
|
+
when :left
|
|
56
|
+
HorizontalAlignment.left
|
|
57
|
+
when :right
|
|
58
|
+
HorizontalAlignment.right
|
|
59
|
+
when :stretch
|
|
60
|
+
HorizontalAlignment.stretch
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def to_binding_mode
|
|
65
|
+
case self
|
|
66
|
+
when :default
|
|
67
|
+
BindingMode.default
|
|
68
|
+
when :one_time
|
|
69
|
+
BindingMode.one_time
|
|
70
|
+
when :one_way
|
|
71
|
+
BindingMode.one_way
|
|
72
|
+
when :one_way_to_source
|
|
73
|
+
BindingMode.one_way_to_source
|
|
74
|
+
when :two_way
|
|
75
|
+
BindingMode.two_way
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
class System::Net::WebRequest
|
|
2
|
+
|
|
3
|
+
include IronNails::Logging::ClassLogger
|
|
4
|
+
|
|
5
|
+
def prepare_for_post(parameters = {})
|
|
6
|
+
|
|
7
|
+
params = parameters.to_post_parameters
|
|
8
|
+
|
|
9
|
+
self.clr_member(:Method=).call "POST"
|
|
10
|
+
self.content_type = "application/x-www-form-urlencoded"
|
|
11
|
+
self.content_length = params.length
|
|
12
|
+
|
|
13
|
+
using (stream = StreamWriter.new(self.get_request_stream, System::Text::Encoding.ASCII)) do
|
|
14
|
+
stream.write params
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
params
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def prepare_for_async_post(parameters = {}, &callback)
|
|
21
|
+
self.clr_member(:Method=).call "POST"
|
|
22
|
+
self.content_type = "application/x-www-form-urlencoded"
|
|
23
|
+
self.content_length = parameters.to_post_parameters.length
|
|
24
|
+
|
|
25
|
+
self.begin_get_request_stream(AsyncCallback.new {|ar| callback.call(ar) }, nil)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def perform_post( params, parse_response=nil)
|
|
29
|
+
logger.debug("IronNails: WebRequest: Performing POST to #{request_uri.to_string}")
|
|
30
|
+
self.prepare_for_post(params)
|
|
31
|
+
begin
|
|
32
|
+
res = self.get_response # we get a real HttpWebResponse back instead of the WebResponse for the C# and VB.NET users. yay for duck typing
|
|
33
|
+
unless parse_response.nil?
|
|
34
|
+
using(rdr = StreamReader.new(res.get_response_stream)) do
|
|
35
|
+
return parse_response.call(rdr)
|
|
36
|
+
end
|
|
37
|
+
else
|
|
38
|
+
return res.status_code == HttpStatusCode.OK
|
|
39
|
+
end
|
|
40
|
+
rescue WebException => e
|
|
41
|
+
handle_exception e
|
|
42
|
+
end
|
|
43
|
+
false
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def perform_async_post( params, parse_response=nil, &callback)
|
|
47
|
+
logger.debug("IronNails: WebRequest: Performing asynchronous POST to #{request_uri.to_string}")
|
|
48
|
+
self.prepare_for_async_post params do |async_result|
|
|
49
|
+
using(post_stream = self.end_get_request_stream(async_result)) do
|
|
50
|
+
pars = parameters.to_post_parameters
|
|
51
|
+
post_stream.write pars.convert_to_bytes, 0, pars.size
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
self.begin_get_response(AsyncCallback.new { |response|
|
|
55
|
+
res = self.end_get_response response
|
|
56
|
+
using(rdr = StreamReader.new(res.get_response_stream)) do
|
|
57
|
+
parse_response.call(rdr)
|
|
58
|
+
end unless parse_response.nil?
|
|
59
|
+
callback.call res.status_code == HttpStatusCode.OK if block_given?
|
|
60
|
+
}, nil);
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def perform_get( parse_response=nil)
|
|
66
|
+
logger.debug("IronNails: WebRequest: Performing GET to #{request_uri.to_string}")
|
|
67
|
+
begin
|
|
68
|
+
response = self.get_response
|
|
69
|
+
using(rdr = StreamReader.new(response.get_response_stream)) do
|
|
70
|
+
parse_response.call(rdr)
|
|
71
|
+
end unless parse_response.nil?
|
|
72
|
+
rescue WebException => e
|
|
73
|
+
handle_exception e
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def perform_async_get( parse_response=nil, &callback)
|
|
78
|
+
logger.debug("IronNails: WebRequest: Performing asynchronous GET to #{request_uri.to_string}")
|
|
79
|
+
self.begin_get_response AsyncCallback.new{ |response|
|
|
80
|
+
begin
|
|
81
|
+
res = self.end_get_response(response)
|
|
82
|
+
using(rdr = StreamReader.new(res.get_response_stream)) do
|
|
83
|
+
obj = parse_response.call(rdr)
|
|
84
|
+
callback.call(obj) if block_given?
|
|
85
|
+
end if parse_response
|
|
86
|
+
rescue WebException => e
|
|
87
|
+
handle_exception e
|
|
88
|
+
end
|
|
89
|
+
}, nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def handle_exception(e)
|
|
93
|
+
logger.error("ERROR: IronNails: WebRequest (#{request_uri.to_string}):\nThere was an error while executing the web request: #{e.message}")
|
|
94
|
+
status = e.status;
|
|
95
|
+
if status == WebExceptionStatus.protocol_error
|
|
96
|
+
httpResponse = e.response
|
|
97
|
+
|
|
98
|
+
case httpResponse.status_code
|
|
99
|
+
when HttpStatusCode.NotModified: # 304 Not modified = no new tweets so ignore error.
|
|
100
|
+
break;
|
|
101
|
+
when HttpStatusCode.Unauthorized: # unauthorized
|
|
102
|
+
raise SecurityException.new("Not Authorized.");
|
|
103
|
+
else
|
|
104
|
+
raise
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
raise
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module System
|
|
2
|
+
|
|
3
|
+
module Security
|
|
4
|
+
|
|
5
|
+
class SecureString
|
|
6
|
+
|
|
7
|
+
def to_insecure_string
|
|
8
|
+
IronNails::Security::SecureString.unsecure_string self
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def encrypt
|
|
12
|
+
IronNails::Security::SecureString.encrypt_string self
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module System
|
|
2
|
+
|
|
3
|
+
module Windows
|
|
4
|
+
|
|
5
|
+
class UIElement
|
|
6
|
+
|
|
7
|
+
@@empty_delegate = System::Action.new { }
|
|
8
|
+
@@empty_priorty = System::Windows::Threading::DispatcherPriority.render
|
|
9
|
+
|
|
10
|
+
def refresh
|
|
11
|
+
self.dispatcher.invoke @@empty_priorty, @@empty_delegate
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'time'
|
|
2
|
+
class Time
|
|
3
|
+
|
|
4
|
+
def humanize
|
|
5
|
+
humanized_time = ""
|
|
6
|
+
delta = Time.now - self
|
|
7
|
+
case
|
|
8
|
+
when delta <= 1
|
|
9
|
+
humanized_time = "just now"
|
|
10
|
+
when delta < 60
|
|
11
|
+
humanized_time = "#{delta.floor} seconds ago"
|
|
12
|
+
when delta < 120
|
|
13
|
+
humanized_time = "about a minute ago"
|
|
14
|
+
when delta < (45 * 60)
|
|
15
|
+
humanized_time = "#{(delta / 60).round} minutes ago"
|
|
16
|
+
when delta < (90 * 60)
|
|
17
|
+
humanized_time = "about an hour ago"
|
|
18
|
+
when delta < (86400)
|
|
19
|
+
humanized_time = "about #{(delta / 3600 ).round } hours ago"
|
|
20
|
+
when delta < (48 * 3600)
|
|
21
|
+
humanized_time = "1 day ago"
|
|
22
|
+
else
|
|
23
|
+
humanized_time = "#{(delta / 86400).round} days ago"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
humanized_time
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'ironnails/core_ext/array'
|
|
2
|
+
require 'ironnails/core_ext/class'
|
|
3
|
+
require 'ironnails/core_ext/fixnum'
|
|
4
|
+
require 'ironnails/core_ext/hash'
|
|
5
|
+
require 'ironnails/core_ext/kernel'
|
|
6
|
+
require 'ironnails/core_ext/string'
|
|
7
|
+
require 'ironnails/core_ext/symbol'
|
|
8
|
+
require 'ironnails/core_ext/time'
|
|
9
|
+
require 'ironnails/core_ext/system/net/web_request'
|
|
10
|
+
require 'ironnails/core_ext/system/windows/markup/xaml_reader'
|
|
11
|
+
require 'ironnails/core_ext/system/windows/ui_element'
|
|
12
|
+
require 'ironnails/core_ext/system/security/secure_string'
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module IronNails
|
|
2
|
+
|
|
3
|
+
module Errors
|
|
4
|
+
|
|
5
|
+
class IronNailsError < StandardError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class ContractError < IronNails::Errors::IronNailsError
|
|
11
|
+
|
|
12
|
+
def initialize(method)
|
|
13
|
+
super "#{method} needs to be overridden in an implementing class"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module IronNails
|
|
2
|
+
|
|
3
|
+
module Core
|
|
4
|
+
|
|
5
|
+
class IronXml
|
|
6
|
+
|
|
7
|
+
attr_reader :xml_node, :parent
|
|
8
|
+
|
|
9
|
+
def initialize(xml_doc, parent=nil)
|
|
10
|
+
@xml_node = xml_doc
|
|
11
|
+
@parent = parent
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# selects multiple child nodes from the tree
|
|
15
|
+
def elements(name, &b)
|
|
16
|
+
if has_element? name
|
|
17
|
+
ele = @xml_node.select_nodes xp_pref(name)
|
|
18
|
+
ele.each do |el|
|
|
19
|
+
raise "Expected a block for multiple elements" unless block_given?
|
|
20
|
+
b.call IronXml.new(el, self) unless el.nil?
|
|
21
|
+
end
|
|
22
|
+
else
|
|
23
|
+
[]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# selects a single child node from the tree
|
|
28
|
+
def element(name)
|
|
29
|
+
if has_element? name
|
|
30
|
+
ele = @xml_node.select_single_node xp_pref(name)
|
|
31
|
+
xml = IronXml.new(ele, self)
|
|
32
|
+
yield xml if block_given?
|
|
33
|
+
xml
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# indicates whether the element is present in the selected nodes.
|
|
38
|
+
def has_element?(name)
|
|
39
|
+
!@xml_node.nil? && @xml_node.select_nodes("#{name}").count > 0
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# the XPath prefix (rooted or not?)
|
|
43
|
+
def xp_pref(name)
|
|
44
|
+
@parent.nil? ? "//#{name}" : name
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# the value of the selected node
|
|
48
|
+
def value
|
|
49
|
+
@xml_node.inner_text
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# parses an xml document. +content+ can be either
|
|
53
|
+
# a string containing xml, a path to an xml document
|
|
54
|
+
# or a System::IO::Reader. You tell IronXml which type of
|
|
55
|
+
# content you have by passing in a +content_type+.
|
|
56
|
+
# +content_type+ is a symbol that defaults to :string
|
|
57
|
+
# it expects a block to traverse the xml provided.
|
|
58
|
+
def self.parse(content, content_type = :string, &b)
|
|
59
|
+
xdoc = XmlDocument.new
|
|
60
|
+
|
|
61
|
+
if content_type == :string
|
|
62
|
+
xdoc.load_xml(content)
|
|
63
|
+
else
|
|
64
|
+
xdoc.load(content)
|
|
65
|
+
end
|
|
66
|
+
b.call(IronXml.new(xdoc))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def method_missing(sym, *args, &b)
|
|
70
|
+
# this is what gives us the syntactic sugar over the
|
|
71
|
+
# Xlinq like syntax
|
|
72
|
+
if block_given?
|
|
73
|
+
self.elements(sym.to_s, &b)
|
|
74
|
+
else
|
|
75
|
+
self.element(sym.to_s).value
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|