rb-appscript 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/CHANGES +37 -0
  2. data/LICENSE +6 -2
  3. data/README +7 -4
  4. data/TODO +6 -2
  5. data/doc/aem-manual/01_introduction.html +1 -1
  6. data/doc/aem-manual/02_apioverview.html +1 -1
  7. data/doc/aem-manual/03_packingandunpackingdata.html +3 -3
  8. data/doc/aem-manual/04_references.html +18 -13
  9. data/doc/aem-manual/05_targettingapplications.html +33 -13
  10. data/doc/aem-manual/06_buildingandsendingevents.html +1 -1
  11. data/doc/aem-manual/07_findapp.html +1 -1
  12. data/doc/aem-manual/08_examples.html +1 -1
  13. data/doc/aem-manual/index.html +1 -1
  14. data/doc/appscript-manual/01_introduction.html +1 -1
  15. data/doc/appscript-manual/02_aboutappscripting.html +4 -4
  16. data/doc/appscript-manual/03_quicktutorial.html +1 -1
  17. data/doc/appscript-manual/04_gettinghelp.html +13 -42
  18. data/doc/appscript-manual/05_keywordconversion.html +1 -1
  19. data/doc/appscript-manual/06_classesandenums.html +1 -1
  20. data/doc/appscript-manual/07_applicationobjects.html +19 -1
  21. data/doc/appscript-manual/08_realvsgenericreferences.html +1 -1
  22. data/doc/appscript-manual/09_referenceforms.html +1 -1
  23. data/doc/appscript-manual/10_referenceexamples.html +1 -1
  24. data/doc/appscript-manual/11_applicationcommands.html +1 -1
  25. data/doc/appscript-manual/12_commandexamples.html +1 -1
  26. data/doc/appscript-manual/13_performanceissues.html +1 -1
  27. data/doc/appscript-manual/14_notes.html +1 -1
  28. data/doc/appscript-manual/index.html +1 -1
  29. data/doc/index.html +1 -1
  30. data/doc/mactypes-manual/index.html +13 -1
  31. data/doc/osax-manual/index.html +37 -6
  32. data/extconf.rb +2 -2
  33. data/rb-appscript.gemspec +1 -1
  34. data/sample/AB_export_vcard.rb +31 -0
  35. data/sample/Add_iCal_event.rb +4 -4
  36. data/src/lib/_aem/connect.rb +88 -8
  37. data/src/lib/_aem/mactypes.rb +27 -21
  38. data/src/lib/_appscript/reservedkeywords.rb +1 -0
  39. data/src/lib/aem.rb +40 -5
  40. data/src/lib/appscript.rb +104 -30
  41. data/src/lib/kae.rb +1 -0
  42. data/src/lib/osax.rb +35 -19
  43. data/src/rbae.c +115 -1
  44. data/test/README +3 -1
  45. data/test/test_appscriptcommands.rb +5 -4
  46. data/test/test_codecs.rb +7 -1
  47. data/test/testall.sh +1 -1
  48. metadata +24 -23
@@ -11,21 +11,6 @@ module MacTypes
11
11
  require "kae"
12
12
 
13
13
  class FileBase
14
-
15
- URLPrefix = 'file://localhost'
16
- URLPatt = Regexp.new('file://.*?(/.*)', Regexp::IGNORECASE)
17
-
18
- def FileBase._path_to_url(path)
19
- return URLPrefix + path.gsub(/[^a-zA-Z0-9_.-\/]/) { |c| "%%%02x" % c[0] }
20
- end
21
-
22
- def FileBase._url_to_path(url)
23
- match = url.match(URLPatt)
24
- if not match
25
- raise ArgumentError, "Not a file:// URL."
26
- end
27
- return match[1].gsub(/%../) { |s| "%c" % s[1,2].hex }
28
- end
29
14
 
30
15
  def FileBase._coerce(desc, type, path=nil)
31
16
  begin
@@ -72,13 +57,20 @@ module MacTypes
72
57
  def Alias.path(path)
73
58
  # Make Alias object from POSIX path.
74
59
  return new(FileBase._coerce(
75
- AE::AEDesc.new(KAE::TypeFileURL, FileBase._path_to_url(path)),
60
+ AE::AEDesc.new(KAE::TypeFileURL, AE.convert_posix_path_to_url(path)),
61
+ KAE::TypeAlias, path))
62
+ end
63
+
64
+ def Alias.hfs_path(path)
65
+ # Make Alias object from HFS path.
66
+ return new(FileBase._coerce(
67
+ AE::AEDesc.new(KAE::TypeFileURL, AE.convert_hfs_path_to_url(path)),
76
68
  KAE::TypeAlias, path))
