javaobjs 0.3

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.
@@ -0,0 +1,42 @@
1
+ require 'rbconfig'
2
+ require 'find'
3
+ require 'ftools'
4
+
5
+ include Config
6
+
7
+ $ruby = CONFIG['ruby_install_name']
8
+
9
+ $sitedir = CONFIG["sitelibdir"]
10
+ unless $sitedir
11
+ version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
12
+ $libdir = File.join(CONFIG["libdir"], "ruby", version)
13
+ $sitedir = $:.find {|x| x =~ /site_ruby/}
14
+ if !$sitedir
15
+ $sitedir = File.join($libdir, "site_ruby")
16
+ elsif $sitedir !~ Regexp.quote(version)
17
+ $sitedir = File.join($sitedir, version)
18
+ end
19
+ end
20
+
21
+ if (destdir = ENV['DESTDIR'])
22
+ $sitedir = destdir + $sitedir
23
+ File::makedirs($sitedir)
24
+ end
25
+
26
+ rake_dest = File.join($sitedir, "rake")
27
+ File::makedirs(rake_dest, true)
28
+ File::chmod(0755, rake_dest)
29
+
30
+ # The library files
31
+
32
+ files = Dir.chdir('lib') { Dir['**/*.rb'] }
33
+
34
+ for fn in files
35
+ fn_dir = File.dirname(fn)
36
+ target_dir = File.join($sitedir, fn_dir)
37
+ if ! File.exist?(target_dir)
38
+ File.makedirs(target_dir)
39
+ end
40
+ File::install(File.join('lib', fn), File.join($sitedir, fn), 0644, true)
41
+ end
42
+
@@ -0,0 +1,2 @@
1
+ /javaobs.rb/1.2/Sun Apr 16 22:41:16 2006//
2
+ D
@@ -0,0 +1 @@
1
+ trunk/lib
@@ -0,0 +1 @@
1
+ :ext:wsobel@rubyforge.org:/var/cvs/javaobs
@@ -0,0 +1,686 @@
1
+
2
+ require 'delegate'
3
+
4
+ # Java Objects namespace to read and write Java serialized objects to streams.
5
+ # Any Java serialized object can be read from a stream. To write a Java object,
6
+ # the meta class must be primed with a sample input serialized object. The is
7
+ # required because Java uses a UUID to identify classes and it is generated using
8
+ # a complex hashing scheme of data and method signatures. Since this system does
9
+ # not have access to that information, it needs to get it from a serialized object.
10
+ #
11
+ # Objects that have custom serialization methods can be read and written by
12
+ # creating a class as we have for the Date class:
13
+ # module Java
14
+ # module Util
15
+ # class Date < SimpleDelegator
16
+ # extend JavaObject
17
+ #
18
+ # def initialize
19
+ # super(Time)
20
+ # end
21
+ #
22
+ # # Set the time with a Time object.
23
+ # def time=(time)
24
+ # __setobj__(time)
25
+ # end
26
+ #
27
+ # def _readJavaData(stream)
28
+ # data = stream.readBlockData
29
+ # t, = data.unpack("Q")
30
+ # __setobj__(Time.at(t / 1000, (t % 1000) * 1000))
31
+ # end
32
+ #
33
+ # # Get the data in the form needed for the Java date serialization.
34
+ # def _writeJavaData(stream)
35
+ # t = __getobj__.tv_sec * 1000 + __getobj__.tv_usec / 1000
36
+ # stream.writeBlockData([t].pack("Q"))
37
+ # end
38
+ # end
39
+ # end
40
+ # end
41
+ #
42
+ # The important methods are the data method that is used for writing the
43
+ # the object to a stream.
44
+ #
45
+ # All other classes will be auto-generated when the stream is read and persisted.
46
+ # A Java Meta Class is added to the Ruby Class that contains all the Java field
47
+ # information needed to serialize the objects.
48
+
49
+ module Java
50
+
51
+ # An error thrown when a serialization error occurs.
52
+ class SerializationError < RuntimeError
53
+ end
54
+
55
+ # An representation of a Java instance variable used to serialize
56
+ # data to and from a stream.
57
+ class JavaField
58
+ attr_reader :name, :type
59
+ attr_accessor :subtype
60
+
61
+ # Create a java instance variable with a name and data type.
62
+ def initialize(name, type)
63
+ @name = name
64
+ @type = type
65
+ @subtype = nil
66
+ end
67
+
68
+ def inspect
69
+ "<JavaField: #{@name}:#{@type.chr}:#{@subtype}>"
70
+ end
71
+ end
72
+
73
+ # The Java meta class with all the information needed for
74
+ # serialization of the Ruby class to the stream. This class
75
+ # is attached to the Ruby class.
76
+ class JavaClass
77
+ attr_accessor :superClass, :rubyClass
78
+ attr_reader :name, :uid, :fields, :javaName, :flags, :arrayType
79
+
80
+ def initialize(name, uid, flags)
81
+ @name = @javaName = name
82
+ ind = name.rindex('.')
83
+ @name = name.slice(ind + 1..name.length) if ind
84
+ @flags = flags
85
+ @uid = uid
86
+ @fields = []
87
+ @arrayType = name[1] if name[0] == ?[
88
+ end
89
+
90
+ # Add a field to the class.
91
+ def addField(field)
92
+ @fields << field
93
+ end
94
+
95
+ def to_s
96
+ @name
97
+ end
98
+ end
99
+
100
+ # A small mixin to extend a Ruby class with the associated
101
+ # JavaClass.
102
+ module JavaObject
103
+ def javaClass
104
+ @javaClass
105
+ end
106
+ end
107
+
108
+ # The custom serialization of the Java Date class
109
+ module Util
110
+ class Date < SimpleDelegator
111
+ extend JavaObject
112
+
113
+ def initialize
114
+ super(Time)
115
+ end
116
+
117
+ # Set the time with a Time object.
118
+ def time=(time)
119
+ __setobj__(time)
120
+ end
121
+
122
+ def _readJavaData(stream)
123
+ data = stream.readBlockData
124
+ t, = data.unpack("Q")
125
+ __setobj__(Time.at(t / 1000, (t % 1000) * 1000))
126
+ end
127
+
128
+ # Get the data in the form needed for the Java date serialization.
129
+ def _writeJavaData(stream)
130
+ t = __getobj__.tv_sec * 1000 + __getobj__.tv_usec / 1000
131
+ stream.writeBlockData([t].pack("Q"))
132
+ end
133
+ end
134
+
135
+ class HashMap < SimpleDelegator
136
+ extend JavaObject
137
+
138
+ def initialize
139
+ super(Hash)
140
+ @loadFactor = 0.75
141
+ @threshold = 12
142
+ end
143
+
144
+ def _readJavaData(stream)
145
+ # Read loadFactor and threshold.
146
+ stream.defaultReadObject(self)
147
+ stream.readBlockStart
148
+ len = stream.readInt
149
+ size = stream.readInt
150
+
151
+ h = Hash.new
152
+ size.times do
153
+ k = stream.readObject
154
+ v = stream.readObject
155
+ h[k] = v
156
+ end
157
+ stream.readBlockEnd
158
+ __setobj__(h)
159
+ end
160
+
161
+ def _writeJavaData(stream)
162
+ obj = __getobj__;
163
+ stream.defaultWriteObject(self)
164
+ stream.writeBlockStart(8)
165
+ l = 16
166
+ len = obj.length
167
+ while l < len
168
+ l << 1
169
+ end
170
+ stream.writeInt(l)
171
+ stream.writeInt(len)
172
+ obj.each do |k, v|
173
+ stream.writeObject(k)
174
+ stream.writeObject(v)
175
+ end
176
+ stream.writeBlockEnd
177
+ end
178
+ end
179
+ end
180
+
181
+ # The Java Array wrapper using an Ruby Array.
182
+ class JavaArray < Array
183
+ extend JavaObject
184
+ end
185
+
186
+ # Container for the Java serialization constants.
187
+ module ObjectStream
188
+ STREAM_MAGIC = 0xACED
189
+ STREAM_VERSION = 5
190
+
191
+ TC_NULL = 0x70
192
+ TC_REFERENCE = 0x71
193
+ TC_CLASSDESC = 0x72
194
+ TC_OBJECT = 0x73
195
+ TC_STRING = 0x74
196
+ TC_ARRAY = 0x75
197
+ TC_CLASS = 0x76
198
+ TC_BLOCKDATA = 0x77
199
+ TC_ENDBLOCKDATA = 0x78
200
+ TC_RESET = 0x79
201
+ TC_BLOCKDATALONG = 0x7A
202
+ TC_EXCEPTION = 0x7B
203
+ TC_LONGSTRING = 0x7C
204
+ TC_PROXYCLASSDESC = 0x7D
205
+
206
+ SC_WRITE_METHOD = 0x01
207
+ SC_SERIALIZABLE = 0x02
208
+ SC_EXTERNALIZABLE = 0x04
209
+ SC_BLOCKDATA = 0x08
210
+
211
+ PRIM_BYTE = 66 # 'B'
212
+ PRIM_CHAR = 67 # 'C'
213
+ PRIM_DOUBLE = 68 # 'D'
214
+ PRIM_FLOAT = 70 # 'F'
215
+ PRIM_INT = 73 # 'I'
216
+ PRIM_LONG = 74 # 'J'
217
+ PRIM_SHORT = 83 # 'S'
218
+ PRIM_BOOL = 90 # 'Z'
219
+
220
+ PRIM_ARRAY = 91 # '['
221
+ PRIM_OBJECT = 76 # 'L'
222
+ end
223
+
224
+ # The Ruby version of the Java ObjectInputStream. Creates a Ruby
225
+ # proxy class for each Java Class.
226
+ class ObjectInputStream
227
+ include ObjectStream
228
+
229
+ def readByte; @str.read(1)[0]; end
230
+ def readUShort; @str.read(2).unpack("n")[0]; end
231
+ def readShort; @str.read(2).unpack("s")[0]; end
232
+ def readInt; @str.read(4).unpack("i")[0]; end
233
+ def readDouble; @str.read(8).unpack("G")[0]; end
234
+ def readFloat; @str.read(4).unpack("g")[0]; end
235
+ def readString; @str.read(readShort); end
236
+ def readBool; @str.read(1)[0] != 0; end
237
+ def readUID; @str.read(8); end
238
+ def readLong; @str.read(8).unpack("Q").first; end
239
+
240
+ def readBlockStart
241
+ byte = readByte
242
+ size = nil
243
+ case byte
244
+ when TC_BLOCKDATA
245
+ size = readByte
246
+
247
+ when TC_BLOCKDATALONG
248
+ size = readInt
249
+
250
+ else
251
+ raise SerializationError, "Expecting TC_BLOCKDATA, got #{'0x%X' % byte}" unless byte == TC_BLOCKDATA
252
+ end
253
+ size
254
+ end
255
+
256
+ def readBlockEnd
257
+ byte = readByte
258
+ raise SerializationError, "Unexpected byte #{byte}" unless byte == TC_ENDBLOCKDATA
259
+ end
260
+
261
+ # Read a Java block of data with a size and then the following data.
262
+ def readBlockData
263
+ size = readBlockStart
264
+ data = @str.read(size)
265
+ readBlockEnd
266
+ data
267
+ end
268
+
269
+
270
+ # Read all the fields from the stream and add them to the class.
271
+ def readFields(klass)
272
+ fieldCount = readShort
273
+ 1.upto(fieldCount) do
274
+ type = readByte
275
+ name = readString
276
+ field = JavaField.new(name, type)
277
+
278
+ # Check for array and object types
279
+ if type == PRIM_OBJECT || type == PRIM_ARRAY
280
+ field.subtype = readObject
281
+ end
282
+ klass.addField(field)
283
+ end
284
+ end
285
+
286
+ # Read the class annotation. We do not currently handle annotations.
287
+ def readClassAnnotation
288
+ ebd = readByte
289
+ raise SerializationError, "We do not handle annotations!" unless ebd == TC_ENDBLOCKDATA
290
+ end
291
+
292
+ # Gets or creates a corresponding Ruby class for the Java class. This
293
+ # will drop leading com or java and transform the rest of the dotted
294
+ # names to modules.
295
+ def rubyClassFor(name, super_name)
296
+ context = name.split('.')
297
+ f, = context
298
+ context.shift if f == 'java' or f == 'com'
299
+ context.map! { |n| n.capitalize! if n !~ /^[A-Z]/o; n }
300
+ kname = context.pop
301
+
302
+ mod = Java
303
+ context.each do |m|
304
+ unless mod.constants.include?(m)
305
+ mod = mod.module_eval "#{m} = Module.new"
306
+ else
307
+ mod = mod.const_get(m)
308
+ end
309
+ end
310
+
311
+ unless mod.constants.include?(kname)
312
+ rclass = mod.module_eval "#{kname} = Class.new(#{super_name})"
313
+ else
314
+ rclass = mod.const_get(kname)
315
+ end
316
+ rclass
317
+ end
318
+
319
+ # Read the Java class description and create a Ruby class to proxy it
320
+ # in this name-space. Added special handling for the Date class.
321
+ def readClassDesc
322
+ name = readString
323
+ uid = readUID
324
+ flags = readByte
325
+ klass = JavaClass.new(name, uid, flags)
326
+
327
+ @objects << klass
328
+
329
+ readFields(klass)
330
+ readClassAnnotation
331
+
332
+ klass.superClass = readObject
333
+
334
+ # Create Ruby object representing class
335
+ if name =~ /^[A-Z.]+/i
336
+ # Create the class within the correct module.
337
+ rclass = rubyClassFor(name, klass.superClass.to_s)
338
+
339
+ unless rclass.methods.index('javaClass')
340
+ rclass.class_eval "extend JavaObject"
341
+ end
342
+
343
+ rclass.class_eval "@javaClass = klass"
344
+ vars = klass.fields.map do |f|
345
+ ':' + f.name
346
+ end
347
+ rclass.class_eval "attr_accessor #{vars.join(',')}"
348
+ klass.rubyClass = rclass
349
+ else
350
+ # Arrays
351
+ newName = 'JavaArray' + klass.name[1..klass.name.length]
352
+ unless Java.constants.index(newName)
353
+ rclass = Java.module_eval "#{newName} = Class.new(JavaArray)"
354
+ else
355
+ rclass = Java.const_get(newName)
356
+ end
357
+ rclass.class_eval "@javaClass = klass"
358
+ klass.rubyClass = rclass
359
+ end
360
+
361
+ klass
362
+ end
363
+
364
+ # Read an array of objects.
365
+ def readArray(klass)
366
+ size = readInt
367
+ a = klass.rubyClass.new
368
+ type = klass.arrayType
369
+ 1.upto(size) do
370
+ a << readType(type)
371
+ end
372
+ a
373
+ end
374
+
375
+ # Read a primitive data type.
376
+ def readType(type, arrayType = nil, field = nil)
377
+ case type
378
+ when PRIM_BYTE
379
+ readByte
380
+
381
+ when PRIM_CHAR
382
+ readByte
383
+
384
+ when PRIM_DOUBLE
385
+ readDouble
386
+
387
+ when PRIM_FLOAT
388
+ readFloat
389
+
390
+ when PRIM_INT
391
+ readInt
392
+
393
+ when PRIM_LONG
394
+ readLong
395
+
396
+ when PRIM_SHORT
397
+ readShort
398
+
399
+ when PRIM_BOOL
400
+ readBool
401
+
402
+ when PRIM_OBJECT, PRIM_ARRAY
403
+ readObject
404
+
405
+ else
406
+ raise SerializationError, "Unknown type #{type}"
407
+ end
408
+ end
409
+
410
+ # Cover method for java method.
411
+ def defaultReadObject(object)
412
+ readObjectFields(object.class.javaClass, object)
413
+ end
414
+
415
+ # Reads the object fields from the stream.
416
+ def readObjectFields(klass, object)
417
+ klass.fields.each do |f|
418
+ v = readType(f.type, f.subtype, f)
419
+ object.send((f.name + '=').intern, v)
420
+ end
421
+ end
422
+
423
+ # Read class data and recursively read parent classes.
424
+ def readClassData(klass, object = nil)
425
+ if object == nil
426
+ object = klass.rubyClass.new()
427
+ @objects << object
428
+ end
429
+
430
+ readClassData(klass.superClass, object) if (klass.superClass)
431
+
432
+ if klass.flags == SC_SERIALIZABLE
433
+ readObjectFields(klass, object)
434
+ else
435
+ object._readJavaData(self)
436
+ end
437
+
438
+ object
439
+ end
440
+
441
+ # Read an object from the stream.
442
+ def readObject
443
+ object = nil
444
+ byte = readByte
445
+ case byte
446
+ when TC_OBJECT
447
+ klass = readObject
448
+ object = readClassData(klass)
449
+
450
+ when TC_REFERENCE
451
+ readShort
452
+ object = @objects[readShort]
453
+
454
+ when TC_ARRAY
455
+ klass = readObject
456
+ object = readArray(klass)
457
+ @objects << object
458
+
459
+ when TC_STRING
460
+ object = readString
461
+ @objects << object
462
+
463
+ when TC_CLASSDESC
464
+ object = readClassDesc
465
+
466
+ when TC_NULL
467
+ object = nil
468
+
469
+ else
470
+ raise SerializationError, "Unexpected byte #{byte} at #{@str.pos}"
471
+ end
472
+
473
+ object
474
+ end
475
+
476
+ # Initialize from a stream.
477
+ def initialize(str)
478
+ @str = str
479
+ magic = readUShort
480
+ streamVersion = readShort
481
+ @objects = []
482
+
483
+ raise "Bad stream #{magic.to_s(16)}:#{streamVersion.to_s(16)}" if magic != STREAM_MAGIC ||
484
+ streamVersion != STREAM_VERSION
485
+
486
+ end
487
+
488
+ # Read all objects in the stream. Calls readObject until the stream
489
+ # eof is reached.
490
+ def readObjects
491
+ objs = []
492
+ until (@str.eof)
493
+ objs << readObject
494
+ end
495
+ objs
496
+ end
497
+ end
498
+
499
+ # A Ruby version of the Java ObjectOutputStream. The Ruby classes must
500
+ # have attached Java meta classes to attach UUID.
501
+ class ObjectOutputStream
502
+ include ObjectStream
503
+
504
+ def writeByte(b); @str.putc b; end
505
+ def writeUShort(s); @str.write [s].pack("n"); end
506
+ def writeShort(s); @str.write [s].pack("s"); end
507
+ def writeInt(i); @str.write [i].pack("i"); end
508
+ def writeDouble(d); @str.write [d].pack("G"); end
509
+ def writeFloat(f); @str.write [f].pack("g"); end
510
+ def writeString(s); writeShort(s.length); @str.write s; end
511
+ def writeBool(b); writeByte(b ? 1 : 0); end
512
+ def writeUID(u); @str.write u; end
513
+ def writeLong(l); @str.write [l].pack("Q"); end
514
+
515
+ # Creates object reference handles.
516
+ def nextHandle
517
+ h = @nextHandle
518
+ @nextHandle += 1
519
+ h
520
+ end
521
+
522
+ # Write an array of objects.
523
+ def writeArray(klass, v)
524
+ type = klass.arrayType
525
+ writeInt(v.length)
526
+ v.each do |e|
527
+ writeType(type, e)
528
+ end
529
+ end
530
+
531
+ def writeBlockStart(size)
532
+ if (size <= 255)
533
+ writeByte(TC_BLOCKDATA)
534
+ writeByte(size)
535
+ else
536
+ writeByte(TC_BLOCKDATALONG)
537
+ writeInt(size)
538
+ end
539
+ end
540
+
541
+ def writeBlockEnd
542
+ writeByte(TC_ENDBLOCKDATA)
543
+ end
544
+
545
+ # Writes a block of data to the stream.
546
+ def writeBlockData(data)
547
+ writeBlockStart(data.length)
548
+ @str.write data
549
+ writeBlockEnd
550
+ end
551
+
552
+ # Reads a Java primitive type.
553
+ def writeType(type, v)
554
+ case type
555
+ when PRIM_BYTE
556
+ writeByte(v)
557
+
558
+ when PRIM_CHAR
559
+ writeByte(v)
560
+
561
+ when PRIM_DOUBLE
562
+ writeDouble(v)
563
+
564
+ when PRIM_FLOAT
565
+ writeFloat(v)
566
+
567
+ when PRIM_INT
568
+ writeInt(v)
569
+
570
+ when PRIM_LONG
571
+ writeLong(v)
572
+
573
+ when PRIM_SHORT
574
+ writeShort(v)
575
+
576
+ when PRIM_BOOL
577
+ writeBool(v)
578
+
579
+ when PRIM_OBJECT, PRIM_ARRAY
580
+ writeObject(v)
581
+
582
+ else
583
+ raise SerializationError, "Unknown type #{type}"
584
+ end
585
+ end
586
+
587
+ # Writes the class description to the stream.
588
+ def writeClassDesc(klass)
589
+ @handles[klass] = nextHandle
590
+
591
+ writeString klass.javaName
592
+ writeUID klass.uid
593
+ writeByte klass.flags
594
+
595
+ writeShort(klass.fields.length)
596
+ klass.fields.each do |f|
597
+ writeByte(f.type)
598
+ writeString(f.name)
599
+ writeObject(f.subtype) if f.subtype
600
+ end
601
+
602
+ writeByte(TC_ENDBLOCKDATA) # Annotations
603
+ writeObject(klass.superClass)
604
+ end
605
+
606
+ def defaultWriteObject(object)
607
+ writeObjectFields(object.class.javaClass, object)
608
+ end
609
+
610
+ def writeObjectFields(klass, object)
611
+ klass.fields.each do |f|
612
+ v = object.send(f.name.intern)
613
+ writeType(f.type, v)
614
+ end
615
+ end
616
+
617
+ # Write the object and class to the stream.
618
+ def writeObjectData(klass, obj)
619
+ writeObjectData(klass.superClass, obj) if klass.superClass
620
+
621
+ if klass.flags == SC_SERIALIZABLE
622
+ writeObjectFields(klass, obj)
623
+ else
624
+ obj._writeJavaData(self)
625
+ end
626
+ end
627
+
628
+ # Writes the object and class data to the stream. Will
629
+ # write a reference if the object has already been written
630
+ # once.
631
+ def writeObject(obj)
632
+ unless obj
633
+ writeByte(TC_NULL)
634
+ else
635
+ handle = @handles[obj]
636
+ if (handle)
637
+ writeByte(TC_REFERENCE)
638
+ writeShort(0x007E)
639
+ writeShort(handle)
640
+ else
641
+ case obj
642
+ when JavaClass
643
+ writeByte(TC_CLASSDESC)
644
+ writeClassDesc(obj)
645
+
646
+ when JavaArray
647
+ writeByte(TC_ARRAY)
648
+ writeObject(obj.class.javaClass)
649
+ writeArray(obj.class.javaClass, obj)
650
+ @handles[obj] = nextHandle
651
+
652
+ when String
653
+ writeByte(TC_STRING)
654
+ writeString(obj)
655
+ @handles[obj] = nextHandle
656
+
657
+ else
658
+ writeByte(TC_OBJECT)
659
+ klass = obj.class.javaClass
660
+ writeObject(klass)
661
+ @handles[obj] = nextHandle
662
+ writeObjectData(klass, obj)
663
+ end
664
+ end
665
+ end
666
+ end
667
+
668
+ # Write an array of objects to the stream.
669
+ def writeObjects(objs)
670
+ objs.each do |o|
671
+ writeObject o
672
+ end
673
+ end
674
+
675
+ # Create an o writer on with a stream.
676
+ def initialize(str)
677
+ @str = str
678
+ @handles = {}
679
+ @nextHandle = 0
680
+
681
+ writeUShort(STREAM_MAGIC)
682
+ writeShort(STREAM_VERSION)
683
+ end
684
+ end
685
+ end
686
+
@@ -0,0 +1,176 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+
9
+ PKG_BUILD = '3'
10
+ PKG_NAME = 'javaobjs'
11
+ PKG_VERSION = '0.3'
12
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
13
+
14
+ RELEASE_NAME = "REL #{PKG_VERSION}"
15
+ RUBY_FORGE_PROJECT = "javaobs"
16
+ RUBY_FORGE_USER = "wsobel"
17
+
18
+ desc "Default Task"
19
+ task :default => [ :test ]
20
+
21
+ Rake::TestTask.new do |t|
22
+ t.libs << "test"
23
+ t.test_files = Dir.glob( "test/test.rb" )
24
+ t.verbose = true
25
+ end
26
+
27
+ Rake::RDocTask.new do |rdoc|
28
+ rdoc.rdoc_dir = 'doc'
29
+ rdoc.title = "Java Objects"
30
+ rdoc.main = 'README.rdoc'
31
+ rdoc.options << '--line-numbers' << '--inline-source'
32
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
33
+ rdoc.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
34
+ end
35
+
36
+ dist_dirs = [ "lib", "test", "examples" ]
37
+
38
+ spec = Gem::Specification.new do |s|
39
+ s.platform = Gem::Platform::RUBY
40
+ s.name = PKG_NAME
41
+ s.version = PKG_VERSION
42
+ s.summary = "Decode Java Serialized Objects to Ruby Objects."
43
+ s.description = %q{Takes Java serialized objects in a file or stream and creates Ruby wrapper objects and decodes. The package can also write Java objects once UUID is read from sample.}
44
+
45
+ s.author = "William Sobel"
46
+ s.email = "willsobel@mac.com"
47
+ s.rubyforge_project = "javaobj"
48
+ s.homepage = "http://www.rubyforge.org"
49
+
50
+ s.has_rdoc = true
51
+ s.requirements << 'none'
52
+
53
+ s.require_path = 'lib'
54
+
55
+ s.files = [ "rakefile", "install.rb" ]
56
+ dist_dirs.each do |dir|
57
+ s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
58
+ end
59
+ end
60
+
61
+ Rake::GemPackageTask.new(spec) do |p|
62
+ p.gem_spec = spec
63
+ p.need_tar = true
64
+ p.need_zip = true
65
+ end
66
+
67
+ task :release => [:repackage] do
68
+ files = ["gem", "zip", "tgz"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
69
+
70
+ if RUBY_FORGE_PROJECT then
71
+ require 'net/http'
72
+ require 'open-uri'
73
+
74
+ project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
75
+ project_data = open(project_uri) { |data| data.read }
76
+ puts project_data
77
+ group_id = project_data[/[?&]group_id=(\d+)/, 1]
78
+ raise "Couldn't get group id" unless group_id
79
+
80
+ # This echos password to shell which is a bit sucky
81
+ if ENV["RUBY_FORGE_PASSWORD"]
82
+ password = ENV["RUBY_FORGE_PASSWORD"]
83
+ else
84
+ print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
85
+ password = STDIN.gets.chomp
86
+ end
87
+
88
+ login_response = Net::HTTP.post_form(URI.parse('http://rubyforge.org/account/login.php'),
89
+ {'form_loginname'=> RUBY_FORGE_USER,
90
+ 'form_pw'=> password, 'login' => 1})
91
+
92
+ cookie = login_response["set-cookie"]
93
+ raise "Login failed" unless cookie
94
+ headers = { "Cookie" => cookie }
95
+
96
+ release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
97
+ release_data = open(release_uri, headers) { |data| data.read }
98
+ package_id = release_data[/[?&]package_id=(\d+)/, 1]
99
+ raise "Couldn't get package id" unless package_id
100
+
101
+ first_file = true
102
+ release_id = ""
103
+
104
+
105
+ files.each do |filename|
106
+ basename = File.basename(filename)
107
+ file_ext = File.extname(filename)
108
+ file_data = File.open(filename, "rb") { |file| file.read }
109
+
110
+ puts "Releasing #{basename}..."
111
+
112
+ release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
113
+ release_date = Time.now.strftime("%Y-%m-%d %H:%M")
114
+ type_map = {
115
+ ".zip" => "3000",
116
+ ".tgz" => "3110",
117
+ ".gz" => "3110",
118
+ ".gem" => "1400"
119
+ }; type_map.default = "9999"
120
+ type = type_map[file_ext]
121
+ boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
122
+
123
+ query_hash = if first_file then
124
+ {
125
+ "group_id" => group_id,
126
+ "package_id" => package_id,
127
+ "release_name" => RELEASE_NAME,
128
+ "release_date" => release_date,
129
+ "type_id" => type,
130
+ "processor_id" => "8000", # Any
131
+ "release_notes" => "",
132
+ "release_changes" => "",
133
+ "preformatted" => "1",
134
+ "submit" => "1"
135
+ }
136
+ else
137
+ {
138
+ "group_id" => group_id,
139
+ "release_id" => release_id,
140
+ "package_id" => package_id,
141
+ "step2" => "1",
142
+ "type_id" => type,
143
+ "processor_id" => "8000", # Any
144
+ "submit" => "Add This File"
145
+ }
146
+ end
147
+
148
+ query = "?" + query_hash.map do |(name, value)|
149
+ [name, URI.encode(value)].join("=")
150
+ end.join("&")
151
+
152
+ data = [
153
+ "--" + boundary,
154
+ "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
155
+ "Content-Type: application/octet-stream",
156
+ "Content-Transfer-Encoding: binary",
157
+ "", file_data, ""
158
+ ].join("\x0D\x0A")
159
+
160
+ release_headers = headers.merge(
161
+ "Content-Type" => "multipart/form-data; boundary=#{boundary}"
162
+ )
163
+
164
+ target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
165
+ http.post(target + query, data, release_headers)
166
+ end
167
+
168
+ if first_file then
169
+ release_id = release_response.body[/release_id=(\d+)/, 1]
170
+ raise("Couldn't get release id") unless release_id
171
+ end
172
+
173
+ first_file = false
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,4 @@
1
+ /Test.java/1.2/Sun Apr 16 22:42:34 2006//
2
+ /Test2.java/1.1/Sun Apr 16 22:48:25 2006//
3
+ /test.rb/1.2/Sun Apr 16 22:56:39 2006//
4
+ D
@@ -0,0 +1 @@
1
+ trunk/test
@@ -0,0 +1 @@
1
+ :ext:wsobel@rubyforge.org:/var/cvs/javaobs
@@ -0,0 +1,62 @@
1
+ import java.io.*;
2
+ import java.util.Date;
3
+ import java.util.Calendar;
4
+ import java.util.HashMap;
5
+ import java.util.Map;
6
+
7
+ public class Test implements Serializable
8
+ {
9
+ int a;
10
+ int b;
11
+ long c;
12
+ String d;
13
+ int e[];
14
+ Date date;
15
+ Map map;
16
+
17
+
18
+ public void setA(int x) { a = x; }
19
+ public void setB(int x) { b = x; }
20
+ public void setC(long l) { c = l; }
21
+ public void setD(String s) { d = s; }
22
+ public void setE(int x[]) { e = x; }
23
+ public void setDate(Date d) { date = d; }
24
+ public void setMap(Map m) { map = m; }
25
+
26
+ public static void main(String args[])
27
+ {
28
+ Test t = new Test();
29
+ t.setA(1);
30
+ t.setB(2);
31
+ t.setC(1000000000000000L);
32
+ t.setD("Hello");
33
+ int a[] = new int[20];
34
+ for (int i = 0; i < 20; i++)
35
+ {
36
+ a[i] = i;
37
+ }
38
+
39
+ t.setE(a);
40
+ Calendar cal = Calendar.getInstance();
41
+ cal.set(2006, 5, 5, 13, 20, 00);
42
+ cal.set(Calendar.MILLISECOND, 0);
43
+ t.setDate(cal.getTime());
44
+
45
+ try
46
+ {
47
+ FileOutputStream fos = new FileOutputStream("t.tmp");
48
+ ObjectOutputStream oos = new ObjectOutputStream(fos);
49
+
50
+ oos.writeObject(t);
51
+ oos.writeObject(new Date());
52
+ oos.close();
53
+ }
54
+
55
+ catch (Throwable x)
56
+ {
57
+ System.err.println(x);
58
+ }
59
+
60
+ System.exit(0);
61
+ }
62
+ }
@@ -0,0 +1,40 @@
1
+ import java.io.*;
2
+ import java.util.Date;
3
+ import java.util.Calendar;
4
+ import java.util.HashMap;
5
+ import java.util.Map;
6
+
7
+ public class Test2 implements Serializable
8
+ {
9
+ Map map;
10
+ public void setMap(Map m) { map = m; }
11
+
12
+ public static void main(String args[])
13
+ {
14
+ Test2 t = new Test2();
15
+ t.map = new HashMap();
16
+ t.map.put("One", new Integer(1));
17
+ t.map.put("Two", new Integer(2));
18
+ t.map.put("Three", new Integer(3));
19
+ t.map.put("Four", new Integer(4));
20
+ t.map.put("Five", new Integer(5));
21
+ t.map.put("Six", new Integer(6));
22
+ t.map.put("Seven", new Integer(7));
23
+
24
+ try
25
+ {
26
+ FileOutputStream fos = new FileOutputStream("t2.tmp");
27
+ ObjectOutputStream oos = new ObjectOutputStream(fos);
28
+
29
+ oos.writeObject(t);
30
+ oos.close();
31
+ }
32
+
33
+ catch (Throwable x)
34
+ {
35
+ System.err.println(x);
36
+ }
37
+
38
+ System.exit(0);
39
+ }
40
+ }
@@ -0,0 +1,111 @@
1
+
2
+ $testdir = File.dirname(__FILE__)
3
+ $: << "#{$testdir}/../lib"
4
+
5
+ require 'javaobs'
6
+ require 'test/unit'
7
+
8
+ class JavaTest < Test::Unit::TestCase
9
+
10
+ def setup
11
+ system("javac #{$testdir}/Test.java")
12
+ system("java -classpath #{$testdir} Test")
13
+ system("javac #{$testdir}/Test2.java")
14
+ system("java -classpath #{$testdir} Test2")
15
+ end
16
+
17
+ def teardown
18
+ File.unlink('t.tmp') rescue nil
19
+ File.unlink('t2.tmp') rescue nil
20
+ File.unlink('t.tmp.new') rescue nil
21
+ File.unlink("#{$testdir}/Test.class") rescue nil
22
+ File.unlink("#{$testdir}/Test2.class") rescue nil
23
+ end
24
+
25
+ def test_read
26
+ orig = ''
27
+ objs = nil
28
+ File.open("t.tmp") do |f|
29
+ f.binmode
30
+
31
+ orig = f.read
32
+ f.seek(0)
33
+
34
+ os = Java::ObjectInputStream.new(f)
35
+ assert os
36
+ objs = os.readObjects
37
+ assert objs
38
+ end
39
+
40
+ obj1, obj2 = objs
41
+ assert_equal obj1.a, 1
42
+ assert_equal obj1.b, 2
43
+ assert_equal obj1.c, 1000000000000000
44
+ assert_equal obj1.d, "Hello"
45
+ obj1.e.each_with_index { |v, i| assert_equal v, i }
46
+ assert_kind_of Java::Util::Date, obj1.date
47
+ assert_equal obj1.date, Time.local(2006, 06, 05, 13, 20, 0)
48
+
49
+ assert_equal obj2.class, Java::Util::Date
50
+ end
51
+
52
+ def test_read_map
53
+ orig = ''
54
+ objs = nil
55
+ File.open("t2.tmp") do |f|
56
+ f.binmode
57
+
58
+ orig = f.read
59
+ f.seek(0)
60
+
61
+ os = Java::ObjectInputStream.new(f)
62
+ assert os
63
+ objs = os.readObjects
64
+ assert objs
65
+ end
66
+
67
+ obj1, = objs
68
+ map = obj1.map
69
+ assert_equal ["Five", "Four", "One", "Seven", "Six", "Three", "Two"], map.keys.sort
70
+ {"One" => 1, "Two" => 2, "Three" => 3, "Four" => 4,
71
+ "Five" => 5, "Six" => 6, "Seven" => 7}.each do |k, v|
72
+ assert_equal v, map[k].value
73
+ end
74
+ end
75
+
76
+ def test_write
77
+ orig = ''
78
+ objs = nil
79
+ File.open("t.tmp") do |f|
80
+ f.binmode
81
+
82
+ orig = f.read
83
+ f.seek(0)
84
+
85
+ os = Java::ObjectInputStream.new(f)
86
+ assert os
87
+ objs = os.readObjects
88
+ assert objs
89
+ end
90
+
91
+ File.open('t.tmp.new', 'w') do |f|
92
+ f.binmode
93
+
94
+ os = Java::ObjectOutputStream.new(f)
95
+ os.writeObjects(objs)
96
+ end
97
+
98
+ mine = File.open('t.tmp.new').read
99
+ assert_equal mine, orig
100
+ end
101
+ end
102
+
103
+
104
+ if $0 == __FILE__
105
+ suite = Test::Unit::TestSuite.new('DataSource')
106
+ ObjectSpace.each_object(Class) do |klass|
107
+ suite << klass.suite if (Test::Unit::TestCase > klass)
108
+ end
109
+ require 'test/unit/ui/console/testrunner'
110
+ Test::Unit::UI::Console::TestRunner.run(suite).passed?
111
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: javaobjs
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.3"
7
+ date: 2006-04-16 00:00:00 -07:00
8
+ summary: Decode Java Serialized Objects to Ruby Objects.
9
+ require_paths:
10
+ - lib
11
+ email: willsobel@mac.com
12
+ homepage: http://www.rubyforge.org
13
+ rubyforge_project: javaobj
14
+ description: Takes Java serialized objects in a file or stream and creates Ruby wrapper objects and decodes. The package can also write Java objects once UUID is read from sample.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors:
29
+ - William Sobel
30
+ files:
31
+ - rakefile
32
+ - install.rb
33
+ - lib/CVS
34
+ - lib/javaobs.rb
35
+ - lib/CVS/Entries
36
+ - lib/CVS/Repository
37
+ - lib/CVS/Root
38
+ - test/CVS
39
+ - test/Test.java
40
+ - test/test.rb
41
+ - test/Test2.java
42
+ - test/CVS/Entries
43
+ - test/CVS/Repository
44
+ - test/CVS/Root
45
+ test_files: []
46
+
47
+ rdoc_options: []
48
+
49
+ extra_rdoc_files: []
50
+
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ requirements:
56
+ - none
57
+ dependencies: []
58
+