haplo 2.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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