infopark_fiona7 0.30.0.2 → 0.70.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/fiona7.js +1 -282
  3. data/app/assets/javascripts/fiona7_ui.js +335 -0
  4. data/app/assets/stylesheets/fiona7.css.scss +4 -36
  5. data/app/assets/stylesheets/fiona7_ui.css.scss +39 -0
  6. data/app/controllers/fiona7/blobs_controller.rb +13 -23
  7. data/app/controllers/fiona7/release_controller.rb +1 -0
  8. data/app/controllers/fiona7/sessions_controller.rb +3 -5
  9. data/app/helpers/fiona7_override_helper.rb +6 -2
  10. data/app/models/fiona7/edited_obj.rb +6 -1
  11. data/app/models/fiona7/released_obj.rb +11 -3
  12. data/app/models/fiona7/write_obj.rb +18 -3
  13. data/app/models/fiona7_login_page.rb +3 -0
  14. data/app/views/scrivito/ui/index.html.erb +16 -0
  15. data/config/routes.rb +2 -0
  16. data/infopark_fiona7.gemspec +6 -4
  17. data/lib/fiona7/builder/batch_widget_writer.rb +7 -3
  18. data/lib/fiona7/builder/obj_builder.rb +130 -42
  19. data/lib/fiona7/builder/obj_class_builder.rb +3 -59
  20. data/lib/fiona7/builder/obj_class_updater.rb +7 -44
  21. data/lib/fiona7/builder/obj_updater.rb +25 -7
  22. data/lib/fiona7/builder/widget_builder.rb +24 -0
  23. data/lib/fiona7/builder/widget_building.rb +2 -7
  24. data/lib/fiona7/builder/widget_updater.rb +21 -0
  25. data/lib/fiona7/controllers/content_service/obj_controller.rb +16 -25
  26. data/lib/fiona7/controllers/rest_api/blob_controller.rb +41 -2
  27. data/lib/fiona7/controllers/rest_api/obj_controller.rb +19 -7
  28. data/lib/fiona7/controllers/rest_api/workspace_controller.rb +1 -1
  29. data/lib/fiona7/engine.rb +58 -7
  30. data/lib/fiona7/fiona_connector_patches/basic_obj.rb +46 -0
  31. data/lib/fiona7/initializer.rb +15 -11
  32. data/lib/fiona7/json/obj_decorator.rb +53 -31
  33. data/lib/fiona7/json/reverse_obj_decorator.rb +36 -0
  34. data/lib/fiona7/json/widget_decorator.rb +3 -1
  35. data/lib/fiona7/link_converter/fiona_to_scrivito.rb +45 -13
  36. data/lib/fiona7/link_converter/scrivito_to_fiona.rb +1 -1
  37. data/lib/fiona7/middleware/server_detection_middleware.rb +27 -0
  38. data/lib/fiona7/middleware/table_switching_middleware.rb +33 -0
  39. data/lib/fiona7/mode_switch/cms_routes/scrivito_sdk.rb +5 -11
  40. data/lib/fiona7/mode_switch/composite.rb +2 -4
  41. data/lib/fiona7/naive_search_engine.rb +66 -16
  42. data/lib/fiona7/routers/rest_api.rb +50 -45
  43. data/lib/fiona7/routing_monkey_patch.rb +5 -3
  44. data/lib/fiona7/scrivito_patches/attribute_content.rb +9 -10
  45. data/lib/fiona7/scrivito_patches/attribute_serializer.rb +15 -0
  46. data/lib/fiona7/scrivito_patches/basic_obj.rb +25 -19
  47. data/lib/fiona7/scrivito_patches/basic_widget.rb +4 -0
  48. data/lib/fiona7/scrivito_patches/binary.rb +452 -33
  49. data/lib/fiona7/scrivito_patches/client_config.rb +0 -19
  50. data/lib/fiona7/scrivito_patches/cms_backend.rb +48 -0
  51. data/lib/fiona7/scrivito_patches/cms_field_tag.rb +19 -0
  52. data/lib/fiona7/scrivito_patches/cms_rest_api.rb +20 -3
  53. data/lib/fiona7/scrivito_patches/cms_routing.rb +20 -34
  54. data/lib/fiona7/scrivito_patches/controller_actions.rb +0 -8
  55. data/lib/fiona7/scrivito_patches/migrator.rb +4 -0
  56. data/lib/fiona7/scrivito_patches/objs_controller.rb +18 -0
  57. data/lib/fiona7/scrivito_patches/type_computer.rb +12 -12
  58. data/lib/fiona7/scrivito_patches/webservice_controller.rb +21 -0
  59. data/lib/fiona7/scrivito_patches/workspace.rb +8 -5
  60. data/lib/fiona7/shadow_classes.rb +74 -0
  61. data/lib/fiona7/table_switcher.rb +39 -0
  62. data/lib/fiona7/type_loader.rb +63 -0
  63. data/lib/fiona7/type_register.rb +170 -89
  64. data/lib/fiona7/type_synchronizer.rb +68 -0
  65. data/lib/fiona7/version.rb +1 -1
  66. data/lib/fiona7/version_helper.rb +35 -54
  67. data/lib/fiona7/widget_resolver.rb +1 -1
  68. data/lib/tasks/fiona7_tasks.rake +0 -8
  69. metadata +57 -18
  70. data/lib/fiona7/controllers/rest_api/obj_class_controller.rb +0 -39
  71. data/lib/fiona7/json/obj_class_decorator.rb +0 -45
  72. data/lib/fiona7/mode_switch/constants.rb +0 -86
  73. data/lib/fiona7/type_register_mixin.rb +0 -9
