haplo 2.1.0-java

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.
@@ -0,0 +1,197 @@
1
+
2
+ def end_on_error(err)
3
+ puts err
4
+ exit 1
5
+ end
6
+
7
+ File.open("#{File.dirname(__FILE__)}/version.txt") do |f|
8
+ puts "Haplo Plugin Tool (#{f.read.chomp})"
9
+ end
10
+
11
+ PluginTool.try_load_custom
12
+
13
+ PluginTool::LocalConfig.load
14
+
15
+ # Commands not needing server
16
+ LOCAL_ONLY_COMMANDS = {"license-key" => true, "pack" => true, "check" => true}
17
+
18
+ # Plugin names
19
+ plugin_names = []
20
+
21
+ # Options for passing to plugin objects
22
+ options = Struct.new(:output, :minimiser, :no_console, :show_system_audit, :args, :force, :server_substring).new
23
+
24
+ # Parse arguments
25
+ show_help = false
26
+ opts = GetoptLong.new(
27
+ ['--help', '-h', GetoptLong::NO_ARGUMENT],
28
+ ['--plugin', '-p', GetoptLong::OPTIONAL_ARGUMENT],
29
+ ['--server', '-s', GetoptLong::REQUIRED_ARGUMENT],
30
+ ['--force', GetoptLong::NO_ARGUMENT],
31
+ ['--output', GetoptLong::REQUIRED_ARGUMENT],
32
+ ['--no-console', '-n', GetoptLong::NO_ARGUMENT],
33
+ ['--show-system-audit', GetoptLong::NO_ARGUMENT],
34
+ ['--minimise', '--minimize', '-m', GetoptLong::NO_ARGUMENT]
35
+ )
36
+ option_output = nil
37
+ opts.each do |opt, argument|
38
+ case opt
39
+ when '--help'
40
+ show_help = true
41
+ when '--plugin'
42
+ plugin_names = argument.split(',').map {|n| n.gsub(/[\/\\]+\z/,'')} # remove trailing dir separators
43
+ when '--server'
44
+ options.server_substring = argument
45
+ when '--output'
46
+ options.output = argument
47
+ when '--no-console'
48
+ options.no_console = true
49
+ when '--show-system-audit'
50
+ options.show_system_audit = true
51
+ when '--minimise', '--minimize'
52
+ options.minimiser = PluginTool::Minimiser.new
53
+ when '--force'
54
+ options.force = true
55
+ end
56
+ end
57
+ # Handle rest of command line -- first arg is the command, the rest are passed on
58
+ PLUGIN_TOOL_COMMAND = (ARGV.shift || 'develop')
59
+ options.args = ARGV
60
+
61
+ automatic_plugin_exclusion = false
62
+
63
+ # Help message?
64
+ if show_help || PLUGIN_TOOL_COMMAND == 'help'
65
+ puts File.open("#{File.dirname(__FILE__)}/usage.txt") { |f| f.read }
66
+ exit 0
67
+ end
68
+
69
+ # Plugin names handling
70
+ def find_all_plugins()
71
+ all_plugins = []
72
+ Dir.glob("**/plugin.json").each do |p|
73
+ if p =~ /\A([a-zA-Z0-9_]+)\/plugin\.json\z/
74
+ all_plugins << $1
75
+ end
76
+ end
77
+ all_plugins
78
+ end
79
+
80
+ if plugin_names.length == 1 && plugin_names[0] == 'ALL'
81
+ plugin_names = find_all_plugins()
82
+ automatic_plugin_exclusion = true
83
+ end
84
+
85
+ # Some commands don't require a server or plugin to be specified
86
+ case PLUGIN_TOOL_COMMAND
87
+ when 'new'
88
+ end_on_error "Plugin name not specified, use --plugin option." if plugin_names.empty?
89
+ end_on_error "Only one plugin name should be specified for new command" if plugin_names.length > 1
90
+ PluginTool.make_new_plugin(plugin_names.first)
91
+ exit 0
92
+ when 'auth'
93
+ PluginTool.cmd_auth options
94
+ exit 0
95
+ when 'server'
96
+ PluginTool.cmd_server options
97
+ exit 0
98
+ end
99
+
100
+ # Find a plugin if none was specified
101
+ if plugin_names.empty?
102
+ all_plugins = find_all_plugins()
103
+ end_on_error "No plugin found" if all_plugins.length == 0
104
+ if all_plugins.length > 1
105
+ puts "Too many plugins in the current directory for automatic selection."
106
+ puts "Use -p plugin_name to specify. Eg:"
107
+ all_plugins.each do |name|
108
+ puts " #{$0} -p #{name}"
109
+ end
110
+ exit 1
111
+ end
112
+ plugin_names = all_plugins
113
+ end
114
+
115
+ # Make plugin objects, start them, sort by order the server will load them
116
+ plugins = plugin_names.map do |name|
117
+ PluginTool::Plugin.new(name, options)
118
+ end
119
+ plugins.each { |p| p.start }
120
+ plugins.sort! do |a,b|
121
+ pri_a = a.plugin_load_priority
122
+ pri_b = b.plugin_load_priority
123
+ (pri_a == pri_b) ? (a.name <=> b.name) : (pri_a <=> pri_b)
124
+ end
125
+ plugins.each { |p| p.print_banner }
126
+
127
+ # Custom behaviour for this repo?
128
+ PluginTool.custom_behaviour.start(plugins, PLUGIN_TOOL_COMMAND, options, LOCAL_ONLY_COMMANDS[PLUGIN_TOOL_COMMAND])
129
+
130
+ # Special handling for some commands
131
+ case PLUGIN_TOOL_COMMAND
132
+ when 'pack'
133
+ end_on_error "Output directory not specified, use --output option." unless options.output != nil
134
+ require "#{File.dirname(__FILE__)}/packing.rb"
135
+ when 'check'
136
+ PluginTool.check_plugins(plugins)
137
+ exit 0
138
+ end
139
+
140
+ # Set up server communications
141
+ unless LOCAL_ONLY_COMMANDS[PLUGIN_TOOL_COMMAND]
142
+ PluginTool.setup_auth(options)
143
+ PluginTool.check_for_certificate_file
144
+
145
+ PluginTool.custom_behaviour.server_ready(plugins, PLUGIN_TOOL_COMMAND, options)
146
+
147
+ if automatic_plugin_exclusion
148
+ exclusions = PluginTool::LocalConfig.get_list("exclude")
149
+ plugins = plugins.select do |plugin|
150
+ if exclusions.include?(plugin.name)
151
+ puts "NOTICE: Excluded plugin #{plugin.name}"
152
+ false
153
+ else
154
+ true
155
+ end
156
+ end
157
+ end
158
+
159
+ plugins.each { |p| p.setup_for_server }
160
+ end
161
+
162
+ # Run the command
163
+ plugins.each { |p| p.command(PLUGIN_TOOL_COMMAND) }
164
+
165
+ # It this isn't the long-running develop command, stop now
166
+ if PLUGIN_TOOL_COMMAND != 'develop'
167
+ exit 0
168
+ end
169
+
170
+ # Syntax checking in the background
171
+ PluginTool.start_syntax_check
172
+
173
+ # Notifications support (including console)
174
+ PluginTool.start_notifications(options) unless options.no_console
175
+
176
+ # Open watcher
177
+ watcher = PluginTool.make_watcher(plugins.map { |p| p.plugin_dir })
178
+
179
+ # Start plugins
180
+ plugins.each { |p| p.develop_setup }
181
+
182
+ # Upload changes
183
+ first_run = true
184
+ while(true)
185
+ puts "Scanning plugin files..."
186
+ plugins.each { |p| p.develop_scan_and_upload(first_run) }
187
+ PluginTool::Plugin.do_apply
188
+ PluginTool.finish_with_connection
189
+ puts "Waiting for changes..."
190
+ if first_run
191
+ puts " Any changes you make to your local copy of the plugin will be automatically"
192
+ puts " uploaded to the server."
193
+ end
194
+ first_run = false
195
+ watcher.wait(3600)
196
+ end
197
+
@@ -0,0 +1,67 @@
1
+
2
+ # Make sure we use a JRuby which has been tested
3
+ PLUGIN_TOOL_JRUBY_REQUIREMENT = '9.0.4.0'
4
+ PLUGIN_TOOL_JAVA_REQUIREMENT = '1.8'
5
+ PLUGIN_TOOL_JAVA_REQUIREMENT_READABLE = "at least Java 8"
6
+
7
+ unless defined? JRUBY_VERSION
8
+ puts "haplo-plugin can only run under JRuby"
9
+ exit 1
10
+ end
11
+
12
+ require 'rubygems'
13
+
14
+ unless Gem::Dependency.new('', '>= '+PLUGIN_TOOL_JRUBY_REQUIREMENT).match?('', JRUBY_VERSION)
15
+ puts "haplo-plugin requires JRuby #{PLUGIN_TOOL_JRUBY_REQUIREMENT} or later, you have #{JRUBY_VERSION}"
16
+ exit 1
17
+ end
18
+
19
+ require 'java'
20
+
21
+ unless Gem::Dependency.new('', '>= '+PLUGIN_TOOL_JAVA_REQUIREMENT).match?('', java.lang.System.getProperty("java.version").gsub(/[^0-9\.].+?\z/,''))
22
+ puts "haplo-plugin requires #{PLUGIN_TOOL_JAVA_REQUIREMENT_READABLE}"
23
+ exit 1
24
+ end
25
+
26
+ require 'digest/sha1'
27
+ require 'net/http'
28
+ require 'net/https'
29
+ require 'getoptlong'
30
+ require 'fileutils'
31
+ require 'thread'
32
+
33
+ gem 'json'
34
+ require 'json'
35
+
36
+ PLUGIN_TOOL_ROOT_DIR = File.expand_path(File.dirname(__FILE__)+'/..')
37
+
38
+ JS_JAR = "#{PLUGIN_TOOL_ROOT_DIR}/lib/js.jar"
39
+ unless File.exists? JS_JAR
40
+ puts "Can't find JavaScript interpreter .jar file"
41
+ exit 1
42
+ end
43
+ require JS_JAR
44
+
45
+ TEMPLATES_JAR = "#{PLUGIN_TOOL_ROOT_DIR}/lib/haplo-templates.jar"
46
+ unless File.exists? TEMPLATES_JAR
47
+ puts "Can't find Haplo Templates .jar file"
48
+ exit 1
49
+ end
50
+ require TEMPLATES_JAR
51
+
52
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/hmac.rb"
53
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/local_config.rb"
54
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/manifest.rb"
55
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/auth.rb"
56
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/server.rb"
57
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/schema_requirements.rb"
58
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/syntax_checking.rb"
59
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/notifications.rb"
60
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/plugin.rb"
61
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/new_plugin.rb"
62
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/misc.rb"
63
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/watchers.rb"
64
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/minimise.rb"
65
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/check.rb"
66
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/custom.rb"
67
+ require "#{PLUGIN_TOOL_ROOT_DIR}/lib/plugin_tool.rb"
@@ -0,0 +1,63 @@
1
+
2
+ module PluginTool
3
+
4
+ class SchemaRequirements
5
+ IGNORE_LINE = /\A\s*(\#.+)?\z/m # comment or blank line
6
+ OBJECT_FORMAT = /\A(OPTIONAL )?(?<kind>\S+)\s+(?<code>[a-zA-Z0-9_:-]+)\s*(as\s+(?<name>[a-zA-Z0-9_]+))?\s*\z/m
7
+
8
+ SCHEMA_LOCALS = {
9
+ "type" => "T",
10
+ "attribute" => "A",
11
+ "aliased-attribute" => "AA",
12
+ "qualifier" => "Q",
13
+ "label" => "Label",
14
+ "group" => "Group"
15
+ }
16
+
17
+ def initialize(filename)
18
+ # Define the special attributes by default
19
+ @schema_names = {"A" => {
20
+ "Parent" => true,
21
+ "Type" => true,
22
+ "Title" => true
23
+ }}
24
+ return unless File.exist?(filename)
25
+ File.open(filename) do |file|
26
+ file.each do |line|
27
+ if (line !~ IGNORE_LINE) && (match = OBJECT_FORMAT.match(line))
28
+ kind = SCHEMA_LOCALS[match[:kind]] || 'UNUSED'
29
+ @schema_names[kind] ||= {}
30
+ name = match[:name]
31
+ if name && !name.empty?
32
+ @schema_names[kind][name] = true
33
+ end
34
+ end
35
+ end
36
+ end
37
+ @schema_names.delete('UNUSED')
38
+ end
39
+
40
+ def locals
41
+ @schema_names.keys.dup
42
+ end
43
+
44
+ FIND_USE_REGEXP = Regexp.new("\\b(#{SCHEMA_LOCALS.values.join('|')})\\.([a-zA-Z0-9]+)\\b")
45
+
46
+ def report_usage(js)
47
+ report = []
48
+ js.split(/\r?\n/).each_with_index do |line, index|
49
+ line.scan(FIND_USE_REGEXP) do
50
+ kind = $1
51
+ name = $2
52
+ lookup = @schema_names[kind]
53
+ unless lookup && lookup.has_key?(name)
54
+ report << "line #{index+1}: Schema name #{kind}.#{name} isn't declared in requirements.schema\n\n"
55
+ end
56
+ end
57
+ end
58
+ report.empty? ? nil : report.join
59
+ end
60
+ end
61
+
62
+ end
63
+
@@ -0,0 +1,143 @@
1
+
2
+ module PluginTool
3
+
4
+ def self.set_server(hostname, port, key)
5
+ @@server_hostname = hostname
6
+ @@server_port = port
7
+ @@server_key = key
8
+ end
9
+
10
+ def self.get_server_hostname
11
+ @@server_hostname
12
+ end
13
+
14
+ def self.check_for_certificate_file
15
+ @@server_ca = nil
16
+ hostname_parts = (@@server_hostname || '').split('.')
17
+ search_list = (0..hostname_parts.length).map do |n|
18
+ filename = "server"
19
+ search_parts = hostname_parts[n..hostname_parts.length]
20
+ filename << '.' unless search_parts.empty?
21
+ filename << search_parts.join('.')
22
+ filename << ".crt"
23
+ end
24
+ @@server_ca = search_list.find { |f| File.file?(f) }
25
+ if @@server_ca
26
+ puts "NOTICE: Using alternative CAs for SSL from #{@@server_ca}"
27
+ else
28
+ # Use build in certificate bundle
29
+ @@server_ca = "#{File.dirname(__FILE__)}/CertificateBundle.pem"
30
+ end
31
+ end
32
+
33
+ def self.make_http_connection
34
+ http = Net::HTTP.new(@@server_hostname, @@server_port)
35
+ ssl_ca = OpenSSL::X509::Store.new
36
+ unless ssl_ca.respond_to? :add_file
37
+ puts
38
+ puts "jruby-openssl gem is not installed or bouncy castle crypto not available on CLASSPATH."
39
+ puts "See installation instructions."
40
+ puts
41
+ exit 1
42
+ end
43
+ ssl_ca.add_file(@@server_ca)
44
+ http.use_ssl = true
45
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
46
+ http.cert_store = ssl_ca
47
+ http.start
48
+ http
49
+ end
50
+
51
+ @@http = nil
52
+ def self.get_http
53
+ @@http ||= make_http_connection
54
+ end
55
+
56
+ def self.finish_with_connection
57
+ if @@http != nil
58
+ @@http.finish
59
+ @@http = nil
60
+ end
61
+ end
62
+
63
+ def self.setup_request(req)
64
+ req['User-Agent'] = 'plugin-tool'
65
+ req['X-ONEIS-Key'] = @@server_key if @@server_key
66
+ end
67
+
68
+ def self.get(path)
69
+ http = get_http
70
+ request = Net::HTTP::Get.new(path)
71
+ setup_request(request)
72
+ http.request(request).body
73
+ end
74
+
75
+ def self.get_with_json_response(path)
76
+ report_errors_from_server(JSON.parse(get(path)))
77
+ end
78
+
79
+ def self.post(path, params = nil, files = nil)
80
+ http = get_http
81
+ request = Net::HTTP::Post.new(path)
82
+ setup_request(request)
83
+ if files == nil
84
+ request.set_form_data(params) if params != nil
85
+ else
86
+ boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"
87
+ request["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
88
+ body = ''
89
+ if params != nil
90
+ params.each do |key,value|
91
+ body << <<-EOF
92
+ --#{boundary}\r
93
+ Content-Disposition: form-data; name="#{key}"\r
94
+ \r
95
+ #{value}\r
96
+ EOF
97
+ end
98
+ end
99
+ files.each do |key,info|
100
+ pathname, data = info
101
+ body << <<-EOF
102
+ --#{boundary}\r
103
+ Content-Disposition: form-data; name="#{key}"; filename="#{pathname}"\r
104
+ Content-Type: application/octet-stream\r
105
+ Content-Length: #{data.length}\r
106
+ \r
107
+ #{data}\r
108
+ EOF
109
+ end
110
+ body << "--#{boundary}--\r"
111
+ request.body = body
112
+ end
113
+ http.request(request).body
114
+ end
115
+
116
+ def self.post_with_json_response(path, params = nil, files = nil)
117
+ report_errors_from_server(JSON.parse(post(path, params, files)))
118
+ end
119
+
120
+ def self.report_errors_from_server(r)
121
+ unless r.kind_of? Hash
122
+ r = {
123
+ "result" => 'error',
124
+ "protocol_error" => true,
125
+ "message" => "Unknown error. Either the server is not enabled for development, or the credentials in #{SERVER_INFO} are not valid."
126
+ }
127
+ end
128
+ if r["result"] != 'success' && r.has_key?("message")
129
+ puts "\n\n**************************************************************"
130
+ puts " ERROR REPORTED BY SERVER"
131
+ puts "**************************************************************\n\n"
132
+ puts r["message"]
133
+ puts "\n**************************************************************\n\n"
134
+ beep
135
+ end
136
+ r
137
+ end
138
+
139
+ def self.get_application_info
140
+ @@server_application_info ||= JSON.parse(get("/api/development-plugin-loader/application-info"))
141
+ end
142
+
143
+ end