cmis_server 1.2.1 → 1.3.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/app/controllers/cmis_server/atom_pub/entries_controller.rb +2 -1
- data/app/controllers/cmis_server/atom_pub/folder_collection_controller.rb +55 -11
- data/app/controllers/cmis_server/atom_pub/query_controller.rb +44 -16
- data/app/controllers/cmis_server/atom_pub/service_documents_controller.rb +1 -1
- data/app/services/cmis_server/discovery_service.rb +58 -9
- data/app/services/cmis_server/navigation_service.rb +62 -3
- data/app/services/cmis_server/object_service.rb +112 -13
- 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 +4 -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 +3 -0
- data/app/views/cmis_server/atom_pub/query_results_feed.atom_feed.builder +59 -0
- data/app/views/cmis_server/atom_pub/queryable_types_feed.atom_feed.builder +35 -0
- data/app/views/cmis_server/atom_pub/service_documents/_workspace.atom_service.builder +1 -1
- data/config/initializers/cmis_core_configuration.rb +31 -8
- data/lib/cmis_server/atom_pub/entry_parser.rb +57 -22
- data/lib/cmis_server/cmis_object.rb +32 -2
- data/lib/cmis_server/configuration.rb +4 -3
- data/lib/cmis_server/connectors/CORE_CONNECTOR_QUERIES.md +180 -0
- data/lib/cmis_server/connectors/core_connector.rb +189 -69
- data/lib/cmis_server/constants.rb +3 -2
- data/lib/cmis_server/document_adapter.rb +135 -0
- data/lib/cmis_server/document_object.rb +1 -1
- data/lib/cmis_server/engine.rb +95 -0
- data/lib/cmis_server/exceptions.rb +19 -0
- data/lib/cmis_server/folder_adapter.rb +126 -0
- data/lib/cmis_server/property.rb +40 -4
- data/lib/cmis_server/query/parser.rb +11 -0
- data/lib/cmis_server/query/{parser.racc.rb → parser_racc.rb} +2 -2
- data/lib/cmis_server/query/{parser.rex.rb → parser_rex.rb} +6 -1
- data/lib/cmis_server/query/simple_parser.rb +276 -0
- data/lib/cmis_server/query/statement.rb +3 -389
- data/lib/cmis_server/query/statement.rb.bak +395 -0
- data/lib/cmis_server/query.rb +11 -2
- data/lib/cmis_server/renderable_collection.rb +23 -2
- data/lib/cmis_server/repository.rb +1 -1
- data/lib/cmis_server/version.rb +1 -1
- data/lib/cmis_server.rb +13 -0
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bc9d9ec2eaf839148dcb6721c119047890413d107a85595a74bc35cbb53bd84
|
4
|
+
data.tar.gz: 8872e2dd94ccc9012f78de2d1481b32efaccebe36dfa3f363d37f19b9f666ccd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff9ac2fa277eac8327b9aa4e59b0756abdfc8df9a801dfd43d72419ecb202d8650403f0385bce7770b45536bf59380d214215cf2576ce4b7ab3e261640f407fd
|
7
|
+
data.tar.gz: 71165260bafa6571c3a0b85426c911cb01256e29573c0f2e8aba8206bcf5e5cf9fedc570798763b2d195b56cbfd9278909be6a3a116cf1317d38f8ce5433fdea
|
@@ -9,56 +9,100 @@ module CmisServer
|
|
9
9
|
|
10
10
|
|
11
11
|
def get_children
|
12
|
-
|
13
|
-
|
12
|
+
|
13
|
+
begin
|
14
|
+
service =NavigationService.new(@repository, current_context)
|
15
|
+
response=service.get_children(params[:id], max_items: max_items_param, order_by: params[:orderBy])
|
16
|
+
|
17
|
+
rescue => e
|
18
|
+
Rails.logger.error "FolderCollectionController#get_children - Error: #{e.message}"
|
19
|
+
Rails.logger.error "FolderCollectionController#get_children - Backtrace: #{e.backtrace.first(10).join("\n")}"
|
20
|
+
raise e
|
21
|
+
end
|
14
22
|
|
15
|
-
|
16
|
-
|
23
|
+
# Utiliser le connecteur pour récupérer le dossier parent
|
24
|
+
connector = CmisServer::Connectors::ConnectorFactory.create_connector(
|
25
|
+
user: current_context.current_user
|
26
|
+
)
|
27
|
+
parent_object = connector.find_object_by_id(params[:id])
|
28
|
+
|
29
|
+
# Gérer le cas spécial du root folder
|
30
|
+
if params[:id] == 'root_folder' || params[:id] == 'root_folder_id' || params[:id] == 'core_root' || params[:id] == 'root'
|
31
|
+
# Pour le root, utiliser directement nil comme parent_folder
|
32
|
+
# car c'est un dossier virtuel qui n'a pas besoin d'être dans la collection
|
33
|
+
parent_folder = nil
|
34
|
+
elsif parent_object
|
35
|
+
# C'est un objet Core normal, le convertir en objet CMIS
|
36
|
+
adapter = CmisServer::FolderAdapter.new(nil, context: current_context)
|
37
|
+
parent_folder = adapter.find(parent_object.id.to_s)
|
38
|
+
else
|
39
|
+
raise CmisServer::ObjectNotFound.new("Folder '#{params[:id]}' not found")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Si nous avons une erreur avec les objets, retourner une collection vide
|
43
|
+
items = response[:objects] || []
|
44
|
+
|
45
|
+
|
46
|
+
@collection=RenderableCollection.new(base_object: parent_folder,
|
47
|
+
items: items)
|
17
48
|
render 'cmis_server/atom_pub/feeds/feed', formats: :atom_feed
|
18
49
|
end
|
19
50
|
|
20
51
|
def create_children
|
21
52
|
#Check if Document exists
|
22
53
|
begin
|
54
|
+
|
23
55
|
if request_entry_parser.cmis_object_id
|
24
56
|
#We move the document to the folder
|
25
57
|
|
26
58
|
else
|
27
59
|
#We create the document
|
28
60
|
object_type=request_entry_parser.object_type
|
29
|
-
|
61
|
+
|
62
|
+
# Protection si object_type est nil
|
63
|
+
if object_type.nil?
|
64
|
+
Rails.logger.error "Object type is nil, cannot determine type"
|
65
|
+
raise "Invalid object type in request"
|
66
|
+
end
|
67
|
+
|
68
|
+
service =ObjectService.new(@repository, current_context)
|
30
69
|
case object_type.base_type.id
|
31
70
|
when "cmis:document"
|
32
71
|
id =service.create_document(request_entry_parser.object_properties, folder_id: params[:id], content_stream: request_entry_parser.content_stream)
|
33
|
-
@object=CmisServer::DocumentAdapter
|
72
|
+
@object=CmisServer::DocumentAdapter.class_adapter(context: current_context).find(id).to_renderable_object
|
34
73
|
render 'cmis_server/atom_pub/entries/object_entry', formats: :atom_entry, status: :created
|
35
74
|
when "cmis:folder"
|
36
|
-
id =service.create_folder(request_entry_parser.object_properties)
|
37
|
-
@object=CmisServer::FolderAdapter.class_adapter(context:
|
75
|
+
id =service.create_folder(request_entry_parser.object_properties, parent_folder_id: params[:id])
|
76
|
+
@object=CmisServer::FolderAdapter.class_adapter(context: current_context).find(id).to_renderable_object
|
38
77
|
render 'cmis_server/atom_pub/entries/object_entry', formats: :atom_entry, status: :created
|
39
78
|
when "cmis:policy"
|
40
79
|
# Implémentation future de la gestion des politiques
|
41
80
|
when "cmis:item"
|
42
81
|
id =service.create_item(request_entry_parser.object_properties)
|
43
|
-
@object=CmisServer::ItemAdapter.class_adapter(context:
|
82
|
+
@object=CmisServer::ItemAdapter.class_adapter(context: current_context).find(id).to_renderable_object
|
44
83
|
render 'cmis_server/atom_pub/entries/object_entry', formats: :atom_entry, status: :created
|
45
84
|
else
|
46
85
|
raise "Unknown type #{object_type.base_type.id}"
|
47
86
|
end
|
48
87
|
end
|
49
88
|
rescue CmisServer::ObjectService::DuplicateFile => e
|
89
|
+
Rails.logger.error "DuplicateFile error: #{e.message}"
|
50
90
|
@object=e.duplicate.to_renderable_object
|
51
91
|
render 'cmis_server/atom_pub/entries/object_entry', formats: :atom_entry, status: :conflict
|
92
|
+
rescue => e
|
93
|
+
Rails.logger.error "Error in create_children: #{e.message}"
|
94
|
+
Rails.logger.error "Backtrace: #{e.backtrace.first(10).join("\n")}"
|
95
|
+
raise e
|
52
96
|
end
|
53
97
|
end
|
54
98
|
|
55
99
|
def get_descendants
|
56
|
-
service=NavigationService.new(@repository,
|
100
|
+
service=NavigationService.new(@repository, current_context)
|
57
101
|
service.get_descendants(params[:id])
|
58
102
|
end
|
59
103
|
|
60
104
|
def destroy
|
61
|
-
service = ObjectService.new(@repository,
|
105
|
+
service = ObjectService.new(@repository, current_context)
|
62
106
|
service.delete_object(params[:id])
|
63
107
|
head :no_content
|
64
108
|
end
|
@@ -13,8 +13,9 @@ module CmisServer
|
|
13
13
|
|
14
14
|
begin
|
15
15
|
discovery_service = CmisServer::DiscoveryService.new(@repository, current_context)
|
16
|
+
|
16
17
|
results = discovery_service.query(
|
17
|
-
|
18
|
+
query_data[:statement],
|
18
19
|
search_all_versions: query_data[:search_all_versions],
|
19
20
|
include_allowable_actions: query_data[:include_allowable_actions],
|
20
21
|
include_relationships: query_data[:include_relationships],
|
@@ -23,19 +24,31 @@ module CmisServer
|
|
23
24
|
skip_count: query_data[:skip_count]
|
24
25
|
)
|
25
26
|
|
27
|
+
|
26
28
|
respond_to do |format|
|
27
29
|
format.atom_feed { render "cmis_server/atom_pub/query_results_feed", locals: { results: results } }
|
28
30
|
format.json { render json: format_query_results_for_json(results) }
|
29
31
|
end
|
30
32
|
rescue => e
|
31
|
-
|
33
|
+
Rails.logger.error "QueryController#query: Error occurred: #{e.class} - #{e.message}"
|
34
|
+
Rails.logger.error "QueryController#query: Backtrace:\n#{e.backtrace.join("\n")}"
|
35
|
+
|
36
|
+
# Add detailed error message to response
|
37
|
+
respond_to do |format|
|
38
|
+
format.atom_feed do
|
39
|
+
render xml: { error: { type: e.class.name, message: e.message, backtrace: e.backtrace[0..5] } }.to_xml(root: 'error'), status: 500
|
40
|
+
end
|
41
|
+
format.json do
|
42
|
+
render json: { error: { type: e.class.name, message: e.message, backtrace: e.backtrace[0..5] } }, status: 500
|
43
|
+
end
|
44
|
+
end
|
32
45
|
end
|
33
46
|
end
|
34
47
|
|
35
48
|
# GET /query/types
|
36
49
|
def queryable_types
|
37
50
|
repository = repository_from_request
|
38
|
-
queryable_types =
|
51
|
+
queryable_types = CmisServer::TypeRegistry.types.select { |_, type| type.queryable }
|
39
52
|
|
40
53
|
respond_to do |format|
|
41
54
|
format.atom_feed { render "cmis_server/atom_pub/queryable_types_feed", locals: { types: queryable_types } }
|
@@ -105,23 +118,38 @@ module CmisServer
|
|
105
118
|
end
|
106
119
|
|
107
120
|
def parse_atom_pub_query_request
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
121
|
+
# Rails parse automatiquement le JSON et le met dans params
|
122
|
+
if params[:query]
|
123
|
+
# Les données sont déjà parsées par Rails
|
124
|
+
{
|
125
|
+
statement: params[:query][:statement] || params[:statement],
|
126
|
+
search_all_versions: params[:query][:searchAllVersions] == true,
|
127
|
+
include_allowable_actions: params[:query][:includeAllowableActions] == true,
|
128
|
+
include_relationships: params[:query][:includeRelationships] || "none",
|
129
|
+
rendition_filter: params[:query][:renditionFilter] || "",
|
130
|
+
max_items: (params[:query][:maxItems] || 100).to_i,
|
131
|
+
skip_count: (params[:query][:skipCount] || 0).to_i
|
132
|
+
}
|
133
|
+
else
|
134
|
+
# Fallback pour le XML si nécessaire
|
135
|
+
doc = Nokogiri::XML(request.body.read)
|
136
|
+
doc.remove_namespaces!
|
137
|
+
|
138
|
+
{
|
139
|
+
statement: doc.at_xpath("//statement")&.text || params[:q],
|
140
|
+
search_all_versions: doc.at_xpath("//searchAllVersions")&.text == "true",
|
141
|
+
include_allowable_actions: doc.at_xpath("//includeAllowableActions")&.text == "true",
|
142
|
+
include_relationships: doc.at_xpath("//includeRelationships")&.text || "none",
|
143
|
+
rendition_filter: doc.at_xpath("//renditionFilter")&.text || "",
|
144
|
+
max_items: (doc.at_xpath("//maxItems")&.text || params[:maxItems] || 100).to_i,
|
145
|
+
skip_count: (doc.at_xpath("//skipCount")&.text || params[:skipCount] || 0).to_i
|
146
|
+
}
|
147
|
+
end
|
120
148
|
end
|
121
149
|
|
122
150
|
def format_query_results_for_json(results)
|
123
151
|
{
|
124
|
-
results: results[:objects].map { |obj| obj.to_json },
|
152
|
+
results: (results[:query_results] || results[:objects] || []).map { |obj| obj.to_json },
|
125
153
|
hasMoreItems: results[:has_more_items],
|
126
154
|
numItems: results[:num_items]
|
127
155
|
}
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
1
3
|
module CmisServer
|
2
4
|
class DiscoveryService
|
3
5
|
|
@@ -8,23 +10,70 @@ module CmisServer
|
|
8
10
|
|
9
11
|
|
10
12
|
def query(statement, search_all_versions: false, include_relationships: :none, rendition_filter: "cmis:none", include_allowable_actions: false, max_items: 10, skip_count: 0)
|
11
|
-
|
12
|
-
|
13
|
+
|
14
|
+
begin
|
15
|
+
|
16
|
+
query_statement=CmisServer::Query::Parser.parse(statement)
|
17
|
+
|
18
|
+
rescue => e
|
19
|
+
Rails.logger.error "Error in DiscoveryService.query: #{e.class} - #{e.message}"
|
20
|
+
Rails.logger.error e.backtrace.join("\n")
|
21
|
+
raise
|
22
|
+
end
|
13
23
|
|
14
24
|
#Verify that there is only one Table
|
15
25
|
table=query_statement.query_expression.from.tables.first
|
16
|
-
|
17
|
-
|
26
|
+
# La vérification est déjà faite dans le lambda is_a?
|
27
|
+
raise "Join are not supported" unless table.is_a?.call(CmisServer::Query::Statement::Table)
|
28
|
+
|
29
|
+
# Récupérer le type CMIS
|
30
|
+
target_type=CmisServer::TypeRegistry.get_type(table.name)
|
31
|
+
unless target_type
|
32
|
+
raise ::CmisServer::InvalidArgument.new("Type '#{table.name}' not found")
|
33
|
+
end
|
18
34
|
|
19
|
-
|
35
|
+
# Utiliser le connecteur pour faire la recherche
|
36
|
+
connector = CmisServer::Connectors::ConnectorFactory.create_connector(
|
37
|
+
user: @context.current_user
|
38
|
+
)
|
39
|
+
|
40
|
+
# Convertir les conditions WHERE en conditions de recherche
|
41
|
+
conditions = query_statement.query_expression.where ? query_statement.query_expression.where.to_h : {}
|
42
|
+
|
43
|
+
# Rechercher selon le type
|
44
|
+
objects = case target_type.base_id.to_s
|
45
|
+
when 'cmis:document'
|
46
|
+
connector.find_documents(conditions.merge(page: (skip_count / max_items) + 1, per_page: max_items))
|
47
|
+
when 'cmis:folder'
|
48
|
+
connector.find_folders(conditions.merge(page: (skip_count / max_items) + 1, per_page: max_items))
|
49
|
+
else
|
50
|
+
[]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Convertir en objets renderable
|
54
|
+
renderable_objects = objects.map do |obj|
|
55
|
+
# Utiliser les adapters pour créer les objets CMIS correctement
|
56
|
+
if target_type.base_id.to_s == 'cmis:document' && obj.is_a?(::Doc)
|
57
|
+
adapter = CmisServer::DocumentAdapter.new(nil, context: @context)
|
58
|
+
cmis_doc = adapter.find(obj.id.to_s)
|
59
|
+
cmis_doc.to_renderable_object
|
60
|
+
elsif target_type.base_id.to_s == 'cmis:folder' && (obj.is_a?(::Tagset) || (obj.respond_to?(:is_space) && obj.is_space))
|
61
|
+
adapter = CmisServer::FolderAdapter.new(nil, context: @context)
|
62
|
+
cmis_folder = adapter.find(obj.id.to_s)
|
63
|
+
cmis_folder.to_renderable_object
|
64
|
+
else
|
65
|
+
# Fallback pour les types non supportés
|
66
|
+
Rails.logger.warn "DiscoveryService: Unsupported object type for query result: #{obj.class}"
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
end.compact
|
20
70
|
|
21
71
|
{
|
22
|
-
query_results:
|
23
|
-
has_more_items:
|
24
|
-
num_items: nil, #
|
72
|
+
query_results: renderable_objects,
|
73
|
+
has_more_items: objects.count == max_items, # Si on a le max, il y en a peut-être d'autres
|
74
|
+
num_items: nil, # Non supporté pour l'instant
|
25
75
|
}
|
26
76
|
|
27
|
-
|
28
77
|
end
|
29
78
|
|
30
79
|
end
|
@@ -8,11 +8,70 @@ module CmisServer
|
|
8
8
|
|
9
9
|
def get_children(folder_id, max_items: 10, skip_count: 0, order_by: {'cmis:creationDate' => :asc}, filter: [], include_relationships: :none, rendition_filter: "cmis:none", include_allowable_actions: false, include_path_segment: false, with_object: false)
|
10
10
|
|
11
|
-
|
11
|
+
# Utiliser le connecteur pour récupérer le dossier et ses enfants
|
12
|
+
connector = CmisServer::Connectors::ConnectorFactory.create_connector(
|
13
|
+
user: @context.current_user
|
14
|
+
)
|
15
|
+
|
16
|
+
# Récupérer le dossier parent
|
17
|
+
folder = connector.find_object_by_id(folder_id)
|
18
|
+
unless folder
|
19
|
+
raise CmisServer::ObjectNotFound.new(debug_data: "Folder '#{folder_id}' not found")
|
20
|
+
end
|
21
|
+
|
22
|
+
# Déterminer quels enfants récupérer selon le type de dossier
|
23
|
+
children = []
|
24
|
+
|
25
|
+
# Si c'est le dossier racine, retourner les espaces favoris de l'utilisateur
|
26
|
+
if folder_id == 'core_root' || folder_id == 'root_folder' || folder_id == 'root_folder_id' || folder_id == 'root'
|
27
|
+
# Les espaces favoris sont les "dossiers racines" de l'utilisateur dans Core
|
28
|
+
children = connector.find_root_folders()
|
29
|
+
else
|
30
|
+
# Pour un espace spécifique, récupérer:
|
31
|
+
# 1. Les documents dans cet espace
|
32
|
+
documents = connector.find_documents({'space_ids' => [folder_id]})
|
33
|
+
# 2. Les sous-espaces (si applicable)
|
34
|
+
sub_spaces = connector.find_folders({'parent_id' => folder_id})
|
35
|
+
|
36
|
+
children = documents + sub_spaces
|
37
|
+
end
|
38
|
+
|
39
|
+
# Convertir en objets renderable
|
40
|
+
renderable_objects = children.map do |obj|
|
41
|
+
begin
|
42
|
+
|
43
|
+
# Déterminer le type d'objet et créer l'adaptateur approprié
|
44
|
+
if obj.is_a?(::Doc)
|
45
|
+
# Document Core -> CMIS Document
|
46
|
+
adapter = CmisServer::DocumentAdapter.new(nil, context: @context)
|
47
|
+
cmis_doc = adapter.find(obj.id.to_s)
|
48
|
+
cmis_doc.to_renderable_object
|
49
|
+
elsif obj.is_a?(::Tagset) || (obj.respond_to?(:is_space) && obj.is_space)
|
50
|
+
# Tagset/Space Core -> CMIS Folder
|
51
|
+
adapter = CmisServer::FolderAdapter.new(nil, context: @context)
|
52
|
+
cmis_folder = adapter.find(obj.id.to_s)
|
53
|
+
cmis_folder.to_renderable_object
|
54
|
+
else
|
55
|
+
# Fallback: créer un document CMIS générique
|
56
|
+
doc_type = CmisServer::TypeRegistry.get_type('cmis:document') || CmisServer::DocumentType.base
|
57
|
+
properties = {
|
58
|
+
'cmis:objectId' => CmisServer::Property.new(id: 'cmis:objectId', value: obj.id.to_s),
|
59
|
+
'cmis:name' => CmisServer::Property.new(id: 'cmis:name', value: obj.respond_to?(:title) ? obj.title : 'Unknown')
|
60
|
+
}
|
61
|
+
cmis_doc = CmisServer::DocumentObject.new(type: doc_type, properties: properties)
|
62
|
+
cmis_doc.cmis_object_id = obj.id.to_s
|
63
|
+
cmis_doc.to_renderable_object
|
64
|
+
end
|
65
|
+
rescue => e
|
66
|
+
Rails.logger.error "NavigationService: Error converting object: #{e.message}"
|
67
|
+
Rails.logger.error "NavigationService: Backtrace: #{e.backtrace.first(5).join("\n")}"
|
68
|
+
raise e
|
69
|
+
end
|
70
|
+
end
|
12
71
|
|
13
72
|
{
|
14
|
-
objects:
|
15
|
-
has_more_items:
|
73
|
+
objects: renderable_objects,
|
74
|
+
has_more_items: children.count == max_items,
|
16
75
|
}
|
17
76
|
end
|
18
77
|
|
@@ -16,11 +16,23 @@ module CmisServer
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def create_document(properties, folder_id: nil, content_stream: nil, versionning_state: :none, policies: [], add_aces: [], remove_aces: [])
|
19
|
-
|
19
|
+
# Utiliser le connecteur pour créer le document
|
20
|
+
connector = CmisServer::Connectors::ConnectorFactory.create_connector(
|
21
|
+
user: @context[:current_user] || @context.current_user
|
22
|
+
)
|
23
|
+
|
24
|
+
# Si le connecteur supporte la création directe
|
25
|
+
if connector.respond_to?(:create_document)
|
26
|
+
return connector.create_document(properties, folder_id: folder_id, content_stream: content_stream)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Sinon, utiliser l'ancien système d'adapters
|
30
|
+
doc =CmisServer::DocumentObject.new(type: CmisServer::DocumentType.base, properties: properties)
|
20
31
|
adapter=CmisServer::DocumentAdapter.new(doc, context: @context)
|
21
32
|
|
22
|
-
if folder_id
|
23
|
-
|
33
|
+
if folder_id
|
34
|
+
folder_adapter = CmisServer::FolderAdapter.class_adapter(context: @context).find(folder_id)
|
35
|
+
adapter.add_to_folder(folder_adapter)
|
24
36
|
end
|
25
37
|
|
26
38
|
if content_stream
|
@@ -35,8 +47,23 @@ module CmisServer
|
|
35
47
|
raise NotImplemented
|
36
48
|
end
|
37
49
|
|
38
|
-
def create_folder(properties, add_aces: [], remove_aces: [])
|
39
|
-
|
50
|
+
def create_folder(properties, parent_folder_id: nil, add_aces: [], remove_aces: [])
|
51
|
+
# Utiliser le connecteur pour créer le dossier
|
52
|
+
connector = CmisServer::Connectors::ConnectorFactory.create_connector(
|
53
|
+
user: @context[:current_user] || @context.current_user
|
54
|
+
)
|
55
|
+
|
56
|
+
# Si le connecteur supporte la création directe
|
57
|
+
if connector.respond_to?(:create_folder)
|
58
|
+
return connector.create_folder(properties, parent_folder_id: parent_folder_id)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Sinon, utiliser l'ancien système d'adapters
|
62
|
+
folder = CmisServer::FolderObject.new(type: CmisServer::TypeRegistry.get_type('cmis:folder'), properties: properties)
|
63
|
+
adapter = CmisServer::FolderAdapter.new(folder, context: @context)
|
64
|
+
|
65
|
+
adapter.save!
|
66
|
+
adapter.object.cmis_object_id
|
40
67
|
end
|
41
68
|
|
42
69
|
def create_relationship
|
@@ -48,7 +75,7 @@ module CmisServer
|
|
48
75
|
end
|
49
76
|
|
50
77
|
def create_item(properties, folder_id: nil, policies: [], add_aces: [], remove_aces: [])
|
51
|
-
item = CmisServer::ItemObject.new(type: ItemType.base, properties: properties)
|
78
|
+
item = CmisServer::ItemObject.new(type: CmisServer::ItemType.base, properties: properties)
|
52
79
|
adapter = CmisServer::ItemAdapter.new(item, context: @context)
|
53
80
|
|
54
81
|
if folder_id && folder = CmisServer::FolderAdapter.class_adapter(context: @context).find(folder_id)
|
@@ -72,9 +99,39 @@ module CmisServer
|
|
72
99
|
record = connector.find_object_by_id(id)
|
73
100
|
raise CmisServer::ObjectNotFound unless record
|
74
101
|
|
75
|
-
#
|
76
|
-
|
77
|
-
|
102
|
+
# Convertir l'objet Core en objet CMIS avec RenderableObject
|
103
|
+
if record.is_a?(::Doc)
|
104
|
+
adapter = CmisServer::DocumentAdapter.new(nil, context: @context)
|
105
|
+
cmis_obj = adapter.find(record.id.to_s)
|
106
|
+
cmis_obj.to_renderable_object
|
107
|
+
elsif record.is_a?(::Tagset) || (record.respond_to?(:is_space) && record.is_space)
|
108
|
+
adapter = CmisServer::FolderAdapter.new(nil, context: @context)
|
109
|
+
cmis_obj = adapter.find(record.id.to_s)
|
110
|
+
cmis_obj.to_renderable_object
|
111
|
+
else
|
112
|
+
# Pour les objets déjà CMIS (comme root folder OpenStruct), créer un RenderableObject
|
113
|
+
# directement à partir de l'objet
|
114
|
+
if record.respond_to?(:to_renderable_object)
|
115
|
+
record.to_renderable_object
|
116
|
+
else
|
117
|
+
# Fallback : créer un folder CMIS basique
|
118
|
+
folder_type = CmisServer::TypeRegistry.get_type('cmis:folder') || CmisServer::FolderType.base
|
119
|
+
properties = {
|
120
|
+
'cmis:objectId' => CmisServer::Property.new(id: 'cmis:objectId', value: record.id.to_s),
|
121
|
+
'cmis:name' => CmisServer::Property.new(id: 'cmis:name', value: record.respond_to?(:title) ? record.title : record.respond_to?(:name) ? record.name : 'Unknown'),
|
122
|
+
'cmis:baseTypeId' => CmisServer::Property.new(id: 'cmis:baseTypeId', value: 'cmis:folder'),
|
123
|
+
'cmis:objectTypeId' => CmisServer::Property.new(id: 'cmis:objectTypeId', value: 'cmis:folder'),
|
124
|
+
'cmis:createdBy' => CmisServer::Property.new(id: 'cmis:createdBy', value: record.respond_to?(:responsible) ? record.responsible : 'System'),
|
125
|
+
'cmis:creationDate' => CmisServer::Property.new(id: 'cmis:creationDate', value: record.respond_to?(:created_at) ? record.created_at : Time.now),
|
126
|
+
'cmis:lastModifiedBy' => CmisServer::Property.new(id: 'cmis:lastModifiedBy', value: record.respond_to?(:responsible) ? record.responsible : 'System'),
|
127
|
+
'cmis:lastModificationDate' => CmisServer::Property.new(id: 'cmis:lastModificationDate', value: record.respond_to?(:updated_at) ? record.updated_at : Time.now),
|
128
|
+
'cmis:parentId' => CmisServer::Property.new(id: 'cmis:parentId', value: nil)
|
129
|
+
}
|
130
|
+
folder = CmisServer::FolderObject.new(type: folder_type, properties: properties)
|
131
|
+
folder.cmis_object_id = record.id.to_s
|
132
|
+
folder.to_renderable_object
|
133
|
+
end
|
134
|
+
end
|
78
135
|
end
|
79
136
|
|
80
137
|
def get_properties(id, filter: [])
|
@@ -90,9 +147,39 @@ module CmisServer
|
|
90
147
|
record = connector.find_object_by_path(path)
|
91
148
|
raise CmisServer::ObjectNotFound unless record
|
92
149
|
|
93
|
-
#
|
94
|
-
|
95
|
-
|
150
|
+
# Utiliser la même logique que get_object pour convertir en RenderableObject
|
151
|
+
if record.is_a?(::Doc)
|
152
|
+
adapter = CmisServer::DocumentAdapter.new(nil, context: @context)
|
153
|
+
cmis_obj = adapter.find(record.id.to_s)
|
154
|
+
cmis_obj.to_renderable_object
|
155
|
+
elsif record.is_a?(::Tagset) || (record.respond_to?(:is_space) && record.is_space)
|
156
|
+
adapter = CmisServer::FolderAdapter.new(nil, context: @context)
|
157
|
+
cmis_obj = adapter.find(record.id.to_s)
|
158
|
+
cmis_obj.to_renderable_object
|
159
|
+
else
|
160
|
+
# Pour les objets déjà CMIS (comme root folder OpenStruct), créer un RenderableObject
|
161
|
+
if record.respond_to?(:to_renderable_object)
|
162
|
+
record.to_renderable_object
|
163
|
+
else
|
164
|
+
# Fallback : créer un folder CMIS basique
|
165
|
+
folder_type = CmisServer::TypeRegistry.get_type('cmis:folder') || CmisServer::FolderType.base
|
166
|
+
properties = {
|
167
|
+
'cmis:objectId' => CmisServer::Property.new(id: 'cmis:objectId', value: record.id.to_s),
|
168
|
+
'cmis:name' => CmisServer::Property.new(id: 'cmis:name', value: record.respond_to?(:title) ? record.title : record.respond_to?(:name) ? record.name : 'Unknown'),
|
169
|
+
'cmis:path' => CmisServer::Property.new(id: 'cmis:path', value: path),
|
170
|
+
'cmis:baseTypeId' => CmisServer::Property.new(id: 'cmis:baseTypeId', value: 'cmis:folder'),
|
171
|
+
'cmis:objectTypeId' => CmisServer::Property.new(id: 'cmis:objectTypeId', value: 'cmis:folder'),
|
172
|
+
'cmis:createdBy' => CmisServer::Property.new(id: 'cmis:createdBy', value: record.respond_to?(:responsible) ? record.responsible : 'System'),
|
173
|
+
'cmis:creationDate' => CmisServer::Property.new(id: 'cmis:creationDate', value: record.respond_to?(:created_at) ? record.created_at : Time.now),
|
174
|
+
'cmis:lastModifiedBy' => CmisServer::Property.new(id: 'cmis:lastModifiedBy', value: record.respond_to?(:responsible) ? record.responsible : 'System'),
|
175
|
+
'cmis:lastModificationDate' => CmisServer::Property.new(id: 'cmis:lastModificationDate', value: record.respond_to?(:updated_at) ? record.updated_at : Time.now),
|
176
|
+
'cmis:parentId' => CmisServer::Property.new(id: 'cmis:parentId', value: nil)
|
177
|
+
}
|
178
|
+
folder = CmisServer::FolderObject.new(type: folder_type, properties: properties)
|
179
|
+
folder.cmis_object_id = record.id.to_s
|
180
|
+
folder.to_renderable_object
|
181
|
+
end
|
182
|
+
end
|
96
183
|
end
|
97
184
|
|
98
185
|
def get_content_stream
|
@@ -156,7 +243,19 @@ module CmisServer
|
|
156
243
|
raise NotImplemented
|
157
244
|
end
|
158
245
|
|
159
|
-
def delete_object
|
246
|
+
def delete_object(id, all_versions: true)
|
247
|
+
# Utiliser le connecteur pour supprimer l'objet
|
248
|
+
connector = CmisServer::Connectors::ConnectorFactory.create_connector(
|
249
|
+
user: @context[:current_user] || @context.current_user
|
250
|
+
)
|
251
|
+
|
252
|
+
# Si le connecteur supporte la suppression directe
|
253
|
+
if connector.respond_to?(:delete_object)
|
254
|
+
connector.delete_object(id)
|
255
|
+
return
|
256
|
+
end
|
257
|
+
|
258
|
+
# Sinon, utiliser l'ancien système
|
160
259
|
raise NotImplemented
|
161
260
|
end
|
162
261
|
|
@@ -1,3 +1,3 @@
|
|
1
1
|
xml.link(rel: 'down',
|
2
|
-
href: url_for(controller: 'cmis_server/atom_pub/folder_collection', action: 'get_children', id: object.cmis_object_id, only_path: false),
|
2
|
+
href: url_for(controller: 'cmis_server/atom_pub/folder_collection', action: 'get_children', id: object.respond_to?(:cmis_object_id) ? object.cmis_object_id : object.base_object.cmis_object_id, only_path: false),
|
3
3
|
type: "application/atomsvc+xml")
|
@@ -15,8 +15,8 @@ xml.tag!('entry', 'xmlns:atom' => 'http://www.w3.org/2005/Atom',
|
|
15
15
|
xml.content type: cs.media_type.to_s, src: url_for(controller: 'cmis_server/atom_pub/content', action: 'show', id: cs.id, only_path: false)
|
16
16
|
end
|
17
17
|
xml.link(rel: 'service', href: url_for(controller: 'cmis_server/atom_pub/service_documents', action: 'service_document', only_path: false), type: 'application/atomsvc+xml')
|
18
|
-
xml.link(rel: 'self', href: url_for(controller: 'cmis_server/atom_pub/entries', action: 'show', id: object.base_object.cmis_object_id, only_path: false), type: 'application/atomsvc+xml')
|
19
|
-
xml<<links_for(object.base_object)
|
18
|
+
xml.link(rel: 'self', href: url_for(controller: 'cmis_server/atom_pub/entries', action: 'show', id: object.respond_to?(:cmis_object_id) ? object.cmis_object_id : object.base_object.cmis_object_id, only_path: false), type: 'application/atomsvc+xml')
|
19
|
+
xml<<links_for(object.respond_to?(:type) ? object : object.base_object)
|
20
20
|
|
21
21
|
|
22
22
|
# Non-AtomPub elements must be put at the end to validate XSD schema
|
@@ -57,7 +57,8 @@ xml.tag!('entry', 'xmlns:atom' => 'http://www.w3.org/2005/Atom',
|
|
57
57
|
end
|
58
58
|
|
59
59
|
if try(:with_path_segment)
|
60
|
-
|
60
|
+
path_segment_object = object.respond_to?(:path_segment) ? object : object.base_object
|
61
|
+
xml.tag!('cmisra:pathSegment', path_segment_object.path_segment)
|
61
62
|
end
|
62
63
|
|
63
64
|
end
|
@@ -12,7 +12,7 @@ xml.tag!('entry', 'xmlns:atom' => 'http://www.w3.org/2005/Atom',
|
|
12
12
|
xml.name 'unknown'
|
13
13
|
end
|
14
14
|
|
15
|
-
xml.link(rel: 'service', href:
|
15
|
+
xml.link(rel: 'service', href: url_for(controller: 'cmis_server/atom_pub/service_documents', action: 'service_document', only_path: false), type: 'application/atomsvc+xml')
|
16
16
|
xml.link(rel: 'self', href: url_for(controller: 'cmis_server/atom_pub/uri_templates', action: 'type_by_id', id: @type.id, only_path: false), type: 'application/atomsvc+xml')
|
17
17
|
|
18
18
|
xml.tag!("app:edited", DateTime.now)
|
@@ -16,6 +16,9 @@ xml.tag!('atom:feed', 'xmlns:atom' => 'http://www.w3.org/2005/Atom',
|
|
16
16
|
title: "Folder Collection",
|
17
17
|
accept: "application/cmisatom+xml",
|
18
18
|
})
|
19
|
+
else
|
20
|
+
# Pour le root folder virtuel, pas de collection link
|
21
|
+
# Car il n'a pas de parent
|
19
22
|
end
|
20
23
|
|
21
24
|
if @collection.total_items_count
|