unageanu-javaclass 0.0.1 → 0.1.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/lib/javaclass.rb CHANGED
@@ -1,8 +1,8 @@
1
-
2
- require "javaclass/base"
3
- require "javaclass/accessflag"
4
- require "javaclass/attribute"
5
- require "javaclass/class"
6
- require "javaclass/constant"
7
- require "javaclass/member"
1
+
2
+ require "javaclass/base"
3
+ require "javaclass/accessflag"
4
+ require "javaclass/attribute"
5
+ require "javaclass/class"
6
+ require "javaclass/constant"
7
+ require "javaclass/member"
8
8
  require "javaclass/reader"
data/sample/class_list.rb CHANGED
@@ -3,7 +3,7 @@ require "rubygems"
3
3
  require "javaclass"
4
4
  require "zip/zip"
5
5
 
6
-
6
+ # ZipInputStreamにはgetcが実装されていないので、追加する。
7
7
  module Zip
8
8
  class ZipInputStream
9
9
  def getc
@@ -12,11 +12,41 @@ module Zip
12
12
  end
13
13
  end
14
14
 
15
- Zip::ZipFile.foreach(ARGV[0]) {|entry|
16
- next unless entry.file?
17
- next unless entry.name =~ /.*\.class$/
18
- entry.get_input_stream {|io|
19
- jc = JavaClass.from io
20
- puts jc.name
15
+ # Zipエントリ内のクラス一覧を列挙して解析する。
16
+ def each_class ( zip_file, &block )
17
+ Zip::ZipFile.foreach(ARGV[0]) {|entry|
18
+ next unless entry.file?
19
+ next unless entry.name =~ /.*\.class$/
20
+ entry.get_input_stream {|io|
21
+ jc = JavaClass.from io
22
+ block.call( jc ) if block_given?
23
+ }
21
24
  }
22
- }
25
+ end
26
+
27
+ class TypeHierarchy
28
+ def initialize
29
+ @classes = {}
30
+ end
31
+ def add( jc )
32
+ (jc.interfaces << jc.super_class).each {
33
+ if ( super_class != "java.lang.Object" )
34
+ @classes[super_class] = Type.new unless @classes.key? super_class
35
+
36
+ end
37
+ }
38
+
39
+ end
40
+ def to_s
41
+
42
+ end
43
+ end
44
+
45
+ class Type
46
+ def initialize( java_class=nil )
47
+ @implementors = []
48
+ @java_class = java_class
49
+ end
50
+ attr :java_class, true
51
+ attr :implementors, true
52
+ end
@@ -1,69 +1,69 @@
1
-
2
-
3
- $: << "../lib"
4
-
5
- require "javaclass"
6
- require "kconv"
7
- require "erb"
8
-
9
-
10
- PATH = 'aaa'
11
-
12
- def create( file )
13
- erb = ERB.new(IO.read("./assert.erb"), nil, "%" )
14
- open( PATH + "/" + file, "r+b" ) {|io|
15
- jc = JavaClass.from io
16
- puts erb.result(binding).tosjis
17
- }
18
- end
19
-
20
- Dir.foreach( PATH.gsub(/\\/, "/") ) {|f|
21
- create( f ) if f =~ /\.class$/ && !( f =~ /\$[0-9]+\.class$/ )
22
- }
23
-
24
- =begin
25
- % name = jc.this_class.name
26
- /**
27
- * {@link <%= name.gsub(/\$/, ".") %>} が同一であることを評価する。
28
- *
29
- * @param expected 期待値
30
- * @param actual 実際の値
31
- */
32
- public static final void assertEquals(
33
- <%= name.gsub(/\$/, ".") %> expected,
34
- <%= name.gsub(/\$/, ".") %> actual ) {
35
- % jc.methods.each { |m|
36
- % if m.name =~ /^get([A-Z][0-9a-zA-Z\_]+)/ || m.name =~ /^is([A-Z][0-9a-zA-Z\_])+/
37
- % sname = $1
38
- % prefix = m.attributes.key?('Deprecated') ? "//" : ""
39
- % d = m.convert_method_descriptor( m.descriptor )
40
- % next if d[:args].length > 0
41
- % if d[:return] =~ /List/
42
- <%= prefix %> <%= d[:return] %> actual<%= sname%> = actual.<%= m.name %>();
43
- <%= prefix %> <%= d[:return] %> expected<%= sname%> = expected.<%= m.name %>();
44
- <%= prefix %> if ( expected<%= sname%> != null ) {
45
- <%= prefix %> assertEquals( actual<%= sname%>.size(), expected<%= sname%>.size() );
46
- <%= prefix %> for ( int i = 0; i < expected<%= sname%>.size(); i++ ) {
47
- <%= prefix %> assertEquals( expected<%= sname%>.get(i), actual<%= sname%>.get(i) );
48
- <%= prefix %> }
49
- <%= prefix %> } else {
50
- <%= prefix %> assertEquals( actual<%= sname%>, expected<%= sname%> );
51
- <%= prefix %> }
52
- % elsif d[:return] =~ /.*\[\]/
53
- <%= prefix %> <%= d[:return] %> actual<%= sname%> = actual.<%= m.name %>();
54
- <%= prefix %> <%= d[:return] %> expected<%= sname%> = expected.<%= m.name %>();
55
- <%= prefix %> if ( expected<%= sname%> != null ) {
56
- <%= prefix %> assertEquals( actual<%= sname%>.length, expected<%= sname%>.length );
57
- <%= prefix %> for ( int i = 0; i < expected<%= sname%>.length; i++ ) {
58
- <%= prefix %> assertEquals( expected<%= sname%>[i], actual<%= sname%>[i] );
59
- <%= prefix %> }
60
- <%= prefix %> } else {
61
- <%= prefix %> assertEquals( actual<%= sname%>, expected<%= sname%> );
62
- <%= prefix %> }
63
- % else
64
- <%= prefix %> assertEquals( expected.<%= m.name %>(), actual.<%= m.name %>() );
65
- % end
66
- % end
67
- % }
68
- }
1
+
2
+
3
+ $: << "../lib"
4
+
5
+ require "javaclass"
6
+ require "kconv"
7
+ require "erb"
8
+
9
+
10
+ PATH = 'aaa'
11
+
12
+ def create( file )
13
+ erb = ERB.new(IO.read("./assert.erb"), nil, "%" )
14
+ open( PATH + "/" + file, "r+b" ) {|io|
15
+ jc = JavaClass.from io
16
+ puts erb.result(binding).tosjis
17
+ }
18
+ end
19
+
20
+ Dir.foreach( PATH.gsub(/\\/, "/") ) {|f|
21
+ create( f ) if f =~ /\.class$/ && !( f =~ /\$[0-9]+\.class$/ )
22
+ }
23
+
24
+ =begin
25
+ % name = jc.this_class.name
26
+ /**
27
+ * {@link <%= name.gsub(/\$/, ".") %>} が同一であることを評価する。
28
+ *
29
+ * @param expected 期待値
30
+ * @param actual 実際の値
31
+ */
32
+ public static final void assertEquals(
33
+ <%= name.gsub(/\$/, ".") %> expected,
34
+ <%= name.gsub(/\$/, ".") %> actual ) {
35
+ % jc.methods.each { |m|
36
+ % if m.name =~ /^get([A-Z][0-9a-zA-Z\_]+)/ || m.name =~ /^is([A-Z][0-9a-zA-Z\_])+/
37
+ % sname = $1
38
+ % prefix = m.attributes.key?('Deprecated') ? "//" : ""
39
+ % d = m.convert_method_descriptor( m.descriptor )
40
+ % next if d[:args].length > 0
41
+ % if d[:return] =~ /List/
42
+ <%= prefix %> <%= d[:return] %> actual<%= sname%> = actual.<%= m.name %>();
43
+ <%= prefix %> <%= d[:return] %> expected<%= sname%> = expected.<%= m.name %>();
44
+ <%= prefix %> if ( expected<%= sname%> != null ) {
45
+ <%= prefix %> assertEquals( actual<%= sname%>.size(), expected<%= sname%>.size() );
46
+ <%= prefix %> for ( int i = 0; i < expected<%= sname%>.size(); i++ ) {
47
+ <%= prefix %> assertEquals( expected<%= sname%>.get(i), actual<%= sname%>.get(i) );
48
+ <%= prefix %> }
49
+ <%= prefix %> } else {
50
+ <%= prefix %> assertEquals( actual<%= sname%>, expected<%= sname%> );
51
+ <%= prefix %> }
52
+ % elsif d[:return] =~ /.*\[\]/
53
+ <%= prefix %> <%= d[:return] %> actual<%= sname%> = actual.<%= m.name %>();
54
+ <%= prefix %> <%= d[:return] %> expected<%= sname%> = expected.<%= m.name %>();
55
+ <%= prefix %> if ( expected<%= sname%> != null ) {
56
+ <%= prefix %> assertEquals( actual<%= sname%>.length, expected<%= sname%>.length );
57
+ <%= prefix %> for ( int i = 0; i < expected<%= sname%>.length; i++ ) {
58
+ <%= prefix %> assertEquals( expected<%= sname%>[i], actual<%= sname%>[i] );
59
+ <%= prefix %> }
60
+ <%= prefix %> } else {
61
+ <%= prefix %> assertEquals( actual<%= sname%>, expected<%= sname%> );
62
+ <%= prefix %> }
63
+ % else
64
+ <%= prefix %> assertEquals( expected.<%= m.name %>(), actual.<%= m.name %>() );
65
+ % end
66
+ % end
67
+ % }
68
+ }
69
69
  =end
data/sample/sample.rb CHANGED
@@ -1,27 +1,27 @@
1
-
2
- require "rubygems"
3
- require "javaclass"
4
- require "kconv"
5
-
6
- [
7
- "./java_class/com/example/Kitten.class",
8
- "./java_class/HelloWorld.class",
9
- "./java_class/com/example/Constants.class",
10
- "./java_class/com/example/InnerClass.class",
11
- "./java_class/com/example/InnerClassImpl.class",
12
- "./java_class/com/example/InnerClass$StaticInnerClass.class",
13
- "./java_class/com/example/ThrowsException.class",
14
- "./java_class/com/example/InnerClassImpl$1MethodInnerClass.class",
15
- "./java_class/com/example/InnerClassImpl$2.class",
16
- "./java_class/com/example/types/TypeVariables.class",
17
- "./java_class/com/example/Deprecated.class",
18
- "./java_class/com/example/annotation/Annotated.class",
19
- "./java_class/com/example/annotation/HasDefaultValue.class",
20
- "./java_class/com/example/annotation/AnnotatedMethod.class"
21
- ].each { |c|
22
- open( c, "r+b" ) {|io|
23
- jc = JavaClass.from io
24
- puts jc.to_s.tosjis
25
- puts ""
26
- }
1
+
2
+ #require "rubygems"
3
+ require "javaclass"
4
+ require "kconv"
5
+
6
+ [
7
+ "./java_class/com/example/Kitten.class",
8
+ "./java_class/HelloWorld.class",
9
+ "./java_class/com/example/Constants.class",
10
+ "./java_class/com/example/InnerClass.class",
11
+ "./java_class/com/example/InnerClassImpl.class",
12
+ "./java_class/com/example/InnerClass$StaticInnerClass.class",
13
+ "./java_class/com/example/ThrowsException.class",
14
+ "./java_class/com/example/InnerClassImpl$1MethodInnerClass.class",
15
+ "./java_class/com/example/InnerClassImpl$2.class",
16
+ "./java_class/com/example/types/TypeVariables.class",
17
+ "./java_class/com/example/Deprecated.class",
18
+ "./java_class/com/example/annotation/Annotated.class",
19
+ "./java_class/com/example/annotation/HasDefaultValue.class",
20
+ "./java_class/com/example/annotation/AnnotatedMethod.class"
21
+ ].each { |c|
22
+ open( c, "r+b" ) {|io|
23
+ jc = JavaClass.from io
24
+ puts jc.to_s.tosjis
25
+ puts ""
26
+ }
27
27
  }
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # jar内のクラスファイルの型階層を表示する。
4
+ #
5
+ # ./type_hierarchy.rb <jarファイル>
6
+ #
7
+
8
+ require "rubygems"
9
+ require "javaclass"
10
+ require "zip/zip"
11
+ require "kconv"
12
+
13
+ # ZipInputStreamにはgetcが実装されていないので、追加する。
14
+ module Zip
15
+ class ZipInputStream
16
+ def getc
17
+ read(1)[0]
18
+ end
19
+ end
20
+ end
21
+
22
+ # Zipエントリ内のクラス一覧を列挙して解析する。
23
+ def each_class ( zip_file, &block )
24
+ Zip::ZipFile.foreach(ARGV[0]) {|entry|
25
+ next unless entry.file?
26
+ next unless entry.name =~ /.*\.class$/
27
+ entry.get_input_stream {|io|
28
+ jc = JavaClass.from io
29
+ block.call( jc ) if block_given?
30
+ }
31
+ }
32
+ end
33
+
34
+ # 型階層
35
+ class TypeHierarchy
36
+ def initialize
37
+ @classes = {}
38
+ end
39
+ def <<( jc )
40
+ (jc.interfaces << jc.super_class).each {|parent|
41
+ next if parent == nil || parent == "java.lang.Object"
42
+ @classes[parent] = Type.new(parent) unless @classes.key? parent
43
+ @classes[parent] << jc.name
44
+ }
45
+ name = jc.name
46
+ @classes[name] = Type.new(name) unless @classes.key? name
47
+ @classes[name].java_class = jc
48
+ end
49
+ def to_s
50
+ strs = ""
51
+ @classes.each{|k,v|
52
+ jc = v.java_class
53
+ next if jc != nil && jc.super_class != nil && jc.super_class != "java.lang.Object"
54
+ next if jc != nil && jc.interfaces.length > 0
55
+ strs << "---\n" << v.node_to_string( "", @classes ) << "\n"
56
+ }
57
+ return strs
58
+ end
59
+ end
60
+
61
+ # 型
62
+ class Type
63
+ def initialize( name, java_class=nil )
64
+ @name = name
65
+ @implementors = []
66
+ @java_class = java_class
67
+ end
68
+ def <<(implementor)
69
+ @implementors << implementor
70
+ end
71
+ def node_to_string( indent, pool )
72
+ str = indent.dup
73
+ str << ( java_class == nil ? "(unknown) " : java_class.access_flag.type + " " )
74
+ str << name
75
+ str << "\n"
76
+ child_indent = indent.gsub(/├/, "│").gsub(/└/, " ")
77
+ @implementors.each_index {|i|
78
+ next if implementors[i] == nil
79
+ tmp = child_indent + ( i >= implementors.length-1 ? "└" : "├" )
80
+ str << pool[implementors[i]].node_to_string( tmp, pool )
81
+ }
82
+ return str
83
+ end
84
+ attr :name, true
85
+ attr :java_class, true
86
+ attr :implementors, true
87
+ end
88
+
89
+ th = TypeHierarchy.new
90
+ each_class( ARGV[0] ){|jc|
91
+ th << jc
92
+ }
93
+ puts th.to_s.tosjis