javaclass 0.0.3 → 0.0.4

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.
Files changed (175) hide show
  1. data/Rakefile +67 -56
  2. data/Readme.txt +42 -39
  3. data/example_task.rb +172 -0
  4. data/examples/check_interface_names.rb +44 -0
  5. data/examples/corpus.rb +19 -0
  6. data/examples/count_classes_in_modules.rb +38 -0
  7. data/examples/cumulative_dependencies.rb +39 -0
  8. data/examples/find_all_imported_types.rb +44 -0
  9. data/examples/find_referenced_modules.rb +53 -0
  10. data/examples/find_unreferenced_classes.rb +65 -0
  11. data/examples/generate_class_lists.rb +67 -43
  12. data/examples/profiler_scratchpad.rb +33 -0
  13. data/examples/simple_usage.rb +42 -0
  14. data/history.txt +29 -7
  15. data/javaclass.gemspec +31 -0
  16. data/lib/javaclass/adder_tree.rb +92 -0
  17. data/lib/javaclass/analyse/dependencies.rb +52 -0
  18. data/lib/javaclass/{metric/metrics.txt → analyse/ideas.txt} +2 -2
  19. data/lib/javaclass/analyse/transitive_dependencies.rb +52 -0
  20. data/lib/javaclass/classfile/access_flag_constants.rb +24 -0
  21. data/lib/javaclass/classfile/access_flags.rb +49 -26
  22. data/lib/javaclass/classfile/class_format_error.rb +37 -0
  23. data/lib/javaclass/classfile/class_magic.rb +16 -8
  24. data/lib/javaclass/classfile/class_version.rb +19 -25
  25. data/lib/javaclass/classfile/constant_pool.rb +110 -45
  26. data/lib/javaclass/classfile/constants/base.rb +33 -12
  27. data/lib/javaclass/classfile/constants/double_reference.rb +55 -41
  28. data/lib/javaclass/classfile/constants/single_reference.rb +29 -21
  29. data/lib/javaclass/classfile/constants/value.rb +43 -33
  30. data/lib/javaclass/classfile/java_class_header.rb +72 -46
  31. data/lib/javaclass/classfile/java_class_header_as_java_name.rb +33 -0
  32. data/lib/javaclass/classfile/java_class_header_shortcuts.rb +19 -0
  33. data/lib/javaclass/classfile/references.rb +21 -19
  34. data/lib/javaclass/classlist/class_entry.rb +26 -27
  35. data/lib/javaclass/classlist/jar_searcher.rb +34 -25
  36. data/lib/javaclass/classlist/list.rb +31 -31
  37. data/lib/javaclass/classlist/package_entry.rb +25 -24
  38. data/lib/javaclass/classpath/any_classpath.rb +48 -0
  39. data/lib/javaclass/classpath/class_not_found_error.rb +20 -0
  40. data/lib/javaclass/classpath/classpaths.txt +2 -2
  41. data/lib/javaclass/classpath/composite_classpath.rb +56 -54
  42. data/lib/javaclass/classpath/convention_classpath.rb +38 -0
  43. data/lib/javaclass/classpath/eclipse_classpath.rb +74 -0
  44. data/lib/javaclass/classpath/factory.rb +65 -0
  45. data/lib/javaclass/classpath/file_classpath.rb +47 -0
  46. data/lib/javaclass/classpath/folder_classpath.rb +42 -44
  47. data/lib/javaclass/classpath/jar_classpath.rb +91 -52
  48. data/lib/javaclass/classpath/java_home_classpath.rb +24 -13
  49. data/lib/javaclass/classpath/maven_classpath.rb +44 -0
  50. data/lib/javaclass/classpath/temporary_unpacker.rb +111 -0
  51. data/lib/javaclass/classpath/tracking_classpath.rb +144 -0
  52. data/lib/javaclass/classscanner/ideas.txt +3 -0
  53. data/lib/javaclass/classscanner/imported_types.rb +29 -0
  54. data/lib/javaclass/classscanner/scanners.rb +29 -0
  55. data/lib/javaclass/delegate_directive.rb +15 -0
  56. data/lib/javaclass/dsl/caching_classpath.rb +38 -0
  57. data/lib/javaclass/dsl/classpath_analysers.rb +27 -0
  58. data/lib/javaclass/dsl/java_name_factory.rb +79 -0
  59. data/lib/javaclass/dsl/loader.rb +42 -0
  60. data/lib/javaclass/dsl/loading_classpath.rb +53 -0
  61. data/lib/javaclass/dsl/mixin.rb +54 -0
  62. data/lib/javaclass/gems/zip_file.rb +154 -0
  63. data/lib/javaclass/java_language.rb +50 -0
  64. data/lib/javaclass/java_name.rb +329 -55
  65. data/lib/javaclass/java_name_scanner.rb +95 -0
  66. data/lib/javaclass/resources/iso_3166_countries.txt +240 -0
  67. data/lib/javaclass/resources/jdk0_packages.txt +6 -0
  68. data/lib/javaclass/resources/jdk1_packages.txt +6 -0
  69. data/lib/javaclass/resources/jdk2_packages.txt +4 -0
  70. data/lib/javaclass/resources/jdk3_packages.txt +6 -0
  71. data/lib/javaclass/resources/jdk4_packages.txt +22 -0
  72. data/lib/javaclass/resources/jdk5_packages.txt +5 -0
  73. data/lib/javaclass/resources/jdk6_packages.txt +7 -0
  74. data/lib/javaclass/resources/jdk7_packages.txt +0 -0
  75. data/lib/javaclass/resources/jdk_packages.txt +53 -0
  76. data/lib/javaclass/resources/reserved_words.txt +50 -0
  77. data/lib/javaclass/string_hexdump.rb +76 -0
  78. data/lib/javaclass/string_ux.rb +21 -10
  79. data/lib/javaclass.rb +16 -41
  80. data/license.txt +28 -0
  81. data/planned.txt +13 -0
  82. data/test/data/Object_102.class +0 -0
  83. data/test/data/Runnable_102.class +0 -0
  84. data/test/data/access_flags/AccessFlagsTestAnnotation.class +0 -0
  85. data/test/data/access_flags/AccessFlagsTestAnnotation.java +3 -0
  86. data/test/data/access_flags/AccessFlagsTestEnum$1.class +0 -0
  87. data/test/data/access_flags/AccessFlagsTestEnum.class +0 -0
  88. data/test/data/access_flags/AccessFlagsTestEnum.java +6 -0
  89. data/test/data/access_flags/AccessFlagsTestInner$1.class +0 -0
  90. data/test/data/access_flags/AccessFlagsTestInner$2.class +0 -0
  91. data/test/data/access_flags/AccessFlagsTestInner.class +0 -0
  92. data/test/data/access_flags/AccessFlagsTestInner.java +13 -0
  93. data/test/data/access_flags/AccessFlagsTestPackage.class +0 -0
  94. data/test/data/access_flags/AccessFlagsTestPackage.java +1 -1
  95. data/test/data/api/packagename/AccessFlagsTestPublic.class +0 -0
  96. data/test/data/class_version/ClassVersionTest17.class +0 -0
  97. data/test/data/class_version/make.bat +6 -2
  98. data/test/data/eclipse_classpath/classes/ClassVersionTest12.class +0 -0
  99. data/test/data/eclipse_classpath/lib/JarClasspathTest.jar +0 -0
  100. data/test/data/eclipse_classpath/test-classes/ClassVersionTest13.class +0 -0
  101. data/test/data/folder_classpath/{JarClasspathTestFolder → classes}/ClassVersionTest10.class +0 -0
  102. data/test/data/folder_classpath/{JarClasspathTestFolder → classes}/package/ClassVersionTest11.class +0 -0
  103. data/test/data/jar_classpath/JarClasspathTest.jar +0 -0
  104. data/test/data/jar_classpath/JarClasspathTest.zip +0 -0
  105. data/test/data/jar_classpath/JarClasspathTestManifest.jar +0 -0
  106. data/test/data/jar_classpath/JarClasspathTestMultiManifest.jar +0 -0
  107. data/test/data/jar_classpath/make.bat +6 -2
  108. data/test/data/jar_searcher/BrokenRunnable_102.class +0 -0
  109. data/test/data/java_home_classpath/jdk118/lib/classes.zip +0 -0
  110. data/test/data/java_name_scanner/META-INF/MANIFEST.MF +12 -0
  111. data/test/data/java_name_scanner/plugin.xml +18 -0
  112. data/test/data/maven_classpath/module/pom.xml +8 -0
  113. data/test/data/maven_classpath/module/target/classes/ClassVersionTest12.class +0 -0
  114. data/test/data/maven_classpath/pom.xml +8 -0
  115. data/test/data/maven_classpath/target/classes/ClassVersionTest10.class +0 -0
  116. data/test/data/maven_classpath/target/test-classes/ClassVersionTest11.class +0 -0
  117. data/test/data/transitive_dependencies/A.class +0 -0
  118. data/test/data/transitive_dependencies/A.java +5 -0
  119. data/test/data/transitive_dependencies/B.class +0 -0
  120. data/test/data/transitive_dependencies/B.java +3 -0
  121. data/test/data/transitive_dependencies/C.class +0 -0
  122. data/test/data/transitive_dependencies/C.java +3 -0
  123. data/test/data/transitive_dependencies/Start.class +0 -0
  124. data/test/data/transitive_dependencies/Start.java +4 -0
  125. data/test/data/transitive_dependencies/make.bat +3 -0
  126. data/test/data/zip_file/commons-math-2.2-broken.zip +0 -0
  127. data/test/data/zip_file/regenerated-with-7zip.zip +0 -0
  128. data/test/data/zip_file/regenerated-with-jar.zip +0 -0
  129. data/test/dot_classpath.rb +33 -0
  130. data/test/logging_folder_classpath.rb +19 -0
  131. data/test/setup.rb +1 -1
  132. data/test/test_access_flags.rb +58 -32
  133. data/test/test_adder_tree.rb +78 -0
  134. data/test/test_any_classpath.rb +39 -0
  135. data/test/test_base.rb +9 -7
  136. data/test/test_caching_classpath.rb +41 -0
  137. data/test/test_class_entry.rb +60 -60
  138. data/test/test_class_magic.rb +31 -0
  139. data/test/test_class_version.rb +25 -25
  140. data/test/test_composite_classpath.rb +22 -23
  141. data/test/test_constant_pool.rb +37 -13
  142. data/test/test_convention_classpath.rb +39 -0
  143. data/test/test_eclipse_classpath.rb +73 -0
  144. data/test/test_factory.rb +61 -0
  145. data/test/test_folder_classpath.rb +26 -10
  146. data/test/test_imported_types.rb +34 -0
  147. data/test/test_jar_classpath.rb +29 -14
  148. data/test/test_jar_searcher.rb +27 -14
  149. data/test/test_java_class_header.rb +22 -10
  150. data/test/test_java_class_header_as_java_name.rb +41 -0
  151. data/test/test_java_home_classpath.rb +17 -11
  152. data/test/test_java_name.rb +204 -64
  153. data/test/test_java_name_factory.rb +52 -0
  154. data/test/test_java_name_scanner.rb +24 -0
  155. data/test/test_javaclass_api.rb +43 -0
  156. data/test/test_list.rb +58 -44
  157. data/test/test_load_directive.rb +34 -0
  158. data/test/test_maven_classpath.rb +46 -0
  159. data/test/test_package_entry.rb +27 -22
  160. data/test/test_references.rb +14 -14
  161. data/test/test_string_hexdump.rb +24 -0
  162. data/test/test_string_ux.rb +18 -106
  163. data/test/test_tracking_classpath.rb +112 -0
  164. data/test/test_transitive_dependencies.rb +31 -0
  165. data/test/test_unpacking_jar_classpath.rb +43 -0
  166. data/test/test_zip_file.rb +33 -0
  167. data/test/ts_all_tests.rb +80 -18
  168. data/thanks.txt +2 -0
  169. metadata +151 -22
  170. data/lib/javaclass/classpath/port_ClassPathEntry.java +0 -202
  171. data/lib/javaclass/classpath/port_ClassPathEntryFactory.java +0 -311
  172. data/lib/javaclass/classpath/port_DirectoryRepository.java +0 -24
  173. data/lib/javaclass/metric/ccd.rb +0 -68
  174. data/lib/javaclass/metric/class_usage.rb +0 -41
  175. data/test/test_javaclass.rb +0 -22