@@ -0,0 +1,63 @@
1
+ module Fiona7
2
+ class TypeLoader
3
+ class AttributeTypeHelper
4
+ attr_accessor :cms_attribute
5
+
6
+ def initialize(cms_attribute)
7
+ self.cms_attribute = cms_attribute
8
+ end
9
+
10
+ def real_type
11
+ self.cms_attribute.attribute_type
12
+ end
13
+
14
+ def virtual_type
15
+ ::JSON.parse(cms_attribute.help_text(:de))['type'].to_sym rescue nil
16
+ end
17
+ end
18
+
19
+ attr_reader :obj_class, :rc_obj_class
20
+
21
+ def initialize(obj_class)
22
+ self.obj_class = obj_class
23
+ self.name_aliaser = TypeRegister::NameAliaser.new(virtual: obj_class)
24
+ self.rc_obj_class = RailsConnector::Meta::EagerLoader.instance.obj_class(self.name_aliaser.real_obj_class)
25
+
26
+ end
27
+
28
+ def load(type_definition)
29
+ #puts "loading #{obj_class}"
30
+ if Fiona7.mode == :legacy
31
+ type_definition.add_attr('title', :string, 'title', :string)
32
+ if self.rc_obj_class.obj_type == 'publication' || self.rc_obj_class.obj_type == 'document'
33
+ type_definition.add_attr('body', :html, 'body', :html)
34
+ elsif self.rc_obj_class.obj_type == 'image' || self.rc_obj_class.obj_type == 'generic'
35
+ type_definition.add_attr('blob', :binary, 'blob', :binary)
36
+ end
37
+ end
38
+
39
+ self.rc_obj_class.custom_attributes.each do |real_name, cms_attribute|
40
+ next if real_name == 'X_widget_pool'
41
+
42
+ # TODO: move this to a better place
43
+ if Fiona7.mode == :standalone
44
+ virtual_name = real_name.sub("s_#{self.rc_obj_class.name}__", "")
45
+ else
46
+ virtual_name = real_name
47
+ end
48
+
49
+ type_helper = AttributeTypeHelper.new(cms_attribute)
50
+ real_type = type_helper.real_type
51
+ virtual_type = type_helper.virtual_type || real_type
52
+ values = cms_attribute.values
53
+
54
+ type_definition.add_attr(virtual_name, virtual_type, real_name, real_type, values)
55
+ end
56
+ end
57
+
58
+ protected
59
+ attr_accessor :name_aliaser
60
+ attr_writer :obj_class, :rc_obj_class
61
+
62
+ end
63
+ end
@@ -1,140 +1,221 @@
1
1
  require 'set'
2
+ require 'singleton'
3
+ require 'fiona7/type_loader'
4
+ require 'fiona7/type_synchronizer'
2
5
 
3
6
  module Fiona7
4
7
  class TypeRegister
8
+ include Singleton
9
+
5
10
  TYPE_MAP = {
6
11
  link: :linklist,
7
12
  reference: :linklist,
8
13
  referencelist: :linklist,
9
- widget: :linklist,
10
- binary: :linklist
11
- }
12
-
13
- class << self
14
- def instance
15
- self.new
14
+ widgetlist: :linklist,
15
+ binary: :linklist,
16
+ stringlist: :text
17
+ }.freeze
18
+
19
+ class NameAliaser
20
+ attr_accessor :virtual_obj_class, :real_obj_class
21
+
22
+ def initialize(input={})
23
+ if input[:virtual]
24
+ self.virtual_obj_class = input[:virtual]
25
+ self.real_obj_class = input[:virtual].gsub('::', '__')
26
+ elsif input[:real]
27
+ self.real_obj_class = input[:real]
28
+ self.virtual_obj_class = input[:real].gsub('__','::')
29
+ else
30
+ raise "Invalid input for NameAliaser"
31
+ end
16
32
  end
