javaobjs 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+