data/Rakefile CHANGED
@@ -1,63 +1,56 @@
1
- #require 'FileUtils' # already required
2
1
  require 'net/http'
3
2
  require 'rubygems'
4
3
  require 'rubygems/gem_runner' # install and uninstall
4
+ require 'rubygems/package_task'
5
5
  require 'rake'
6
6
  require 'rake/clean' # for clean/clobber
7
7
  require 'rake/testtask'
8
- require 'rake/gempackagetask'
9
8
  require 'rake/packagetask'
10
9
  require 'rake/rdoctask'
10
+ require 'example_task'
11
11
 
12
12
  # Test, package and publish functions.
13
- # Author:: Peter Kofler
14
- # See: http://rake.rubyforge.org/files/doc/rakefile_rdoc.html
15
- GEM_NAME = 'javaclass'
16
- GOOGLE_PROJECT = "#{GEM_NAME}-rb"
13
+ # Author:: Peter Kofler
14
+ # See:: http://rake.rubyforge.org/files/doc/rakefile_rdoc.html
15
+ # Acknowledgement:: Building this Rake file was supported as System One Research Day. Thank you System One for funding Open Source :-)
16
+
17
17
  RDOC_DIR = 'html'
18
18
  RDOC_REPO = 'api'
19
19
 
20
- gemspec = Gem::Specification.new do |s|
21
- s.version = '0.0.3'
22
- s.name = GEM_NAME
23
- s.rubyforge_project = 'javaclass' # old, just redirects
24
- s.summary = 'A parser and disassembler for Java class files'
25
- s.description = 'Provides access to the package, protected, and public fields and methods of the classes passed to it together with a list of all outgoing references.'
26
- s.homepage = "http://code.google.com/p/#{GOOGLE_PROJECT}/"
27
- s.author = 'Peter Kofler'
28
- s.email = 'peter dot kofler at code minus cop dot org'
29
-
30
- s.files = FileList['Readme.txt', '{lib,test,examples}/**/*.*', 'history.txt', 'Rakefile']
31
- s.test_files = FileList['test/**/test_*.rb']
32
- s.require_path = 'lib'
33
- s.add_dependency('rubyzip', '>= 0.9.1')
34
- s.required_ruby_version = '>= 1.8.6'
35
- s.platform = Gem::Platform::RUBY
36
- s.add_development_dependency('rake', '>= 0.8.4')
37
- s.add_development_dependency('ZenTest', '>= 4.4.0')
38
-
39
- s.has_rdoc = true
40
- s.extra_rdoc_files = ['Readme.txt', 'history.txt']
41
- s.rdoc_options << '--title' << "#{s.name}-#{s.version} Documentation" <<
42
- '--main' << 'Readme.txt'
43
- end
20
+ gemspec = eval(IO.readlines('javaclass.gemspec').join)
44
21
  full_gem_name = "#{gemspec.name}-#{gemspec.version}"