77
69
  end
78
70
 
79
71
  def Alias.url(url)
80
72
  # Make Alias object from file URL. Note: only the path portion of the URL is used; the domain will always be localhost.
81
- return Alias.path(_url_to_path(url))
73
+ return Alias.path(AE.convert_url_to_posix_path(url))
82
74
  end
83
75
 
84
76
  def Alias.desc(desc)
@@ -97,7 +89,12 @@ module MacTypes
97
89
 
98
90
  def path
99
91
  # Get as POSIX path.
100
- return FileBase._url_to_path(FileBase._coerce(@desc, KAE::TypeFileURL).data)
92
+ return AE.convert_url_to_posix_path(FileBase._coerce(@desc, KAE::TypeFileURL).data)
93
+ end
94
+
95
+ def hfs_path
96
+ # Get as HFS path.
97
+ return AE.convert_url_to_hfs_path(FileBase._coerce(@desc, KAE::TypeFileURL).data)
101
98
  end
102
99
 
103
100
  alias_method :to_s, :path
@@ -136,9 +133,14 @@ module MacTypes
136
133
  return new(path, nil)
137
134
  end
138
135
 
136
+ def FileURL.hfs_path(path)
137
+ # Make FileURL object from HFS path.
138
+ return new(AE.convert_url_to_posix_path(AE.convert_hfs_path_to_url(path)), nil)
139
+ end
140
+
139
141
  def FileURL.url(url)
140
142
  # Make FileURL object from file URL. Note: only the path portion of the URL is used; the domain will always be localhost.
141
- return FileURL.path(_url_to_path(url))
143
+ return FileURL.path(AE.convert_url_to_posix_path(url))
142
144
  end
143
145
 
144
146
  def FileURL.desc(desc)
@@ -151,7 +153,7 @@ module MacTypes
151
153
  def desc
152
154
  # Get as AEDesc. If constructed from Ruby, descriptor's type is always typeFileURL; if returned by aem, its type mat be typeFSS, typeFSRef or typeFileURL.
153
155
  if not @desc
154
- @desc = AE::AEDesc.new(KAE::TypeFileURL, FileBase._path_to_url(@path))
156
+ @desc = AE::AEDesc.new(KAE::TypeFileURL, AE.convert_posix_path_to_url(@path))
155
157
  end
156
158
  return @desc
157
159
  end
@@ -164,11 +166,15 @@ module MacTypes
164
166
  def path
165
167
  # Get as POSIX path.
166
168
  if not @path
167
- @path = FileBase._url_to_path(FileBase._coerce(@desc, KAE::TypeFileURL).data)
169
+ @path = AE.convert_url_to_posix_path(FileBase._coerce(@desc, KAE::TypeFileURL).data)
168
170
  end
169
171
  return @path
170
172
  end
171
173
 
174
+ def hfs_path
175
+ return AE.convert_url_to_hfs_path(AE.convert_posix_path_to_url(path))
176
+ end
177
+
172
178
  alias_method :to_s, :path
173
179
 
174
180
  def inspect
