cmis-ruby 0.2 → 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.
- checksums.yaml +4 -4
- data/cmis-ruby.gemspec +0 -1
- data/lib/cmis-ruby.rb +3 -6
- data/lib/cmis/children.rb +7 -5
- data/lib/cmis/connection.rb +39 -49
- data/lib/cmis/document.rb +18 -14
- data/lib/cmis/exceptions.rb +17 -0
- data/lib/cmis/folder.rb +15 -17
- data/lib/cmis/helpers.rb +1 -3
- data/lib/cmis/item.rb +0 -4
- data/lib/cmis/object.rb +29 -31
- data/lib/cmis/object_factory.rb +5 -5
- data/lib/cmis/policy.rb +4 -6
- data/lib/cmis/property_definition.rb +1 -3
- data/lib/cmis/query.rb +5 -3
- data/lib/cmis/query_result.rb +0 -2
- data/lib/cmis/relationship.rb +4 -6
- data/lib/cmis/repository.rb +54 -19
- data/lib/cmis/server.rb +10 -11
- data/lib/cmis/type.rb +8 -10
- data/lib/cmis/version.rb +1 -1
- data/readme.md +1 -5
- data/spec/document_spec.rb +3 -1
- data/spec/folder_spec.rb +3 -1
- data/spec/helper.rb +1 -1
- data/spec/repository_spec.rb +2 -2
- data/spec/type_spec.rb +2 -2
- metadata +4 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7687556cd432a42906b9d22bb5126864a2504746
|
4
|
+
data.tar.gz: aae0936ee6a12b24c9e5853ff53a84a68e9e5b7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4236426c4fb12577adaebf6de386a5caa27c02125deebc227c715c773524439ca009237d521ea4f0fde4359d714adb58419f54b85a911c3523b0e6459a7ac0f
|
7
|
+
data.tar.gz: 370f0c6e50f0fe80d684eef49f1b4b1d96ab9274b5c1fc53983f3eedb0a4cc5b45b481d2040698816a2044df43bfd68e73955a3ee6d23abb19cdd8f81c8d7198
|
data/cmis-ruby.gemspec
CHANGED
data/lib/cmis-ruby.rb
CHANGED
@@ -1,20 +1,17 @@
|
|
1
1
|
require 'cmis/connection'
|
2
|
+
require 'cmis/exceptions'
|
2
3
|
require 'cmis/server'
|
3
|
-
|
4
4
|
require 'cmis/helpers'
|
5
|
+
require 'cmis/object_factory'
|
5
6
|
require 'cmis/query_result'
|
6
7
|
require 'cmis/query'
|
7
8
|
require 'cmis/children'
|
8
|
-
|
9
9
|
require 'cmis/repository'
|
10
|
-
|
11
10
|
require 'cmis/object'
|
12
|
-
require 'cmis/object_factory'
|
13
11
|
require 'cmis/document'
|
14
12
|
require 'cmis/folder'
|
15
13
|
require 'cmis/item'
|
16
14
|
require 'cmis/policy'
|
17
15
|
require 'cmis/relationship'
|
18
|
-
|
19
|
-
require 'cmis/type'
|
20
16
|
require 'cmis/property_definition'
|
17
|
+
require 'cmis/type'
|
data/lib/cmis/children.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
require 'active_support/core_ext/hash/slice'
|
2
|
+
|
1
3
|
module CMIS
|
2
4
|
class Children
|
3
|
-
|
4
5
|
# Options: from, page_size
|
5
6
|
def initialize(folder, options = {})
|
6
7
|
@folder = folder
|
@@ -10,8 +11,8 @@ module CMIS
|
|
10
11
|
end
|
11
12
|
|
12
13
|
# Options: limit
|
13
|
-
def
|
14
|
-
return enum_for(:
|
14
|
+
def each_child(options = {}, &block)
|
15
|
+
return enum_for(:each_child, options) unless block_given?
|
15
16
|
|
16
17
|
init_options
|
17
18
|
limit = parse_limit(options)
|
@@ -66,6 +67,8 @@ module CMIS
|
|
66
67
|
@skip_count = @options['from'] || 0
|
67
68
|
@order_by = @options['order_by']
|
68
69
|
@has_next = true
|
70
|
+
|
71
|
+
@opts = @options.slice('query', 'headers')
|
69
72
|
end
|
70
73
|
|
71
74
|
def parse_limit(options)
|
@@ -82,7 +85,7 @@ module CMIS
|
|
82
85
|
objectId: @folder.cmis_object_id,
|
83
86
|
maxItems: @max_items,
|
84
87
|
skipCount: @skip_count,
|
85
|
-
orderBy: @order_by })
|
88
|
+
orderBy: @order_by }, @opts)
|
86
89
|
|
87
90
|
results = result['objects'].map do |r|
|
88
91
|
ObjectFactory.create(r['object'], @folder.repository)
|
@@ -90,6 +93,5 @@ module CMIS
|
|
90
93
|
|
91
94
|
QueryResult.new(results, result['numItems'], result['hasMoreItems'])
|
92
95
|
end
|
93
|
-
|
94
96
|
end
|
95
97
|
end
|
data/lib/cmis/connection.rb
CHANGED
@@ -1,16 +1,11 @@
|
|
1
|
-
require 'active_support
|
2
|
-
require 'date'
|
1
|
+
require 'active_support'
|
3
2
|
require 'typhoeus'
|
4
3
|
require 'net/http/post/multipart'
|
5
|
-
require 'multi_json'
|
6
4
|
|
7
5
|
module CMIS
|
8
|
-
|
9
|
-
class CMISRequestError < Exception; end
|
10
|
-
|
11
6
|
class Connection
|
12
7
|
|
13
|
-
def initialize(service_url, username, password, headers
|
8
|
+
def initialize(service_url, username, password, headers)
|
14
9
|
@service_url = service_url
|
15
10
|
@username = username
|
16
11
|
@password = password
|
@@ -19,14 +14,17 @@ module CMIS
|
|
19
14
|
@url_cache = {}
|
20
15
|
end
|
21
16
|
|
22
|
-
def execute!(params = {},
|
17
|
+
def execute!(params = {}, options = {})
|
18
|
+
options.stringify_keys!
|
19
|
+
query = options['query'] || {}
|
20
|
+
headers = @headers.merge(options['headers'] || {})
|
23
21
|
|
24
22
|
url = get_url(params.delete(:repositoryId), params[:objectId])
|
25
23
|
|
26
24
|
params = transform_hash(params)
|
27
25
|
|
28
|
-
if params
|
29
|
-
method = params
|
26
|
+
if params[:cmisaction]
|
27
|
+
method = params[:content] ? 'multipart_post' : 'post'
|
30
28
|
body = params
|
31
29
|
else
|
32
30
|
method = 'get'
|
@@ -34,13 +32,8 @@ module CMIS
|
|
34
32
|
query.merge!(params)
|
35
33
|
end
|
36
34
|
|
37
|
-
response = perform_request(method: method,
|
38
|
-
|
39
|
-
query: query,
|
40
|
-
body: body,
|
41
|
-
headers: headers)
|
42
|
-
|
43
|
-
result = response.body
|
35
|
+
response = perform_request(method: method, url: url,
|
36
|
+
body: body, query: query, headers: headers)
|
44
37
|
|
45
38
|
content_type = if response.respond_to?(:content_type)
|
46
39
|
response.content_type
|
@@ -48,22 +41,26 @@ module CMIS
|
|
48
41
|
response.headers['Content-Type']
|
49
42
|
end
|
50
43
|
|
51
|
-
result =
|
44
|
+
result = response.body
|
45
|
+
result = JSON.parse(result) if content_type =~ /application\/json/
|
52
46
|
result = result.with_indifferent_access if result.is_a? Hash
|
53
47
|
|
54
|
-
|
55
|
-
if result.is_a?(Hash) && result.has_key?(:exception)
|
56
|
-
raise CMISRequestError, "#{response.code} -- #{result[:exception]} -- #{result[:message]}"
|
57
|
-
else
|
58
|
-
raise CMISRequestError, "#{response.code} -- #{result}"
|
59
|
-
end
|
60
|
-
end
|
48
|
+
check_for_exception!(response.code.to_i, result)
|
61
49
|
|
62
50
|
result
|
63
51
|
end
|
64
52
|
|
65
53
|
private
|
66
54
|
|
55
|
+
def check_for_exception!(code, result)
|
56
|
+
unless (200...300).include?(code)
|
57
|
+
if result.is_a?(Hash) && result['exception']
|
58
|
+
exception_class = "CMIS::Exceptions::#{result['exception'].camelize}"
|
59
|
+
raise exception_class.constantize, "#{result['message']}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
67
64
|
def get_url(repository_id, cmis_object_id)
|
68
65
|
if repository_id.nil?
|
69
66
|
@service_url
|
@@ -79,8 +76,8 @@ module CMIS
|
|
79
76
|
|
80
77
|
def repository_urls(repository_id)
|
81
78
|
if @url_cache[repository_id].nil?
|
82
|
-
repository_infos =
|
83
|
-
raise "
|
79
|
+
repository_infos = JSON.parse(perform_request(url: @service_url).body)
|
80
|
+
raise Exceptions::ObjectNotFound, "repositoryId: #{repository_id}" unless repository_infos.has_key?(repository_id)
|
84
81
|
repository_info = repository_infos[repository_id]
|
85
82
|
@url_cache[repository_id] = { repository_url: repository_info['repositoryUrl'],
|
86
83
|
root_folder_url: repository_info['rootFolderUrl'] }
|
@@ -91,28 +88,22 @@ module CMIS
|
|
91
88
|
def transform_hash(hash)
|
92
89
|
hash.reject! { |_, v| v.nil? }
|
93
90
|
|
94
|
-
if hash
|
95
|
-
content =
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
value = (value.to_f * 1000).to_i if value.is_a?(Time)
|
107
|
-
if value.is_a?(Array)
|
108
|
-
hash.merge!("propertyId[#{index}]" => id)
|
109
|
-
value.each_with_index do |v, idx|
|
110
|
-
hash.merge!("propertyValue[#{index}][#{idx}]" => value[idx])
|
111
|
-
end
|
112
|
-
else
|
113
|
-
hash.merge!("propertyId[#{index}]" => id,
|
114
|
-
"propertyValue[#{index}]" => value)
|
91
|
+
if content_hash = hash[:content]
|
92
|
+
hash[:content] = UploadIO.new(content_hash[:stream], content_hash[:mime_type], content_hash[:filename])
|
93
|
+
end
|
94
|
+
|
95
|
+
if props = hash.delete(:properties)
|
96
|
+
props.each_with_index do |(id, value), index|
|
97
|
+
value = value.to_time if value.is_a?(Date) or value.is_a?(DateTime)
|
98
|
+
value = (value.to_f * 1000).to_i if value.is_a?(Time)
|
99
|
+
if value.is_a?(Array)
|
100
|
+
hash.merge!("propertyId[#{index}]" => id)
|
101
|
+
value.each_with_index do |v, idx|
|
102
|
+
hash.merge!("propertyValue[#{index}][#{idx}]" => value[idx])
|
115
103
|
end
|
104
|
+
else
|
105
|
+
hash.merge!("propertyId[#{index}]" => id,
|
106
|
+
"propertyValue[#{index}]" => value)
|
116
107
|
end
|
117
108
|
end
|
118
109
|
end
|
@@ -142,6 +133,5 @@ module CMIS
|
|
142
133
|
opts = url.scheme == 'https' ? { use_ssl: true , verify_mode: OpenSSL::SSL::VERIFY_NONE } : {}
|
143
134
|
Net::HTTP.start(url.host, url.port, opts) { |http| http.request(req) }
|
144
135
|
end
|
145
|
-
|
146
136
|
end
|
147
137
|
end
|
data/lib/cmis/document.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module CMIS
|
2
2
|
class Document < Object
|
3
|
-
|
4
3
|
def initialize(raw, repository)
|
5
4
|
super
|
6
5
|
cmis_properties %w( cmis:isImmutable cmis:isLatestVersion
|
@@ -13,39 +12,45 @@ module CMIS
|
|
13
12
|
cmis:contentStreamFileName cmis:contentStreamId )
|
14
13
|
end
|
15
14
|
|
16
|
-
def create_in_folder(folder)
|
15
|
+
def create_in_folder(folder, opts = {})
|
17
16
|
r = connection.execute!({ cmisaction: 'createDocument',
|
18
17
|
repositoryId: repository.id,
|
19
18
|
properties: properties,
|
20
19
|
objectId: folder.cmis_object_id,
|
21
20
|
folderId: folder.cmis_object_id,
|
22
|
-
content: @local_content })
|
21
|
+
content: @local_content }, opts)
|
23
22
|
|
24
23
|
ObjectFactory.create(r, repository)
|
25
24
|
end
|
26
25
|
|
27
|
-
def copy_in_folder(folder)
|
26
|
+
def copy_in_folder(folder, opts = {})
|
28
27
|
id = connection.execute!({ cmisaction: 'createDocument',
|
29
28
|
repositoryId: repository.id,
|
30
29
|
sourceId: cmis_object_id,
|
31
|
-
objectId: folder.cmis_object_id })
|
30
|
+
objectId: folder.cmis_object_id }, opts)
|
32
31
|
|
33
32
|
repository.object(id)
|
34
33
|
end
|
35
34
|
|
36
|
-
def content
|
35
|
+
def content(opts = {})
|
37
36
|
connection.execute!({ cmisselector: 'content',
|
38
37
|
repositoryId: repository.id,
|
39
|
-
objectId: cmis_object_id })
|
38
|
+
objectId: cmis_object_id }, opts)
|
40
39
|
|
41
|
-
rescue
|
40
|
+
rescue Exceptions::Constraint
|
41
|
+
# Check for specific constraint?
|
42
42
|
nil
|
43
43
|
end
|
44
44
|
|
45
|
-
def set_content(
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
def set_content(opts = {})
|
46
|
+
opts.stringify_keys!
|
47
|
+
content = { stream: opts.delete('stream'),
|
48
|
+
mime_type: opts.delete('mime_type'),
|
49
|
+
filename: opts.delete('filename') }
|
50
|
+
|
51
|
+
if content[:stream].is_a? String
|
52
|
+
content[:stream] = StringIO.new(content[:stream])
|
53
|
+
end
|
49
54
|
|
50
55
|
if detached?
|
51
56
|
@local_content = content
|
@@ -54,9 +59,8 @@ module CMIS
|
|
54
59
|
repositoryId: repository.id,
|
55
60
|
objectId: cmis_object_id,
|
56
61
|
content: content,
|
57
|
-
changeToken: change_token })
|
62
|
+
changeToken: change_token }, opts)
|
58
63
|
end
|
59
64
|
end
|
60
|
-
|
61
65
|
end
|
62
66
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CMIS
|
2
|
+
module Exceptions
|
3
|
+
class InvalidArgument < Exception; end
|
4
|
+
class NotSupported < Exception; end
|
5
|
+
class ObjectNotFound < Exception; end
|
6
|
+
class PermissionDenied < Exception; end
|
7
|
+
class Runtime < Exception; end
|
8
|
+
class Constraint < Exception; end
|
9
|
+
class ContentAlreadyExists < Exception; end
|
10
|
+
class FilterNotValid < Exception; end
|
11
|
+
class NameConstraintViolation < Exception; end
|
12
|
+
class Storage < Exception; end
|
13
|
+
class StreamNotSupported < Exception; end
|
14
|
+
class UpdateConflict < Exception; end
|
15
|
+
class Versioning < Exception; end
|
16
|
+
end
|
17
|
+
end
|
data/lib/cmis/folder.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
module CMIS
|
2
2
|
class Folder < Object
|
3
|
-
|
4
3
|
def initialize(raw, repository)
|
5
4
|
super
|
6
5
|
cmis_properties %w( cmis:parentId cmis:path
|
7
6
|
cmis:allowedChildObjectTypeIds )
|
8
7
|
end
|
9
8
|
|
10
|
-
def parent
|
11
|
-
repository.object(parent_id) if parent_id
|
9
|
+
def parent(opts = {})
|
10
|
+
repository.object(parent_id, opts) if parent_id
|
12
11
|
end
|
13
12
|
|
14
13
|
def allowed_child_object_types
|
@@ -16,34 +15,34 @@ module CMIS
|
|
16
15
|
allowed_child_object_type_ids.map { |type_id| repository.type(type_id) }
|
17
16
|
end
|
18
17
|
|
19
|
-
def children(
|
20
|
-
Children.new(self,
|
18
|
+
def children(opts = {})
|
19
|
+
Children.new(self, opts)
|
21
20
|
end
|
22
21
|
|
23
|
-
def create(object)
|
22
|
+
def create(object, opts = {})
|
24
23
|
case object
|
25
24
|
when Relationship
|
26
25
|
raise "'cmis:relationship' is not fileable. Use Repository#create_relationship"
|
27
26
|
|
28
27
|
when Document
|
29
|
-
return object.create_in_folder(self)
|
28
|
+
return object.create_in_folder(self, opts)
|
30
29
|
|
31
30
|
when Folder
|
32
31
|
o = connection.execute!({ cmisaction: 'createFolder',
|
33
32
|
repositoryId: repository.id,
|
34
33
|
properties: object.properties,
|
35
|
-
objectId: cmis_object_id })
|
34
|
+
objectId: cmis_object_id }, opts)
|
36
35
|
|
37
36
|
when Policy
|
38
37
|
o = connection.execute!({ cmisaction: 'createPolicy',
|
39
38
|
repositoryId: repository.id,
|
40
39
|
properties: object.properties,
|
41
|
-
objectId: cmis_object_id })
|
40
|
+
objectId: cmis_object_id }, opts)
|
42
41
|
when Item
|
43
42
|
o = connection.execute!({ cmisaction: 'createItem',
|
44
43
|
repositoryId: repository.id,
|
45
44
|
properties: object.properties,
|
46
|
-
objectId: cmis_object_id })
|
45
|
+
objectId: cmis_object_id }, opts)
|
47
46
|
|
48
47
|
else
|
49
48
|
raise "Unexpected base_type_id: #{object.base_type_id}"
|
@@ -52,25 +51,24 @@ module CMIS
|
|
52
51
|
ObjectFactory.create(o, repository)
|
53
52
|
end
|
54
53
|
|
55
|
-
def delete_tree
|
54
|
+
def delete_tree(opts = {})
|
56
55
|
connection.execute!({ cmisaction: 'deleteTree',
|
57
56
|
repositoryId: repository.id,
|
58
|
-
objectId: cmis_object_id })
|
57
|
+
objectId: cmis_object_id }, opts)
|
59
58
|
end
|
60
59
|
|
61
|
-
def add(object)
|
60
|
+
def add(object, opts = {})
|
62
61
|
connection.execute!({ cmisaction: 'addObjectToFolder',
|
63
62
|
repositoryId: repository.id,
|
64
63
|
objectId: object.cmis_object_id,
|
65
|
-
folderId: cmis_object_id })
|
64
|
+
folderId: cmis_object_id }, opts)
|
66
65
|
end
|
67
66
|
|
68
|
-
def remove(object)
|
67
|
+
def remove(object, opts = {})
|
69
68
|
connection.execute!({ cmisaction: 'removeObjectFromFolder',
|
70
69
|
repositoryId: repository.id,
|
71
70
|
objectId: object.cmis_object_id,
|
72
|
-
folderId: cmis_object_id })
|
71
|
+
folderId: cmis_object_id }, opts)
|
73
72
|
end
|
74
|
-
|
75
73
|
end
|
76
74
|
end
|
data/lib/cmis/helpers.rb
CHANGED
@@ -2,7 +2,6 @@ require 'active_support/core_ext'
|
|
2
2
|
|
3
3
|
module CMIS
|
4
4
|
module Helpers
|
5
|
-
|
6
5
|
def initialize_properties(raw)
|
7
6
|
@properties = get_properties_map(raw)
|
8
7
|
end
|
@@ -21,7 +20,7 @@ module CMIS
|
|
21
20
|
elsif r['succinctProperties']
|
22
21
|
@change_token = r['succinctProperties']['cmis:changeToken']
|
23
22
|
else
|
24
|
-
raise "Unexpected
|
23
|
+
raise "Unexpected input: #{r}"
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
@@ -53,6 +52,5 @@ module CMIS
|
|
53
52
|
|
54
53
|
result.with_indifferent_access
|
55
54
|
end
|
56
|
-
|
57
55
|
end
|
58
56
|
end
|
data/lib/cmis/item.rb
CHANGED
data/lib/cmis/object.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module CMIS
|
2
2
|
class Object
|
3
|
-
|
4
3
|
include Helpers
|
5
4
|
|
6
5
|
attr_reader :connection
|
@@ -18,103 +17,102 @@ module CMIS
|
|
18
17
|
@connection = repository.connection
|
19
18
|
end
|
20
19
|
|
21
|
-
def object_type
|
22
|
-
repository.type(object_type_id)
|
20
|
+
def object_type(opts = {})
|
21
|
+
repository.type(object_type_id, opts)
|
23
22
|
end
|
24
23
|
|
25
|
-
def delete
|
24
|
+
def delete(opts = {})
|
26
25
|
connection.execute!({ cmisaction: 'delete',
|
27
26
|
repositoryId: repository.id,
|
28
27
|
objectId: cmis_object_id,
|
29
|
-
allVersions: true })
|
28
|
+
allVersions: true }, opts)
|
30
29
|
end
|
31
30
|
|
32
|
-
def update_properties(properties)
|
31
|
+
def update_properties(properties, opts = {})
|
33
32
|
update_change_token connection.execute!({ cmisaction: 'update',
|
34
33
|
repositoryId: repository.id,
|
35
34
|
objectId: cmis_object_id,
|
36
35
|
properties: properties,
|
37
|
-
changeToken: change_token })
|
36
|
+
changeToken: change_token }, opts)
|
38
37
|
end
|
39
38
|
|
40
|
-
def parents
|
39
|
+
def parents(opts = {})
|
41
40
|
result = connection.execute!({ cmisselector: 'parents',
|
42
41
|
repositoryId: repository.id,
|
43
|
-
objectId: cmis_object_id })
|
42
|
+
objectId: cmis_object_id }, opts)
|
44
43
|
|
45
44
|
result.map { |o| ObjectFactory.create(o['object'], repository) }
|
46
45
|
end
|
47
46
|
|
48
|
-
def allowable_actions
|
47
|
+
def allowable_actions(opts = {})
|
49
48
|
connection.execute!({ cmisselector: 'allowableActions',
|
50
49
|
repositoryId: repository.id,
|
51
|
-
objectId: cmis_object_id })
|
50
|
+
objectId: cmis_object_id }, opts)
|
52
51
|
end
|
53
52
|
|
54
|
-
def relationships(direction = :either)
|
53
|
+
def relationships(direction = :either, opts = {})
|
55
54
|
result = connection.execute!({ cmisselector: 'relationships',
|
56
55
|
repositoryId: repository.id,
|
57
56
|
objectId: cmis_object_id,
|
58
|
-
relationshipDirection: direction })
|
57
|
+
relationshipDirection: direction }, opts)
|
59
58
|
|
60
59
|
result['objects'].map { |r| Relationship.new(r, repository) }
|
61
60
|
end
|
62
61
|
|
63
|
-
def policies
|
62
|
+
def policies(opts = {})
|
64
63
|
result = connection.execute!({ cmisselector: 'policies',
|
65
64
|
repositoryId: repository.id,
|
66
|
-
objectId: cmis_object_id })
|
65
|
+
objectId: cmis_object_id }, opts)
|
67
66
|
|
68
67
|
result.map { |r| Policy.new(r, repository) }
|
69
68
|
end
|
70
69
|
|
71
70
|
# By default removes from all folders
|
72
|
-
def unfile(folder = nil)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
def unfile(folder = nil, opts = {})
|
72
|
+
params = { repositoryId: repository.id,
|
73
|
+
cmisaction: 'removeObjectFromFolder',
|
74
|
+
objectId: cmis_object_id }
|
75
|
+
params.update!(folderId: folder.cmis_object_id) if folder
|
77
76
|
|
78
|
-
connection.execute!(
|
77
|
+
connection.execute!(params, opts)
|
79
78
|
end
|
80
79
|
|
81
|
-
def move(target_folder)
|
80
|
+
def move(target_folder, opts = {})
|
82
81
|
object_parents = parents
|
83
82
|
|
84
83
|
unless object_parents.size == 1
|
85
|
-
raise 'Cannot move object because it is not in
|
84
|
+
raise 'Cannot move object because it is not in exactly one folder'
|
86
85
|
end
|
87
86
|
|
88
87
|
connection.execute!({ cmisaction: 'move',
|
89
88
|
repositoryId: repository.id,
|
90
89
|
objectId: cmis_object_id,
|
91
90
|
targetFolderId: target_folder.cmis_object_id,
|
92
|
-
sourceFolderId: object_parents.first.cmis_object_id })
|
91
|
+
sourceFolderId: object_parents.first.cmis_object_id }, opts)
|
93
92
|
end
|
94
93
|
|
95
|
-
def acls
|
94
|
+
def acls(opts = {})
|
96
95
|
connection.execute!({ cmisselector: 'acl',
|
97
96
|
repositoryId: repository.id,
|
98
|
-
objectId: cmis_object_id })
|
97
|
+
objectId: cmis_object_id }, opts)
|
99
98
|
end
|
100
99
|
|
101
|
-
def add_aces(aces)
|
100
|
+
def add_aces(aces, opts = {})
|
102
101
|
connection.execute!({ cmisaction: 'applyACL',
|
103
102
|
repositoryId: repository.id,
|
104
103
|
objectId: cmis_object_id,
|
105
|
-
addACEs: aces })
|
104
|
+
addACEs: aces }, opts)
|
106
105
|
end
|
107
106
|
|
108
|
-
def remove_aces(aces)
|
107
|
+
def remove_aces(aces, opts = {})
|
109
108
|
connection.execute!({ cmisaction: 'applyACL',
|
110
109
|
repositoryId: repository.id,
|
111
110
|
objectId: cmis_object_id,
|
112
|
-
removeACEs: aces })
|
111
|
+
removeACEs: aces }, opts)
|
113
112
|
end
|
114
113
|
|
115
114
|
def detached?
|
116
115
|
cmis_object_id.nil?
|
117
116
|
end
|
118
|
-
|
119
117
|
end
|
120
118
|
end
|
data/lib/cmis/object_factory.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
module CMIS
|
2
2
|
class ObjectFactory
|
3
|
-
|
4
3
|
def self.create(raw, repository)
|
5
4
|
case base_type_id(raw)
|
5
|
+
when 'cmis:object' then Object.new(raw, repository)
|
6
6
|
when 'cmis:folder' then Folder.new(raw, repository)
|
7
7
|
when 'cmis:document' then Document.new(raw, repository)
|
8
8
|
when 'cmis:relationship' then Relationship.new(raw, repository)
|
9
9
|
when 'cmis:policy' then Policy.new(raw, repository)
|
10
10
|
when 'cmis:item' then Item.new(raw, repository)
|
11
|
-
else raise "Unexpected baseTypeId: #{base_type_id}
|
11
|
+
else raise "Unexpected baseTypeId: #{base_type_id}"
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
16
16
|
|
17
17
|
def self.base_type_id(raw)
|
18
|
-
if raw['properties']
|
18
|
+
if raw['properties'] && raw['properties']['cmis:baseTypeId']
|
19
19
|
raw['properties']['cmis:baseTypeId']['value']
|
20
|
-
elsif raw['succinctProperties']
|
20
|
+
elsif raw['succinctProperties'] && raw['succinctProperties']['cmis:baseTypeId']
|
21
21
|
raw['succinctProperties']['cmis:baseTypeId']
|
22
22
|
else
|
23
|
-
|
23
|
+
'cmis:object' # no base type id, construct a poco
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/cmis/policy.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module CMIS
|
2
2
|
class Policy < Object
|
3
|
-
|
4
3
|
attr_reader :policy_text
|
5
4
|
|
6
5
|
def initialize(raw, repository)
|
@@ -8,19 +7,18 @@ module CMIS
|
|
8
7
|
cmis_properties %w( cmis:policyText )
|
9
8
|
end
|
10
9
|
|
11
|
-
def apply_to(object)
|
10
|
+
def apply_to(object, opts = {})
|
12
11
|
connection.execute!({ cmisaction: 'applyPolicy',
|
13
12
|
repositoryId: repository_id,
|
14
13
|
policyId: cmis_object_id,
|
15
|
-
objectId: object.cmis_object_id })
|
14
|
+
objectId: object.cmis_object_id }, opts)
|
16
15
|
end
|
17
16
|
|
18
|
-
def remove_from(object)
|
17
|
+
def remove_from(object, opts = {})
|
19
18
|
connection.execute!({ cmisaction: 'removePolicy',
|
20
19
|
repositoryId: repository_id,
|
21
20
|
policyId: cmis_object_id,
|
22
|
-
objectId: object.cmis_object_id })
|
21
|
+
objectId: object.cmis_object_id }, opts)
|
23
22
|
end
|
24
|
-
|
25
23
|
end
|
26
24
|
end
|
@@ -1,8 +1,7 @@
|
|
1
|
-
require 'active_support/core_ext'
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
2
|
|
3
3
|
module CMIS
|
4
4
|
class PropertyDefinition
|
5
|
-
|
6
5
|
def initialize(hash = {})
|
7
6
|
@hash = hash.with_indifferent_access
|
8
7
|
|
@@ -27,6 +26,5 @@ module CMIS
|
|
27
26
|
def to_hash
|
28
27
|
@hash
|
29
28
|
end
|
30
|
-
|
31
29
|
end
|
32
30
|
end
|
data/lib/cmis/query.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
require 'active_support/core_ext/hash/slice'
|
2
|
+
|
1
3
|
module CMIS
|
2
4
|
class Query
|
3
|
-
|
4
5
|
# Options: from, page_size
|
5
6
|
def initialize(repository, statement, options = {})
|
6
7
|
@repository = repository
|
@@ -67,6 +68,8 @@ module CMIS
|
|
67
68
|
@max_items = @options['page_size'] || 10
|
68
69
|
@skip_count = @options['from'] || 0
|
69
70
|
@has_next = true
|
71
|
+
|
72
|
+
@opts = @options.slice('query', 'headers')
|
70
73
|
end
|
71
74
|
|
72
75
|
def parse_limit(options)
|
@@ -87,7 +90,7 @@ module CMIS
|
|
87
90
|
params.merge!(cmisaction: 'query', statement: @statement)
|
88
91
|
end
|
89
92
|
|
90
|
-
result = @repository.connection.execute!(params)
|
93
|
+
result = @repository.connection.execute!(params, @opts)
|
91
94
|
|
92
95
|
results = result['results'].map do |r|
|
93
96
|
ObjectFactory.create(r, @repository)
|
@@ -95,6 +98,5 @@ module CMIS
|
|
95
98
|
|
96
99
|
QueryResult.new(results, result['numItems'], result['hasMoreItems'])
|
97
100
|
end
|
98
|
-
|
99
101
|
end
|
100
102
|
end
|
data/lib/cmis/query_result.rb
CHANGED
data/lib/cmis/relationship.rb
CHANGED
@@ -1,18 +1,16 @@
|
|
1
1
|
module CMIS
|
2
2
|
class Relationship < Object
|
3
|
-
|
4
3
|
def initialize(raw, repository)
|
5
4
|
super
|
6
5
|
cmis_properties %w( cmis:sourceId cmis:targetId )
|
7
6
|
end
|
8
7
|
|
9
|
-
def source
|
10
|
-
repository.object(source_id)
|
8
|
+
def source(opts = {})
|
9
|
+
repository.object(source_id, opts)
|
11
10
|
end
|
12
11
|
|
13
|
-
def target
|
14
|
-
repository.object(target_id)
|
12
|
+
def target(opts = {})
|
13
|
+
repository.object(target_id, opts)
|
15
14
|
end
|
16
|
-
|
17
15
|
end
|
18
16
|
end
|
data/lib/cmis/repository.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
require 'active_support/core_ext/date_time'
|
2
|
+
|
1
3
|
module CMIS
|
2
4
|
class Repository
|
3
|
-
|
4
5
|
attr_reader :connection
|
5
6
|
|
6
7
|
def initialize(raw, connection)
|
@@ -33,72 +34,107 @@ module CMIS
|
|
33
34
|
Policy.new({}, self)
|
34
35
|
end
|
35
36
|
|
36
|
-
def
|
37
|
+
def new_type
|
38
|
+
Type.new({}, self)
|
39
|
+
end
|
40
|
+
|
41
|
+
def root(opts = {})
|
37
42
|
result = connection.execute!({ cmisselector: 'object',
|
38
43
|
repositoryId: id,
|
39
|
-
objectId: root_folder_id })
|
44
|
+
objectId: root_folder_id }, opts)
|
40
45
|
|
41
46
|
ObjectFactory.create(result, self)
|
42
47
|
end
|
43
48
|
|
44
|
-
def object(cmis_object_id)
|
49
|
+
def object(cmis_object_id, opts = {})
|
45
50
|
result = connection.execute!({ cmisselector: 'object',
|
46
51
|
repositoryId: id,
|
47
|
-
objectId: cmis_object_id })
|
52
|
+
objectId: cmis_object_id }, opts)
|
48
53
|
|
49
54
|
ObjectFactory.create(result, self)
|
50
55
|
end
|
51
56
|
|
52
|
-
def types
|
57
|
+
def types(opts = {})
|
53
58
|
result = connection.execute!({ cmisselector: 'typeDescendants',
|
54
59
|
repositoryId: id,
|
55
|
-
includePropertyDefinitions: true })
|
60
|
+
includePropertyDefinitions: true }, opts)
|
56
61
|
|
57
62
|
construct_types(result)
|
58
63
|
end
|
59
64
|
|
60
|
-
def type(type_id)
|
65
|
+
def type(type_id, opts = {})
|
61
66
|
result = connection.execute!({ cmisselector: 'typeDefinition',
|
62
67
|
repositoryId: id,
|
63
|
-
typeId: type_id })
|
68
|
+
typeId: type_id }, opts)
|
64
69
|
|
65
70
|
Type.new(result, self)
|
66
71
|
end
|
67
72
|
|
68
73
|
def has_type?(type_id)
|
69
|
-
|
74
|
+
type(type_id)
|
75
|
+
true
|
76
|
+
rescue Exceptions::ObjectNotFound
|
77
|
+
false
|
70
78
|
end
|
71
79
|
|
72
|
-
def create_type(type)
|
80
|
+
def create_type(type, opts = {})
|
73
81
|
result = connection.execute!({ cmisaction: 'createType',
|
74
82
|
repositoryId: id,
|
75
|
-
type:
|
83
|
+
type: JSON.generate(type.to_hash) }, opts)
|
76
84
|
|
77
85
|
Type.new(result, self)
|
78
86
|
end
|
79
87
|
|
80
|
-
def create_relationship(object)
|
88
|
+
def create_relationship(object, opts = {})
|
81
89
|
raise 'Object is not a Relationship' unless object.is_a?(Relationship)
|
82
90
|
|
83
91
|
result = connection.execute!({ cmisaction: 'createRelationship',
|
84
92
|
repositoryId: id,
|
85
|
-
properties: object.properties })
|
93
|
+
properties: object.properties }, opts)
|
86
94
|
|
87
95
|
ObjectFactory.create(result, self)
|
88
96
|
end
|
89
97
|
|
90
|
-
def content_changes(change_log_token)
|
98
|
+
def content_changes(change_log_token, opts = {})
|
91
99
|
connection.execute!({ cmisselector: 'contentChanges',
|
92
100
|
repositoryId: id,
|
93
|
-
changeLogToken: change_log_token })
|
101
|
+
changeLogToken: change_log_token }, opts)
|
102
|
+
end
|
103
|
+
|
104
|
+
def query(statement, opts = {})
|
105
|
+
Query.new(self, statement, opts)
|
94
106
|
end
|
95
107
|
|
96
|
-
def
|
97
|
-
|
108
|
+
def find_object(type_id, properties, opts = {})
|
109
|
+
clause = properties.map { |k, v| "#{k}=#{normalize(v)}" }.join(' and ')
|
110
|
+
statement = "select * from #{type_id} where #{clause}"
|
111
|
+
opts.merge!(page_size: 1)
|
112
|
+
query(statement, opts).results.first
|
98
113
|
end
|
99
114
|
|
100
115
|
private
|
101
116
|
|
117
|
+
BACKSLASH = "\\"
|
118
|
+
QUOTE = "\'"
|
119
|
+
|
120
|
+
def normalize(value)
|
121
|
+
case value
|
122
|
+
when DateTime
|
123
|
+
value = value.strftime('%Y-%m-%dT%H:%M:%S.%L')
|
124
|
+
"TIMESTAMP '#{value}'"
|
125
|
+
when Time
|
126
|
+
value = value.strftime('%Y-%m-%dT%H:%M:%S.%L')
|
127
|
+
"TIMESTAMP '#{value}'"
|
128
|
+
when Date
|
129
|
+
value = value.strftime('%Y-%m-%dT%H:%M:%S.%L')
|
130
|
+
"TIMESTAMP '#{value}'"
|
131
|
+
else
|
132
|
+
# TODO Correct escaping for find_object
|
133
|
+
# value = value.gsub(BACKSLASH, BACKSLASH * 4).gsub(QUOTE, "#{BACKSLASH * 2}#{QUOTE}")
|
134
|
+
"'#{value}'"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
102
138
|
def construct_types(a)
|
103
139
|
types = []
|
104
140
|
a.each do |t|
|
@@ -107,6 +143,5 @@ module CMIS
|
|
107
143
|
end
|
108
144
|
types.flatten
|
109
145
|
end
|
110
|
-
|
111
146
|
end
|
112
147
|
end
|
data/lib/cmis/server.rb
CHANGED
@@ -2,7 +2,6 @@ require 'active_support/core_ext/hash/indifferent_access'
|
|
2
2
|
|
3
3
|
module CMIS
|
4
4
|
class Server
|
5
|
-
|
6
5
|
attr_reader :connection
|
7
6
|
|
8
7
|
def initialize(options = {})
|
@@ -11,33 +10,33 @@ module CMIS
|
|
11
10
|
service_url = options['service_url'] || ENV['CMIS_BROWSER_URL']
|
12
11
|
username = options['username'] || ENV['CMIS_USER']
|
13
12
|
password = options['password'] || ENV['CMIS_PASSWORD']
|
14
|
-
headers = options['headers']
|
13
|
+
headers = options['headers'] || {}
|
15
14
|
|
16
|
-
raise "
|
15
|
+
raise "`service_url` must be set" unless service_url
|
17
16
|
|
18
17
|
@connection = Connection.new(service_url, username, password, headers)
|
19
18
|
end
|
20
19
|
|
21
|
-
def repositories
|
22
|
-
result = connection.execute!
|
20
|
+
def repositories(opts = {})
|
21
|
+
result = connection.execute!({}, opts)
|
23
22
|
|
24
23
|
result.values.map do |r|
|
25
24
|
Repository.new(r, connection)
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
|
-
def repository(repository_id)
|
28
|
+
def repository(repository_id, opts = {})
|
30
29
|
result = connection.execute!({ cmisselector: 'repositoryInfo',
|
31
|
-
repositoryId: repository_id })
|
30
|
+
repositoryId: repository_id }, opts)
|
32
31
|
|
33
32
|
Repository.new(result[repository_id], connection)
|
34
33
|
end
|
35
34
|
|
36
35
|
def has_repository?(repository_id)
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
repository(repository_id)
|
37
|
+
true
|
38
|
+
rescue Exceptions::ObjectNotFound
|
39
|
+
false
|
40
40
|
end
|
41
|
-
|
42
41
|
end
|
43
42
|
end
|
data/lib/cmis/type.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
require 'active_support/core_ext'
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
2
|
|
3
3
|
module CMIS
|
4
4
|
class Type
|
5
|
-
|
6
5
|
attr_accessor :connection
|
7
6
|
attr_accessor :repository
|
8
7
|
|
9
|
-
def initialize(hash
|
8
|
+
def initialize(hash, repository)
|
10
9
|
@repository = repository
|
11
10
|
@connection = repository.connection if repository
|
12
11
|
|
@@ -37,7 +36,7 @@ module CMIS
|
|
37
36
|
repository.create_type(self)
|
38
37
|
end
|
39
38
|
|
40
|
-
def update(changed_property_defs)
|
39
|
+
def update(changed_property_defs, opts = {})
|
41
40
|
new_defs = changed_property_defs.map(&:to_hash).reduce({}) do |result, element|
|
42
41
|
result[element[:id]] = element
|
43
42
|
result
|
@@ -46,17 +45,17 @@ module CMIS
|
|
46
45
|
hash = to_hash
|
47
46
|
hash['propertyDefinitions'] = new_defs
|
48
47
|
|
49
|
-
result = connection.execute!
|
50
|
-
|
51
|
-
|
48
|
+
result = connection.execute!({ cmisaction: 'updateType',
|
49
|
+
repositoryId: repository.id,
|
50
|
+
type: JSON.generate(hash) }, opts)
|
52
51
|
|
53
52
|
Type.new(result, repository)
|
54
53
|
end
|
55
54
|
|
56
|
-
def delete
|
55
|
+
def delete(opts = {})
|
57
56
|
connection.execute!({ cmisaction: 'deleteType',
|
58
57
|
repositoryId: repository.id,
|
59
|
-
typeId: id })
|
58
|
+
typeId: id }, opts)
|
60
59
|
end
|
61
60
|
|
62
61
|
def document_type?
|
@@ -101,6 +100,5 @@ module CMIS
|
|
101
100
|
def to_hash
|
102
101
|
@hash
|
103
102
|
end
|
104
|
-
|
105
103
|
end
|
106
104
|
end
|
data/lib/cmis/version.rb
CHANGED
data/readme.md
CHANGED
@@ -10,12 +10,8 @@ Running the tests requires a running CMIS server.
|
|
10
10
|
|
11
11
|
## TODO
|
12
12
|
|
13
|
-
*
|
14
|
-
* string / symbol consistency
|
15
|
-
* better exceptions and handling
|
16
|
-
* headers / params in low level (options)
|
13
|
+
* cleanup Connection class
|
17
14
|
* facilitate copy between servers (make a flow)
|
18
|
-
* improve exists for repo / type
|
19
15
|
* caching
|
20
16
|
|
21
17
|
## Contributing
|
data/spec/document_spec.rb
CHANGED
@@ -14,7 +14,9 @@ describe CMIS::Document do
|
|
14
14
|
new_object = @repo.new_document
|
15
15
|
new_object.name = 'doc1'
|
16
16
|
new_object.object_type_id = 'cmis:document'
|
17
|
-
new_object.set_content(StringIO.new('content1'),
|
17
|
+
new_object.set_content(stream: StringIO.new('content1'),
|
18
|
+
mime_type: 'text/plain',
|
19
|
+
filename: 'doc1.txt')
|
18
20
|
doc = new_object.create_in_folder(@repo.root)
|
19
21
|
doc.name.should eq 'doc1'
|
20
22
|
doc.content_stream_mime_type.should eq 'text/plain'
|
data/spec/folder_spec.rb
CHANGED
@@ -27,7 +27,9 @@ describe CMIS::Folder do
|
|
27
27
|
new_object = @repo.new_document
|
28
28
|
new_object.name = 'doc1'
|
29
29
|
new_object.object_type_id = 'cmis:document'
|
30
|
-
new_object.set_content(StringIO.new('apple is a fruit'),
|
30
|
+
new_object.set_content(stream: StringIO.new('apple is a fruit'),
|
31
|
+
mime_type: 'text/plain',
|
32
|
+
filename: 'apple.txt')
|
31
33
|
object = @repo.root.create(new_object)
|
32
34
|
object.should be_a_kind_of CMIS::Document
|
33
35
|
object.name.should eq 'doc1'
|
data/spec/helper.rb
CHANGED
data/spec/repository_spec.rb
CHANGED
@@ -105,7 +105,7 @@ describe CMIS::Repository do
|
|
105
105
|
it 'create, get, delete type - document' do
|
106
106
|
type_id = 'apple'
|
107
107
|
|
108
|
-
type =
|
108
|
+
type = @repo.new_type
|
109
109
|
type.id = type_id
|
110
110
|
type.local_name = 'apple'
|
111
111
|
type.query_name = 'apple'
|
@@ -136,7 +136,7 @@ describe CMIS::Repository do
|
|
136
136
|
queryable: true,
|
137
137
|
orderable: true)
|
138
138
|
|
139
|
-
|
139
|
+
type.create
|
140
140
|
|
141
141
|
@repo.type(type_id).tap do |t|
|
142
142
|
t.should be_a_kind_of CMIS::Type
|
data/spec/type_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe CMIS::Type do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'shoud update types' do
|
14
|
-
type =
|
14
|
+
type = @repo.new_type
|
15
15
|
type.id = 'apple'
|
16
16
|
type.local_name = 'apple'
|
17
17
|
type.query_name = 'apple'
|
@@ -44,7 +44,7 @@ describe CMIS::Type do
|
|
44
44
|
orderable: true
|
45
45
|
)
|
46
46
|
|
47
|
-
full_type =
|
47
|
+
full_type = type.create
|
48
48
|
|
49
49
|
new_prop = CMIS::PropertyDefinition.new(
|
50
50
|
id: 'taste',
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cmis-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenneth Geerts
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-02-
|
12
|
+
date: 2014-02-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: typhoeus
|
@@ -39,20 +39,6 @@ dependencies:
|
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '1.1'
|
42
|
-
- !ruby/object:Gem::Dependency
|
43
|
-
name: multi_json
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
45
|
-
requirements:
|
46
|
-
- - "~>"
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '1.5'
|
49
|
-
type: :runtime
|
50
|
-
prerelease: false
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - "~>"
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: '1.5'
|
56
42
|
- !ruby/object:Gem::Dependency
|
57
43
|
name: activesupport
|
58
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,6 +70,7 @@ files:
|
|
84
70
|
- lib/cmis/children.rb
|
85
71
|
- lib/cmis/connection.rb
|
86
72
|
- lib/cmis/document.rb
|
73
|
+
- lib/cmis/exceptions.rb
|
87
74
|
- lib/cmis/folder.rb
|
88
75
|
- lib/cmis/helpers.rb
|
89
76
|
- lib/cmis/item.rb
|
@@ -139,3 +126,4 @@ test_files:
|
|
139
126
|
- spec/repository_spec.rb
|
140
127
|
- spec/server_spec.rb
|
141
128
|
- spec/type_spec.rb
|
129
|
+
has_rdoc:
|