45
22
 
46
23
  desc 'Validates the gemspec'
47
- task :validate_gem do
24
+ task :validate_gem do
48
25
  gemspec.validate
49
26
  end
50
27
 
51
28
  desc 'Displays the current version'
52
- task :version do
29
+ task :version do
53
30
  puts gemspec.version
54
31
  end
55
32
 
56
33
  # :test
57
- Rake::TestTask.new do |t|
34
+ Rake::TestTask.new do |t|
35
+ t.test_files = gemspec.test_files
36
+ t.warning = true
37
+ # t.verbose = false is default
38
+ end
39
+
40
+ begin
41
+ require 'rcov/rcovtask'
42
+
43
+ # :rcov
44
+ Rcov::RcovTask.new do |t|
58
45
  t.test_files = gemspec.test_files
59
46
  t.warning = true
60
- #t.verbose = false is default
47
+ t.rcov_opts << "--sort=coverage"
48
+ t.rcov_opts << "--only-uncovered"
49
+ end
50
+
51
+ rescue LoadError
52
+ # skip if not installed
53
+ warn("rcov not installed. coverage not available. #{$!}")
61
54
  end
62
55
 
63
56
  desc 'Find missing test methods with ZenTest'
@@ -68,12 +61,12 @@ task :zentest do
68
61
  end
69
62
 
70
63
  # :gem