@@ -74,6 +74,7 @@ ReservedKeywords = [
74
74
  "is_a?",
75
75
  "is_in",
76
76
  "is_not_in",
77
+ "is_running?",
77
78
  "its",
78
79
  "keywords",
79
80
  "kind_of?",
@@ -23,6 +23,8 @@ module AEM
23
23
  Codecs = Codecs
24
24
  DefaultCodecs = DefaultCodecs
25
25
  MacOSError = AE::MacOSError
26
+ CantLaunchApplicationError = Connect::CantLaunchApplicationError
27
+
26
28
 
27
29
  AEDesc = AE::AEDesc
28
30
 
@@ -56,7 +58,7 @@ module AEM
56
58
  #######
57
59
  # Application class
58
60
 
59
- class Application
61
+ class Application < AEMReference::Base
60
62
  # Identifies an application and provides an #event method for constructing Apple events targetted at it.
61
63
 
62
64
  require "weakref"
@@ -102,12 +104,37 @@ module AEM
102
104
 
103
105
  def Application.launch(path)
104
106
  # Launches a local application without sending it the usual 'run' event (aevtoapp).
105
- Connect.launch_app(path)
107
+ Connect.launch_app_with_launch_event(path)
108
+ end
109
+
110
+ def Application.is_running?(path) # TO DO: delete
111
+ $stderr.puts('Warning! AEM::Application.is_running? is deprecated; use process_exists_for_path? instead.')
112
+ return Connect.process_exists_for_path?(path)
113
+ end
114
+
115
+ def Application.process_exists_for_path?(path)
116
+ # Does a local process launched from the specified application file exist?
117
+ # Note: if path is invalid, an AE::MacOSError is raised.
118
+ return Connect.process_exists_for_path?(path)
119
+ end
120
+
121
+ def Application.process_exists_for_pid?(pid)
122
+ # Is there a local application process with the given unix process id?
123
+ return Connect.process_exists_for_pid?(pid)
106
124
  end
107
125
 
108
- def Application.is_running?(path)
109
- # Checks if a local application is running.
110
- return Connect.is_running?(path)
126
+ def Application.process_exists_for_url?(url)
127
+ # Does an application process specified by the given eppc:// URL exist?
128
+ # Returns false if process doesn't exist or if access to it isn't allowed.
129
+ # (Implementation note: this method sends an Apple event to the specified process and checks for errors.)
130
+ return Connect.process_exists_for_url?(url)
131
+ end
132
+
133
+ def Application.process_exists_for_desc?(desc)
134
+ # Does an application process specified by the given AEAddressDesc exist?
135
+ # Returns false if process doesn't exist or if access to it isn't allowed.
136
+ # (Implementation note: this method sends an Apple event to the specified process and checks for errors.)
137
+ return Connect.process_exists_for_desc?(desc)
111
138
  end
112
139
 
113
140
  #######
@@ -161,6 +188,14 @@ module AEM
161
188
 
162
189
  # (hash method is provided by attr_reader :hash)
163
190
 
191
+ def AEM_comparable
192
+ return ['AEMApplication', @identity]
193
+ end
194
+
195
+ def AEM_pack_self(codecs)
196
+ return @address_desc
197
+ end
198
+
164
199
  def reconnect
165
200
  # If application has quit since this Application object was created, its AEAddressDesc
166
201
  # is no longer valid so this Application object will not work even when application is restarted.
@@ -5,8 +5,11 @@
5
5
  require "_aem/mactypes"
6
6
 
7
7
  module Appscript
8
+
9
+ Version = '0.5.0'
10
+
8
11
  # The following methods and classes are of interest to end users:
9
- # app, con, its, CommandError, ApplicationNotFoundError
12
+ # app, con, its, CommandError, ApplicationNotFoundError, CantLaunchApplicationError
10
13
  # Other classes are only of interest to implementors who need to hook in their own code.
11
14
 
12
15
  require "kae"
@@ -26,7 +29,7 @@ module Appscript
26
29
 
27
30
  class AppData < AEM::Codecs
28
31
 
29
- HelpAgentID = 'net.sourceforge.appscript.appscripthelpagent'
32
+ ASDictionaryBundleID = 'net.sourceforge.appscript.asdictionary'
30
33
 
31
34
  attr_reader :constructor, :identifier, :reference_codecs
32
35
  attr_writer :reference_codecs
@@ -75,25 +78,35 @@ module Appscript
75
78
  :current => 'current',
76
79
  }
77
80
 
78
- def _make_help_agent
81
+ def _init_help_agent
79
82
  begin
80
- @_help_agent = AEM::Application.by_path(FindApp.by_id(HelpAgentID))
83
+ apppath = FindApp.by_id(ASDictionaryBundleID)
84
+ asdictionary_is_running = AEM::Application.process_exists_for_path?(apppath)
85
+ @_help_agent = AEM::Application.by_path(apppath)
86
+ if not asdictionary_is_running # hide ASDictionary after launching it # TO DO: something less kludgy
87
+ AEM::Application.by_path(FindApp.by_id('com.apple.systemevents')).event('coresetd', {
88
+ '----' => AEM.app.elements('prcs').by_name('ASDictionary').property('pvis'),
89
+ 'data' => false}).send
90
+ sleep(1) # KLUDGE: need a short delay here to workaround ASDictionary 0.9.0's event handling glitches # TO DO: delete after ASDictionary is fixed
91
+ end
81
92
  return true
82
- rescue FindApp::ApplicationNotFoundError
83
- puts "No help available: AppscriptHelpAgent.app not found."
84
- return false
93
+ rescue FindApp::ApplicationNotFoundError => e
94
+ $stderr.puts("No help available: ASDictionary application not found (#{e}).")
95
+ rescue AEM::CantLaunchApplicationError => e
96
+ $stderr.puts("No help available: can't launch ASDictionary application (#{e}).")
85
97
  end
