cmis_server 1.0.3

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 (133) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +51 -0
  5. data/app/assets/javascripts/cmis_server/application.js +13 -0
  6. data/app/assets/stylesheets/cmis_server/application.css +15 -0
  7. data/app/controllers/cmis_server/application_controller.rb +19 -0
  8. data/app/controllers/cmis_server/atom_pub/base_controller.rb +23 -0
  9. data/app/controllers/cmis_server/atom_pub/bulk_controller.rb +302 -0
  10. data/app/controllers/cmis_server/atom_pub/content_controller.rb +178 -0
  11. data/app/controllers/cmis_server/atom_pub/entries_controller.rb +41 -0
  12. data/app/controllers/cmis_server/atom_pub/folder_collection_controller.rb +70 -0
  13. data/app/controllers/cmis_server/atom_pub/query_controller.rb +138 -0
  14. data/app/controllers/cmis_server/atom_pub/repository_controller.rb +75 -0
  15. data/app/controllers/cmis_server/atom_pub/secondary_types_controller.rb +149 -0
  16. data/app/controllers/cmis_server/atom_pub/service_documents_controller.rb +34 -0
  17. data/app/controllers/cmis_server/atom_pub/types_controller.rb +229 -0
  18. data/app/controllers/cmis_server/atom_pub/uri_templates_controller.rb +58 -0
  19. data/app/controllers/concerns/cmis_server/atom_pub/repository_scopable.rb +18 -0
  20. data/app/helpers/cmis_server/application_helper.rb +31 -0
  21. data/app/models/cmis_server/application_record.rb +5 -0
  22. data/app/services/cmis_server/bulk_update_service.rb +69 -0
  23. data/app/services/cmis_server/content_stream_service.rb +75 -0
  24. data/app/services/cmis_server/discovery_service.rb +31 -0
  25. data/app/services/cmis_server/navigation_service.rb +43 -0
  26. data/app/services/cmis_server/object_service.rb +176 -0
  27. data/app/services/cmis_server/repository_service.rb +40 -0
  28. data/app/services/cmis_server/secondary_type_service.rb +120 -0
  29. data/app/services/cmis_server/type_management_service.rb +117 -0
  30. data/app/views/cmis_server/atom_pub/bulk_update_feed.atom.builder +47 -0
  31. data/app/views/cmis_server/atom_pub/entries/_cmis_document_links.atom_entry.builder +0 -0
  32. data/app/views/cmis_server/atom_pub/entries/_cmis_folder_links.atom_entry.builder +3 -0
  33. data/app/views/cmis_server/atom_pub/entries/_object_entry.atom_entry.builder +64 -0
  34. data/app/views/cmis_server/atom_pub/entries/_property.atom_entry.builder +8 -0
  35. data/app/views/cmis_server/atom_pub/entries/object_entry.atom_entry.builder +1 -0
  36. data/app/views/cmis_server/atom_pub/entries/type_entry.atom_entry.builder +59 -0
  37. data/app/views/cmis_server/atom_pub/feeds/_feed_entry.atom_feed.builder +1 -0
  38. data/app/views/cmis_server/atom_pub/feeds/feed.atom_feed.builder +30 -0
  39. data/app/views/cmis_server/atom_pub/service_documents/_uri_template.atom_service.builder +5 -0
  40. data/app/views/cmis_server/atom_pub/service_documents/_workspace.atom_service.builder +89 -0
  41. data/app/views/cmis_server/atom_pub/service_documents/service_document.atom_service.builder +1 -0
  42. data/app/views/cmis_server/atom_pub/shared/_collection.xml.builder +7 -0
  43. data/app/views/cmis_server/atom_pub/shared/atom_entry_layout.atom_entry.builder +0 -0
  44. data/app/views/cmis_server/atom_pub/type_entry.atom.builder +69 -0
  45. data/app/views/cmis_server/atom_pub/types_feed.atom.builder +91 -0
  46. data/app/views/layouts/cmis_server/application.atom_entry.builder +2 -0
  47. data/app/views/layouts/cmis_server/application.atom_feed.builder +3 -0
  48. data/app/views/layouts/cmis_server/application.atom_service.builder +10 -0
  49. data/app/views/layouts/cmis_server/application.html.erb +14 -0
  50. data/config/routes.rb +49 -0
  51. data/lib/cmis_server/atom_pub/entry_parser.rb +72 -0
  52. data/lib/cmis_server/base_objects/base_type.rb +128 -0
  53. data/lib/cmis_server/base_objects/document.rb +68 -0
  54. data/lib/cmis_server/base_objects/folder.rb +104 -0
  55. data/lib/cmis_server/base_objects/item.rb +25 -0
  56. data/lib/cmis_server/base_types.rb +123 -0
  57. data/lib/cmis_server/cmis_object.rb +190 -0
  58. data/lib/cmis_server/configuration.rb +43 -0
  59. data/lib/cmis_server/constants.rb +8 -0
  60. data/lib/cmis_server/content_stream.rb +52 -0
  61. data/lib/cmis_server/context.rb +11 -0
  62. data/lib/cmis_server/document_object.rb +12 -0
  63. data/lib/cmis_server/document_type.rb +67 -0
  64. data/lib/cmis_server/engine.rb +60 -0
  65. data/lib/cmis_server/exceptions.rb +185 -0
  66. data/lib/cmis_server/folder_object.rb +18 -0
  67. data/lib/cmis_server/folder_type.rb +34 -0
  68. data/lib/cmis_server/id.rb +18 -0
  69. data/lib/cmis_server/item_adapter.rb +26 -0
  70. data/lib/cmis_server/item_object.rb +15 -0
  71. data/lib/cmis_server/item_type.rb +7 -0
  72. data/lib/cmis_server/object_adapter.rb +79 -0
  73. data/lib/cmis_server/property.rb +29 -0
  74. data/lib/cmis_server/property_definition.rb +118 -0
  75. data/lib/cmis_server/query/parser.output +2250 -0
  76. data/lib/cmis_server/query/parser.racc +222 -0
  77. data/lib/cmis_server/query/parser.racc.rb +1039 -0
  78. data/lib/cmis_server/query/parser.rex +114 -0
  79. data/lib/cmis_server/query/parser.rex.rb +238 -0
  80. data/lib/cmis_server/query/statement.rb +395 -0
  81. data/lib/cmis_server/query.rb +2 -0
  82. data/lib/cmis_server/renderable_collection.rb +45 -0
  83. data/lib/cmis_server/renderable_object.rb +49 -0
  84. data/lib/cmis_server/repository.rb +91 -0
  85. data/lib/cmis_server/secondary_type.rb +11 -0
  86. data/lib/cmis_server/type.rb +62 -0
  87. data/lib/cmis_server/type_registry.rb +115 -0
  88. data/lib/cmis_server/version.rb +4 -0
  89. data/lib/cmis_server.rb +22 -0
  90. data/lib/tasks/cmis_server_tasks.rake +4 -0
  91. data/test/cmis_server_test.rb +7 -0
  92. data/test/dummy/README.rdoc +28 -0
  93. data/test/dummy/Rakefile +6 -0
  94. data/test/dummy/app/assets/javascripts/application.js +13 -0
  95. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  96. data/test/dummy/app/controllers/application_controller.rb +5 -0
  97. data/test/dummy/app/helpers/application_helper.rb +2 -0
  98. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  99. data/test/dummy/bin/bundle +3 -0
  100. data/test/dummy/bin/rails +4 -0
  101. data/test/dummy/bin/rake +4 -0
  102. data/test/dummy/bin/setup +29 -0
  103. data/test/dummy/config/application.rb +26 -0
  104. data/test/dummy/config/boot.rb +5 -0
  105. data/test/dummy/config/database.yml +25 -0
  106. data/test/dummy/config/environment.rb +5 -0
  107. data/test/dummy/config/environments/development.rb +41 -0
  108. data/test/dummy/config/environments/production.rb +79 -0
  109. data/test/dummy/config/environments/test.rb +42 -0
  110. data/test/dummy/config/initializers/assets.rb +11 -0
  111. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  112. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  113. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  114. data/test/dummy/config/initializers/inflections.rb +16 -0
  115. data/test/dummy/config/initializers/mime_types.rb +4 -0
  116. data/test/dummy/config/initializers/session_store.rb +3 -0
  117. data/test/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
  118. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  119. data/test/dummy/config/locales/en.yml +23 -0
  120. data/test/dummy/config/routes.rb +4 -0
  121. data/test/dummy/config/secrets.yml +22 -0
  122. data/test/dummy/config.ru +4 -0
  123. data/test/dummy/public/404.html +67 -0
  124. data/test/dummy/public/422.html +67 -0
  125. data/test/dummy/public/500.html +66 -0
  126. data/test/dummy/public/favicon.ico +0 -0
  127. data/test/integration/navigation_test.rb +8 -0
  128. data/test/services/bulk_update_service_test.rb +121 -0
  129. data/test/services/content_stream_service_test.rb +176 -0
  130. data/test/services/secondary_type_service_test.rb +174 -0
  131. data/test/services/type_management_service_test.rb +146 -0
  132. data/test/test_helper.rb +16 -0
  133. metadata +326 -0
