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.
- data/Rakefile +67 -56
- data/Readme.txt +42 -39
- data/example_task.rb +172 -0
- data/examples/check_interface_names.rb +44 -0
- data/examples/corpus.rb +19 -0
- data/examples/count_classes_in_modules.rb +38 -0
- data/examples/cumulative_dependencies.rb +39 -0
- data/examples/find_all_imported_types.rb +44 -0
- data/examples/find_referenced_modules.rb +53 -0
- data/examples/find_unreferenced_classes.rb +65 -0
- data/examples/generate_class_lists.rb +67 -43
- data/examples/profiler_scratchpad.rb +33 -0
- data/examples/simple_usage.rb +42 -0
- data/history.txt +29 -7
- data/javaclass.gemspec +31 -0
- data/lib/javaclass/adder_tree.rb +92 -0
- data/lib/javaclass/analyse/dependencies.rb +52 -0
- data/lib/javaclass/{metric/metrics.txt → analyse/ideas.txt} +2 -2
- data/lib/javaclass/analyse/transitive_dependencies.rb +52 -0
- data/lib/javaclass/classfile/access_flag_constants.rb +24 -0
- data/lib/javaclass/classfile/access_flags.rb +49 -26
- data/lib/javaclass/classfile/class_format_error.rb +37 -0
- data/lib/javaclass/classfile/class_magic.rb +16 -8
- data/lib/javaclass/classfile/class_version.rb +19 -25
- data/lib/javaclass/classfile/constant_pool.rb +110 -45
- data/lib/javaclass/classfile/constants/base.rb +33 -12
- data/lib/javaclass/classfile/constants/double_reference.rb +55 -41
- data/lib/javaclass/classfile/constants/single_reference.rb +29 -21
- data/lib/javaclass/classfile/constants/value.rb +43 -33
- data/lib/javaclass/classfile/java_class_header.rb +72 -46
- data/lib/javaclass/classfile/java_class_header_as_java_name.rb +33 -0
- data/lib/javaclass/classfile/java_class_header_shortcuts.rb +19 -0
- data/lib/javaclass/classfile/references.rb +21 -19
- data/lib/javaclass/classlist/class_entry.rb +26 -27
- data/lib/javaclass/classlist/jar_searcher.rb +34 -25
- data/lib/javaclass/classlist/list.rb +31 -31
- data/lib/javaclass/classlist/package_entry.rb +25 -24
- data/lib/javaclass/classpath/any_classpath.rb +48 -0
- data/lib/javaclass/classpath/class_not_found_error.rb +20 -0
- data/lib/javaclass/classpath/classpaths.txt +2 -2
- data/lib/javaclass/classpath/composite_classpath.rb +56 -54
- data/lib/javaclass/classpath/convention_classpath.rb +38 -0
- data/lib/javaclass/classpath/eclipse_classpath.rb +74 -0
- data/lib/javaclass/classpath/factory.rb +65 -0
- data/lib/javaclass/classpath/file_classpath.rb +47 -0
- data/lib/javaclass/classpath/folder_classpath.rb +42 -44
- data/lib/javaclass/classpath/jar_classpath.rb +91 -52
- data/lib/javaclass/classpath/java_home_classpath.rb +24 -13
- data/lib/javaclass/classpath/maven_classpath.rb +44 -0
- data/lib/javaclass/classpath/temporary_unpacker.rb +111 -0
- data/lib/javaclass/classpath/tracking_classpath.rb +144 -0
- data/lib/javaclass/classscanner/ideas.txt +3 -0
- data/lib/javaclass/classscanner/imported_types.rb +29 -0
- data/lib/javaclass/classscanner/scanners.rb +29 -0
- data/lib/javaclass/delegate_directive.rb +15 -0
- data/lib/javaclass/dsl/caching_classpath.rb +38 -0
- data/lib/javaclass/dsl/classpath_analysers.rb +27 -0
- data/lib/javaclass/dsl/java_name_factory.rb +79 -0
- data/lib/javaclass/dsl/loader.rb +42 -0
- data/lib/javaclass/dsl/loading_classpath.rb +53 -0
- data/lib/javaclass/dsl/mixin.rb +54 -0
- data/lib/javaclass/gems/zip_file.rb +154 -0
- data/lib/javaclass/java_language.rb +50 -0
- data/lib/javaclass/java_name.rb +329 -55
- data/lib/javaclass/java_name_scanner.rb +95 -0
- data/lib/javaclass/resources/iso_3166_countries.txt +240 -0
- data/lib/javaclass/resources/jdk0_packages.txt +6 -0
- data/lib/javaclass/resources/jdk1_packages.txt +6 -0
- data/lib/javaclass/resources/jdk2_packages.txt +4 -0
- data/lib/javaclass/resources/jdk3_packages.txt +6 -0
- data/lib/javaclass/resources/jdk4_packages.txt +22 -0
- data/lib/javaclass/resources/jdk5_packages.txt +5 -0
- data/lib/javaclass/resources/jdk6_packages.txt +7 -0
- data/lib/javaclass/resources/jdk7_packages.txt +0 -0
- data/lib/javaclass/resources/jdk_packages.txt +53 -0
- data/lib/javaclass/resources/reserved_words.txt +50 -0
- data/lib/javaclass/string_hexdump.rb +76 -0
- data/lib/javaclass/string_ux.rb +21 -10
- data/lib/javaclass.rb +16 -41
- data/license.txt +28 -0
- data/planned.txt +13 -0
- data/test/data/Object_102.class +0 -0
- data/test/data/Runnable_102.class +0 -0
- data/test/data/access_flags/AccessFlagsTestAnnotation.class +0 -0
- data/test/data/access_flags/AccessFlagsTestAnnotation.java +3 -0
- data/test/data/access_flags/AccessFlagsTestEnum$1.class +0 -0
- data/test/data/access_flags/AccessFlagsTestEnum.class +0 -0
- data/test/data/access_flags/AccessFlagsTestEnum.java +6 -0
- data/test/data/access_flags/AccessFlagsTestInner$1.class +0 -0
- data/test/data/access_flags/AccessFlagsTestInner$2.class +0 -0
- data/test/data/access_flags/AccessFlagsTestInner.class +0 -0
- data/test/data/access_flags/AccessFlagsTestInner.java +13 -0
- data/test/data/access_flags/AccessFlagsTestPackage.class +0 -0
- data/test/data/access_flags/AccessFlagsTestPackage.java +1 -1
- data/test/data/api/packagename/AccessFlagsTestPublic.class +0 -0
- data/test/data/class_version/ClassVersionTest17.class +0 -0
- data/test/data/class_version/make.bat +6 -2
- data/test/data/eclipse_classpath/classes/ClassVersionTest12.class +0 -0
- data/test/data/eclipse_classpath/lib/JarClasspathTest.jar +0 -0
- data/test/data/eclipse_classpath/test-classes/ClassVersionTest13.class +0 -0
- data/test/data/folder_classpath/{JarClasspathTestFolder → classes}/ClassVersionTest10.class +0 -0
- data/test/data/folder_classpath/{JarClasspathTestFolder → classes}/package/ClassVersionTest11.class +0 -0
- data/test/data/jar_classpath/JarClasspathTest.jar +0 -0
- data/test/data/jar_classpath/JarClasspathTest.zip +0 -0
- data/test/data/jar_classpath/JarClasspathTestManifest.jar +0 -0
- data/test/data/jar_classpath/JarClasspathTestMultiManifest.jar +0 -0
- data/test/data/jar_classpath/make.bat +6 -2
- data/test/data/jar_searcher/BrokenRunnable_102.class +0 -0
- data/test/data/java_home_classpath/jdk118/lib/classes.zip +0 -0
- data/test/data/java_name_scanner/META-INF/MANIFEST.MF +12 -0
- data/test/data/java_name_scanner/plugin.xml +18 -0
- data/test/data/maven_classpath/module/pom.xml +8 -0
- data/test/data/maven_classpath/module/target/classes/ClassVersionTest12.class +0 -0
- data/test/data/maven_classpath/pom.xml +8 -0
- data/test/data/maven_classpath/target/classes/ClassVersionTest10.class +0 -0
- data/test/data/maven_classpath/target/test-classes/ClassVersionTest11.class +0 -0
- data/test/data/transitive_dependencies/A.class +0 -0
- data/test/data/transitive_dependencies/A.java +5 -0
- data/test/data/transitive_dependencies/B.class +0 -0
- data/test/data/transitive_dependencies/B.java +3 -0
- data/test/data/transitive_dependencies/C.class +0 -0
- data/test/data/transitive_dependencies/C.java +3 -0
- data/test/data/transitive_dependencies/Start.class +0 -0
- data/test/data/transitive_dependencies/Start.java +4 -0
- data/test/data/transitive_dependencies/make.bat +3 -0
- data/test/data/zip_file/commons-math-2.2-broken.zip +0 -0
- data/test/data/zip_file/regenerated-with-7zip.zip +0 -0
- data/test/data/zip_file/regenerated-with-jar.zip +0 -0
- data/test/dot_classpath.rb +33 -0
- data/test/logging_folder_classpath.rb +19 -0
- data/test/setup.rb +1 -1
- data/test/test_access_flags.rb +58 -32
- data/test/test_adder_tree.rb +78 -0
- data/test/test_any_classpath.rb +39 -0
- data/test/test_base.rb +9 -7
- data/test/test_caching_classpath.rb +41 -0
- data/test/test_class_entry.rb +60 -60
- data/test/test_class_magic.rb +31 -0
- data/test/test_class_version.rb +25 -25
- data/test/test_composite_classpath.rb +22 -23
- data/test/test_constant_pool.rb +37 -13
- data/test/test_convention_classpath.rb +39 -0
- data/test/test_eclipse_classpath.rb +73 -0
- data/test/test_factory.rb +61 -0
- data/test/test_folder_classpath.rb +26 -10
- data/test/test_imported_types.rb +34 -0
- data/test/test_jar_classpath.rb +29 -14
- data/test/test_jar_searcher.rb +27 -14
- data/test/test_java_class_header.rb +22 -10
- data/test/test_java_class_header_as_java_name.rb +41 -0
- data/test/test_java_home_classpath.rb +17 -11
- data/test/test_java_name.rb +204 -64
- data/test/test_java_name_factory.rb +52 -0
- data/test/test_java_name_scanner.rb +24 -0
- data/test/test_javaclass_api.rb +43 -0
- data/test/test_list.rb +58 -44
- data/test/test_load_directive.rb +34 -0
- data/test/test_maven_classpath.rb +46 -0
- data/test/test_package_entry.rb +27 -22
- data/test/test_references.rb +14 -14
- data/test/test_string_hexdump.rb +24 -0
- data/test/test_string_ux.rb +18 -106
- data/test/test_tracking_classpath.rb +112 -0
- data/test/test_transitive_dependencies.rb +31 -0
- data/test/test_unpacking_jar_classpath.rb +43 -0
- data/test/test_zip_file.rb +33 -0
- data/test/ts_all_tests.rb +80 -18
- data/thanks.txt +2 -0
- metadata +151 -22
- data/lib/javaclass/classpath/port_ClassPathEntry.java +0 -202
- data/lib/javaclass/classpath/port_ClassPathEntryFactory.java +0 -311
- data/lib/javaclass/classpath/port_DirectoryRepository.java +0 -24
- data/lib/javaclass/metric/ccd.rb +0 -68
- data/lib/javaclass/metric/class_usage.rb +0 -41
- 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::
|
14
|
-
# See
|
15
|
-
|
16
|
-
|
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 =
|
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
|
-
|
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
|
-
|
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}\"",
|
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
|
-
|
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, :
|
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
|
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
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
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
|
-
* {
|
73
|
-
* {
|
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
|
-
* {
|
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 ")}"
|
data/examples/corpus.rb
ADDED
@@ -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
|