71
- Rake::GemPackageTask.new(gemspec) do |pkg|
64
+ Gem::PackageTask.new(gemspec) do |pkg|
72
65
  pkg.need_zip = true
73
66
  end
74
67
 
75
68
  # :package, :clobber_package, :repackage
76
- Rake::PackageTask.new(gemspec.name, gemspec.version) do |pkg|
69
+ Rake::PackageTask.new(gemspec.name, gemspec.version) do |pkg|
77
70
  #pkg.need_tar = true - no compress in tar on unxutils in Windows
78
71
  #pkg.need_tar_gz = true - no compress in tar on unxutils in Windows
79
72
  pkg.need_zip = true
@@ -99,7 +92,9 @@ end
99
92
  desc 'Tag current version in Hg'
100
93
  task :tag do
101
94
  hg ['tag', '-f', "-m \"Released gem version #{gemspec.version}\"", "#{full_gem_name}"]
95
+ # hg ['push']
102
96
  puts 'Tag created. Don\'t forget to push'
97
+ puts 'hg push'
103
98
  end
104
99
 
105
100
  # internal - desc 'Release the gem to Rubygems'
@@ -112,11 +107,11 @@ end
112
107
  # <code>HOME</code> environment must be set.
113
108
  def user_pass_from_hgrc(authname)
114
109
  lines = IO.readlines(File.expand_path('~/.hgrc'))
