infopark_rails_connector_meta 1.5.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.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/LICENSE +165 -0
- data/Rakefile +30 -0
- data/infopark_rails_connector_meta.gemspec +27 -0
- data/lib/meta.rb +8 -0
- data/lib/meta/attribute.rb +93 -0
- data/lib/meta/base.rb +145 -0
- data/lib/meta/blob_mapping.rb +11 -0
- data/lib/meta/content.rb +11 -0
- data/lib/meta/eager_loader.rb +40 -0
- data/lib/meta/obj_class.rb +132 -0
- data/lib/meta/object_with_meta_data.rb +17 -0
- data/lib/meta/version.rb +5 -0
- data/spec/infopark_rails_connector_meta_spec.rb +90 -0
- data/spec/spec_helper.rb +15 -0
- metadata +159 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
GNU LESSER GENERAL PUBLIC LICENSE
|
2
|
+
Version 3, 29 June 2007
|
3
|
+
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
6
|
+
of this license document, but changing it is not allowed.
|
7
|
+
|
8
|
+
|
9
|
+
This version of the GNU Lesser General Public License incorporates
|
10
|
+
the terms and conditions of version 3 of the GNU General Public
|
11
|
+
License, supplemented by the additional permissions listed below.
|
12
|
+
|
13
|
+
0. Additional Definitions.
|
14
|
+
|
15
|
+
As used herein, "this License" refers to version 3 of the GNU Lesser
|
16
|
+
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
17
|
+
General Public License.
|
18
|
+
|
19
|
+
"The Library" refers to a covered work governed by this License,
|
20
|
+
other than an Application or a Combined Work as defined below.
|
21
|
+
|
22
|
+
An "Application" is any work that makes use of an interface provided
|
23
|
+
by the Library, but which is not otherwise based on the Library.
|
24
|
+
Defining a subclass of a class defined by the Library is deemed a mode
|
25
|
+
of using an interface provided by the Library.
|
26
|
+
|
27
|
+
A "Combined Work" is a work produced by combining or linking an
|
28
|
+
Application with the Library. The particular version of the Library
|
29
|
+
with which the Combined Work was made is also called the "Linked
|
30
|
+
Version".
|
31
|
+
|
32
|
+
The "Minimal Corresponding Source" for a Combined Work means the
|
33
|
+
Corresponding Source for the Combined Work, excluding any source code
|
34
|
+
for portions of the Combined Work that, considered in isolation, are
|
35
|
+
based on the Application, and not on the Linked Version.
|
36
|
+
|
37
|
+
The "Corresponding Application Code" for a Combined Work means the
|
38
|
+
object code and/or source code for the Application, including any data
|
39
|
+
and utility programs needed for reproducing the Combined Work from the
|
40
|
+
Application, but excluding the System Libraries of the Combined Work.
|
41
|
+
|
42
|
+
1. Exception to Section 3 of the GNU GPL.
|
43
|
+
|
44
|
+
You may convey a covered work under sections 3 and 4 of this License
|
45
|
+
without being bound by section 3 of the GNU GPL.
|
46
|
+
|
47
|
+
2. Conveying Modified Versions.
|
48
|
+
|
49
|
+
If you modify a copy of the Library, and, in your modifications, a
|
50
|
+
facility refers to a function or data to be supplied by an Application
|
51
|
+
that uses the facility (other than as an argument passed when the
|
52
|
+
facility is invoked), then you may convey a copy of the modified
|
53
|
+
version:
|
54
|
+
|
55
|
+
a) under this License, provided that you make a good faith effort to
|
56
|
+
ensure that, in the event an Application does not supply the
|
57
|
+
function or data, the facility still operates, and performs
|
58
|
+
whatever part of its purpose remains meaningful, or
|
59
|
+
|
60
|
+
b) under the GNU GPL, with none of the additional permissions of
|
61
|
+
this License applicable to that copy.
|
62
|
+
|
63
|
+
3. Object Code Incorporating Material from Library Header Files.
|
64
|
+
|
65
|
+
The object code form of an Application may incorporate material from
|
66
|
+
a header file that is part of the Library. You may convey such object
|
67
|
+
code under terms of your choice, provided that, if the incorporated
|
68
|
+
material is not limited to numerical parameters, data structure
|
69
|
+
layouts and accessors, or small macros, inline functions and templates
|
70
|
+
(ten or fewer lines in length), you do both of the following:
|
71
|
+
|
72
|
+
a) Give prominent notice with each copy of the object code that the
|
73
|
+
Library is used in it and that the Library and its use are
|
74
|
+
covered by this License.
|
75
|
+
|
76
|
+
b) Accompany the object code with a copy of the GNU GPL and this license
|
77
|
+
document.
|
78
|
+
|
79
|
+
4. Combined Works.
|
80
|
+
|
81
|
+
You may convey a Combined Work under terms of your choice that,
|
82
|
+
taken together, effectively do not restrict modification of the
|
83
|
+
portions of the Library contained in the Combined Work and reverse
|
84
|
+
engineering for debugging such modifications, if you also do each of
|
85
|
+
the following:
|
86
|
+
|
87
|
+
a) Give prominent notice with each copy of the Combined Work that
|
88
|
+
the Library is used in it and that the Library and its use are
|
89
|
+
covered by this License.
|
90
|
+
|
91
|
+
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
92
|
+
document.
|
93
|
+
|
94
|
+
c) For a Combined Work that displays copyright notices during
|
95
|
+
execution, include the copyright notice for the Library among
|
96
|
+
these notices, as well as a reference directing the user to the
|
97
|
+
copies of the GNU GPL and this license document.
|
98
|
+
|
99
|
+
d) Do one of the following:
|
100
|
+
|
101
|
+
0) Convey the Minimal Corresponding Source under the terms of this
|
102
|
+
License, and the Corresponding Application Code in a form
|
103
|
+
suitable for, and under terms that permit, the user to
|
104
|
+
recombine or relink the Application with a modified version of
|
105
|
+
the Linked Version to produce a modified Combined Work, in the
|
106
|
+
manner specified by section 6 of the GNU GPL for conveying
|
107
|
+
Corresponding Source.
|
108
|
+
|
109
|
+
1) Use a suitable shared library mechanism for linking with the
|
110
|
+
Library. A suitable mechanism is one that (a) uses at run time
|
111
|
+
a copy of the Library already present on the user's computer
|
112
|
+
system, and (b) will operate properly with a modified version
|
113
|
+
of the Library that is interface-compatible with the Linked
|
114
|
+
Version.
|
115
|
+
|
116
|
+
e) Provide Installation Information, but only if you would otherwise
|
117
|
+
be required to provide such information under section 6 of the
|
118
|
+
GNU GPL, and only to the extent that such information is
|
119
|
+
necessary to install and execute a modified version of the
|
120
|
+
Combined Work produced by recombining or relinking the
|
121
|
+
Application with a modified version of the Linked Version. (If
|
122
|
+
you use option 4d0, the Installation Information must accompany
|
123
|
+
the Minimal Corresponding Source and Corresponding Application
|
124
|
+
Code. If you use option 4d1, you must provide the Installation
|
125
|
+
Information in the manner specified by section 6 of the GNU GPL
|
126
|
+
for conveying Corresponding Source.)
|
127
|
+
|
128
|
+
5. Combined Libraries.
|
129
|
+
|
130
|
+
You may place library facilities that are a work based on the
|
131
|
+
Library side by side in a single library together with other library
|
132
|
+
facilities that are not Applications and are not covered by this
|
133
|
+
License, and convey such a combined library under terms of your
|
134
|
+
choice, if you do both of the following:
|
135
|
+
|
136
|
+
a) Accompany the combined library with a copy of the same work based
|
137
|
+
on the Library, uncombined with any other library facilities,
|
138
|
+
conveyed under the terms of this License.
|
139
|
+
|
140
|
+
b) Give prominent notice with the combined library that part of it
|
141
|
+
is a work based on the Library, and explaining where to find the
|
142
|
+
accompanying uncombined form of the same work.
|
143
|
+
|
144
|
+
6. Revised Versions of the GNU Lesser General Public License.
|
145
|
+
|
146
|
+
The Free Software Foundation may publish revised and/or new versions
|
147
|
+
of the GNU Lesser General Public License from time to time. Such new
|
148
|
+
versions will be similar in spirit to the present version, but may
|
149
|
+
differ in detail to address new problems or concerns.
|
150
|
+
|
151
|
+
Each version is given a distinguishing version number. If the
|
152
|
+
Library as you received it specifies that a certain numbered version
|
153
|
+
of the GNU Lesser General Public License "or any later version"
|
154
|
+
applies to it, you have the option of following the terms and
|
155
|
+
conditions either of that published version or of any later version
|
156
|
+
published by the Free Software Foundation. If the Library as you
|
157
|
+
received it does not specify a version number of the GNU Lesser
|
158
|
+
General Public License, you may choose any version of the GNU Lesser
|
159
|
+
General Public License ever published by the Free Software Foundation.
|
160
|
+
|
161
|
+
If the Library as you received it specifies that a proxy can decide
|
162
|
+
whether future versions of the GNU Lesser General Public License shall
|
163
|
+
apply, that proxy's public statement of acceptance of any version is
|
164
|
+
permanent authorization for you to choose that version for the
|
165
|
+
Library.
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
task(:release).clear_prerequisites.clear_actions
|
4
|
+
task :release do
|
5
|
+
raise "Don't push me to rubygems.org!"
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
require 'rspec/core'
|
10
|
+
require 'rspec/core/rake_task'
|
11
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
12
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
# remove this task, when this gem is distributed as a `real` gem (and not included in Gemfile through `:path =>` )
|
17
|
+
task :update_gemspec_for_distribution do
|
18
|
+
|
19
|
+
fn = Dir[File.expand_path('../*.gemspec', __FILE__)].first
|
20
|
+
source_gemspec = File.read(fn)
|
21
|
+
|
22
|
+
source_gemspec.gsub!(/^([\t ]*)((s.files\s*=)[^\n]+\n)/m) {|s| "#{$1}##{$2}#{$1}#{$3} #{`git ls-files`.split("\n").inspect}\n"}
|
23
|
+
source_gemspec.gsub!(/^([\t ]*)((s.test_files\s*=)[^\n]+\n)/m) {|s| "#{$1}##{$2}#{$1}#{$3} #{`git ls-files -- {test,spec,features}/*`.split("\n").inspect}\n"}
|
24
|
+
source_gemspec.gsub!(/^([\t ]*)((s.executables\s*=)[^\n]+\n)/m) {|s| "#{$1}##{$2}#{$1}#{$3} #{`git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }.inspect}\n"}
|
25
|
+
|
26
|
+
File.open("#{fn}.resolved", 'w') do |f|
|
27
|
+
f.write source_gemspec
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "meta/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "infopark_rails_connector_meta"
|
7
|
+
s.version = RailsConnector::Meta::VERSION
|
8
|
+
s.authors = ["Tomasz Przedmojski"]
|
9
|
+
s.email = ["tomasz.przedmojski@infopark.de"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %Q{Meta Information on CMS Objects}
|
12
|
+
s.description = %Q{Gives RailsConnector Objs information about its CMS class, attributes, etc.}
|
13
|
+
s.license = 'LGPL-3'
|
14
|
+
|
15
|
+
#s.rubyforge_project = "infopark_rails_connector_meta"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
|
24
|
+
s.add_runtime_dependency "activerecord", '>= 3.0.10', '<= 3.2.9'
|
25
|
+
s.add_runtime_dependency "activesupport", '>= 3.0.10', '<= 3.2.9'
|
26
|
+
s.add_runtime_dependency "infopark_rails_connector"
|
27
|
+
end
|
data/lib/meta.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
|
3
|
+
# The methods date?, enum?, html?, linklist?, markdown?, multienum?, string? and
|
4
|
+
# text? are created by meta programming have no documentation of their own.
|
5
|
+
# Warning: Dependent on the setup of your DB replication, most tables
|
6
|
+
# with meta information will not be available on your live system!
|
7
|
+
class Attribute < RailsConnector::InfoparkBase
|
8
|
+
|
9
|
+
# The possible types of an attribute.
|
10
|
+
TYPES = %w{date enum html linklist markdown multienum string text}
|
11
|
+
|
12
|
+
self.primary_key = :attribute_id
|
13
|
+
|
14
|
+
has_and_belongs_to_many :obj_class_definitions, :class_name => '::RailsConnector::ObjClass',
|
15
|
+
:join_table => "#{table_name_prefix}obj_class_attrs"
|
16
|
+
|
17
|
+
alias_method :obj_class_defs, :obj_class_definitions
|
18
|
+
alias_attribute :name, :attribute_name
|
19
|
+
|
20
|
+
# The (human readable) title.
|
21
|
+
def title(language = :de)
|
22
|
+
load_blob_data
|
23
|
+
@blob_data['titles'].presence && @blob_data['titles'][language.to_s]
|
24
|
+
end
|
25
|
+
|
26
|
+
# The description of the attribute.
|
27
|
+
def help_text(language = :de)
|
28
|
+
load_blob_data
|
29
|
+
@blob_data['helpTexts'].presence && @blob_data['helpTexts'][language.to_s]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Searchable in Content Manager.
|
33
|
+
def searchable_in_cm?
|
34
|
+
load_blob_data
|
35
|
+
@blob_data['isSearchableInCM'].to_i != 0
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns the possible values if attribute is of type `enum' or `multienum'.
|
39
|
+
def values
|
40
|
+
load_blob_data
|
41
|
+
@blob_data['values']
|
42
|
+
end
|
43
|
+
|
44
|
+
def max_size
|
45
|
+
load_blob_data
|
46
|
+
@blob_data["maxSize"]
|
47
|
+
end
|
48
|
+
|
49
|
+
def min_size
|
50
|
+
load_blob_data
|
51
|
+
@blob_data["minSize"]
|
52
|
+
end
|
53
|
+
|
54
|
+
TYPES.each do |type|
|
55
|
+
self.class_eval <<EOM, __FILE__, __LINE__ + 1
|
56
|
+
def #{type}?
|
57
|
+
self.attribute_type == "#{type}"
|
58
|
+
end
|
59
|
+
EOM
|
60
|
+
end
|
61
|
+
|
62
|
+
# Convenience method for find_by_attribute_name
|
63
|
+
def self.find_by_name(*args)
|
64
|
+
self.find_by_attribute_name(*args)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the blob as a JSON object.
|
68
|
+
def self.read_blob_data(name) #:nodoc:
|
69
|
+
blob = RailsConnector::Meta.hello_im_rails_and_im_retarted_so_please_be_patient do # these queries really pollute our logs!
|
70
|
+
blob_name = if RailsConnector::BlobMapping.exists?
|
71
|
+
RailsConnector::BlobMapping.get_fingerprint("#{name}.jsonAttributeDict")
|
72
|
+
else
|
73
|
+
"#{name}.jsonAttributeDict"
|
74
|
+
end
|
75
|
+
|
76
|
+
RailsConnector::Blob.find_without_excluded_blob_data(blob_name)
|
77
|
+
end
|
78
|
+
|
79
|
+
return {} unless blob && blob.blob_data?
|
80
|
+
|
81
|
+
JSON.parse(blob.blob_data)
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
# load attribute details from blob
|
87
|
+
def load_blob_data #:nodoc:
|
88
|
+
@blob_data ||= self.class.read_blob_data(self.attribute_name)
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
data/lib/meta/base.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'meta/eager_loader'
|
2
|
+
|
3
|
+
module RailsConnector
|
4
|
+
|
5
|
+
module Meta
|
6
|
+
|
7
|
+
# This method is an equivalent of Rails.logger.silence, which has been deprecated
|
8
|
+
def self.hello_im_rails_and_im_retarted_so_please_be_patient(&block)
|
9
|
+
begin
|
10
|
+
old_logger_level, Rails.logger.level = Rails.logger.level, Logger::ERROR
|
11
|
+
yield self
|
12
|
+
ensure
|
13
|
+
Rails.logger.level = old_logger_level
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.included(base) #:nodoc:
|
18
|
+
# Class enhancements
|
19
|
+
base.extend(ClassMethods)
|
20
|
+
end
|
21
|
+
|
22
|
+
# The RailsConnector::ObjClass object for this file format.
|
23
|
+
# This will always return a proper object, even if no custom
|
24
|
+
# Ruby class exists.
|
25
|
+
def obj_class_definition
|
26
|
+
@obj_class_definition ||= RailsConnector::Meta::EagerLoader.instance.obj_class(self.obj_class)
|
27
|
+
end
|
28
|
+
alias_method :obj_class_def, :obj_class_definition
|
29
|
+
|
30
|
+
# Returns true, if there is a custom Ruby class defined for the object
|
31
|
+
# or false, if it is represented by RailsConnector::Obj
|
32
|
+
def has_custom_ruby_class?
|
33
|
+
self.class.is_custom_ruby_class?
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the custom attributes in the form of a Hash.
|
37
|
+
def custom_attributes
|
38
|
+
self.obj_class_definition.custom_attributes
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns true, if the file format has an attribute of the given name.
|
42
|
+
def custom_attribute?(attr)
|
43
|
+
self.obj_class_definition.custom_attribute?(attr)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns an Array of String of all mandatory attributes, no mather if it's
|
47
|
+
# custom or built-in. Built-in attributes are underscored (valid_from,
|
48
|
+
# not validFrom).
|
49
|
+
# Possible +options+ are:
|
50
|
+
# <tt>:only_custom_attributes</tt>:: Return only custom attributes, omit
|
51
|
+
# built-in attributes like content_type or valid_from.
|
52
|
+
def mandatory_attribute_names(options = {})
|
53
|
+
self.obj_class_definition.mandatory_attribute_names(options)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns true, if the file format has an mandatory attribute of the given name.
|
57
|
+
def mandatory_attribute?(attr)
|
58
|
+
self.obj_class_definition.mandatory_attribute?(attr)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the version of this object. This number is increased every time
|
62
|
+
# this object is released.
|
63
|
+
def version
|
64
|
+
load_meta_details
|
65
|
+
@object_with_meta_data.version.presence.to_i || 0
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the time of the reminder, if it is set.
|
69
|
+
def reminder_from
|
70
|
+
load_meta_details
|
71
|
+
@object_with_meta_data.reminder_from.presence &&
|
72
|
+
::RailsConnector::DateAttribute.parse(@object_with_meta_data.reminder_from)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the reminder comment, if a reminder is set.
|
76
|
+
def reminder_comment
|
77
|
+
load_meta_details
|
78
|
+
@object_with_meta_data.reminder_comment
|
79
|
+
end
|
80
|
+
|
81
|
+
# Return the name of the workflow, that is assigned to this object.
|
82
|
+
def workflow_name
|
83
|
+
load_meta_details
|
84
|
+
@object_with_meta_data.workflow_name
|
85
|
+
end
|
86
|
+
|
87
|
+
# Return the current editor as a String. If there is no edited content,
|
88
|
+
# which is always the case in live mode, an empty String is returned.
|
89
|
+
# The 'contents' table is queried for this information.
|
90
|
+
def editor
|
91
|
+
return @editor if @editor
|
92
|
+
|
93
|
+
load_meta_details
|
94
|
+
|
95
|
+
content_id = if self.edited?
|
96
|
+
@object_with_meta_data.edited_content_id
|
97
|
+
else
|
98
|
+
@object_with_meta_data.released_cont_id
|
99
|
+
end
|
100
|
+
|
101
|
+
if content_id
|
102
|
+
content = RailsConnector::Content.find(content_id)
|
103
|
+
@editor = content.editor
|
104
|
+
else
|
105
|
+
@editor = ''
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
# Load the objects details from the `objects' tables.
|
112
|
+
def load_meta_details #:nodoc:
|
113
|
+
return if @object_with_meta_data
|
114
|
+
|
115
|
+
@object_with_meta_data = RailsConnector::ObjectWithMetaData.find(self.id)
|
116
|
+
|
117
|
+
# reset depending instance variables
|
118
|
+
@editor = nil
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
# the methods in this module will become class methods
|
123
|
+
module ClassMethods
|
124
|
+
|
125
|
+
# The RailsConnector::ObjClass object for this file format.
|
126
|
+
# This will only return a proper object if a custom Ruby class exists
|
127
|
+
# and will throw a RuntimeError otherwise.
|
128
|
+
def obj_class_definition
|
129
|
+
raise "Obtaining the obj_class_definition of an Obj without custom Ruby class " \
|
130
|
+
"is logically impossible." unless is_custom_ruby_class?
|
131
|
+
# @obj_class_definition ||= RailsConnector::ObjClass.find_by_name(self.name)
|
132
|
+
@obj_class_definition ||= RailsConnector::Meta::EagerLoader.instance.obj_class(self.name)
|
133
|
+
end
|
134
|
+
alias_method :obj_class_def, :obj_class_definition
|
135
|
+
|
136
|
+
# RailsConnector::Obj returns false, everything else true.
|
137
|
+
def is_custom_ruby_class?
|
138
|
+
self != RailsConnector::Obj
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
data/lib/meta/content.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module RailsConnector
|
4
|
+
module Meta
|
5
|
+
class EagerLoader
|
6
|
+
include Singleton
|
7
|
+
def initialize
|
8
|
+
# Rails.logger.debug "EagerLoader: I am eager to start working"
|
9
|
+
@obj_classes = {}
|
10
|
+
# Rails 3.1 contains a bug that screws attribute loading
|
11
|
+
# attributes are set to assigned classes
|
12
|
+
if ::Rails::VERSION::MAJOR == 3 && ::Rails::VERSION::MINOR == 1
|
13
|
+
RailsConnector::ObjClass.all.each do |obj_class|
|
14
|
+
obj_class.custom_attributes
|
15
|
+
@obj_classes[obj_class.name] = obj_class
|
16
|
+
end
|
17
|
+
else
|
18
|
+
RailsConnector::ObjClass.includes(:custom_attributes_raw).all.each do |obj_class|
|
19
|
+
@obj_classes[obj_class.name] = obj_class
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def obj_class(name)
|
25
|
+
name = name.to_s
|
26
|
+
if !@obj_classes.fetch(name, nil).nil?
|
27
|
+
# puts "EagerLoader: I've already loaded it: #{name}"
|
28
|
+
@obj_classes[name]
|
29
|
+
else
|
30
|
+
# puts "EagerLoader: NO HAVE: #{name}"
|
31
|
+
@obj_classes[name] ||= RailsConnector::ObjClass.find_by_obj_class_name(name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def forget_obj_class(name)
|
36
|
+
@obj_classes.delete(name.to_s)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
|
3
|
+
# This class is used to read out the custom attributes,
|
4
|
+
# mandatory attributes and titles of an Obj.
|
5
|
+
# Warning: Dependent on the setup of your DB replication, most tables
|
6
|
+
# with meta information will not be available on your live system!
|
7
|
+
class ObjClass < RailsConnector::InfoparkBase
|
8
|
+
|
9
|
+
self.primary_key = :obj_class_id
|
10
|
+
|
11
|
+
has_and_belongs_to_many :custom_attributes_raw, :class_name => '::RailsConnector::Attribute',
|
12
|
+
:join_table => "#{table_name_prefix}obj_class_attrs"
|
13
|
+
|
14
|
+
alias_attribute :name, :obj_class_name
|
15
|
+
|
16
|
+
# Returns the title of the file format or nil, if it was not set.
|
17
|
+
def title(language)
|
18
|
+
self.titles[language.to_s].presence
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns all titles as a Hash.
|
22
|
+
def titles
|
23
|
+
load_blob_data
|
24
|
+
@blob_data['titles'] || {}
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the custom Ruby class or RailsConnector::Obj.
|
28
|
+
def ruby_class
|
29
|
+
# this must be the same algorithm that the rest of the RailsConnector uses!
|
30
|
+
RailsConnector::Obj.compute_type(self.name)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns true, if a custom Ruby class exists.
|
34
|
+
def has_custom_ruby_class?
|
35
|
+
self.ruby_class.present? && self.ruby_class != RailsConnector::Obj &&
|
36
|
+
self.ruby_class.ancestors.include?(RailsConnector::Obj)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the custom attributes in the form of a Hash.
|
40
|
+
def custom_attributes
|
41
|
+
# return the cached data
|
42
|
+
return @custom_attributes if @custom_attributes
|
43
|
+
|
44
|
+
# create a Hash (with indifferent access) out of an Array of ActiveRecord objects
|
45
|
+
@custom_attributes = self.custom_attributes_raw.map do |attr|
|
46
|
+
{attr.attribute_name => attr}
|
47
|
+
end.reduce(HashWithIndifferentAccess.new, &:merge)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns true, if the Obj Class has an attribute of the given name.
|
51
|
+
def custom_attribute?(attr)
|
52
|
+
self.custom_attributes.key?(attr)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns an Array of String of all mandatory attributes found for this ObjClass,
|
56
|
+
# no matter if it is a custom or built-in attribute. Built-in attributes
|
57
|
+
# are underscored (valid_from, not validFrom).
|
58
|
+
# Possible +options+ are:
|
59
|
+
# <tt>:only_custom_attributes</tt>:: Return only custom attributes, omit
|
60
|
+
# built-in attributes like content_type or valid_from.
|
61
|
+
def mandatory_attribute_names(options = {})
|
62
|
+
only_custom_attributes ||= options[:only_custom_attributes] || false
|
63
|
+
build_mandatory_attribute_arrays
|
64
|
+
return @mandatory_custom_attributes if only_custom_attributes
|
65
|
+
@mandatory_attributes
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns true, if the file format has an mandatory attribute of the given name.
|
69
|
+
def mandatory_attribute?(attr)
|
70
|
+
self.mandatory_attribute_names.include?(attr.to_s)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Convenience method for find_by_obj_class_name
|
74
|
+
def self.find_by_name(*args)
|
75
|
+
self.find_by_obj_class_name(*args)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Reads a whole bunch of data, where only some of it is useful
|
79
|
+
# in a Rails application:
|
80
|
+
# attributeGroups, availableBlobEditors, bodyTemplateName,
|
81
|
+
# canCreateNewsItems, completionCheck, mandatoryAttributes,
|
82
|
+
# presetAttributes, recordSetCallback, titles, validSubObjClassCheck,
|
83
|
+
# workflowModification
|
84
|
+
def self.read_blob_data(name) #:nodoc:
|
85
|
+
blob = RailsConnector::Meta.hello_im_rails_and_im_retarted_so_please_be_patient do # these queries really pollute our logs!
|
86
|
+
blob_name = if RailsConnector::BlobMapping.exists?
|
87
|
+
RailsConnector::BlobMapping.get_fingerprint("#{name}.jsonObjClassDict")
|
88
|
+
else
|
89
|
+
"#{name}.jsonObjClassDict"
|
90
|
+
end
|
91
|
+
|
92
|
+
RailsConnector::Blob.find_without_excluded_blob_data(blob_name)
|
93
|
+
end
|
94
|
+
|
95
|
+
return {} unless blob && blob.blob_data?
|
96
|
+
|
97
|
+
JSON.parse(blob.blob_data)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def load_blob_data #:nodoc:
|
103
|
+
return if @blob_data
|
104
|
+
|
105
|
+
@blob_data = self.class.read_blob_data(self.name)
|
106
|
+
|
107
|
+
# reset depending instance variables
|
108
|
+
@mandatory_custom_attributes = @mandatory_attributes = nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def build_mandatory_attribute_arrays #:nodoc:
|
112
|
+
return if @mandatory_attributes
|
113
|
+
|
114
|
+
load_blob_data
|
115
|
+
|
116
|
+
@mandatory_custom_attributes = []
|
117
|
+
@mandatory_attributes = []
|
118
|
+
(@blob_data['mandatoryAttributes'] || []).each do |attr|
|
119
|
+
attr_name = attr.to_s
|
120
|
+
if self.custom_attribute?(attr_name)
|
121
|
+
@mandatory_custom_attributes << attr_name
|
122
|
+
else
|
123
|
+
# only modify built-in attributes; i.e. `validFrom` will become `valid_from`
|
124
|
+
attr_name = attr_name.underscore
|
125
|
+
end
|
126
|
+
@mandatory_attributes << attr_name
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
|
3
|
+
# This class allows us to read out the version and
|
4
|
+
# the reminder information of an Obj
|
5
|
+
class ObjectWithMetaData < RailsConnector::InfoparkBase #:nodoc:
|
6
|
+
|
7
|
+
# If we name the class Object, conflicts with the plain Ruby
|
8
|
+
# objects inside the RailsConnector will occur.
|
9
|
+
def self.table_name
|
10
|
+
"#{table_name_prefix}" "objects"
|
11
|
+
end
|
12
|
+
|
13
|
+
self.primary_key = :object_id
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/lib/meta/version.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
#describe "InfoparkRailsConnectorMeta" do
|
4
|
+
|
5
|
+
describe Obj do
|
6
|
+
it "should include RailsConnector::Meta::Base" do
|
7
|
+
Obj.should include(RailsConnector::Meta::Base)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should handle Objs with and without Ruby class correctly" do
|
11
|
+
nil.should be_false # we're off a good start
|
12
|
+
|
13
|
+
# everything should be false here
|
14
|
+
obj = RailsConnector::Obj.where(:obj_class => 'ObjClassWithoutRubyClass').first
|
15
|
+
obj.obj_class_def.has_custom_ruby_class?.should be_false
|
16
|
+
obj.has_custom_ruby_class?.should be_false
|
17
|
+
obj.class.is_custom_ruby_class?.should be_false
|
18
|
+
|
19
|
+
# everything should be true here
|
20
|
+
obj2 = StandardPage.first
|
21
|
+
obj2.obj_class_def.has_custom_ruby_class?.should be_true
|
22
|
+
obj2.has_custom_ruby_class?.should be_true
|
23
|
+
obj2.class.is_custom_ruby_class?.should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should respond to obj_class_def/obj_class_definition correctly" do
|
27
|
+
obj = RailsConnector::Obj.where(:obj_class => 'ObjClassWithoutRubyClass').first
|
28
|
+
obj.obj_class_def.name.should == 'ObjClassWithoutRubyClass'
|
29
|
+
obj.obj_class_definition.name.should == 'ObjClassWithoutRubyClass'
|
30
|
+
|
31
|
+
lambda { obj.class.obj_class_def }.should raise_error(RuntimeError)
|
32
|
+
lambda { obj.class.obj_class_definition }.should raise_error(RuntimeError)
|
33
|
+
|
34
|
+
obj2 = StandardPage.first
|
35
|
+
obj2.obj_class_def.name.should == 'StandardPage'
|
36
|
+
obj2.obj_class_definition.name.should == 'StandardPage'
|
37
|
+
|
38
|
+
obj2.class.obj_class_def.name.should == 'StandardPage'
|
39
|
+
obj2.class.obj_class_definition.name.should == 'StandardPage'
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe RailsConnector::ObjClass do
|
46
|
+
|
47
|
+
it "should serve the proper Ruby class" do
|
48
|
+
obj_class_def = RailsConnector::ObjClass.where(:obj_class_name => 'ObjClassWithoutRubyClass').first
|
49
|
+
obj_class_def.ruby_class.should == RailsConnector::Obj
|
50
|
+
obj_class_def.ruby_class.should == ::Obj
|
51
|
+
obj_class_def.has_custom_ruby_class?.should be_false
|
52
|
+
|
53
|
+
obj2_class_def = RailsConnector::ObjClass.where(:obj_class_name => 'StandardPage').first
|
54
|
+
obj2_class_def.ruby_class.should == StandardPage
|
55
|
+
obj2_class_def.has_custom_ruby_class?.should be_true
|
56
|
+
end
|
57
|
+
|
58
|
+
it "caches blob data" do
|
59
|
+
RailsConnector::ObjClass.should_receive(:read_blob_data) { Hash.new }.once
|
60
|
+
|
61
|
+
obj_class_def = RailsConnector::ObjClass.where(:obj_class_name => 'ObjClassWithoutRubyClass').first
|
62
|
+
obj_class_def.titles
|
63
|
+
obj_class_def.custom_mandatory_attributes
|
64
|
+
end
|
65
|
+
|
66
|
+
context "for classes with proper titles" do
|
67
|
+
it "returns correct titles" do
|
68
|
+
obj_class_def = RailsConnector::ObjClass.where(:obj_class_name => 'ObjClassWithoutRubyClass').first
|
69
|
+
obj_class_def.titles.should be_kind_of(Hash)
|
70
|
+
obj_class_def.titles.should be_kind_of(HashWithIndifferentAccess)
|
71
|
+
obj_class_def.title('de').should == 'Vorlage ohne Ruby Klasse'
|
72
|
+
obj_class_def.title(:en).should == 'File Format withoud Ruby Class'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
context "for classes without proper titles" do
|
76
|
+
it "returns nil for titles" do
|
77
|
+
pending
|
78
|
+
obj_class_def = RailsConnector::ObjClass.where(:obj_class_name => 'ObjClassWithoutTitles').first
|
79
|
+
obj_class_def.titles.should be_kind_of(Hash)
|
80
|
+
obj_class_def.titles.should be_kind_of(HashWithIndifferentAccess)
|
81
|
+
obj_class_def.title('de').should be_nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
#it "gets all ObjClass objects from the database" do
|
88
|
+
# all = RailsConnector::ObjClass.all
|
89
|
+
# #puts all.map(&:name).join(', ')
|
90
|
+
#end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
+
ENV["RAILS_ENV"] ||= 'test'
|
3
|
+
require 'active_support/all'
|
4
|
+
require File.expand_path("../../config/environment", __FILE__)
|
5
|
+
require 'rspec/rails'
|
6
|
+
|
7
|
+
|
8
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
9
|
+
# in spec/support/ and its subdirectories.
|
10
|
+
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.color_enabled = true
|
14
|
+
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: infopark_rails_connector_meta
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 1
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 5
|
9
|
+
- 1
|
10
|
+
version: 1.5.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Tomasz Przedmojski
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-12-12 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: activerecord
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 19
|
44
|
+
segments:
|
45
|
+
- 3
|
46
|
+
- 0
|
47
|
+
- 10
|
48
|
+
version: 3.0.10
|
49
|
+
- - <=
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
hash: 29
|
52
|
+
segments:
|
53
|
+
- 3
|
54
|
+
- 2
|
55
|
+
- 9
|
56
|
+
version: 3.2.9
|
57
|
+
type: :runtime
|
58
|
+
version_requirements: *id002
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: activesupport
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
hash: 19
|
68
|
+
segments:
|
69
|
+
- 3
|
70
|
+
- 0
|
71
|
+
- 10
|
72
|
+
version: 3.0.10
|
73
|
+
- - <=
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 29
|
76
|
+
segments:
|
77
|
+
- 3
|
78
|
+
- 2
|
79
|
+
- 9
|
80
|
+
version: 3.2.9
|
81
|
+
type: :runtime
|
82
|
+
version_requirements: *id003
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: infopark_rails_connector
|
85
|
+
prerelease: false
|
86
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 3
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
version: "0"
|
95
|
+
type: :runtime
|
96
|
+
version_requirements: *id004
|
97
|
+
description: Gives RailsConnector Objs information about its CMS class, attributes, etc.
|
98
|
+
email:
|
99
|
+
- tomasz.przedmojski@infopark.de
|
100
|
+
executables: []
|
101
|
+
|
102
|
+
extensions: []
|
103
|
+
|
104
|
+
extra_rdoc_files: []
|
105
|
+
|
106
|
+
files:
|
107
|
+
- .gitignore
|
108
|
+
- Gemfile
|
109
|
+
- LICENSE
|
110
|
+
- Rakefile
|
111
|
+
- infopark_rails_connector_meta.gemspec
|
112
|
+
- lib/meta.rb
|
113
|
+
- lib/meta/attribute.rb
|
114
|
+
- lib/meta/base.rb
|
115
|
+
- lib/meta/blob_mapping.rb
|
116
|
+
- lib/meta/content.rb
|
117
|
+
- lib/meta/eager_loader.rb
|
118
|
+
- lib/meta/obj_class.rb
|
119
|
+
- lib/meta/object_with_meta_data.rb
|
120
|
+
- lib/meta/version.rb
|
121
|
+
- spec/infopark_rails_connector_meta_spec.rb
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
has_rdoc: true
|
124
|
+
homepage: ""
|
125
|
+
licenses:
|
126
|
+
- LGPL-3
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
hash: 3
|
138
|
+
segments:
|
139
|
+
- 0
|
140
|
+
version: "0"
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
hash: 3
|
147
|
+
segments:
|
148
|
+
- 0
|
149
|
+
version: "0"
|
150
|
+
requirements: []
|
151
|
+
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 1.5.2
|
154
|
+
signing_key:
|
155
|
+
specification_version: 3
|
156
|
+
summary: Meta Information on CMS Objects
|
157
|
+
test_files:
|
158
|
+
- spec/infopark_rails_connector_meta_spec.rb
|
159
|
+
- spec/spec_helper.rb
|