17
33
  end
34
+ class TypeDefinition
35
+ class Attribute < Struct.new(:name, :type, :real_name, :real_type, :values)
36
+ class Core < Struct.new(:name, :type)
37
+ end
18
38
 
19
- class ObjClass < Struct.new('ObjClass', :name, :type, :attributes)
20
- end
21
-
22
- class Attribute < Struct.new(:real_name, :virtual_name, :real_type, :virtual_type, :values)
23
- end
39
+ def eql?(other)
40
+ other.kind_of?(self.class) &&
41
+ self.name.eql?(other.name)
42
+ #Core.new(self.name, self.type).eql?(Core.new(other.name, other.type))
43
+ end
24
44
 
25
- def cached_type(obj_class_name)
26
- @@cached_type ||= {}
27
- @@cached_type[obj_class_name.to_s] ||= ObjClass.new.tap do |obj_class|
28
- cms_class = RailsConnector::ObjClass.find_by_obj_class_name(obj_class_name)
29
- obj_class.name = cms_class.name
30
- obj_class.type = cms_class.obj_type
45
+ def hash
46
+ return self.name.hash
47
+ #Core.new(self.name, self.type).hash
48
+ end
49
+ end
31
50
 
32
- attributes = Set.new
33
- cms_class.custom_attributes.each do |real_name, cms_attribute|
34
- real_name = real_name.to_sym
51
+ attr_accessor :name
52
+ attr_accessor :attrs
53
+ attr_accessor :aliaser
35
54
 
36
- next if real_name == :X_widget_pool
55
+ def initialize(name)
56
+ self.name = name
57
+ self.attrs = Set.new
58
+ self.aliaser = NameAliaser.new(virtual: name)
59
+ end
37
60
 