98
+ return false
86
99
  end
87
100
 
88
101
  def _display_help(flags, ref)
89
102
  begin
90
- puts @_help_agent.event('ASHAHelp', {
103
+ $stderr.puts(@_help_agent.event('AppSHelp', {
91
104
  'Cons' => Constructors[@constructor],
92
- 'Iden' => @constructor == :by_aem_app ? @identifier.address_desc : @identifier,
105
+ 'Iden' => @identifier,
93
106
  'Styl' => 'rb-appscript',
94
107
  'Flag' => flags,
95
108
  'aRef' => pack(ref),
96
- }).send
109
+ }).send)
97
110
  return nil
98
111
  rescue AEM::CommandError => e
99
112
  return e
@@ -101,15 +114,25 @@ module Appscript
101
114
  end
102
115
 
103
116
  def help(flags, ref)
104
- if not @_help_agent
105
- return ref if not _make_help_agent
106
- end
107
- e = _display_help(flags, ref)
108
- if e and [-600, -609].include?(e.number) # not running
109
- return ref if not _make_help_agent
117
+ begin
118
+ if not @_help_agent
119
+ return ref if not _init_help_agent
120
+ end
110
121
  e = _display_help(flags, ref)
122
+ if e and [-600, -609].include?(e.number) # not running
123
+ return ref if not _init_help_agent
124
+ e = _display_help(flags, ref)
125
+ end
126
+ if e
127
+ if e.number == -1708 # event wasn't handled, presumably because available ASDictionary is too old
128
+ $stderr.puts("No help available: ASDictionary 0.9.0 or later required.")
129
+ else
130
+ $stderr.puts("No help available: ASDictionary raised an error: #{e}.")
131
+ end
132
+ end
133
+ rescue => err
134
+ $stderr.puts("No help available: unknown error: #{err}")
111
135
  end
112
- puts "No help available: AppscriptHelpAgent raised an error: #{e}." if e
113
136
  return ref
114
137
  end
115
138
 
@@ -298,9 +321,9 @@ module Appscript
298
321
  s= @_call[0]
299
322
  @_call[1, @_call.length].each do |name, args| if name == :[]
300
323
  if args.length == 1
301
- s += "[#{args[0]}]"
324
+ s += "[#{args[0].inspect}]"
302
325
  else
303
- s += "[#{args[0]}, #{args[1]}]"
326
+ s += "[#{args[0].inspect}, #{args[1].inspect}]"
304
327
  end
305
328
  else
306
329
  if args.length > 0
@@ -485,7 +508,7 @@ module Appscript
485
508
  rescue => e
486
509
  if e.is_a?(AEM::CommandError)
487
510
  if [-600, -609].include?(e.number) and @AS_app_data.constructor == :by_path
488
- if not AEM::Application.is_running?(@AS_app_data.identifier)
511
+ if not AEM::Application.process_exists_for_path?(@AS_app_data.identifier)
489
512
  if code == 'ascrnoop'
490
513
  AEM::Application.launch(@AS_app_data.identifier)
491
514
  elsif code != 'aevtoapp'
@@ -510,8 +533,8 @@ module Appscript
510
533
  #######
511
534
  # introspection
512
535
 
513
- def respond_to?(name)
514
- if super
536
+ def respond_to?(name, includePriv=false)
537
+ if Object.respond_to?(name)
515
538
  return true
516
539
  else
517
540
  return @AS_app_data.reference_by_name.has_key?(name.is_a?(String) ? name.intern : name)
@@ -519,7 +542,7 @@ module Appscript
519
542
  end
520
543
 
521
544
  def methods
522
- return super + @AS_app_data.reference_by_name.keys.collect { |name| name.to_s }
545
+ return (Object.instance_methods + @AS_app_data.reference_by_name.keys.collect { |name| name.to_s }).uniq
523
546
  end
524
547
 
525
548
  def commands
@@ -571,24 +594,73 @@ module Appscript
571
594
 
572
595
  alias_method :inspect, :to_s
573
596
 
597
+ #######
598
+ # Utility methods
599
+
600
+ def is_running?
601
+ identifier = @AS_app_data.identifier
602
+ case @AS_app_data.constructor
603
+ when :by_path
604
+ return AEM::Application.process_exists_for_path?(identifier)
605
+ when :by_pid
606
+ return AEM::Application.process_exists_for_pid?(identifier)
607
+ when :by_url
608
+ return AEM::Application.process_exists_for_url?(identifier)
609
+ when :by_aem_app
610
+ return AEM::Application.process_exists_for_desc?(identifier.address_desc)
611
+ else # when :current
612
+ return true
613
+ end
614
+ end
615
+
574
616
  #######
