cmis-ruby 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|