38
- if Fiona7.mode == :standalone
39
- virtual_name = real_name.to_s.sub(/^s_#{Regexp.escape obj_class_name}__/, '').to_sym
40
- elsif Fiona7.mode == :legacy
41
- # X_blob simulates blob attribute
42
- if real_name == :X_blob
43
- virtual_name = :blob
44
- else
45
- virtual_name = real_name.to_sym
46
- end
47
- else
48
- raise "Invalid Fiona7.mode = #{Fiona7.mode}"
49
- end
61
+ def real_name
62
+ self.aliaser.real_obj_class
63
+ end
50
64
 
51
- real_type = cms_attribute.attribute_type.to_sym
52
- virtual_type = ::JSON.parse(cms_attribute.help_text(:de))['type'].to_sym rescue nil
53
- virtual_type ||= real_type
65
+ def virtual_name
66
+ self.aliaser.virtual_obj_class
67
+ end
54
68
 
55
- # real_type = virtual_type in this case
56
- if [:enum, :multienum].include?(real_type)
57
- values = cms_attribute.values
58
- else
59
- values = nil
60
- end
69
+ def add_attr(name, type, real_name=nil, real_type=nil, values=nil)
70
+ real_type ||= TYPE_MAP[type.to_sym] || type
71
+ # TODO: move this to a better place
72
+ if Fiona7.mode == :standalone
73
+ real_name ||= "s_#{self.real_name}__#{name}"
74
+ else
75
+ real_name ||= name
76
+ end
77
+ self.attrs << Attribute.new(name.to_s, type.to_sym, real_name.to_s, real_type.to_sym, values)
78
+ end
61
79
 
62
- attributes << Attribute.new(real_name, virtual_name, real_type, virtual_type, values)
80
+ def find_attribute(name)
81
+ name = name.to_s
82
+ self.attrs.find do |attr|
83
+ attr.name == name
63
84
  end
85
+ end
64
86
 
65
- if Fiona7.mode == :legacy
66
- # include built-in title and body
67
- attributes << Attribute.new(:title, :title, :string, :string, nil)
68
- if cms_class.obj_type != "image" && cms_class.obj_type != "generic"
69
- attributes << Attribute.new(:body, :body, :html, :html, nil)
87
+ # TODO: conflict handling for type errors
88
+ def merge(other_definition)
89
+ other_definition.attrs.each do |other_attr|
90
+ if !self.attrs.include?(other_attr)
91
+ self.attrs << other_attr
70
92
  end
71
93
  end
94
+ self
95
+ end
96
+ end
97
+ class AdHocTypeDefinition
98
+ attr_accessor :values, :obj_class
99
+ def initialize(values, obj_class=nil)
100
+ self.values = values
101
+ self.obj_class = obj_class || values.delete(:_obj_class)
102
+ end
72
103
 
73
- obj_class.attributes = attributes.to_a
104
+ def type_definition
105
+ type_definition = TypeDefinition.new(self.obj_class)
106
+ pp values
107
+ values.each do |name, possible_pair|
108
+ next if name =~ /\A_/ # built-in attribute
109
+ next unless possible_pair.kind_of?(Array) && possible_pair.length == 2
110
+
111
+ type, _ = *possible_pair
112
+ type_definition.add_attr(name, type)
113
+ end
114
+ type_definition
74
115
  end
75
116
  end
117
+ attr_accessor :cms_defs
118
+ attr_accessor :usr_defs
76
119
 
77
- def invalidate_cached_type(obj_class_name)
78
- @@cached_type.delete(obj_class_name.to_s)
79
- # clear reactor cache as well
80
- RailsConnector::Meta::EagerLoader.instance.forget_obj_class(obj_class_name)
120
+ def initialize
121
+ self.cms_defs = {}
122
+ self.usr_defs = {}
81
123
  end
82
124
 
83
- def annotated_attributes(obj_class_name)
84
- obj_class = cached_type(obj_class_name)
85
- raise "Unknown obj_class: #{obj_class_name}" unless obj_class
86
- obj_class.attributes
125
+ def read?(obj_class)
126
+ self.cms_def_present?(obj_class)
87
127
  end
88
128
 
89
- def attributes(obj_class_name)
90
- raise "Deprecated"
129
+ def write?(obj_class)
130
+ true &&
131
+ self.usr_def_present?(obj_class) &&
132
+ self.cms_def_present?(obj_class) &&
133
+ self.defs_compatible?(self.cms_defs[obj_class], self.usr_defs[obj_class])
91
134
  end
92
135
 
93
- def obj_type(obj_class_name)
94
- self.cached_type(obj_class_name).type
136
+ def read_mangled(obj_class)
137
+ read(NameAliaser.new(real: obj_class).virtual_obj_class)
95
138
  end
96
139
 
97
- def attribute_type(obj_class_name, attribute_name)
98
- attribute = self.cached_type(obj_class_name).attributes.find {|a| a.virtual_name.to_s == attribute_name.to_s }
140
+ def read(obj_class)
141
+ if !self.read?(obj_class)
142
+ self.load(obj_class)
143
+ end
144
+ self.cms_defs[obj_class]
145
+ end
99
146
 
100
- if attribute
101
- attribute.virtual_type
102
- else
103
- raise "unknown attribute: #{attribute_name} in #{obj_class_name}"
147
+ def write(obj_class)
148
+ if !self.write?(obj_class)
149
+ self.synchronize(obj_class)
150
+ self.load(obj_class)
104
151
  end
152
+ self.cms_defs[obj_class]
105
153
  end
106
154
 
107
- def real_attribute_name(obj_class_name, attribute_name)
108
- if Fiona7.mode == :standalone
109
- :"s_#{obj_class_name}__#{attribute_name}"
110
- elsif Fiona7.mode == :legacy
111
- # blob attribute is always mapped to X_blob attribute if present
112
- if attribute_name.to_sym == :blob
113
- :X_blob
114
- else
115
- attribute_name.to_sym
116
- end
155
+ def add_usr_attr(obj_class, name, type, values=nil)
156
+ self.usr_defs[obj_class] ||= TypeDefinition.new(obj_class)
157
+ self.usr_defs[obj_class].add_attr(name, type, nil, nil, values)
158
+ end
159
+
160
+ def ad_hoc_synchronize(type_definition)
161
+ puts "Ad hoc synchronize of #{type_definition.name}"
162
+ obj_class = type_definition.name
163
+
164
+ existing_definition = self.usr_defs[obj_class]
165
+ if existing_definition
166
+ type_definition = existing_definition.merge(type_definition)
117
167
  else
118
- raise "Invalid Fiona7.mode = #{Fiona7.mode}"
168
+ self.usr_defs[obj_class] = type_definition
119
169
  end
170
+
171
+ return if true &&
172
+ self.cms_def_present?(obj_class) &&
173
+ defs_compatible?(self.cms_defs[obj_class], type_definition)
174
+
175
+ puts "Ad hoc synchronization required of #{type_definition.name}"
176
+
177
+ self.synchronize(obj_class)
178
+ self.load(obj_class)
179
+ end
180
+
181
+ protected
182
+ def usr_def_present?(obj_class)
183
+ self.usr_defs[obj_class].present?
120
184
  end
121
185
 
122
- def virtual_attribute_name(obj_class_name, attribute_name)
123
- attribute_name.to_s.sub("s_#{obj_class_name}__", '').to_sym
186
+ def cms_def_present?(obj_class)
187
+ self.cms_defs[obj_class].present?
124
188
  end
125
189
 
126
- def attribute_real_type(obj_class_name, attribute_name)
127
- attribute = self.cached_type(obj_class_name).attributes.find {|a| a.virtual_name.to_s == attribute_name.to_s }
190
+ def defs_compatible?(cms_def, usr_def)
191
+ cms_attr_map = {}
192
+ cms_def.attrs.each do |attr|
193
+ cms_attr_map[attr.name] = attr
194
+ end
128
195
 
129
- if attribute
130
- attribute.real_type
131
- else
132
- raise "unknown attribute: #{attribute_name} in #{obj_class_name}"
196
+ usr_def.attrs.each do |attr|
197
+ return false if !cms_attr_map[attr.name]
198
+ return false if attr.type != cms_attr_map[attr.name].type
133
199
  end
200
+
201
+ return true
134
202
  end
135
203
 
136
- def map_virtual_to_real_type(virtual_type)
137
- TYPE_MAP[virtual_type.to_sym] || virtual_type.to_sym
204
+ def load(obj_class)
205
+ type_loader = TypeLoader.new(obj_class)
206
+ type_definition = TypeDefinition.new(obj_class)
207
+
208
+ type_loader.load(type_definition)
209
+ self.cms_defs[obj_class] = type_definition
210
+ end
211
+
212
+ def synchronize(obj_class)
213
+ type_definition = self.usr_defs[obj_class]
214
+ if type_definition.nil?
215
+ raise "type definition for #{obj_class} missing, unable to synchronize"
216
+ end
217
+ type_synchronizer = TypeSynchronizer.new(type_definition)
218
+ type_synchronizer.synchronize
138
219
  end
139
220
  end
140
221
  end
@@ -0,0 +1,68 @@
1
+ require 'fiona7/builder/obj_class_builder'
2
+ require 'fiona7/builder/obj_class_updater'
3
+
4
+ module Fiona7
5
+ class TypeSynchronizer
6
+ attr_reader :type_definition, :name_aliaser
7
+
8
+ def initialize(type_definition)
9
+ self.type_definition = type_definition
10
+ self.name_aliaser = TypeRegister::NameAliaser.new(virtual: type_definition.name)
11
+ end
12
+
13
+ def synchronize
14
+ return if skip_this_class?
15
+
16
+ Reactor::Sudo.su(Fiona7.root) do
17
+ if RailsConnector::ObjClass.exists?(:obj_class_name => self.name_aliaser.real_obj_class)
18
+ Fiona7::Builder::ObjClassUpdater.new(self.builder_values).build
19
+ else
20
+ Fiona7::Builder::ObjClassBuilder.new(self.builder_values).build
21
+ end
22
+
23
+ RailsConnector::Meta::EagerLoader.instance.forget_obj_class(self.name_aliaser.real_obj_class)
24
+ end
25
+ end
26
+
27
+ protected
28
+ attr_writer :type_definition, :name_aliaser
29
+
30
+ def skip_this_class?
31
+ case self.type_definition.name
32
+ when 'Scrivito::BasicWidget', 'Scrivito::BasicObj', 'Obj', 'Scrivito::Obj'
33
+ true
34
+ else
35
+ false
36
+ end
37
+ end
38
+
39
+ def builder_values
40
+ {
41
+ name: self.name_aliaser.real_obj_class,
42
+ attributes: self.builder_attributes
43
+ }
44
+ end
45
+
46
+ def builder_attributes
47
+ self.type_definition.attrs.map do |attribute_definition|
48
+ next if ['title', 'body'].include?(attribute_definition.real_name)
49
+
50
+ desc = {
51
+ real_name: attribute_definition.real_name,
52
+ real_type: attribute_definition.real_type,
53
+ name: attribute_definition.name,
54
+ type: attribute_definition.type
55
+ }
56
+
57
+ # this workaround is needed, because attribute_definition.values
58
+ # always returns a valid value, be it an empty array
59
+ case attribute_definition.type
60
+ when :enum, :multienum
61
+ desc[:values] = attribute_definition.values
62
+ end
63
+
64
+ desc
65
+ end.compact
66
+ end
67
+ end
68
+ end
@@ -1,3 +1,3 @@
1
1
  module Fiona7
2
- VERSION = "0.30.0.2"
2
+ VERSION = "0.70.0.1"
3
3
  end