jaxrsdoc 0.0.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/bin/jaxrsdoc ADDED
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path("../../lib/parse.rb", __FILE__)
3
+ require File.expand_path("../../lib/site.rb", __FILE__)
4
+ require 'optparse'
5
+ require "rexml/document"
6
+
7
+ options = {}
8
+ optparse = OptionParser.new do |opts|
9
+ opts.banner = "USAGE\n jaxrsdoc [options] source_location"
10
+ opts.separator "\nOPTIONS\n"
11
+
12
+ options[:pattern] = "*Resource.java"
13
+ opts.on( '-p', '--pattern PATTERN', 'Naming pattern of your Jaxrs annotated files java resources. Default is: "*Resource.java".' ) do |pattern|
14
+ options[:pattern] = pattern
15
+ end
16
+
17
+ opts.on( '-m', '--maven', 'Indicates a maven project. Project name & version will be derived the pom.xml at the directory level' ) do |maven|
18
+ options[:maven] = true
19
+ end
20
+
21
+ opts.on( '-a', '--artifact ARTIFACT', 'Name of the artifact/project/module to be included on the website banner.' ) do |artifact_name|
22
+ options[:artifact_name] = artifact_name
23
+ end
24
+
25
+ opts.on( '-v', '--version VERSION', 'Version of your artifact/project/module to be included on the website banner.' ) do |artifact_version|
26
+ options[:artifact_version] = artifact_version
27
+ end
28
+
29
+ opts.on( '-h', '--help', 'Display this screen' ) do
30
+ puts opts
31
+ exit
32
+ end
33
+ end
34
+
35
+ begin
36
+ optparse.parse!
37
+ rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument
38
+ puts "#{$!.message}"
39
+ puts "try 'jaxrsdoc -h' for more information"
40
+ exit
41
+ end
42
+
43
+ resources_location = ARGV.first
44
+
45
+ puts "Looking files recursively at #{resources_location}"
46
+ matched_files = Dir.glob("#{resources_location}/**/#{options[:pattern]}").select{ |entry| File.file?(entry) }
47
+ puts "Found #{matched_files.size} files matching '#{options[:pattern]}'"
48
+
49
+ processed_resources = matched_files.map {|file|
50
+ JaxrsDoc::ResourceParser.parse(File.new(file))
51
+ }.select {|resource| resource.valid? and not resource.nil? }
52
+ puts "Processed #{processed_resources.size} files with a @Path type annotation"
53
+
54
+ project_version = options[:artifact_version]
55
+ project_name = options[:artifact_name]
56
+
57
+ if(options[:maven]) then
58
+ puts "Looking for a pom.xml file at #{resources_location}"
59
+ pom_xml = Dir.glob("#{resources_location}/pom.xml").first
60
+ pom = REXML::Document.new File.new(pom_xml)
61
+ project_name = pom.elements["//artifactId"].first
62
+ project_version = pom.elements["//version"].first
63
+ puts "Found maven project with name: #{project_name}, version: #{project_version}"
64
+ end
65
+
66
+ output_dir = JaxrsDoc::Site.new(processed_resources, Dir.pwd, {:project_version => project_version, :project_name => project_name}).generate
67
+
68
+ puts "Site generated. Open #{output_dir.path}/index.html"
69
+
70
+
@@ -0,0 +1,104 @@
1
+ module JaxrsDoc
2
+
3
+ class Resource
4
+ include Comparable
5
+
6
+ attr_reader :name, :description, :params_descriptions, :path, :verbs, :gets, :posts, :puts, :deletes, :consumes
7
+
8
+ def initialize(file_name, type_annotations, verbs_annotations = {}, type_description = nil, params_descriptions = {})
9
+ @name = file_name
10
+ @description = type_description
11
+ @params_descriptions = params_descriptions
12
+ @path = type_annotations.annotations.find {|a| a.name.eql?"Path"}
13
+ @consumes = type_annotations.annotations.find {|a| a.name.eql?"Consumes"}
14
+ @gets = verbs_annotations[:gets]
15
+ @posts = verbs_annotations[:posts]
16
+ @puts = verbs_annotations[:puts]
17
+ @deletes = verbs_annotations[:deletes]
18
+ @verbs = verbs_annotations
19
+ end
20
+
21
+ def valid?
22
+ not @path.nil?
23
+ end
24
+
25
+ def add_param_description(param_description)
26
+ @params_descriptions.update(param_description)
27
+ end
28
+
29
+ def <=>(another)
30
+ path.value <=> another.path.value
31
+ end
32
+
33
+ def to_s
34
+ "#{@name} [#{@path.value}]"
35
+ end
36
+
37
+ # Support ERB templating of member data.
38
+ def get_binding
39
+ binding
40
+ end
41
+
42
+ end
43
+
44
+ class AnnotationsGroup
45
+
46
+ attr_reader :annotations
47
+
48
+ def initialize(annotations = [])
49
+ @annotations = Array.new(annotations)
50
+ end
51
+
52
+ def method_missing(method_name, *args)
53
+ if(method_name.to_s.include?"params")
54
+ @annotations.select{|a| /\b(Form|FormData|Query)Param\b/ =~ a.name }
55
+ else
56
+ @annotations.find {|a| method_name.to_s.eql?(a.name.downcase) }
57
+ end
58
+ end
59
+
60
+ def empty?
61
+ @annotations.empty?
62
+ end
63
+
64
+ def size
65
+ @annotations.size
66
+ end
67
+
68
+ def to_s
69
+ @annotations.to_s
70
+ end
71
+
72
+ end
73
+
74
+
75
+ class Annotation
76
+
77
+ attr_reader :name, :values, :value
78
+
79
+ def initialize(annotation_text)
80
+ @text = annotation_text.strip
81
+ @name = @text.delete("@").split("(")[0]
82
+ parse_values
83
+ end
84
+
85
+ def to_s
86
+ @text
87
+ end
88
+
89
+ private
90
+
91
+ def parse_values
92
+ @values = []
93
+ if(matches = /\((.*)\)/.match(@text))
94
+ tokens = matches[1].split(",")
95
+ tokens.each { |v|
96
+ @values << v.gsub(/\"|'/, "").strip
97
+ }
98
+ @value = tokens.first.gsub(/\"|'/, "").strip
99
+ end
100
+ end
101
+
102
+ end
103
+
104
+ end
@@ -0,0 +1,3 @@
1
+ module JaxrsDoc
2
+ VERSION = '0.0.1'
3
+ end
data/lib/parse.rb ADDED
@@ -0,0 +1,91 @@
1
+ require File.expand_path("../annotations.rb", __FILE__)
2
+
3
+ module JaxrsDoc
4
+
5
+ module AnnotationScanner
6
+
7
+ JAXRS_ANNOTATIONS = %w[ ApplicationPath Consumes CookieParam DefaultValue
8
+ DELETE Encoded FormParam FormDataParam GET HEAD HeaderParam
9
+ HttpMethod MatrixParam OPTIONS Path PathParam
10
+ POST Produces PUT QueryParam ]
11
+
12
+ def self.scan_annotations(text)
13
+ annotations = []
14
+ text.scan(jaxrs_annotations_regexp) {|s| annotations << JaxrsDoc::Annotation.new(s.first)}
15
+ JaxrsDoc::AnnotationsGroup.new(annotations)
16
+ end
17
+
18
+ private
19
+
20
+ def self.jaxrs_annotations_regexp
21
+ regexp = JAXRS_ANNOTATIONS.map { |a|
22
+ ["#{a}(?=[[:space:]])", "#{a}\\(?.*?\\)"]
23
+ }
24
+ Regexp.new("@(#{regexp.join('|')})")
25
+ end
26
+
27
+ end
28
+
29
+ module ParamDescriptionScanner
30
+
31
+ def self.scan_params_descriptions(text)
32
+ params_descriptions = Hash.new("")
33
+ text.each_line { |line|
34
+ if(param_index = line.index("@param"))
35
+ param_name, param_desc = line[(param_index + 6)..-1].split(" ", 2);
36
+ params_descriptions.store(param_name, param_desc)
37
+ end
38
+ }
39
+ params_descriptions
40
+ end
41
+
42
+ end
43
+
44
+ module ResourceParser
45
+ include AnnotationScanner
46
+
47
+ def self.parse(file)
48
+ @filename = File.basename(file.path)
49
+ parse_content(file.read)
50
+ end
51
+
52
+ def self.parse_content(text)
53
+ verbs_annotations = {:gets => [], :posts => [], :puts => [], :deletes => []}
54
+ descriptions = {}
55
+ java_sections = text.split(/(?<=\s)({)/);
56
+ resource_head_section = java_sections.shift
57
+ type_annotations = AnnotationScanner.scan_annotations(resource_head_section)
58
+ descriptions.update(ParamDescriptionScanner.scan_params_descriptions(resource_head_section))
59
+ type_description = parse_resource_description(resource_head_section)
60
+ java_sections.each { |section|
61
+ group = AnnotationScanner.scan_annotations(section)
62
+ descriptions.update(ParamDescriptionScanner.scan_params_descriptions(section))
63
+ unless group.empty?
64
+ verbs_annotations[:gets] << group if(group.get)
65
+ verbs_annotations[:posts] << group if(group.post)
66
+ verbs_annotations[:puts] << group if(group.put)
67
+ verbs_annotations[:deletes] << group if(group.delete)
68
+ end
69
+ }
70
+ JaxrsDoc::Resource.new(@filename, type_annotations, verbs_annotations, type_description, descriptions)
71
+ end
72
+
73
+ private
74
+
75
+ def self.parse_resource_description(head_text_section)
76
+ from_package_only_head_section = head_text_section.each_line.drop_while {|line|
77
+ not line.strip.start_with?("package")
78
+ }.join
79
+
80
+ if (description_match = /^\/\*\*(.+)\*\/$/m.match(from_package_only_head_section))
81
+ full_text = description_match[1].gsub("*", "")
82
+ description = ""
83
+ full_text.each_line { |line|
84
+ description << line unless line.include?("@param")
85
+ }
86
+ description
87
+ end
88
+ end
89
+
90
+ end
91
+ end
data/lib/site.rb ADDED
@@ -0,0 +1,60 @@
1
+ require File.expand_path("../templates.rb", __FILE__)
2
+ require 'erb'
3
+ require 'fileutils'
4
+
5
+ module JaxrsDoc
6
+
7
+ class Site
8
+
9
+ attr_reader :resources, :project_version, :project_name, :output_dir
10
+
11
+ def initialize(resources, output_location, options = {})
12
+ @resources = resources.sort!
13
+ @project_version = options[:project_version]
14
+ @project_name = options[:project_name]
15
+ make_output_dir(output_location)
16
+ copy_resources_to_output_dir
17
+ end
18
+
19
+ def generate
20
+ @resources.each { |resource|
21
+ File.open(resource_file_path(resource.name), "w") { |f|
22
+ content = ERB.new(JaxrsDoc::Templates.get_resource_page).result(binding)
23
+ f.syswrite(content)
24
+ }
25
+ }
26
+
27
+ File.open(index_file_path, "w") { |f|
28
+ content = ERB.new(JaxrsDoc::Templates.get_index_page).result(binding)
29
+ f.syswrite(content)
30
+ }
31
+ @output_dir
32
+ end
33
+
34
+ private
35
+
36
+ def resource_file_path(resource_name)
37
+ File.join(@output_dir.path, "#{resource_name}.html")
38
+ end
39
+
40
+ def index_file_path
41
+ File.join(@output_dir.path, "index.html")
42
+ end
43
+
44
+ def make_output_dir(output_location)
45
+ output_path = "#{output_location}"
46
+ output_path << "/jaxrsdoc"
47
+ output_path << "/#{@project_name}" unless @project_name.nil?
48
+ output_path << "/#{@project_version}" unless @project_version.nil?
49
+ FileUtils.mkdir_p(output_path)
50
+ @output_dir = Dir.new(output_path)
51
+ end
52
+
53
+ def copy_resources_to_output_dir
54
+ bootstrap_file_path = File.expand_path("../../site/bootstrap.css", __FILE__)
55
+ jaxrsdoc_css_file_path = File.expand_path("../../site/jaxrsdoc.css", __FILE__)
56
+ FileUtils.cp(bootstrap_file_path, File.join(@output_dir.path, "bootstrap.css"))
57
+ FileUtils.cp(jaxrsdoc_css_file_path, File.join(@output_dir.path, "jaxrsdoc.css"))
58
+ end
59
+ end
60
+ end
data/lib/templates.rb ADDED
@@ -0,0 +1,208 @@
1
+ module JaxrsDoc
2
+
3
+ module Templates
4
+
5
+ def self.get_index_page
6
+ %q{
7
+ <html>
8
+ <head>
9
+ <link rel="stylesheet" type="text/css" href="bootstrap.css" />
10
+ <link rel="stylesheet" type="text/css" href="jaxrsdoc.css" />
11
+ </head>
12
+ <body>
13
+ <div class="navbar">
14
+ <div class="navbar-inner">
15
+ <div class="container">
16
+ <a class="brand" href="#"><%= @project_name %> <%= @project_version %></a>
17
+ <ul class="nav">
18
+ <li class="active"><a href="index.html">API index</a></li>
19
+ </ul>
20
+ <p class="navbar-text pull-right">Last update <%= Time.now.strftime("%d %B - %H:%M:%S") %></p>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ <div class="container">
25
+ <% @resources.each_slice(20) do |big_packets_of_resources| %>
26
+ <div class="row">
27
+ <% big_packets_of_resources.each_slice(10) do |small_packets_of_resources|%>
28
+ <div class="span6">
29
+ <pre><ul><% small_packets_of_resources.each do |resource|%><li><a href="<%= resource.name %>.html"> <% if resource.path %><%= resource.path.value %><% end %></a></li><% end%></ul></pre>
30
+ </div>
31
+ <% end %>
32
+ </div>
33
+ <% end%>
34
+ <footer class="modal-footer"><span>Powered by <a href="https://github.com/simcap/jaxrsdoc">Jaxrsdoc</a></span></footer>
35
+ </div>
36
+ <body>
37
+ </html>
38
+ }
39
+ end
40
+
41
+ def self.get_resource_page
42
+ %q{
43
+ <html>
44
+ <head>
45
+ <link rel="stylesheet" type="text/css" href="bootstrap.css" />
46
+ <link rel="stylesheet" type="text/css" href="jaxrsdoc.css" />
47
+ </head>
48
+ <body>
49
+ <div class="navbar">
50
+ <div class="navbar-inner">
51
+ <div class="container">
52
+ <a class="brand" href="#"><%= @project_name %> <%= @project_version %></a>
53
+ <ul class="nav">
54
+ <li class="active"><a href="index.html">API index</a></li>
55
+ </ul>
56
+ <p class="navbar-text pull-right">Updated <%= Time.now.strftime("%d %B - %H:%M:%S") %></p>
57
+ </div>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="container">
62
+
63
+ <div class="page-header">
64
+ <h1><% if resource.path %><%= resource.path.value %><% end %><pre class="pull-right"><%= resource.name %></pre></h1>
65
+ </div>
66
+
67
+ <% if resource.description %>
68
+ <div>
69
+ <pre><%= resource.description %></pre>
70
+ </div>
71
+ <% end %>
72
+
73
+ <% resource.gets.each do |annot_group| %>
74
+ <div class="row">
75
+ <div class="get span12">
76
+ <button class="btn btn-success pull-left disabled" href="#"><%= annot_group.get.name %></button>
77
+ <h3 class="pagination-centered"><% if annot_group.path %> <%= annot_group.path.value %> <% end %></h3>
78
+ </div>
79
+ </div>
80
+
81
+ <% unless annot_group.queryparams.empty? %>
82
+ <div class="row">
83
+ <div class="span12">
84
+ <table class="table table-bordered table-striped">
85
+ <colgroup>
86
+ <col class="span1">
87
+ </colgroup>
88
+ <thead>
89
+ <tr><th>Parameter</th><th>Description</th></tr>
90
+ </thead>
91
+ <tbody>
92
+ <% annot_group.queryparams.each do |param| %>
93
+ <tr>
94
+ <td><%= param.value %></td>
95
+ <td><%= resource.params_descriptions[param.value] %></td>
96
+ </tr>
97
+ <% end %>
98
+ </tbody>
99
+ </table>
100
+ </div>
101
+ </div>
102
+ <% end %>
103
+ <% end %>
104
+
105
+ <% resource.posts.each do |annot_group| %>
106
+ <div class="row">
107
+ <div class="post span12">
108
+ <button class="btn btn-info pull-left disabled" href="#"><%= annot_group.post.name %></button>
109
+ <h3 class="pagination-centered"><% if annot_group.path %> <%= annot_group.path.value %> <% end %></h3>
110
+ </div>
111
+ </div>
112
+
113
+ <% unless annot_group.params.empty? %>
114
+ <div class="row">
115
+ <div class="span12">
116
+ <table class="table table-bordered table-striped">
117
+ <colgroup>
118
+ <col class="span1">
119
+ </colgroup>
120
+ <thead>
121
+ <tr><th>Parameter</th><th>Description</th></tr>
122
+ </thead>
123
+ <tbody>
124
+ <% annot_group.params.each do |param| %>
125
+ <tr>
126
+ <td><%= param.value %></td>
127
+ <td><%= resource.params_descriptions[param.value] %></td>
128
+ </tr>
129
+ <% end %>
130
+ </tbody>
131
+ </table>
132
+ </div>
133
+ </div>
134
+ <% end %>
135
+ <% end %>
136
+
137
+ <% resource.puts.each do |annot_group| %>
138
+ <div class="row">
139
+ <div class="put span12">
140
+ <button class="btn btn-warning pull-left disabled" href="#"><%= annot_group.put.name %></button>
141
+ <h3 class="pagination-centered"><% if annot_group.path %> <%= annot_group.path.value %> <% end %></h3>
142
+ </div>
143
+ </div>
144
+
145
+ <% unless annot_group.params.empty? %>
146
+ <div class="row">
147
+ <div class="span12">
148
+ <table class="table table-bordered table-striped">
149
+ <colgroup>
150
+ <col class="span1">
151
+ </colgroup>
152
+ <thead>
153
+ <tr><th>Parameter</th><th>Description</th></tr>
154
+ </thead>
155
+ <tbody>
156
+ <% annot_group.params.each do |param| %>
157
+ <tr>
158
+ <td><%= param.value %></td>
159
+ <td><%= resource.params_descriptions[param.value] %></td>
160
+ </tr>
161
+ <% end %>
162
+ </tbody>
163
+ </table>
164
+ </div>
165
+ </div>
166
+ <% end %>
167
+ <% end %>
168
+
169
+ <% resource.deletes.each do |annot_group| %>
170
+ <div class="row">
171
+ <div class="post span12">
172
+ <button class="btn btn-danger pull-left disabled" href="#"><%= annot_group.delete.name %></button>
173
+ <h3 class="pagination-centered"><% if annot_group.path %> <%= annot_group.path.value %> <% end %></h3>
174
+ </div>
175
+ </div>
176
+
177
+ <% unless annot_group.params.empty? %>
178
+ <div class="row">
179
+ <div class="span12">
180
+ <table class="table table-bordered table-striped">
181
+ <colgroup>
182
+ <col class="span1">
183
+ </colgroup>
184
+ <thead>
185
+ <tr><th>Parameter</th><th>Description</th></tr>
186
+ </thead>
187
+ <tbody>
188
+ <% annot_group.params.each do |param| %>
189
+ <tr>
190
+ <td><%= param.value %></td>
191
+ <td><%= resource.params_descriptions[param.value] %></td>
192
+ </tr>
193
+ <% end %>
194
+ </tbody>
195
+ </table>
196
+ </div>
197
+ </div>
198
+ <% end %>
199
+ <% end %>
200
+
201
+
202
+ </div>
203
+ <body>
204
+ </html>
205
+ }
206
+ end
207
+ end
208
+ end