rave 0.1.2-java
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/bin/rave +28 -0
- data/lib/commands/appcfg.rb +9 -0
- data/lib/commands/create.rb +153 -0
- data/lib/commands/server.rb +8 -0
- data/lib/commands/task.rb +156 -0
- data/lib/commands/usage.rb +19 -0
- data/lib/commands/war.rb +28 -0
- data/lib/exceptions.rb +20 -0
- data/lib/ext/logger.rb +7 -0
- data/lib/gems.yaml +9 -0
- data/lib/jars/appengine-api-1.0-sdk-1.3.0.jar +0 -0
- data/lib/mixins/controller.rb +72 -0
- data/lib/mixins/data_format.rb +206 -0
- data/lib/mixins/logger.rb +19 -0
- data/lib/mixins/object_factory.rb +87 -0
- data/lib/mixins/time_utils.rb +19 -0
- data/lib/models/annotation.rb +148 -0
- data/lib/models/blip.rb +305 -0
- data/lib/models/component.rb +42 -0
- data/lib/models/context.rb +174 -0
- data/lib/models/document.rb +9 -0
- data/lib/models/element.rb +113 -0
- data/lib/models/event.rb +230 -0
- data/lib/models/operation.rb +79 -0
- data/lib/models/range.rb +14 -0
- data/lib/models/robot.rb +79 -0
- data/lib/models/user.rb +62 -0
- data/lib/models/wave.rb +45 -0
- data/lib/models/wavelet.rb +269 -0
- data/lib/ops/blip_ops.rb +233 -0
- data/lib/rave.rb +28 -0
- metadata +135 -0
data/lib/models/blip.rb
ADDED
@@ -0,0 +1,305 @@
|
|
1
|
+
module Rave
|
2
|
+
module Models
|
3
|
+
# Represents a blip, containing formated text, gadgets and other elements.
|
4
|
+
# It is part of a Wavelet within a Wave.
|
5
|
+
class Blip < Component
|
6
|
+
include Rave::Mixins::TimeUtils
|
7
|
+
include Rave::Mixins::Logger
|
8
|
+
|
9
|
+
JAVA_CLASS = 'com.google.wave.api.impl.BlipData' # :nodoc:
|
10
|
+
|
11
|
+
# Version number of the contents of the blip [Integer]
|
12
|
+
def version
|
13
|
+
@version.dup
|
14
|
+
end
|
15
|
+
|
16
|
+
# Annotations on the blip [Array of Annotation]
|
17
|
+
def annotations # :nodoc:
|
18
|
+
@annotations.dup
|
19
|
+
end
|
20
|
+
|
21
|
+
# IDs of the children of this blip [Array of String]
|
22
|
+
def child_blip_ids # :nodoc:
|
23
|
+
@child_blip_ids.map { |id| id.dup }
|
24
|
+
end
|
25
|
+
|
26
|
+
# IDs (email addresses) of those who have altered this blip [Array of String]
|
27
|
+
def contributor_ids # :nodoc:
|
28
|
+
@contributor_ids.map { |id| id.dup }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Elements contained within this blip [Array of Element]
|
32
|
+
def elements # :nodoc:
|
33
|
+
@elements.dup
|
34
|
+
end
|
35
|
+
|
36
|
+
# Last time the blip was altered [Time]
|
37
|
+
def last_modified_time # :nodoc:
|
38
|
+
@last_modified_time.dup
|
39
|
+
end
|
40
|
+
|
41
|
+
# ID of this blip's parent [String or nil for a root blip]
|
42
|
+
def parent_blip_id # :nodoc:
|
43
|
+
@parent_blip_id.nil? ? nil : @parent_blip_id.dup
|
44
|
+
end
|
45
|
+
|
46
|
+
# ID of the wave this blip belongs to [String]
|
47
|
+
def wave_id # :nodoc:
|
48
|
+
@wave_id.nil? ? nil : @wave_id.dup
|
49
|
+
end
|
50
|
+
|
51
|
+
# ID of the wavelet this blip belongs to [String]
|
52
|
+
def wavelet_id # :nodoc:
|
53
|
+
@wavelet_id.nil? ? nil : @wavelet_id.dup
|
54
|
+
end
|
55
|
+
|
56
|
+
# Wavelet that the blip is a part of [Wavelet]
|
57
|
+
def wavelet # :nodoc:
|
58
|
+
@context.wavelets[@wavelet_id]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Wave that this blip is a part of [Wave]
|
62
|
+
def wave # :nodoc:
|
63
|
+
@context.waves[@wave_id]
|
64
|
+
end
|
65
|
+
|
66
|
+
# Blip that this Blip is a direct reply to. Will be nil if the root blip
|
67
|
+
# in a wavelet [Blip or nil for a root blip]
|
68
|
+
def parent_blip # :nodoc:
|
69
|
+
@context.blips[@parent_blip_id]
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns true if this is a root blip (no parent blip) [Boolean]
|
73
|
+
def root? # :nodoc:
|
74
|
+
@parent_blip_id.nil?
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns true if this is a leaf node (has no children). [Boolean]
|
78
|
+
def leaf? # :nodoc:
|
79
|
+
@child_blip_ids.empty?
|
80
|
+
end
|
81
|
+
|
82
|
+
# Has the blip been deleted? [Boolean]
|
83
|
+
def deleted? # :nodoc:
|
84
|
+
[:deleted, :null].include? @state
|
85
|
+
end
|
86
|
+
|
87
|
+
# Has the blip been completely destroyed? [Boolean]
|
88
|
+
def null? # :nodoc:
|
89
|
+
@state == :null
|
90
|
+
end
|
91
|
+
|
92
|
+
# Text contained in the blip [String]
|
93
|
+
def content # :nodoc:
|
94
|
+
@content.dup
|
95
|
+
end
|
96
|
+
|
97
|
+
# Users that have made a contribution to the blip [Array of User]
|
98
|
+
def contributors # :nodoc:
|
99
|
+
@contributor_ids.map { |c| @context.users[c] }
|
100
|
+
end
|
101
|
+
|
102
|
+
# Original creator of the blip [User]
|
103
|
+
def creator # :nodoc:
|
104
|
+
@context.users[@creator]
|
105
|
+
end
|
106
|
+
|
107
|
+
# List of direct children of this blip. The first one will be continuing
|
108
|
+
# the thread, others will be indented replies [Array of Blip]
|
109
|
+
def child_blips # :nodoc:
|
110
|
+
@child_blip_ids.map { |id| @context.blips[id] }
|
111
|
+
end
|
112
|
+
|
113
|
+
# Ensure that all elements within the blip are given a context.
|
114
|
+
def context=(value) # :nodoc:
|
115
|
+
super(value)
|
116
|
+
@elements.each_value { |e| e.context = value }
|
117
|
+
end
|
118
|
+
|
119
|
+
VALID_STATES = [:normal, :null, :deleted] # :nodoc: As passed to initializer in :state option.
|
120
|
+
|
121
|
+
#Options include:
|
122
|
+
# - :annotations
|
123
|
+
# - :child_blip_ids
|
124
|
+
# - :content
|
125
|
+
# - :contributors
|
126
|
+
# - :creator
|
127
|
+
# - :elements
|
128
|
+
# - :last_modified_time
|
129
|
+
# - :parent_blip_id
|
130
|
+
# - :version
|
131
|
+
# - :wave_id
|
132
|
+
# - :wavelet_id
|
133
|
+
# - :id
|
134
|
+
# - :context
|
135
|
+
# - :state
|
136
|
+
def initialize(options = {}) # :nodoc:
|
137
|
+
@annotations = options[:annotations] || []
|
138
|
+
@child_blip_ids = options[:child_blip_ids] || []
|
139
|
+
@content = options[:content] || ''
|
140
|
+
@contributor_ids = options[:contributors] || []
|
141
|
+
@creator = options[:creator] || User::NOBODY_ID
|
142
|
+
@elements = options[:elements] || {}
|
143
|
+
@last_modified_time = time_from_json(options[:last_modified_time]) || Time.now
|
144
|
+
@parent_blip_id = options[:parent_blip_id]
|
145
|
+
@version = options[:version] || -1
|
146
|
+
@wave_id = options[:wave_id]
|
147
|
+
@wavelet_id = options[:wavelet_id]
|
148
|
+
@state = options[:state] || :normal
|
149
|
+
|
150
|
+
unless VALID_STATES.include? @state
|
151
|
+
raise ArgumentError.new("Bad state #{options[:state]}. Should be one of #{VALID_STATES.join(', ')}")
|
152
|
+
end
|
153
|
+
|
154
|
+
# If the blip doesn't have a defined ID, since we just created it,
|
155
|
+
# assign a temporary, though unique, ID, based on the ID of the wavelet.
|
156
|
+
if options[:id].nil?
|
157
|
+
options[:id] = "#{GENERATED_PREFIX}_blip_#{unique_id}"
|
158
|
+
end
|
159
|
+
|
160
|
+
super(options)
|
161
|
+
end
|
162
|
+
|
163
|
+
#Returns true if an annotation with the given name exists in this blip
|
164
|
+
def has_annotation?(name)
|
165
|
+
@annotations.any? { |a| a.name == name }
|
166
|
+
end
|
167
|
+
|
168
|
+
# Adds an annotation to the Blip.
|
169
|
+
def add_annotation(annotation)
|
170
|
+
@annotations << annotation
|
171
|
+
self
|
172
|
+
end
|
173
|
+
|
174
|
+
#Creates a child blip under this blip
|
175
|
+
def create_child_blip
|
176
|
+
blip = Blip.new(:wave_id => @wave_id, :parent_blip_id => @id, :wavelet_id => @wavelet_id,
|
177
|
+
:context => @context, :contributors => [Robot.instance.id])
|
178
|
+
@context.add_operation(:type => Operation::BLIP_CREATE_CHILD, :blip_id => @id, :wave_id => @wave_id, :wavelet_id => @wavelet_id, :property => blip)
|
179
|
+
add_child_blip(blip)
|
180
|
+
blip
|
181
|
+
end
|
182
|
+
|
183
|
+
# Adds a created child blip to this blip.
|
184
|
+
def add_child_blip(blip) # :nodoc:
|
185
|
+
@child_blip_ids << blip.id
|
186
|
+
@context.add_blip(blip)
|
187
|
+
end
|
188
|
+
|
189
|
+
# INTERNAL
|
190
|
+
# Removed a child blip.
|
191
|
+
def remove_child_blip(blip) # :nodoc:
|
192
|
+
@child_blip_ids.delete(blip.id)
|
193
|
+
|
194
|
+
# Destroy oneself completely if you are no longer useful to structure.
|
195
|
+
destroy_me if deleted? and leaf? and not root?
|
196
|
+
end
|
197
|
+
|
198
|
+
# Delete this blip from its wavelet.
|
199
|
+
# Returns the blip id.
|
200
|
+
def delete
|
201
|
+
if deleted?
|
202
|
+
logger.warning("Attempt to delete blip that has already been deleted: #{id}")
|
203
|
+
elsif root?
|
204
|
+
logger.warning("Attempt to delete root blip: #{id}")
|
205
|
+
else
|
206
|
+
@context.add_operation(:type => Operation::BLIP_DELETE,
|
207
|
+
:blip_id => @id, :wave_id => @wave_id, :wavelet_id => @wavelet_id)
|
208
|
+
delete_me
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Convert to string.
|
213
|
+
def to_s
|
214
|
+
str = @content.gsub(/\n/, "\\n")
|
215
|
+
str = str.length > 24 ? "#{str[0..20]}..." : str
|
216
|
+
|
217
|
+
str = case @state
|
218
|
+
when :normal
|
219
|
+
"#{contributors.join(',')}:#{str}"
|
220
|
+
when :deleted
|
221
|
+
'<DELETED>'
|
222
|
+
when :null
|
223
|
+
'<NULL>'
|
224
|
+
end
|
225
|
+
|
226
|
+
"#{super}:#{str}"
|
227
|
+
end
|
228
|
+
|
229
|
+
# *INTERNAL*
|
230
|
+
# Write out a formatted block of text showing the blip and its descendants.
|
231
|
+
def print_structure(indent = 0) # :nodoc:
|
232
|
+
str = "#{' ' * indent}#{to_s}\n"
|
233
|
+
|
234
|
+
unless @child_blip_ids.empty?
|
235
|
+
# Move the first blip to the end, since it will be looked at last.
|
236
|
+
blip_ids = @child_blip_ids
|
237
|
+
blip_ids.push(blip_ids.shift)
|
238
|
+
|
239
|
+
# All children, except the first, should be indented.
|
240
|
+
blip_ids.each_with_index do |blip_id, index|
|
241
|
+
is_last_blip = (index == blip_ids.size - 1)
|
242
|
+
|
243
|
+
# All except the last one should be indented again.
|
244
|
+
ind = is_last_blip ? indent : indent + 1
|
245
|
+
blip = @context.blips[blip_id]
|
246
|
+
if blip
|
247
|
+
str << blip.print_structure(ind)
|
248
|
+
else
|
249
|
+
str << "#{' ' * ind}<undefined-blip>:#{blip_id}\n"
|
250
|
+
end
|
251
|
+
|
252
|
+
str << "\n" unless is_last_blip # Gap between reply chains.
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
str
|
257
|
+
end
|
258
|
+
|
259
|
+
# *INTERNAL*
|
260
|
+
# Convert to json for sending in an operation. We should never need to
|
261
|
+
# send more data than this, although blips we receive will have more data.
|
262
|
+
def to_json # :nodoc:
|
263
|
+
{
|
264
|
+
'blipId' => @id,
|
265
|
+
'javaClass' => JAVA_CLASS,
|
266
|
+
'waveId' => @wave_id,
|
267
|
+
'waveletId' => @wavelet_id
|
268
|
+
}.to_json
|
269
|
+
end
|
270
|
+
|
271
|
+
# *INTERNAL*
|
272
|
+
# Delete the blip or, if appropriate, destroy it instead.
|
273
|
+
def delete_me(allow_destroy = true) # :nodoc:
|
274
|
+
raise "Can't delete root blip" if root?
|
275
|
+
|
276
|
+
if leaf? and allow_destroy
|
277
|
+
destroy_me
|
278
|
+
else
|
279
|
+
# Blip is marked as deleted, but stays in place to maintain structure.
|
280
|
+
@state = :deleted
|
281
|
+
@content = ''
|
282
|
+
end
|
283
|
+
|
284
|
+
@id
|
285
|
+
end
|
286
|
+
|
287
|
+
protected
|
288
|
+
# *INTERNAL*
|
289
|
+
# Remove the blip entirely, leaving it null.
|
290
|
+
def destroy_me # :nodoc:
|
291
|
+
raise "Can't destroy root blip" if root?
|
292
|
+
raise "Can't destroy non-leaf blip" unless leaf?
|
293
|
+
|
294
|
+
# Remove the blip entirely to the realm of oblivion.
|
295
|
+
parent_blip.remove_child_blip(self)
|
296
|
+
@parent_blip_id = nil
|
297
|
+
@context.remove_blip(self)
|
298
|
+
@state = :null
|
299
|
+
@content = ''
|
300
|
+
|
301
|
+
@id
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Rave
|
2
|
+
module Models
|
3
|
+
# A wave or wave component.
|
4
|
+
# This is an abstract class.
|
5
|
+
class Component
|
6
|
+
include Rave::Mixins::Logger
|
7
|
+
|
8
|
+
GENERATED_PREFIX = 'TBD' # :nodoc: Prefixes blips and wavelets that are created by the robot.
|
9
|
+
GENERATED_PATTERN = /^#{GENERATED_PREFIX}/ # :nodoc:
|
10
|
+
|
11
|
+
@@last_id = 0 # For generated components, this is a unique ID number for them.
|
12
|
+
|
13
|
+
attr_writer :context # :nodoc: Allow context to set link to it.
|
14
|
+
|
15
|
+
# Has this component been generated by the robot [Boolean]
|
16
|
+
def generated? # :nodoc:
|
17
|
+
# This is true for all components except Users, who would override this.
|
18
|
+
not (@id =~ /^#{GENERATED_PREFIX}/).nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Generate a unique id number (from 1) [Integer]
|
22
|
+
def unique_id # :nodoc:
|
23
|
+
@@last_id += 1
|
24
|
+
end
|
25
|
+
|
26
|
+
# ID [String]
|
27
|
+
def id # :nodoc:
|
28
|
+
@id.dup
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(options = {}) # :nodoc:
|
32
|
+
@id = options[:id] or raise ArgumentError.new(":id option is required for #{self.class.name}")
|
33
|
+
@context = options[:context]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Convert to string.
|
37
|
+
def to_s
|
38
|
+
"#{self.class.name[/[^:]*$/]}:#{@id}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module Rave
|
2
|
+
module Models
|
3
|
+
# Contains server request information including current waves and operations.
|
4
|
+
class Context
|
5
|
+
|
6
|
+
attr_reader :primary_wavelet # :nodoc: API users should use Event#wavelet
|
7
|
+
attr_reader :robot # The robot managing this context.
|
8
|
+
|
9
|
+
# All waves by ID [Hash of String => Wave]
|
10
|
+
def waves # :nodoc:
|
11
|
+
@waves.dup
|
12
|
+
end
|
13
|
+
|
14
|
+
# All wavelets by ID [Hash of String => Wavelet]
|
15
|
+
def wavelets # :nodoc:
|
16
|
+
@wavelets.dup
|
17
|
+
end
|
18
|
+
|
19
|
+
# All wavelets by ID [Hash of String => Wavelet]
|
20
|
+
def blips # :nodoc:
|
21
|
+
@blips.dup
|
22
|
+
end
|
23
|
+
|
24
|
+
# All operations [Array of Operation]
|
25
|
+
def operations # :nodoc:
|
26
|
+
@operations.dup
|
27
|
+
end
|
28
|
+
|
29
|
+
# All users by ID [Hash of String => User]
|
30
|
+
def users # :nodoc:
|
31
|
+
@users.dup
|
32
|
+
end
|
33
|
+
|
34
|
+
JAVA_CLASS = 'com.google.wave.api.impl.OperationMessageBundle' # :nodoc:
|
35
|
+
|
36
|
+
#Options include:
|
37
|
+
# - :waves
|
38
|
+
# - :wavelets
|
39
|
+
# - :blips
|
40
|
+
# - :operations
|
41
|
+
# - :users
|
42
|
+
def initialize(options = {}) # :nodoc:
|
43
|
+
@waves = options[:waves] || {}
|
44
|
+
@waves.values.each { |wave| wave.context = self } #Set up self as this wave's context
|
45
|
+
|
46
|
+
@wavelets = options[:wavelets] || {}
|
47
|
+
@wavelets.values.each { |wavelet| wavelet.context = self } #Set up self as this wavelet's context
|
48
|
+
@primary_wavelet = @wavelets.values[0] # As opposed to any that are created later.
|
49
|
+
|
50
|
+
|
51
|
+
@blips = options[:blips] || {}
|
52
|
+
@blips.values.each { |blip| blip.context = self } #Set up self as this blip's context
|
53
|
+
|
54
|
+
@operations = options[:operations] || []
|
55
|
+
|
56
|
+
@users = options[:users] || {}
|
57
|
+
@users.values.each { |user| user.context = self } #Set up self as this user's context
|
58
|
+
|
59
|
+
resolve_user_references(options[:robot])
|
60
|
+
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
# Create users for every reference to one in the wave.
|
64
|
+
def resolve_user_references(robot) # :nodoc:
|
65
|
+
if robot
|
66
|
+
@users[robot.id] = robot
|
67
|
+
robot.context = self
|
68
|
+
@robot = robot
|
69
|
+
end
|
70
|
+
|
71
|
+
@wavelets.each_value do |wavelet|
|
72
|
+
wavelet.participant_ids.each do |id|
|
73
|
+
unless @users[id]
|
74
|
+
add_user(:id => id)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
unless @users[wavelet.creator_id]
|
79
|
+
add_user(:id => wavelet.creator_id)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
@blips.each_value do |blip|
|
84
|
+
blip.contributor_ids.each do |id|
|
85
|
+
unless @users[id]
|
86
|
+
add_user(:id => id)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
public
|
93
|
+
# Add a blip to blips (Use an Operation to actually add the blip to the Wave).
|
94
|
+
# Returns: The blip [Blip].
|
95
|
+
def add_blip(blip) # :nodoc:
|
96
|
+
@blips[blip.id] = blip
|
97
|
+
blip.context = self
|
98
|
+
blip
|
99
|
+
end
|
100
|
+
|
101
|
+
# Add an operation to the list to be executed.
|
102
|
+
# Returns: self [Context]
|
103
|
+
def add_operation(options) # :nodoc:
|
104
|
+
@operations << Operation.new(options)
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
# Add a wavelet to wavelets (Use an Operation to actually add the blip to the Wave).
|
109
|
+
# Returns: The wavelet [Wavelet].
|
110
|
+
def add_wavelet(wavelet)# :nodoc:
|
111
|
+
@wavelets[wavelet.id] = wavelet
|
112
|
+
wavelet.context = self
|
113
|
+
wavelet
|
114
|
+
end
|
115
|
+
|
116
|
+
# Add a wave to waves (Use an Operation to actually add the wave).
|
117
|
+
# Returns: The wave [Wave].
|
118
|
+
def add_wave(wave)# :nodoc:
|
119
|
+
@waves[wave.id] = wave
|
120
|
+
wave.context = self
|
121
|
+
wave
|
122
|
+
end
|
123
|
+
|
124
|
+
# +participants+:: Participants to exist in the new wavelet, as IDs or objects [Array of String/User]
|
125
|
+
# Returns: Newly created wave [Wave]
|
126
|
+
def create_wavelet(participants) # :nodoc:
|
127
|
+
# Map participants to strings, since they could be Users.
|
128
|
+
participant_ids = participants.map {|p| p.to_s.downcase }
|
129
|
+
participant_ids << @robot.id unless participant_ids.include? @robot.id
|
130
|
+
|
131
|
+
wavelet = Wavelet.new(:context => self, :participants => participant_ids)
|
132
|
+
add_wavelet(wavelet)
|
133
|
+
|
134
|
+
# TODO: Get wave id from sensible place?
|
135
|
+
add_operation(:type => Operation::WAVELET_CREATE, :wave_id => @waves.keys[0],
|
136
|
+
:property => wavelet)
|
137
|
+
|
138
|
+
wavelet
|
139
|
+
end
|
140
|
+
|
141
|
+
# Remove a blip.
|
142
|
+
def remove_blip(blip) # :nodoc:
|
143
|
+
@blips.delete(blip.id)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Add a user to users (Use an Operation to actually add the blip to the Wave).
|
147
|
+
def add_user(options) # :nodoc:
|
148
|
+
options[:id].downcase! if options[:id]
|
149
|
+
raise DuplicatedIDError.new("Can't add another User with id #{options[:id]}") if @users.has_key? options[:id].downcase
|
150
|
+
user = User.new(options)
|
151
|
+
@users[user.id] = user
|
152
|
+
user.context = self
|
153
|
+
user
|
154
|
+
end
|
155
|
+
|
156
|
+
#Serialize the context for use in the line protocol.
|
157
|
+
def to_json # :nodoc:
|
158
|
+
hash = {
|
159
|
+
'operations' => { 'javaClass' => 'java.util.ArrayList', 'list' => @operations },
|
160
|
+
'javaClass' => JAVA_CLASS
|
161
|
+
}
|
162
|
+
hash.to_json
|
163
|
+
end
|
164
|
+
|
165
|
+
def print_structure(indent = 0) # :nodoc:
|
166
|
+
str = ''
|
167
|
+
waves.each_value do |wave|
|
168
|
+
str << wave.print_structure(indent)
|
169
|
+
end
|
170
|
+
str
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|