575
617
  # Public properties and methods; these are called by end-user and other clients (e.g. generic references)
576
618
 
577
619
  def method_missing(name, *args)
578
620
  selector_type, code = @AS_app_data.reference_by_name[name]
579
- case selector_type
621
+ case selector_type # check if name is a property/element/command name, and if it is handle accordingly
580
622
  when :property
581
623
  return Reference.new(@AS_app_data, @AS_aem_reference.property(code))
582
624
  when :element
583
625
  return Reference.new(@AS_app_data, @AS_aem_reference.elements(code))
584
626
  when :command
585
627
  return _send_command(args, name, code[0], code[1])
586
- else
587
- msg = "Unknown property, element or command: '#{name}'"
588
- if @AS_app_data.reference_by_name.has_key?("#{name}_".intern)
589
- msg += " (Did you mean '#{name}_'?)"
628
+ else
629
+ # see if it's a method that has been added to Object class [presumably] at runtime, but excluded
630
+ # by AE_SafeObject to avoid potential conflicts with property/element/command names
631
+ begin
632
+ # Notes:
633
+ # rb-appscript has to prevent arbitrary methods that are added to Ruby's base Object class
634
+ # by client code from automatically appearing in Appscript::Reference as well, as these new
635
+ # methods may inadvertently mask property/element/command names, causing appscript to
636
+ # behave incorrectly. However, once it is confirmed that a given method will not mask an existing
637
+ # property/element/command name, it can be added retrospectively to the Reference instance
638
+ # upon which it was called, which is what happens here.
639
+ #
640
+ # This means that methods such as #pretty_print and #pretty_inspect, which are
641
+ # injected into Object when the 'pp' module is loaded, will still be available in appscript
642
+ # references, even though they are not on AS_SafeObject's official list of permitted methods,
643
+ # *as long as* properties/elements/commands of the same name do not already exist for that
644
+ # reference.
645
+ #
646
+ # Where properties/elements/commands of the same name do already exist, appscript
647
+ # will still defer to those, of course, and this may cause problems for the caller if
648
+ # they were wanting the other behaviour. (But, that's the risk one runs with any sort
649
+ # of subclassing exercise when the contents of the superclass are not known for certain
650
+ # beforehand.) Clients that require access to these methods will need to add their names
651
+ # to the ReservedKeywords list (see _appscript/reservedkeywords.rb) at runtime, thereby
652
+ # forcing appscript to append underscores to the conflicting property/element/command
653
+ # names in order to disambiguate them, and modifying any code that refers to those
654
+ # properties/elements/commands accordingly.
655
+ meth = Object.instance_method(name)
656
+ rescue NameError # message not handled
657
+ msg = "Unknown property, element or command: '#{name}'"
658
+ if @AS_app_data.reference_by_name.has_key?("#{name}_".intern)
659
+ msg += " (Did you mean '#{name}_'?)"
660
+ end
661
+ raise RuntimeError, msg
590
662
  end
591
- raise RuntimeError, msg
663
+ return meth.bind(self).call(*args)
592
664
  end
593
665
  end
594
666
 
@@ -785,6 +857,8 @@ module Appscript
785
857
  return ref.AS_resolve(@AS_app_data)
786
858
  elsif ref.is_a?(AEMReference::Base)
787
859
  return Reference.new(@AS_app_data, ref)
860
+ elsif ref == nil
861
+ return Reference.new(@AS_app_data, AEM.app)
788
862
  else
789
863
  return Reference.new(@AS_app_data, AEM.custom_root(ref))
790
864
  end
@@ -924,6 +998,6 @@ module Appscript
924
998
  end
925
999
  end
926
1000
 
927
-
928
1001
  ApplicationNotFoundError = FindApp::ApplicationNotFoundError
1002
+ CantLaunchApplicationError = Connect::CantLaunchApplicationError
929
1003
  end
@@ -1485,4 +1485,5 @@ module KAE
1485
1485
  # new in 10.5
1486
1486
  TypeUInt16 = 'ushr'
1487
1487
  TypeUInt64 = 'ucom'
1488
+ TypeCFAbsoluteTime = 'cfat'
1488
1489
  end