@@ -0,0 +1,190 @@
1
+ module CmisServer
2
+
3
+ class CmisObject
4
+
5
+ attr_reader :type
6
+ attr_reader :properties
7
+ attr_reader :secondary_types
8
+
9
+ class InvalidType < StandardError; end
10
+
11
+ def initialize(type:, properties: {}, secondary_types: [])
12
+ self.type = type
13
+ @secondary_types = []
14
+ initialize_properties
15
+
16
+ # Ajouter les types secondaires s'ils sont fournis
17
+ secondary_types.each do |secondary_type|
18
+ add_secondary_type(secondary_type)
19
+ end
20
+
21
+ properties.to_h.each do |property, value|
22
+ self.send(property.to_s.gsub(/[^0-9a-z]/i, '_').underscore+"=", value)
23
+ end
24
+ end
25
+
26
+ def to_renderable_object
27
+ CmisServer::RenderableObject.new(base_object: self)
28
+ end
29
+
30
+ def copy_properties_values_of object
31
+ self.properties.each{|_k,property| property.value=object.send(property.property_definition.getter_method_name)}
32
+ end
33
+
34
+ # CMIS 1.1: Méthodes pour gérer les types secondaires
35
+ def add_secondary_type(secondary_type)
36
+ # Vérifier que le type est bien un type secondaire
37
+ unless secondary_type.base_id == 'cmis:secondary'
38
+ raise InvalidType.new("#{secondary_type.id} is not a secondary type")
39
+ end
40
+
41
+ # Vérifier que le type n'est pas déjà ajouté
42
+ if has_secondary_type?(secondary_type.id)
43
+ raise InvalidType.new("#{secondary_type.id} is already added")
44
+ end
45
+
46
+ # Ajouter le type secondaire
47
+ @secondary_types << secondary_type
48
+
49
+ # Ajouter les propriétés du type secondaire
50
+ add_secondary_type_properties(secondary_type)
51
+
52
+ # Mettre à jour la propriété cmis:secondaryObjectTypeIds
53
+ update_secondary_type_ids
54
+
55
+ secondary_type
56
+ end
57
+
58
+ def remove_secondary_type(type_id)
59
+ # Trouver le type secondaire
60
+ secondary_type = @secondary_types.find { |st| st.id == type_id }
61
+ unless secondary_type
62
+ raise InvalidType.new("#{type_id} is not a secondary type of this object")
63
+ end
64
+
65
+ # Supprimer le type secondaire
66
+ @secondary_types.delete(secondary_type)
67
+
68
+ # Supprimer les propriétés associées à ce type secondaire
69
+ remove_secondary_type_properties(secondary_type)
70
+
71
+ # Mettre à jour la propriété cmis:secondaryObjectTypeIds
72
+ update_secondary_type_ids
73
+
74
+ true
75
+ end
76
+
77
+ def has_secondary_type?(type_id)
78
+ @secondary_types.any? { |st| st.id == type_id }
79
+ end
80
+
81
+ def update_properties(properties_hash)
82
+ properties_hash.each do |prop_id, value|
83
+ if @properties.key?(prop_id)
84
+ @properties[prop_id].value = value
85
+ else
86
+ # Vérifier si cette propriété appartient à un type secondaire que nous n'avons pas encore
87
+ property_def = find_property_definition(prop_id)
88
+ if property_def && property_def.owning_type && property_def.owning_type.base_id == 'cmis:secondary'
89
+ # Ajouter automatiquement le type secondaire
90
+ add_secondary_type(property_def.owning_type)
91
+ # Puis définir la valeur
92
+ @properties[prop_id].value = value
93
+ else
94
+ raise ArgumentError, "Property #{prop_id} does not exist for this object"
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ def save
101
+ # À implémenter selon votre système de stockage
102
+ # Cette méthode devrait sauvegarder l'objet avec toutes ses propriétés
103
+ true
104
+ end
105
+
106
+ def all_property_definitions
107
+ # Combine les définitions de propriétés du type principal et des types secondaires
108
+ all_defs = type.property_definitions.to_a
109
+
110
+ @secondary_types.each do |secondary_type|
111
+ all_defs.concat(secondary_type.property_definitions.to_a)
112
+ end
113
+
114
+ all_defs
115
+ end
116
+
117
+ private
118
+
119
+ def find_property_definition(prop_id)
120
+ # Chercher dans les types secondaires disponibles
121
+ CmisServer::TypeRegistry.types.values.each do |available_type|
122
+ if available_type.base_id == 'cmis:secondary'
123
+ prop_def = available_type.property_definitions.find { |pd| pd.id == prop_id }
124
+ return prop_def if prop_def
125
+ end
126
+ end
127
+ nil
128
+ end
129
+
130
+ def add_secondary_type_properties(secondary_type)
131
+ secondary_type.property_definitions.each do |pd|
132
+ # Ajouter la propriété si elle n'existe pas déjà
133
+ unless @properties.key?(pd.id)
134
+ @properties[pd.id] = Property.new(pd, pd.default_value, self)
135
+
136
+ # Ajouter les méthodes getter et setter
137
+ define_singleton_method(pd.getter_method_name) { @properties[pd.id].value }
138
+ define_singleton_method(pd.setter_method_name) { |v| @properties[pd.id].value = v }
139
+ define_singleton_method(pd.property_method_name) { @properties[pd.id] }
140
+ end
141
+ end
142
+ end
143
+
144
+ def remove_secondary_type_properties(secondary_type)
145
+ secondary_type.self_property_definitions.each do |pd|
146
+ # Vérifier que la propriété n'est pas également définie par le type principal ou un autre type secondaire
147
+ unless property_defined_elsewhere?(pd.id, secondary_type.id)
148
+ @properties.delete(pd.id)
149
+
150
+ # Supprimer les méthodes associées
151
+ singleton_class.send(:remove_method, pd.getter_method_name) if respond_to?(pd.getter_method_name)
152
+ singleton_class.send(:remove_method, pd.setter_method_name) if respond_to?(pd.setter_method_name)
153
+ singleton_class.send(:remove_method, pd.property_method_name) if respond_to?(pd.property_method_name)
154
+ end
155
+ end
156
+ end
157
+
158
+ def property_defined_elsewhere?(prop_id, excluding_type_id)
159
+ # Vérifier si la propriété est définie par le type principal
160
+ return true if type.property_definitions.any? { |pd| pd.id == prop_id }
161
+
162
+ # Vérifier si la propriété est définie par un autre type secondaire
163
+ @secondary_types.any? do |st|
164
+ st.id != excluding_type_id && st.property_definitions.any? { |pd| pd.id == prop_id }
165
+ end
166
+ end
167
+
168
+ def update_secondary_type_ids
169
+ # Mettre à jour la propriété cmis:secondaryObjectTypeIds avec les IDs des types secondaires
170
+ if @properties.key?('cmis:secondaryObjectTypeIds')
171
+ @properties['cmis:secondaryObjectTypeIds'].value = @secondary_types.map(&:id)
172
+ end
173
+ end
174
+
175
+ def type=(type)
176
+ @type=type
177
+ type.property_definitions.each do |pd|
178
+ define_singleton_method(pd.getter_method_name) { @properties[pd.id].value }
179
+ define_singleton_method(pd.setter_method_name) { |v| @properties[pd.id].value=v }
180
+ define_singleton_method(pd.property_method_name) { @properties[pd.id] }
181
+ end
182
+ end
183
+
184
+ def initialize_properties
185
+ @properties=type.property_definitions.map do |pd|
186
+ [pd.id, Property.new(pd, pd.value, self)]
187
+ end.to_h
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,43 @@
1
+ module CmisServer
2
+ class Configuration
3
+
4
+ attr_accessor :http_basic_auth_procedure
5
+ attr_accessor :arguments_for_root_folder
6
+ attr_accessor :default_page_size
7
+ attr_accessor :debug
8
+ attr_accessor :repository_info
9
+ attr_accessor :optimizations
10
+
11
+ def initialize
12
+
13
+ #defines default values
14
+
15
+ @http_basic_auth_procedure = Proc.new do |user, password|
16
+ puts "Set your identification procedure in the CmisServer gem configuration with key http_basic_auth_procedure."
17
+ puts "example : config.http_basic_auth_procedure = Proc.new{|user,password| User.find_by(username: user)&.valid_password?(password)}"
18
+ raise "http_basic_auth_procedure configuration not set"
19
+ end
20
+
21
+ @arguments_for_root_folder={
22
+ type: FolderType.base,
23
+ properties:{
24
+ cmis_object_id: 'cmis:root_folder',
25
+ cmis_name: "Root Folder",
26
+ cmis_last_modification_date: DateTime.now,
27
+ cmis_creation_date: DateTime.now,
28
+ cmis_created_by: 'unknown'
29
+ }
30
+ }
31
+
32
+ @default_page_size = 10
33
+
34
+ @debug=false
35
+
36
+ @repository_info = {}
37
+
38
+ @optimizations = {}
39
+
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,8 @@
1
+ module CmisServer
2
+
3
+ CMIS_NAMESPACE ="http://docs.oasis-open.org/ns/cmis/core/201107/"
4
+ CMIS_REST_ATOM_NAMESPACE="http://docs.oasis-open.org/ns/cmis/restatom/201107/"
5
+ CMIS_VERSION_SUPPORTED ="1.1"
6
+
7
+ end
8
+
@@ -0,0 +1,52 @@
1
+ require 'mime/types'
2
+ require 'tempfile'
3
+ require 'base64'
4
+
5
+ module CmisServer
6
+ class ContentStream
7
+
8
+ attr_accessor :media_type
9
+ attr_accessor :base64
10
+ attr_accessor :filename
11
+ attr_accessor :id
12
+
13
+ def initialize(id: nil, base64: nil, media_type: nil, filename: nil)
14
+ @media_type=media_type
15
+ @base64 =base64
16
+ @id =id
17
+ @filename =filename
18
+ end
19
+
20
+ def length
21
+ content.bytesize
22
+ end
23
+
24
+ def default_extensions
25
+ MIME::Types[self.media_type].first&.extensions&.first||'txt'
26
+ end
27
+
28
+ def content
29
+ Base64.decode64(self.base64)
30
+ end
31
+
32
+ def tempfile(name='tempfile')
33
+ t=Tempfile.new([name, ".#{default_extensions}"])
34
+ t.binmode
35
+ t.write(self.content)
36
+ t.close
37
+ t.open
38
+ t
39
+ end
40
+
41
+ def with_tempfile(&block)
42
+ temp_file=self.tempfile
43
+ begin
44
+ block.call(temp_file)
45
+ ensure
46
+ temp_file.close
47
+ temp_file.unlink
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,11 @@
1
+ module CmisServer
2
+ class Context
3
+
4
+ attr_accessor :current_user
5
+
6
+ def initialize(current_user: nil)
7
+ @current_user= current_user
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module CmisServer
2
+ class DocumentObject < CmisServer::CmisObject
3
+
4
+ attr_accessor :content_stream
5
+
6
+ def initialize(type:, properties: {})
7
+ raise InvalidType unless type.base_id == 'cmis:document'
8
+ super
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,67 @@
1
+ module CmisServer
2
+ class DocumentType < Type
3
+
4
+ attr_accessor :versionable,
5
+ :content_stream_allowed
6
+ # notallowed
7
+ # A content stream MUST NOT be included.
8
+ # allowed
9
+ # A content stream MAY be included.
10
+ # required
11
+ # A content stream MUST be included (i.e. MUST be included when the object is created, and MUST NOT be deleted).
12
+
13
+ def initialize(attrs={})
14
+ @versionable = attrs.fetch(:versionable, false)
15
+ @content_stream_allowed = attrs.fetch(:content_stream_allowed, :allowed)
16
+ super
17
+ end
18
+
19
+ def adapter_class
20
+ DocumentAdapter
21
+ end
22
+
23
+
24
+ def self.base
25
+ @base||=new(id: 'cmis:document',
26
+ parent_type: nil,
27
+ description: "A CMIS document",
28
+ display_name: 'Document',
29
+ creatable: true,
30
+ fileable: true,
31
+ queryable: true,
32
+ property_definitions: [
33
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:name'.freeze, type: String, required: true, updatability: :readwrite}),
34
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:description'.freeze, type: String, required: false, updatability: :readwrite}),
35
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:objectId'.freeze, type: CmisServer::Id, required: true, updatability: :readonly}),
36
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:baseTypeId'.freeze, type: CmisServer::Id, required: true, updatability: :readonly, value: ->(obj) { obj.type.base_id }}),
37
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:objectTypeId'.freeze, type: CmisServer::Id, required: true, updatability: :oncreate, value: ->(obj) { obj.type.id }}),
38
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:createdBy'.freeze, type: String, required: false, updatability: :readonly, queryable: true, orderable: true}),
39
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:creationDate'.freeze, type: DateTime, required: false, updatability: :readonly, queryable: true, orderable: true}),
40
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:lastModifiedBy'.freeze, type: String, required: false, updatability: :readonly, queryable: true, orderable: true}),
41
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:lastModificationDate'.freeze, type: DateTime, required: false, updatability: :readonly, queryable: true, orderable: true}),
42
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:changeToken'.freeze, type: String, required: false, updatability: :readonly}),
43
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:isImmutable'.freeze, type: Boolean, required: false, updatability: :readonly, default: false}),
44
+
45
+ # Versionning properties
46
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:isLatestVersion'.freeze, type: Boolean, required: false, updatability: :readonly}),
47
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:isMajorVersion'.freeze, type: Boolean, required: false, updatability: :readonly}),
48
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:isLatestMajorVersion'.freeze, type: Boolean, required: false, updatability: :readonly}),
49
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:isPrivateWorkingCopy'.freeze, type: Boolean, required: false, updatability: :readonly}),
50
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:versionLabel'.freeze, type: String, required: false, cardinality: :single, updatability: :readonly}),
51
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:versionSeriesId'.freeze, type: CmisServer::Id, required: false, cardinality: :single, updatability: :readonly}),
52
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:isVersionSeriesCheckedOut'.freeze, type: Boolean, required: false, cardinality: :single, updatability: :readonly}),
53
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:versionSeriesCheckedOutBy'.freeze, type: String, required: false, cardinality: :single, updatability: :readonly}),
54
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:versionSeriesCheckedOutId'.freeze, type: Id, required: false, cardinality: :single, updatability: :readonly}),
55
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:checkinComment'.freeze, type: String, required: false, cardinality: :single, updatability: :readonly}),
56
+
57
+ # ContentStream properties
58
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:contentStreamLength'.freeze, type: Integer, required: false, cardinality: :single, updatability: :readonly, value: ->(obj) { obj.content_stream&.length }}),
59
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:contentStreamMimeType'.freeze, type: String, required: false, cardinality: :single, updatability: :readonly, value: ->(obj) { obj.content_stream&.media_type }}),
60
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:contentStreamFileName'.freeze, type: String, required: false, cardinality: :single, updatability: :readonly, value: ->(obj) { obj.content_stream&.filename }}),
61
+ CmisServer::PropertyDefinition.register_property_definition({id: 'cmis:contentStreamId'.freeze, type: String, required: false, cardinality: :single, updatability: :readonly, value: ->(obj) { obj.content_stream&.id }}),
62
+ ])
63
+ end
64
+
65
+
66
+ end
67
+ end
@@ -0,0 +1,60 @@
1
+ module CmisServer
2
+ class Engine < ::Rails::Engine
3
+ config.autoload_paths << File.expand_path("../../app/services", __FILE__)
4
+ isolate_namespace CmisServer
5
+
6
+ # Enregistrement des types MIME selon les conventions de Rails 7+
7
+ initializer "cmis_server.register_mime_types" do
8
+ Mime::Type.register "application/atom+xml", :atom_xml
9
+ Mime::Type.register "application/atom+xml;type=feed", :atom_feed
10
+ Mime::Type.register "application/atom+xml;type=entry", :atom_entry
11
+ Mime::Type.register "application/atomsvc+xml", :atom_service
12
+ end
13
+ end
14
+ end
15
+
16
+ require 'cmis_server/version'
17
+ require 'cmis_server/constants'
18
+ require 'cmis_server/configuration'
19
+
20
+ require 'cmis_server/exceptions'
21
+
22
+ #CMIS special types
23
+ require 'cmis_server/id'
24
+ require 'cmis_server/content_stream'
25
+
26
+ require 'cmis_server/repository'
27
+ require 'cmis_server/property_definition'
28
+ require 'cmis_server/property'
29
+
30
+ # Charger BaseType en premier
31
+ require 'cmis_server/base_objects/base_type'
32
+
33
+ require 'cmis_server/type'
34
+ require 'cmis_server/base_types'
35
+ require 'cmis_server/type_registry'
36
+ require 'cmis_server/cmis_object'
37
+ require 'cmis_server/document_type'
38
+ require 'cmis_server/document_object'
39
+ require 'cmis_server/folder_type'
40
+ require 'cmis_server/folder_object'
41
+ require 'cmis_server/item_type'
42
+ require 'cmis_server/item_object'
43
+ require 'cmis_server/secondary_type'
44
+ # require 'cmis_server/type_registry'
45
+
46
+
47
+ require 'cmis_server/object_adapter'
48
+ require 'cmis_server/item_adapter'
49
+ require 'cmis_server/base_objects/base_type'
50
+ require 'cmis_server/base_objects/document'
51
+ require 'cmis_server/base_objects/folder'
52
+ require 'cmis_server/base_objects/item'
53
+
54
+ require 'cmis_server/atom_pub/entry_parser'
55
+
56
+ require 'cmis_server/context'
57
+
58
+ require 'cmis_server/query'
59
+ require 'cmis_server/renderable_object'
60
+ require 'cmis_server/renderable_collection'
@@ -0,0 +1,185 @@
1
+ module CmisServer
2
+
3
+ class CmisStandardError < StandardError
4
+
5
+ attr_reader :http_status_code, :debug_data, :trigger, :title
6
+
7
+ def initialize(attrs= {})
8
+ self.http_status_code = attrs.fetch(:http_status, 500)
9
+ @debug_data = attrs.fetch(:debug_data, nil)
10
+ @trigger = attrs.fetch(:trigger, nil)
11
+ @title = attrs.fetch(:title, nil)
12
+ end
13
+
14
+ def http_status
15
+ Rack::Utils::HTTP_STATUS_CODES[self.http_status_code]
16
+ end
17
+
18
+ def title
19
+ @title||self.class.name
20
+ end
21
+
22
+ def summary
23
+ "A #{self.title} error occured."
24
+ end
25
+
26
+ def message(debug: CmisServer.configuration.debug)
27
+ message=self.summary
28
+ message+= " It was initially triggered by : #{@trigger}" if @trigger&&debug
29
+ message
30
+ end
31
+
32
+ def to_h(debug: CmisServer.configuration.debug)
33
+ h={
34
+ title: self.title,
35
+ summary: self.summary,
36
+ http_status_code: self.http_status_code,
37
+ http_status: self.http_status,
38
+ }
39
+ if debug
40
+ h[:debug_data]= self.debug_data.to_h
41
+ h[:backtrace] =self.backtrace&.join("\n")
42
+ h[:trigger] ={
43
+ name: self.trigger,
44
+ backtrace: self.trigger&.backtrace&.join("\n")
45
+ }
46
+ end
47
+ h
48
+ end
49
+
50
+ def to_xml(debug: CmisServer.configuration.debug)
51
+ formated_hash=self.to_h(debug: debug).map { |k, v| [k.to_s.camelcase(:lower), v] }.to_h
52
+ formated_hash.to_xml(:root => 'error', :skip_instruct => true)
53
+ end
54
+
55
+ def log(logger)
56
+ logger.error "#{self.class.to_s} (#{self.summary})"
57
+ logger.info self.backtrace.join("\n") if self.backtrace
58
+ if self.trigger
59
+ logger.error "Initialy triggered by : #{self.trigger.class.to_s} (#{self.trigger.message})"
60
+ logger.info self.trigger.backtrace.join("\n") if self.trigger.backtrace
61
+ end
62
+ end
63
+
64
+ protected
65
+
66
+ def http_status_code=(value)
67
+ if value.is_a? Integer
68
+ @http_status_code=value
69
+ else
70
+ @http_status_code=Rack::Utils::SYMBOL_TO_STATUS_CODE[value]||value.to_i
71
+ end
72
+ end
73
+ end
74
+
75
+ class RuntimeError < CmisStandardError
76
+ def title
77
+ "Runtime Error"
78
+ end
79
+
80
+ def summary
81
+ "An unhandled error occurred on the CMIS server."
82
+ end
83
+ end
84
+
85
+ class ObjectNotFound < CmisStandardError
86
+ def title
87
+ "Object Not Found"
88
+ end
89
+
90
+ def summary
91
+ "The requested object could not be found in this CMIS repository or you don't have permissions to access it"
92
+ end
93
+
94
+ def http_status_code
95
+ 404
96
+ end
97
+ end
98
+
99
+ # Exceptions pour CMIS 1.1
100
+ class InvalidType < CmisStandardError
101
+ def title
102
+ "Invalid Type"
103
+ end
104
+
105
+ def summary
106
+ "The specified type is invalid or does not exist."
107
+ end
108
+
109
+ def http_status_code
110
+ 400
111
+ end
112
+ end
113
+
114
+ class InvalidTypeDefinition < CmisStandardError
115
+ def initialize(message = nil, attrs = {})
116
+ super(attrs)
117
+ @message = message
118
+ end
119
+
120
+ def title
121
+ "Invalid Type Definition"
122
+ end
123
+
124
+ def summary
125
+ @message || "The type definition is invalid."
126
+ end
127
+
128
+ def http_status_code
129
+ 400
130
+ end
131
+ end
132
+
133
+ class InvalidOperation < CmisStandardError
134
+ def initialize(message = nil, attrs = {})
135
+ super(attrs)
136
+ @message = message
137
+ end
138
+
139
+ def title
140
+ "Invalid Operation"
141
+ end
142
+
143
+ def summary
144
+ @message || "The requested operation cannot be performed."
145
+ end
146
+
147
+ def http_status_code
148
+ 400
149
+ end
150
+ end
151
+
152
+ class NotSupported < CmisStandardError
153
+ def title
154
+ "Not Supported"
155
+ end
156
+
157
+ def summary
158
+ "The requested operation is not supported by this CMIS repository."
159
+ end
160
+
161
+ def http_status_code
162
+ 405
163
+ end
164
+ end
165
+
166
+ class ConstraintViolation < CmisStandardError
167
+ def initialize(message = nil, attrs = {})
168
+ super(attrs)
169
+ @message = message
170
+ end
171
+
172
+ def title
173
+ "Constraint Violation"
174
+ end
175
+
176
+ def summary
177
+ @message || "A constraint has been violated."
178
+ end
179
+
180
+ def http_status_code
181
+ 409
182
+ end
183
+ end
184
+
185
+ end
@@ -0,0 +1,18 @@
1
+ module CmisServer
2
+ class FolderObject < CmisServer::CmisObject
3
+
4
+ def self.root_folder
5
+ unless @root
6
+ @root=new(CmisServer.configuration.arguments_for_root_folder)
7
+ @root.define_singleton_method :is_root?,(lambda { true })
8
+ end
9
+ @root
10
+ end
11
+
12
+ def initialize(type:, properties: {})
13
+ raise InvalidType unless type.base_id == 'cmis:folder'
14
+ super
15
+ end
16
+
17
+ end
18
+ end