115
- user = lines.find{ |l| l =~ /#{authname}.username/ }[/[^\s=]+$/]
110
+ user = lines.find{ |l| l =~ /#{authname}.username/ }[/[^\s=]+$/]
116
111
  raise "could not find key #{authname}.username in ~/.hgrc" unless user
117
112
  pass = lines.find{ |l| l =~ /#{authname}.password/ }[/[^\s=]+$/]
118
113
  raise "could not find key #{authname}.password in ~/.hgrc" unless pass
119
- [user, pass]
114
+ [user, pass]
120
115
  end
121
116
 
122
117
  # Download the <code>googlecode_upload.py</code> from Google Code repository and save it as _name_ .
@@ -142,19 +137,34 @@ task :release_googlecode => :package do
142
137
  download_googlecode_upload_py 'googlecode_upload.py'
143
138
  ['gem', 'zip'].each do |extension|
144
139
  puts "uploading \"pkg/#{full_gem_name}.#{extension}\"..."
145
- python ['googlecode_upload.py', "-s \"JavaClass #{gemspec.version} #{extension.capitalize}\"", "-p #{GOOGLE_PROJECT}", "-u #{user}", "-w #{pass}", "pkg/#{full_gem_name}.#{extension}"]
140
+ python ['googlecode_upload.py', "-s \"JavaClass #{gemspec.version} #{extension.capitalize}\"",
141
+ "-p #{GOOGLE_PROJECT}", "-u #{user}", "-w #{pass}",
142
+ "pkg/#{full_gem_name}.#{extension}"]
146
143
  end
147
144
  end
148
145
 
149
146
  desc 'Package and upload gem to Rubygems and Google Code'
150
- task :publish_gem => [:clobber_package, :package, :release_rubygems, :release_googlecode]
147
+ task :publish_gem => [:clobber_package, :example, :package, :release_rubygems, :release_googlecode]
148
+
149
+ # :example, :clobber_example, :reexample
150
+ example_task_lib = Rake::ExampleTask.new do |example|
151
+ example.example_files.include 'examples/**/*.rb'
152
+ end
153
+ task :clobber_rdoc => [:clobber_example]
154
+ task :rdoc => [:example]
155
+ task :package => [:example]
151
156
 
152
157
  # :rdoc, :clobber_rdoc, :rerdoc
153
158
  Rake::RDocTask.new do |rdoc|
154
159
  rdoc.rdoc_dir = RDOC_DIR # 'html' is default anyway
155
160
  rdoc.title = "#{full_gem_name} Documentation"
156
161
  rdoc.main = 'Readme.txt'
157
- rdoc.rdoc_files.include 'Readme.txt', 'lib/**/*.rb', 'history.txt'
162
+
163
+ # examples are generated later and not necessarily available at definition time
164
+ examples = example_task_lib.conversion_pairs.map { |a| a[1] }
165
+
166
+ rdoc.rdoc_files.include *examples
167
+ rdoc.rdoc_files.include 'lib/**/*.rb', *gemspec.extra_rdoc_files
158
168
  end
159
169
 
160
170
  # Helper method to add target="_parent" to all external links in _file_ html.
@@ -162,7 +172,7 @@ def add_href_parent(file)
162
172
  lines = IO.readlines(file).collect do |line|
163
173
  if line =~ /(href=(?:'|")https?:\/\/)/
164
174
  "#{$`}target=\"_parent\" #{$1}#{$'}"
165
- else
175
+ else
166
176
  line
167
177
  end
168
178
  end
@@ -170,8 +180,8 @@ def add_href_parent(file)
170
180
  end
171
181
 
172
182
  desc 'Fix the RDoc hrefs in framesets'
173
- task :fix_rdoc => [:rdoc] do
174
- Dir["#{RDOC_DIR}/**/*.html"].each { |file| add_href_parent(file) }
183
+ task :fix_rdoc => [:rdoc] do
184
+ Dir["#{RDOC_DIR}/**/*.html"].each { |file| add_href_parent(file) }
175
185
  end
176
186
 
177
187
  # Helper method to add the gem version _dir_ into index _file_ to frameset links.
@@ -179,7 +189,7 @@ def add_frameset_version(file, dir)
179
189
  lines = IO.readlines(file).collect do |line|
180
190
  if line =~ /(frame src=")/
181
191
  "#{$`}#{$1}#{dir}/#{$'}"
182
- else
192
+ else
183
193
  line
184
194
  end
185
195
  end
@@ -187,35 +197,36 @@ def add_frameset_version(file, dir)
187
197
  end
188
198
 
189
199
  desc 'Publish the RDoc files to Google Code'
190
- task :publish_rdoc => [:clobber_rdoc, :rdoc, :fix_rdoc] do
200
+ task :publish_rdoc => [:clobber_rdoc, :fix_rdoc] do
191
201
  puts "Releasing #{full_gem_name} to API"
192
-
193
- remote_repo = "https://#{RDOC_REPO}.#{GOOGLE_PROJECT}.googlecode.com/hg/"
202
+ remote_repo = "https://code.google.com/p/#{GOOGLE_PROJECT}.#{RDOC_REPO}"
194
203
  remote_dir = "#{gemspec.version}"
195
-
204
+
196
205
  FileUtils.rm_r RDOC_REPO rescue nil
197
206
  hg ['clone', remote_repo, RDOC_REPO]
198
-
207
+
199
208
  FileUtils.rm_r "#{RDOC_REPO}/#{remote_dir}" rescue nil
200
209
  FileUtils.cp_r RDOC_DIR, "#{RDOC_REPO}/#{remote_dir}"
201
-
210
+
202
211
  # modify index, update redirect in frameset
203
212
  file = "#{RDOC_REPO}/index.html"
204
213
  FileUtils.cp "#{RDOC_REPO}/#{remote_dir}/index.html", file
205
214
  add_frameset_version(file, remote_dir)
206
-
215
+
207
216
  hg ['addremove', '-q', "-R #{RDOC_REPO}"]
208
217
  hg ['ci', "-m \"Update Rdoc for version #{gemspec.version}\"", "-R #{RDOC_REPO}"]
209
218
  hg ['tag', '-f', "-m \"Released gem version #{gemspec.version}\"", "-R #{RDOC_REPO}", "#{full_gem_name}"]
210
- hg ['push', "-R #{RDOC_REPO}"]
219
+ # hg ['push', "-R #{RDOC_REPO}"]
220
+ puts 'API site created. Don\'t forget to push'
221
+ puts "hg push -R #{RDOC_REPO}"
211
222
  end
212
223
 
213
- # :clean :clobber
214
- CLOBBER.include(RDOC_REPO, 'googlecode_upload.py')
224
+ # :clean :clobber
225
+ CLOBBER.include(RDOC_REPO, 'googlecode_upload.py', 'ClassLists', 'fullClassList*.txt')
215
226
 
216
227
  # Helper method to grep all the sources for some _pattern_ words.
217
228
  def egrep(pattern)
218
- Dir['**/*'].find_all { |fn| FileTest.file? fn }.each do |fn|
229
+ Dir['**/*'].find_all { |fn| FileTest.file?(fn) && File.basename(fn) != /^\./ }.each do |fn|
219
230
  line_count = 0
220
231
  open(fn) do |f|
221
232
  while line = f.gets
data/Readme.txt CHANGED
@@ -17,10 +17,10 @@ of the classes passed to it together with a list of all outgoing references.
17
17
  I am still doing Java most of the time. I used to be quite enthusiastic about
18
18
  it, but after 11 years I can see the advantages of being a polyglot. So I use
19
19
  Ruby for all kind of stuff, just for fun. When I needed some Java class
20
- analysis I wrote it with Ruby. As I am a puritan, I did not
20
+ analysis I wrote it in Ruby. As I am a puritan, I did not
21
21
  want to call javap from my script, so I started disassembling the class files,
22
22
  which might be the base for some serious static code analysis tools. (I
23
- started adding methods to that end...)
23
+ {started adding methods}[link:/files/history_txt.html] to that end.)
24
24
 
25
25
  == Install
26
26
 
@@ -29,56 +29,59 @@ started adding methods to that end...)
29
29
  * {Gem Hosting}[http://rubygems.org/gems/javaclass]
30
30
  * {Download of tarballs and gems}[http://code.google.com/p/javaclass-rb/downloads/list]
31
31
 
32
- == Usage
33
-
34
- require 'javaclass'
35
-
36
- # load the class directly from the file system
37
- clazz = JavaClass.load_fs('packagename/Public.class')
38
-
39
- # better lookup the class from some classpath
40
- classpath = JavaClass.classpath('some/path')
41
- clazz = JavaClass.load_cp('packagename.Public', classpath)
42
-
43
- clazz.version # => 50.0
44
- clazz.constant_pool.items[1] # => packagename/Public
45
- clazz.access_flags.public? # => true
46
- clazz.this_class # => packagename/Public
47
- clazz.this_class.to_java_file # => packagename/Public.java
48
- clazz.super_class # => java/lang/Object
49
- clazz.super_class.to_classname # => java.lang.Object
50
- clazz.references.referenced_methods[0] # => java/lang/Object.<init>:()V
51
-
52
32
  == Documentation
53
33
 
54
- Module +JavaClass+ is the entry point for most functions in the gem.
55
- The main class is JavaClass::ClassFile::JavaClassHeader which provides access to
56
- all information of a Java class file. There are also some examples in the examples
57
- folder of the gem.
34
+ Module JavaClass is the entry point for basic functions. All advanced functions are
35
+ available in Object through the JavaClass::Dsl::Mixin. The main class or the parser
36
+ is JavaClass::ClassFile::JavaClassHeader which provides access to all information
37
+ of a Java class file.
58
38
 
59
39
  * {API RDoc}[http://api.javaclass-rb.googlecode.com/hg/index.html]
60
40
 
41
+ I tried hard to rdoc all classes and public methods, so just {read it}[http://api.javaclass-rb.googlecode.com/hg/index.html].
42
+
43
+ == Usage
44
+
45
+ See the various examples in the examples folder of the gem.
46
+
47
+ * {Basic Usage}[link:/files/lib/generated/examples/simple_usage_txt.html]
48
+ * {Number of classes in modules/JARs}[link:/files/lib/generated/examples/count_classes_in_modules_txt.html]
49
+ * {Check names of all interfaces}[link:/files/lib/generated/examples/check_interface_names_txt.html]
50
+ * {All imported types}[link:/files/lib/generated/examples/find_all_imported_types_txt.html]
51
+ * {Cumulative dependencies of a class}[link:/files/lib/generated/examples/cumulative_dependencies_txt.html]
52
+ * {Find (un)referenced JARs}[link:/files/lib/generated/examples/find_referenced_modules_txt.html]
53
+ * {Find unused classes}[link:/files/lib/generated/examples/find_unreferenced_classes_txt.html]
54
+ * {Generate lists of JDK classes}[link:/files/lib/generated/examples/generate_class_lists_txt.html]
55
+
56
+ There is some experimental logic to recognize Java class name literals in Ruby
57
+ which are mapped to JavaClass::JavaQualifiedName. Packages have to be suffixed
58
+ with ".*" to be recognized. See JavaClass::Dsl::JavaNameFactory for its usage.
59
+
61
60
  == Support
62
61
 
63
- The bug tracker is available at http://code.google.com/p/javaclass-rb/issues/list or just drop me an email.
62
+ The bug tracker is available at {Google Code}[http://code.google.com/p/javaclass-rb/issues/list]
63
+ or just drop me an email.
64
+
65
+ == How to submit patches
66
+
67
+ Read the {8 steps for fixing other people's code}[http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/]
68
+ and for section 8, use the {Issue Tracker}[http://code.google.com/p/javaclass-rb/issues/list].
69
+
70
+ The trunk repository is available with
71
+
72
+ hg clone https://javaclass-rb.googlecode.com/hg/ javaclass-rb
64
73
 
65
74
  == Dependencies
66
75
 
67
- * Ruby 1.8.6
68
- * {rubyzip}[http://rubyzip.sourceforge.net/]
76
+ * Ruby 1.8.6 (runs with 1.8.7 and 1.9.1, too)
77
+ * {rubyzip}[http://rubyzip.sourceforge.net/] 0.9.1
69
78
 
70
79
  == References
71
80
 
72
- * {JavaWorld: The Java class file lifestyle}[http://www.javaworld.com/javaworld/jw-07-1996/jw-07-classfile.html]
73
- * {VM Spec: The class File Format}[http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html]
74
- * {Similar Project by unageanu}[http://github.com/unageanu/javaclass]
81
+ * {The Java class file lifestyle}[http://www.javaworld.com/javaworld/jw-07-1996/jw-07-classfile.html], JavaWorld 1996.
82
+ * {The class File Format}[http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html], The Java Virtual Machine Specification, Second Edition.
83
+ * {Similar Project by unageanu}[http://github.com/unageanu/javaclass], GitHub 2010.
75
84
 
76
85
  == License
77
86
 
78
- * {New BSD License}[http://www.opensource.org/licenses/bsd-license.php]
79
-
80
- == Disclaimer Note
81
-
82
- This software is provided "as is" and without any express or implied warranties,
83
- including, without limitation, the implied warranties of merchantability and
84
- fitness for a particular purpose.
87
+ * {BSD License}[http://www.opensource.org/licenses/bsd-license.php], it's enclosed in {license.txt}[link:/files/license_txt.html].
data/example_task.rb ADDED
@@ -0,0 +1,172 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+
4
+ module Rake
5
+
6
+ # Create a documentation task that will generate the example files for a project.
7
+ #
8
+ # The ExampleTask will create the following targets:
9
+ #
10
+ # [<b>:<em>example</em></b>]
11
+ # Main task for this example task.
12
+ #
13
+ # [<b>:clobber_<em>example</em></b>]
14
+ # Delete all the example files. This target is automatically added to the main clobber target.
15
+ #
16
+ # [<b>:re<em>example</em></b>]
17
+ # Rebuild the example files from scratch, even if they are not out of date.
18
+ #
19
+ # Simple example:
20
+ #
21
+ # Rake::ExampleTask.new do |rd|
22
+ # rd.target_dir = 'generated/examples'
23
+ # rd.example_files.include('examples/**/*.rb')
24
+ # end
25
+ #
26
+ # The +rd+ object passed to the block is an ExampleTask object. See the
27
+ # attributes list for the ExampleTask class for available customization options.
28
+ #
29
+ # == Specifying different task names
30
+ #
31
+ # You may wish to give the task a different name, such as if you are generating two
32
+ # sets of examples. For instance, if you want to have a development set of examples:
33
+ #
34
+ # Rake::ExampleTask.new(:example_dev) do |rd|
35
+ # rd.example_files.include('dev_examples/**/*.rb')
36
+ # end
37
+ #
38
+ # The tasks would then be named :<em>example_dev</em>, :clobber_<em>example_dev</em>, and :re<em>example_dev</em>.
39
+ #
40
+ class ExampleTask < TaskLib
41
+
42
+ # Name of the main, top level task. (default is :example)
43
+ attr_accessor :name
44
+
45
+ # Name of directory to receive the example output files. (default is 'lib/generated/examples')
46
+ attr_accessor :target_dir
47
+
48
+ # List of files to be included in the example generation. (default is [])
49
+ attr_accessor :example_files
50
+
51
+ # Create the Example tasks with the given base _name_ .
52
+ def initialize(name = :example) # :yield: self
53
+ @name = name
54
+ @example_files = Rake::FileList.new
55
+ @target_dir = 'lib/generated/examples'
56
+
57
+ yield self if block_given?
58
+
59
+ define_tasks
60
+ end
61
+
62
+ private
63
+
64
+ # Create the tasks defined by this task lib.
65
+ def define_tasks
66
+ define_repeat_task
67
+ define_clobber_task
68
+ define_build_task
69
+ end
70
+
71
+ def define_repeat_task
72
+ desc 'Force a rebuild of the example files'
73
+ task repeat_task_name => [clobber_task_name, build_task_name]
74
+ end
75
+
76
+ def define_clobber_task
77
+ desc 'Remove example products'
78
+ task clobber_task_name do
79
+ rm_r @target_dir rescue nil
80
+ end
81
+
82
+ task :clobber => [clobber_task_name]
83
+ end
84
+
85
+ def define_build_task
86
+ desc "Build the #{build_task_name} files"
87
+ task build_task_name
88
+
89
+ directory @target_dir
90
+ conversion_pairs.each { | a | define_transform(*a) }
91
+ end
92
+
93
+ def conversion_pairs
94
+ files_to_convert.map do |example_path|
95
+ [example_path, to_target_file(example_path)]
96
+ end
97
+ end
98
+ public :conversion_pairs
99
+
100
+ def files_to_convert
101
+ @example_files.find_all { |example_path| convert?(example_path) }
102
+ end
103
+
104
+ def define_transform(example_path, example_target)
105
+ task build_task_name => [example_target]
106
+ file example_target => [example_path, Rake.application.rakefile] do
107
+ print '.'
108
+ transform(example_path, example_target)
109
+ end
110
+ end
111
+
112
+ def build_task_name
113
+ name.to_s
114
+ end
115
+
116
+ def clobber_task_name
117
+ "clobber_#{name}"
118
+ end
119
+
120
+ def repeat_task_name
121
+ "re#{name}"
122
+ end
123
+
124
+ def convert?(text_file)
125
+ IO.readlines(text_file).find { |line| line =~ /# *:nodoc:/ } == nil
126
+ end
127
+
128
+ def to_target_file(file)
129
+ target_file = File.basename(file)
130
+ target_file[/\.rb$/] = '.txt'
131
+ File.join(@target_dir, target_file)
132
+ end
133
+
134
+ def transform(source, dest)
135
+ input = IO.readlines(source)
136
+ if source =~ /\.rb$/
137
+ lines = commentify(input)
138
+ else
139
+ lines = source
140
+ end
141
+ save(dest, lines)
142
+ end
143
+
144
+ def commentify(input)
145
+ lines = []
146
+ input.inject(true) do |add, line|
147
+ if line =~ /^#--/
148
+ false
149
+ elsif line =~ /^#\+\+/
150
+ true
151
+ elsif !add
152
+ false
153
+ elsif line =~ /^#/
154
+ lines << line
155
+ true
156
+ else
157
+ lines << "# #{line}"
158
+ true
159
+ end
160
+ end
161
+ lines
162
+ end
163
+
164
+ def save(name, lines)
165
+ folder = File.dirname(name)
166
+ mkdir_p folder unless File.exist?(folder)
167
+ File.delete name rescue nil
168
+ File.open(name, 'w') { |f| f.print lines.join }
169
+ end
170
+
171
+ end
172
+ end
@@ -0,0 +1,44 @@
1
+ # Example usage of classpath and class files: Scan all classes of an workspace.
2
+ # Find all interfaces, print their names and find all which are prefixed with 'I'.
3
+ # Author:: Peter Kofler
4
+ # Copyright:: Copyright (c) 2009, Peter Kofler.
5
+ # License:: {BSD License}[link:/files/license_txt.html]
6
+ #
7
+ # === Steps
8
+
9
+ #--
10
+ # add the lib of this gem to the load path
11
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
12
+ require File.join(File.dirname(__FILE__), 'corpus')
13
+
14
+ location = Corpus[:Base]
15
+ package = 'at.kugel'
16
+ #++
17
+ require 'javaclass/dsl/mixin'
18
+
19
+ # 1) define the location of the project and a package you are interrested
20
+ # location = 'C:\Eclipse\workspace'
21
+ # package = 'com.biz.app'
22
+
23
+ # e.g. add an Eclipse classpath variable to find external dependencies.
24
+ Eclipse.add_variable('KOR_HOME', location)
25
+
26
+ # 2) create the classpath of the given workspace
27
+ cp = workspace(location)
28
+ puts "#{cp.elements.size} classpaths found under the workspace #{location}:"
29
+ puts " #{cp.elements.join("\n ")}"
30
+ puts "#{cp.count} classes found on classpath"
31
+
32
+ # 3) filter the classes to analyse, using JavaClass::JavaQualifiedName methods
33
+ to_analyse = cp.names { |classname| classname.same_or_subpackage_of?(package) }
34
+ puts "#{to_analyse.size} classes matched #{package}"
35
+
36
+ # 4) load all selected classes, parse into JavaClass::ClassFile, find all interfaces and collect their qualified names
37
+ names = cp.values(to_analyse).
38
+ find_all { |clazz| clazz.interface? }.
39
+ collect { |clazz| clazz.to_classname }
40
+ puts "#{names.size} interfaces found:\n #{names.sort.join("\n ")}"
41
+
42
+ # 5) print all qualified names have a simple namee staring with an I
43
+ inames = names.find_all { |classname| classname.simple_name =~ /^I[A-Z][a-z]/ }
44
+ puts "#{inames.size} interfaces start with I:\n #{inames.join("\n ")}"
@@ -0,0 +1,19 @@
1
+ # :nodoc:
2
+ # Set location of the test data corpus.
3
+ corpus_root = 'E:\OfficeDateien\Corpus'
4
+ Corpus = Hash[
5
+ *[
6
+ %w[Sun10 Java1_JDK-1.0.2(Sun_official) ],
7
+ %w[WF Java2_Swing(WF_iMagine) ],
8
+ %w[S1 Java5_Batch(S1_Fabric) ],
9
+ %w[Harmony15 Java5_JDK-1.5M15-r991518(Apache_Harmony) ],
10
+ %w[Harmony16 Java5_JDK-1.6M3-r991881(Apache_Harmony) ],
11
+ %w[RCP Java5_RCP_2011(IBM_Costing) ],
12
+ %w[BIA Java6_Swing(BIA_Monarch) ],
13
+ %w[HBD Java6_Web(HBD_Online) ],
14
+ ].map { |pair|
15
+ [pair[0].to_sym, File.join(corpus_root, pair[1])]
16
+ }.flatten
17
+ ]
18
+ Corpus[:Base] = 'E:\Develop\Java'
19
+ Corpus[:Lib] = 'E:\Develop\Java\CodeLib'
@@ -0,0 +1,38 @@
1
+ # Example usage of classpath (JavaClass::Classpath): Scan all classpaths (e.g. modules)
2
+ # of an an Eclipse "workspace". A workspace is a folder containing several Eclipse
3
+ # projects, e.g. JavaClass::Classpath::EclipseClasspath. Report the number of found
4
+ # classes per module.
5
+ # Author:: Peter Kofler
6
+ # Copyright:: Copyright (c) 2009, Peter Kofler.
7
+ # License:: {BSD License}[link:/files/license_txt.html]
8
+ #
9
+ # === Steps
10
+
11
+ #--
12
+ # add the lib of this gem to the load path
13
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
14
+ require File.join(File.dirname(__FILE__), 'corpus')
15
+
16
+ location = Corpus[:HBD]
17
+ #++
18
+ require 'javaclass/classpath/factory'
19
+ include JavaClass::Classpath::Factory
20
+ # The require/include above just imports what is needed, but usually one would require the whole
21
+ # JavaClass::Dsl::Mixin for conveniance, e.g. require 'javaclass/dsl/mixin'.
22
+
23
+ # 1) define the location of the project
24
+ # location = 'C:\Eclipse\workspace'
25
+
26
+ # 2) create a JavaClass::Classpath::CompositeClasspath of the complete workspace, which will contain many classpath elements.
27
+ cp = workspace(location)
28
+ puts "#{cp.elements.size} classpaths found under the workspace #{location}"
29
+
30
+ # 3a) find all empty elements by querying the classpath elements
31
+ empty = cp.elements.find_all { |clp| clp.count == 0 }
32
+ puts "\n#{empty.size} empty modules found:\n #{empty.join("\n ")}"
33
+
34
+ # 3b) or print the list of each element with its class count
35
+ puts "library (module path): number of contained classes"
36
+ puts cp.elements.map { |clp| [clp.to_s, clp.count] }.
37
+ sort { |a,b| a[1] <=> b[1] }.
38
+ map { |e| " #{e[0]}: #{e[1]}" }
@@ -0,0 +1,39 @@
1
+ # Example usage of the featuress of JavaClass::Analyse::TransitiveDependencies
2
+ # to collect all transitive dependencies of a certain class or a whole package
3
+ # (Cumulative Component Dependencies).
4
+ # Author:: Peter Kofler
5
+ # Copyright:: Copyright (c) 2009, Peter Kofler.
6
+ # License:: {BSD License}[link:/files/license_txt.html]
7
+ # See:: Another example how to {list all imported types}[link:/files/lib/generated/examples/find_all_imported_types_txt.html]
8
+ #
9
+ # === Steps
10
+
11
+ #--
12
+ # add the lib of this gem to the load path
13
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
14
+ require File.join(File.dirname(__FILE__), 'corpus')
15
+
16
+ location = Corpus[:HBD]
17
+ package = 'at.herold'
18
+ start_class = 'at.herold.waf.hbd.servlet.HBDServlet'
19
+ # 'at/spardat/krimiaps/service/client/service/impl/ClientSmeSearchServiceImpl'
20
+ # 'at/spardat/krimiaps/service/client/service/impl/ClientPrivateSearchServiceImpl'
21
+ #++
22
+ require 'javaclass/dsl/mixin'
23
+
24
+ # 1) create the classpath of the given workspace
25
+ cp = workspace(location)
26
+ puts "#{cp.count} classes found on classpath"
27
+
28
+ # define a filter to limit all operations to the classes we are interested in
29
+ filter = Proc.new { |classname| classname.same_or_subpackage_of?(package) }
30
+
31
+ # 2a) collect all transitive dependencies of a single class into an AdderTree
32
+ dependencies = cp.transitive_dependency_tree(start_class.to_javaname, &filter)
33
+ puts "#{dependencies.size} classes in transitive dependency graph of class #{start_class}"
34
+ dependencies.debug_print
35
+
36
+ # 2b) or collect all transitive dependencies of a whole package
37
+ dependencies = cp.transitive_dependencies_package(start_class.to_javaname.package, &filter)
38
+ puts "#{dependencies.size} classes in transitive dependency graph of package"
39
+ # dependencies.debug_print