@@ -23,18 +23,22 @@ module OSAX
23
23
  OSAXCache = {}
24
24
  OSAXNames = []
25
25
 
26
- se = Appscript.app.by_id('com.apple.systemevents')
27
- [se.system_domain, se.local_domain, se.user_domain].each do |domain|
28
- osaxen = domain.scripting_additions_folder.files[
29
- Appscript.its.file_type.eq('osax').or(Appscript.its.name_extension.eq('osax'))]
30
- osaxen.name.get.zip(osaxen.POSIX_path.get).each do |name, path|
31
- name = name.sub(/(?i)\.osax$/, '') # remove name extension, if any
32
- OSAXNames.push(name)
33
- OSAXCache[name.downcase] = [path, nil]
26
+ se = AEM::Application.by_path(FindApp.by_id('com.apple.systemevents'))
27
+ ['flds', 'fldl', 'fldu'].each do |domain_code|
28
+ osaxen = AEM.app.property(domain_code).property('$scr').elements('file').by_filter(
29
+ AEM.its.property('asty').eq('osax').or(AEM.its.property('extn').eq('osax')))
30
+ if se.event('coredoex', {'----' => osaxen.property('pnam')}).send # domain has ScriptingAdditions folder
31
+ names = se.event('coregetd', {'----' => osaxen.property('pnam')}).send
32
+ paths = se.event('coregetd', {'----' => osaxen.property('posx')}).send
33
+ names.zip(paths).each do |name, path|
34
+ name = name.sub(/(?i)\.osax$/, '') # remove name extension, if any
35
+ OSAXNames.push(name)
36
+ OSAXCache[name.downcase] = [path, nil]
37
+ end
34
38
  end
35
39
  end
36
40
  OSAXNames.sort!.uniq!
37
-
41
+
38
42
  #######
39
43
  # modified AppData class
40
44
 
@@ -122,28 +126,40 @@ module OSAX
122
126
  class ScriptingAddition < Appscript::Reference
123
127
  # Represents a single scripting addition.
124
128
 
125
- def initialize(name, osax_data=nil)
129
+ def initialize(name, terms=nil)
126
130
  # name: string -- a scripting addition's name, e.g. "StandardAdditions";
127
131
  # basically its filename minus the '.osax' suffix
128
132
  #
133
+ # terms : module or nil -- an optional terminology glue module,
134
+ # as exported by Terminology.dump; if given, ScriptingAddition
135
+ # will use this instead of retrieving the terminology dynamically
136
+ #
129
137
  # Note that name is case-insensitive and an '.osax' suffix is ignored if given.
130
138
  @_osax_name = name
131
- if not osax_data
139
+ if not terms
132
140
  osax_name = name.downcase.sub(/(?i)\.osax$/, '')
133
- path, terms = OSAXCache[osax_name]
141
+ path, terminology_tables = OSAXCache[osax_name]
134
142
  if not path
135
143
  raise ArgumentError, "Scripting addition not found: #{name.inspect}"
136
144
  end
137
- if not terms
138
- aetes_desc = AE.get_app_terminology(path) # will raise NotImplementedError in 64-bit processes
145
+ if not terminology_tables
146
+ begin
147
+ aetes_desc = AE.get_app_terminology(path) # will raise NotImplementedError in 64-bit processes
148
+ rescue NotImplementedError
149
+ raise RuntimeError, "OSAX::ScriptingAddition can't dynamically retrieve scripting addition terminology within a 64-bit process."
150
+ end
139
151
  aetes = DefaultCodecs.unpack(aetes_desc.coerce(KAE::TypeAEList))
140
- terms = Terminology.tables_for_aetes(aetes)
141
- OSAXCache[osax_name][1] = terms
152
+ terminology_tables = Terminology.tables_for_aetes(aetes)
153
+ OSAXCache[osax_name][1] = terminology_tables
142
154
  end
143
- @_terms = terms
144
- osax_data = OSAXData.new(:current, nil, @_terms)
155
+ @_terms = terminology_tables
156
+ terms = OSAXData.new(:current, nil, @_terms)
157
+ elsif not terms.is_a?(OSAX::OSAXData) # assume it's a glue module
158
+ terminology_tables = Terminology.tables_for_module(terms)
159
+ @_terms = terminology_tables
160
+ terms = OSAXData.new(:current, nil, @_terms)
145
161
  end
146
- super(osax_data, AEM.app)
162
+ super(terms, AEM.app)
147
163
  end
148
164
 
149
165
  def to_s