infopark_fiona7 0.30.0.2 → 0.70.0.1

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