cmis_server 1.0.3 → 1.2.0
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.
- checksums.yaml +4 -4
- data/Rakefile +14 -0
- data/app/controllers/cmis_server/atom_pub/base_controller.rb +43 -0
- data/app/controllers/cmis_server/atom_pub/bulk_controller.rb +2 -0
- data/app/controllers/cmis_server/atom_pub/content_controller.rb +2 -0
- data/app/controllers/cmis_server/atom_pub/entries_controller.rb +2 -0
- data/app/controllers/cmis_server/atom_pub/folder_collection_controller.rb +8 -0
- data/app/controllers/cmis_server/atom_pub/query_controller.rb +8 -2
- data/app/controllers/cmis_server/atom_pub/repository_controller.rb +5 -1
- data/app/controllers/cmis_server/atom_pub/secondary_types_controller.rb +2 -0
- data/app/controllers/cmis_server/atom_pub/service_documents_controller.rb +4 -1
- data/app/controllers/cmis_server/atom_pub/types_controller.rb +2 -0
- data/app/controllers/cmis_server/atom_pub/uri_templates_controller.rb +32 -21
- data/app/services/cmis_server/object_service.rb +21 -11
- data/app/services/cmis_server/repository_service.rb +10 -8
- data/app/views/cmis_server/atom_pub/entries/_cmis_folder_links.atom_entry.builder +1 -1
- data/app/views/cmis_server/atom_pub/entries/_object_entry.atom_entry.builder +3 -3
- data/app/views/cmis_server/atom_pub/entries/type_entry.atom_entry.builder +1 -1
- data/app/views/cmis_server/atom_pub/feeds/feed.atom_feed.builder +1 -1
- data/app/views/cmis_server/atom_pub/service_documents/_workspace.atom_service.builder +6 -26
- data/config/initializers/cmis_base_types.rb +95 -0
- data/config/initializers/cmis_core_configuration.rb +60 -0
- data/config/initializers/inflections.rb +16 -0
- data/config/routes.rb +37 -28
- data/config/routes_standard.rb +49 -0
- data/lib/cmis_server/base_objects/base_type.rb +14 -1
- data/lib/cmis_server/base_objects/folder.rb +1 -1
- data/lib/cmis_server/base_types.rb +11 -1
- data/lib/cmis_server/configuration.rb +12 -3
- data/lib/cmis_server/connectors/base_connector.rb +41 -0
- data/lib/cmis_server/connectors/connector_factory.rb +20 -0
- data/lib/cmis_server/connectors/core_connector.rb +300 -0
- data/lib/cmis_server/context.rb +10 -0
- data/lib/cmis_server/engine.rb +13 -54
- data/lib/cmis_server/engine_diagnostics.rb +56 -0
- data/lib/cmis_server/folder_object.rb +12 -1
- data/lib/cmis_server/inflections.rb +13 -0
- data/lib/cmis_server/repository.rb +116 -5
- data/lib/cmis_server/type.rb +1 -1
- data/lib/cmis_server/version.rb +1 -1
- data/lib/cmis_server/zeitwerk_configuration.rb +39 -0
- data/lib/cmis_server.rb +264 -1
- data/test/dummy/log/test.log +0 -0
- metadata +47 -4
@@ -0,0 +1,16 @@
|
|
1
|
+
# Configure inflections for CMIS Server
|
2
|
+
# This ensures Rails understands how to autoload classes with CMIS in the name
|
3
|
+
|
4
|
+
ActiveSupport::Inflector.inflections(:en) do |inflect|
|
5
|
+
# Don't treat 'cmis' as an acronym that should be capitalized to 'CMIS'
|
6
|
+
# We want CmisServer, not CMISServer
|
7
|
+
|
8
|
+
# Remove any existing CMIS acronym if it exists
|
9
|
+
inflect.acronym_regex = /(?=a)b/ if inflect.respond_to?(:acronym_regex=)
|
10
|
+
|
11
|
+
# Ensure proper pluralization
|
12
|
+
inflect.irregular 'cmis_server', 'cmis_servers'
|
13
|
+
end
|
14
|
+
|
15
|
+
# Ensure the module name is correctly resolved
|
16
|
+
Rails.application.config.autoload_paths += %W(#{File.expand_path('../..', __FILE__)}/lib)
|
data/config/routes.rb
CHANGED
@@ -1,47 +1,56 @@
|
|
1
1
|
CmisServer::Engine.routes.draw do
|
2
|
-
namespace
|
2
|
+
# Utiliser scope au lieu de namespace pour éviter les problèmes Zeitwerk
|
3
|
+
scope path: "atom_pub", module: "atom_pub" do
|
3
4
|
get "/" => "service_documents#service_document"
|
4
5
|
|
5
6
|
scope ":repository_id" do
|
6
7
|
# CMIS 1.1: Routes pour les informations du repository
|
7
|
-
get "capabilities" => "repository#capabilities"
|
8
|
-
get "extensions" => "repository#extensions"
|
9
|
-
get "info" => "repository#info"
|
8
|
+
get "capabilities" => "repository#capabilities"
|
9
|
+
get "extensions" => "repository#extensions"
|
10
|
+
get "info" => "repository#info"
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
post "content/:id/append" => "content#append"
|
14
|
-
|
15
|
-
|
16
|
-
delete "content/:id" => "content#delete_content_stream", as: :delete_content_stream
|
12
|
+
# Content routes
|
13
|
+
get "content/:id" => "content#show"
|
14
|
+
post "content/:id/append" => "content#append"
|
15
|
+
put "content/:id" => "content#set_content_stream"
|
16
|
+
delete "content/:id" => "content#delete_content_stream"
|
17
17
|
|
18
|
-
|
18
|
+
# Entry routes
|
19
|
+
get "entry" => "entries#show"
|
20
|
+
put "entry" => "entries#update"
|
21
|
+
delete "entry" => "entries#destroy"
|
19
22
|
|
20
|
-
# CMIS 1.1:
|
21
|
-
|
23
|
+
# CMIS 1.1: Routes pour la gestion des types
|
24
|
+
get "types" => "types#index"
|
25
|
+
get "types/:id" => "types#show"
|
26
|
+
post "types" => "types#create"
|
27
|
+
put "types/:id" => "types#update"
|
28
|
+
delete "types/:id" => "types#destroy"
|
22
29
|
|
23
|
-
# CMIS 1.1:
|
24
|
-
post "bulk" => "bulk#update_properties"
|
30
|
+
# CMIS 1.1: Route pour bulkUpdateProperties
|
31
|
+
post "bulk" => "bulk#update_properties"
|
25
32
|
|
26
33
|
# CMIS 1.1: Nouvelles routes pour les opérations bulk étendues
|
27
|
-
post "bulk/delete" => "bulk#delete_properties"
|
28
|
-
post "bulk/move" => "bulk#move_objects"
|
34
|
+
post "bulk/delete" => "bulk#delete_properties"
|
35
|
+
post "bulk/move" => "bulk#move_objects"
|
29
36
|
|
30
|
-
# CMIS 1.1:
|
31
|
-
get "objects/:id/types" => "secondary_types#index"
|
32
|
-
post "objects/:id/types" => "secondary_types#add_secondary_type"
|
33
|
-
delete "objects/:id/types/:typeId" => "secondary_types#remove_secondary_type"
|
37
|
+
# CMIS 1.1: Routes pour la gestion des types secondaires
|
38
|
+
get "objects/:id/types" => "secondary_types#index"
|
39
|
+
post "objects/:id/types" => "secondary_types#add_secondary_type"
|
40
|
+
delete "objects/:id/types/:typeId" => "secondary_types#remove_secondary_type"
|
34
41
|
|
35
|
-
|
36
|
-
get "
|
37
|
-
get "
|
42
|
+
# URI template routes
|
43
|
+
get "path" => "uri_templates#object_by_path"
|
44
|
+
get "id" => "uri_templates#object_by_id"
|
45
|
+
get "type" => "uri_templates#type_by_id"
|
38
46
|
|
39
47
|
# CMIS 1.1: Routes pour les requêtes avancées
|
40
|
-
post "query" => "query#query"
|
41
|
-
get "query/types" => "query#queryable_types"
|
42
|
-
post "query/validate" => "query#validate_query"
|
48
|
+
post "query" => "query#query"
|
49
|
+
get "query/types" => "query#queryable_types"
|
50
|
+
post "query/validate" => "query#validate_query"
|
43
51
|
|
44
|
-
|
52
|
+
# Folder collection routes
|
53
|
+
get "folder_collection/:id" => "folder_collection#get_children"
|
45
54
|
post "folder_collection/:id" => "folder_collection#create_children"
|
46
55
|
delete "folder_collection/:id" => "folder_collection#destroy"
|
47
56
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
namespace :atom_pub do
|
3
|
+
get "/" => "service_documents#service_document"
|
4
|
+
|
5
|
+
scope ":repository_id" do
|
6
|
+
# CMIS 1.1: Routes pour les informations du repository (sans noms pour éviter conflits)
|
7
|
+
get "capabilities" => "repository#capabilities"
|
8
|
+
get "extensions" => "repository#extensions"
|
9
|
+
get "info" => "repository#info"
|
10
|
+
|
11
|
+
get "content/:id" => "content#show"
|
12
|
+
# CMIS 1.1: Ajouter la route pour appendContentStream
|
13
|
+
post "content/:id/append" => "content#append"
|
14
|
+
# CMIS 1.1: Ajouter les routes pour les opérations de content stream étendues
|
15
|
+
put "content/:id" => "content#set_content_stream"
|
16
|
+
delete "content/:id" => "content#delete_content_stream"
|
17
|
+
|
18
|
+
resource :entry, only:[:show,:update,:destroy]
|
19
|
+
|
20
|
+
# CMIS 1.1: Ajouter les routes pour la gestion des types
|
21
|
+
resources :types, only: [:index, :show, :create, :update, :destroy]
|
22
|
+
|
23
|
+
# CMIS 1.1: Ajouter la route pour bulkUpdateProperties
|
24
|
+
post "bulk" => "bulk#update_properties"
|
25
|
+
|
26
|
+
# CMIS 1.1: Nouvelles routes pour les opérations bulk étendues
|
27
|
+
post "bulk/delete" => "bulk#delete_properties"
|
28
|
+
post "bulk/move" => "bulk#move_objects"
|
29
|
+
|
30
|
+
# CMIS 1.1: Ajouter les routes pour la gestion des types secondaires
|
31
|
+
get "objects/:id/types" => "secondary_types#index"
|
32
|
+
post "objects/:id/types" => "secondary_types#add_secondary_type"
|
33
|
+
delete "objects/:id/types/:typeId" => "secondary_types#remove_secondary_type"
|
34
|
+
|
35
|
+
get "path" => "uri_templates#object_by_path"
|
36
|
+
get "id" => "uri_templates#object_by_id"
|
37
|
+
get "type" => "uri_templates#type_by_id"
|
38
|
+
|
39
|
+
# CMIS 1.1: Routes pour les requêtes avancées
|
40
|
+
post "query" => "query#query"
|
41
|
+
get "query/types" => "query#queryable_types"
|
42
|
+
post "query/validate" => "query#validate_query"
|
43
|
+
|
44
|
+
get "folder_collection/:id" => "folder_collection#get_children"
|
45
|
+
post "folder_collection/:id" => "folder_collection#create_children"
|
46
|
+
delete "folder_collection/:id" => "folder_collection#destroy"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -66,7 +66,20 @@ module CmisServer
|
|
66
66
|
def property(id,opts)
|
67
67
|
pd=CmisServer::PropertyDefinition.register_property_definition({id:id.freeze}.merge(opts))
|
68
68
|
@self_property_definitions||=[]
|
69
|
-
|
69
|
+
|
70
|
+
# Gérer les tableaux figés - Créer une copie mutable si nécessaire
|
71
|
+
if @self_property_definitions.frozen?
|
72
|
+
@self_property_definitions = @self_property_definitions.dup
|
73
|
+
end
|
74
|
+
|
75
|
+
# Vérifier à nouveau après copie (au cas où le dup serait aussi figé)
|
76
|
+
unless @self_property_definitions.frozen?
|
77
|
+
@self_property_definitions<<pd
|
78
|
+
else
|
79
|
+
# Fallback : créer un nouveau tableau complètement
|
80
|
+
@self_property_definitions = (@self_property_definitions.to_a + [pd])
|
81
|
+
end
|
82
|
+
|
70
83
|
define_properties_methods(pd)
|
71
84
|
end
|
72
85
|
|
@@ -3,7 +3,7 @@ module CmisServer
|
|
3
3
|
|
4
4
|
def self.root_folder
|
5
5
|
unless @root
|
6
|
-
@root=CmisServer::Folder.new(CmisServer.configuration.arguments_for_root_folder)
|
6
|
+
@root=CmisServer::Folder.new(**CmisServer.configuration.arguments_for_root_folder)
|
7
7
|
@root.define_singleton_method :is_root?, lambda { true }
|
8
8
|
end
|
9
9
|
@root
|
@@ -116,7 +116,17 @@ module CmisServer
|
|
116
116
|
]
|
117
117
|
)
|
118
118
|
|
119
|
-
|
119
|
+
# Utiliser une méthode au lieu d'une constante pour éviter les problèmes de gel automatique
|
120
|
+
def self.base_types_array
|
121
|
+
@base_types_array ||= [DOCUMENT_TYPE, FOLDER_TYPE, SECONDARY_TYPE, ITEM_TYPE]
|
122
|
+
end
|
123
|
+
|
124
|
+
# Pour compatibilité ascendante
|
125
|
+
def self.base_types
|
126
|
+
base_types_array
|
127
|
+
end
|
128
|
+
|
129
|
+
BASE_TYPES = base_types_array
|
120
130
|
|
121
131
|
end
|
122
132
|
|
@@ -2,11 +2,16 @@ module CmisServer
|
|
2
2
|
class Configuration
|
3
3
|
|
4
4
|
attr_accessor :http_basic_auth_procedure
|
5
|
-
|
5
|
+
attr_writer :arguments_for_root_folder
|
6
6
|
attr_accessor :default_page_size
|
7
7
|
attr_accessor :debug
|
8
8
|
attr_accessor :repository_info
|
9
9
|
attr_accessor :optimizations
|
10
|
+
attr_accessor :connector_class
|
11
|
+
|
12
|
+
def arguments_for_root_folder
|
13
|
+
@arguments_for_root_folder || @arguments_for_root_folder_lazy&.call
|
14
|
+
end
|
10
15
|
|
11
16
|
def initialize
|
12
17
|
|
@@ -18,8 +23,9 @@ module CmisServer
|
|
18
23
|
raise "http_basic_auth_procedure configuration not set"
|
19
24
|
end
|
20
25
|
|
21
|
-
@
|
22
|
-
|
26
|
+
@arguments_for_root_folder_lazy = Proc.new {
|
27
|
+
{
|
28
|
+
type: defined?(FolderType) ? FolderType.base : nil,
|
23
29
|
properties:{
|
24
30
|
cmis_object_id: 'cmis:root_folder',
|
25
31
|
cmis_name: "Root Folder",
|
@@ -27,6 +33,7 @@ module CmisServer
|
|
27
33
|
cmis_creation_date: DateTime.now,
|
28
34
|
cmis_created_by: 'unknown'
|
29
35
|
}
|
36
|
+
}
|
30
37
|
}
|
31
38
|
|
32
39
|
@default_page_size = 10
|
@@ -36,6 +43,8 @@ module CmisServer
|
|
36
43
|
@repository_info = {}
|
37
44
|
|
38
45
|
@optimizations = {}
|
46
|
+
|
47
|
+
@connector_class = 'CmisServer::Connectors::BaseConnector'
|
39
48
|
|
40
49
|
end
|
41
50
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module CmisServer
|
2
|
+
module Connectors
|
3
|
+
class BaseConnector
|
4
|
+
|
5
|
+
def initialize(user:, config: {})
|
6
|
+
@user = user
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
# Interface pour récupérer les documents d'un utilisateur
|
11
|
+
def find_documents(conditions = {})
|
12
|
+
raise NotImplementedError, "Subclasses must implement find_documents"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Interface pour récupérer les dossiers/espaces d'un utilisateur
|
16
|
+
def find_folders(conditions = {})
|
17
|
+
raise NotImplementedError, "Subclasses must implement find_folders"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Interface pour récupérer un objet spécifique par ID
|
21
|
+
def find_object_by_id(id)
|
22
|
+
raise NotImplementedError, "Subclasses must implement find_object_by_id"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Interface pour récupérer un objet par path
|
26
|
+
def find_object_by_path(path)
|
27
|
+
raise NotImplementedError, "Subclasses must implement find_object_by_path"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Interface pour récupérer les dossiers racines
|
31
|
+
def find_root_folders
|
32
|
+
raise NotImplementedError, "Subclasses must implement find_root_folders"
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
attr_reader :user, :config
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CmisServer
|
2
|
+
module Connectors
|
3
|
+
class ConnectorFactory
|
4
|
+
|
5
|
+
def self.create_connector(user:, config: {})
|
6
|
+
connector_class = CmisServer.configuration.connector_class
|
7
|
+
|
8
|
+
# Constante le connecteur dynamiquement
|
9
|
+
klass = if connector_class.is_a?(String)
|
10
|
+
connector_class.constantize
|
11
|
+
else
|
12
|
+
connector_class
|
13
|
+
end
|
14
|
+
|
15
|
+
klass.new(user: user, config: config)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,300 @@
|
|
1
|
+
require_relative 'base_connector'
|
2
|
+
|
3
|
+
module CmisServer
|
4
|
+
module Connectors
|
5
|
+
class CoreConnector < BaseConnector
|
6
|
+
|
7
|
+
def find_documents(conditions = {})
|
8
|
+
return [] unless search_service_available?
|
9
|
+
|
10
|
+
begin
|
11
|
+
# Convertir les conditions CMIS en paramètres Core search
|
12
|
+
search_params = convert_cmis_to_docs_search_params(conditions)
|
13
|
+
|
14
|
+
# Créer le service de recherche avec les paramètres convertis et l'utilisateur
|
15
|
+
search = docs_search_class.new(search_params, user: user)
|
16
|
+
|
17
|
+
# Exécuter la recherche et retourner les résultats paginés
|
18
|
+
documents = search.paginated_objects
|
19
|
+
|
20
|
+
Rails.logger.info "CoreConnector: Found #{documents.count} documents with params: #{search_params}"
|
21
|
+
documents
|
22
|
+
rescue => e
|
23
|
+
Rails.logger.error "CoreConnector find_documents error: #{e.message}"
|
24
|
+
Rails.logger.error "CoreConnector find_documents backtrace: #{e.backtrace.first(5)}"
|
25
|
+
[]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def find_folders(conditions = {})
|
30
|
+
return [] unless search_service_available?
|
31
|
+
|
32
|
+
begin
|
33
|
+
# Convertir les conditions CMIS en paramètres Core search
|
34
|
+
search_params = convert_cmis_to_spaces_search_params(conditions)
|
35
|
+
|
36
|
+
# Pour les dossiers racines, utiliser les favoris si pas de conditions spécifiques
|
37
|
+
if search_params.empty?
|
38
|
+
search_params = { 'favorite' => true }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Créer le service de recherche avec les paramètres convertis et l'utilisateur
|
42
|
+
search = spaces_search_class.new(search_params, user: user)
|
43
|
+
|
44
|
+
# Exécuter la recherche et retourner les résultats paginés
|
45
|
+
folders = search.paginated_objects
|
46
|
+
|
47
|
+
Rails.logger.info "CoreConnector: Found #{folders.count} folders with params: #{search_params}"
|
48
|
+
folders
|
49
|
+
rescue => e
|
50
|
+
Rails.logger.error "CoreConnector find_folders error: #{e.message}"
|
51
|
+
Rails.logger.error "CoreConnector find_folders backtrace: #{e.backtrace.first(5)}"
|
52
|
+
[]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_object_by_id(id)
|
57
|
+
Rails.logger.info "CoreConnector: Searching for object with ID: #{id}"
|
58
|
+
|
59
|
+
# Cas spécial pour le dossier racine CMIS
|
60
|
+
if id == 'core_root'
|
61
|
+
Rails.logger.info "CoreConnector: Returning root folder for ID: #{id}"
|
62
|
+
return create_root_folder_object
|
63
|
+
end
|
64
|
+
|
65
|
+
# Essayer d'abord comme document
|
66
|
+
doc = find_document_by_id(id)
|
67
|
+
if doc
|
68
|
+
Rails.logger.info "CoreConnector: Found document with ID: #{id}"
|
69
|
+
return doc
|
70
|
+
end
|
71
|
+
|
72
|
+
# Puis essayer comme dossier/espace
|
73
|
+
folder = find_folder_by_id(id)
|
74
|
+
if folder
|
75
|
+
Rails.logger.info "CoreConnector: Found folder with ID: #{id}"
|
76
|
+
return folder
|
77
|
+
end
|
78
|
+
|
79
|
+
Rails.logger.warn "CoreConnector: No object found with ID: #{id}"
|
80
|
+
Rails.logger.info "CoreConnector: Available services - Doc: #{doc_class_available?}, Space: #{space_class_available?}, DocsSearch: #{docs_search_class}, SpacesSearch: #{spaces_search_class}"
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def find_object_by_path(path)
|
85
|
+
Rails.logger.info "CoreConnector: Searching for object with path: #{path}"
|
86
|
+
|
87
|
+
# Cas spécial pour le path racine
|
88
|
+
if path == '/' || path.blank?
|
89
|
+
Rails.logger.info "CoreConnector: Returning root folder for path: #{path}"
|
90
|
+
return create_root_folder_object
|
91
|
+
end
|
92
|
+
|
93
|
+
# Pour les autres paths, chercher dans les espaces Core
|
94
|
+
# TODO: implémenter la recherche par path dans les espaces
|
95
|
+
find_folders({ path: path }).first
|
96
|
+
end
|
97
|
+
|
98
|
+
def find_root_folders
|
99
|
+
# Utiliser les favoris pour les dossiers racines
|
100
|
+
find_folders({})
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def create_root_folder_object
|
106
|
+
# Créer un objet dossier racine virtuel avec l'interface CMIS attendue
|
107
|
+
root_object = OpenStruct.new(
|
108
|
+
id: 'core_root',
|
109
|
+
name: 'Core Repository Root',
|
110
|
+
path: '/',
|
111
|
+
description: 'Dossier racine du repository Core',
|
112
|
+
type: 'cmis:folder',
|
113
|
+
cmis_object_id: 'core_root'
|
114
|
+
)
|
115
|
+
|
116
|
+
# Créer un type object qui simule le type CMIS
|
117
|
+
type_id = OpenStruct.new(path_sanitize: 'cmis_folder')
|
118
|
+
base_id = OpenStruct.new(path_sanitize: 'cmis_folder')
|
119
|
+
|
120
|
+
type_object = OpenStruct.new(
|
121
|
+
id: type_id,
|
122
|
+
base_id: base_id
|
123
|
+
)
|
124
|
+
|
125
|
+
# Créer un base_object qui simule l'objet CMIS sous-jacent
|
126
|
+
base_object = OpenStruct.new(
|
127
|
+
cmis_object_id: 'core_root',
|
128
|
+
type: type_object
|
129
|
+
)
|
130
|
+
root_object.base_object = base_object
|
131
|
+
|
132
|
+
# Ajouter les propriétés CMIS (collection vide pour l'instant)
|
133
|
+
root_object.properties = []
|
134
|
+
|
135
|
+
# Ajouter les méthodes attendues par les vues CMIS
|
136
|
+
def root_object.atompub_entry_properties
|
137
|
+
{
|
138
|
+
id: self.id,
|
139
|
+
title: self.name,
|
140
|
+
summary: self.description,
|
141
|
+
updated: Time.current.iso8601,
|
142
|
+
edited: Time.current.iso8601,
|
143
|
+
author: 'Core System',
|
144
|
+
content: nil
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
root_object
|
149
|
+
end
|
150
|
+
|
151
|
+
def find_document_by_id(id)
|
152
|
+
return nil unless doc_class_available?
|
153
|
+
|
154
|
+
begin
|
155
|
+
doc_class.find_by(id: id)
|
156
|
+
rescue => e
|
157
|
+
Rails.logger.error "CoreConnector find_document_by_id error: #{e.message}"
|
158
|
+
nil
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def find_folder_by_id(id)
|
163
|
+
return nil unless space_class_available?
|
164
|
+
|
165
|
+
begin
|
166
|
+
space_class.find_by(id: id)
|
167
|
+
rescue => e
|
168
|
+
Rails.logger.error "CoreConnector find_folder_by_id error: #{e.message}"
|
169
|
+
nil
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def search_service_available?
|
174
|
+
docs_search_class && spaces_search_class
|
175
|
+
end
|
176
|
+
|
177
|
+
def doc_class_available?
|
178
|
+
doc_class
|
179
|
+
end
|
180
|
+
|
181
|
+
def space_class_available?
|
182
|
+
space_class
|
183
|
+
end
|
184
|
+
|
185
|
+
def docs_search_class
|
186
|
+
@docs_search_class ||= get_core_class('Search', 'DocsSearch')
|
187
|
+
end
|
188
|
+
|
189
|
+
def spaces_search_class
|
190
|
+
@spaces_search_class ||= get_core_class('Search', 'SpacesSearch')
|
191
|
+
end
|
192
|
+
|
193
|
+
def doc_class
|
194
|
+
@doc_class ||= get_core_class(nil, 'Doc')
|
195
|
+
end
|
196
|
+
|
197
|
+
def space_class
|
198
|
+
@space_class ||= get_core_class(nil, 'Space')
|
199
|
+
end
|
200
|
+
|
201
|
+
def get_core_class(namespace, class_name)
|
202
|
+
if namespace
|
203
|
+
# Chercher dans un namespace (ex: Search::DocsSearch)
|
204
|
+
begin
|
205
|
+
namespace_const = Object.const_get(namespace)
|
206
|
+
namespace_const.const_get(class_name)
|
207
|
+
rescue NameError
|
208
|
+
nil
|
209
|
+
end
|
210
|
+
else
|
211
|
+
# Chercher directement (ex: Doc, Space)
|
212
|
+
Object.const_get(class_name) rescue nil
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Convertir les paramètres CMIS en paramètres de recherche Core pour les documents
|
217
|
+
def convert_cmis_to_docs_search_params(conditions)
|
218
|
+
params = {}
|
219
|
+
|
220
|
+
# Mapping des paramètres CMIS vers les paramètres DocsSearch
|
221
|
+
conditions.each do |key, value|
|
222
|
+
case key.to_s
|
223
|
+
when 'cmis:name', 'title', 'name'
|
224
|
+
# Recherche textuelle dans le nom/titre
|
225
|
+
params['text'] = value
|
226
|
+
when 'cmis:parentId', 'parent_id', 'space_id'
|
227
|
+
# Filtrage par espace parent
|
228
|
+
params['space_id'] = value
|
229
|
+
when 'cmis:objectTypeId', 'type_id', 'object_type'
|
230
|
+
# Filtrage par type d'objet (peut correspondre aux templates)
|
231
|
+
params['template_id'] = value
|
232
|
+
when 'favorite', 'favorites'
|
233
|
+
# Filtrage par favoris
|
234
|
+
params['favorite'] = value
|
235
|
+
when 'created_date', 'cmis:creationDate'
|
236
|
+
# Filtres temporels
|
237
|
+
params['created_date'] = value
|
238
|
+
when 'modified_date', 'cmis:lastModificationDate'
|
239
|
+
params['modified_date'] = value
|
240
|
+
when 'tags', 'tag_ids'
|
241
|
+
# Filtrage par tags
|
242
|
+
params['tag_ids'] = value
|
243
|
+
when 'workflow', 'workflow_id'
|
244
|
+
# Filtrage par workflow
|
245
|
+
params['workflow_id'] = value
|
246
|
+
when 'page', 'per_page', 'sort'
|
247
|
+
# Paramètres de pagination et tri
|
248
|
+
params[key] = value
|
249
|
+
else
|
250
|
+
# Passer les autres paramètres tels quels
|
251
|
+
params[key] = value
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
params
|
256
|
+
end
|
257
|
+
|
258
|
+
# Convertir les paramètres CMIS en paramètres de recherche Core pour les espaces/dossiers
|
259
|
+
def convert_cmis_to_spaces_search_params(conditions)
|
260
|
+
params = {}
|
261
|
+
|
262
|
+
# Mapping des paramètres CMIS vers les paramètres SpacesSearch
|
263
|
+
conditions.each do |key, value|
|
264
|
+
case key.to_s
|
265
|
+
when 'cmis:name', 'title', 'name'
|
266
|
+
# Recherche textuelle dans le nom
|
267
|
+
params['text'] = value
|
268
|
+
when 'cmis:parentId', 'parent_id', 'tagset_id'
|
269
|
+
# Filtrage par espace parent (hiérarchie)
|
270
|
+
params['tagset_id'] = value
|
271
|
+
when 'children_ids'
|
272
|
+
# Filtrage par enfants
|
273
|
+
params['children_ids'] = value
|
274
|
+
when 'favorite', 'favorites'
|
275
|
+
# Filtrage par favoris
|
276
|
+
params['favorite'] = value
|
277
|
+
when 'category', 'categories'
|
278
|
+
# Filtrage par catégorie
|
279
|
+
params['category'] = value
|
280
|
+
when 'type', 'space_type'
|
281
|
+
# Filtrage par type d'espace
|
282
|
+
params['type'] = value
|
283
|
+
when 'path'
|
284
|
+
# Recherche par chemin (à implémenter)
|
285
|
+
params['path'] = value
|
286
|
+
when 'page', 'per_page', 'sort'
|
287
|
+
# Paramètres de pagination et tri
|
288
|
+
params[key] = value
|
289
|
+
else
|
290
|
+
# Passer les autres paramètres tels quels
|
291
|
+
params[key] = value
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
params
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
data/lib/cmis_server/context.rb
CHANGED
@@ -6,6 +6,16 @@ module CmisServer
|
|
6
6
|
def initialize(current_user: nil)
|
7
7
|
@current_user= current_user
|
8
8
|
end
|
9
|
+
|
10
|
+
# Méthode pour permettre l'accès par clé comme un hash
|
11
|
+
def [](key)
|
12
|
+
case key.to_sym
|
13
|
+
when :current_user, :user
|
14
|
+
@current_user
|
15
|
+
else
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
9
19
|
|
10
20
|
end
|
11
21
|
end
|