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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 107af5f3b660dfdeb4a37320f00df2dcd1f90482
4
- data.tar.gz: fd8d344df8996b58419b6f2919b0fb0fed6fa58d
3
+ metadata.gz: 7687556cd432a42906b9d22bb5126864a2504746
4
+ data.tar.gz: aae0936ee6a12b24c9e5853ff53a84a68e9e5b7d
5
5
  SHA512:
6
- metadata.gz: b05da4dcef03c6c98e164027e3e3ea019696cf4fce952efbf19d02c75293d8693f6ac248bb4536ca51afac7a154e0a93ba30295acdce48e80ded87064f683ce4
7
- data.tar.gz: 1af4ac5bb0fdcb9395f26388e8d8c2fe372a68195dd3c460c05fd75c336e5f220143eea43064b440bd5261d21e75789e03ac03e69c3b6a6c1c3a5e3c2bd31bfc
6
+ metadata.gz: d4236426c4fb12577adaebf6de386a5caa27c02125deebc227c715c773524439ca009237d521ea4f0fde4359d714adb58419f54b85a911c3523b0e6459a7ac0f
7
+ data.tar.gz: 370f0c6e50f0fe80d684eef49f1b4b1d96ab9274b5c1fc53983f3eedb0a4cc5b45b481d2040698816a2044df43bfd68e73955a3ee6d23abb19cdd8f81c8d7198
data/cmis-ruby.gemspec CHANGED
@@ -18,7 +18,6 @@ Gem::Specification.new do |s|
18
18
 
19
19
  s.add_dependency 'typhoeus', '~> 0.6'
20
20
  s.add_dependency 'multipart-post', '~> 1.1'
21
- s.add_dependency 'multi_json', '~> 1.5'
22
21
  s.add_dependency 'activesupport', '>= 3.2'
23
22
 
24
23
  s.description = <<-DESC.gsub(/^ /, '')
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 each_result(options = {}, &block)
14
- return enum_for(:each_result, options) unless block_given?
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
@@ -1,16 +1,11 @@
1
- require 'active_support/core_ext/hash/indifferent_access'
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 = {}, query = {}, headers = {})
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.has_key?(:cmisaction)
29
- method = params.has_key?(:content) ? 'multipart_post' : 'post'
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
- url: url,
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 = MultiJson.load(result) if content_type =~ /application\/json/
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
- unless (200...300).include?(response.code.to_i)
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 = MultiJson.load(perform_request(url: @service_url).body , symbolize_keys: false)
83
- raise "No repository found with ID #{repository_id}." unless repository_infos.has_key?(repository_id)
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.has_key?(:content)
95
- content = hash.delete(:content)
96
- hash[:content] = UploadIO.new(content[:stream],
97
- content[:mime_type],
98
- content[:filename])
99
- end # Move to multipart_post?
100
-
101
- if hash.has_key?(:properties)
102
- props = hash.delete(:properties)
103
- if props.is_a?(Hash)
104
- props.each_with_index do |(id, value), index|
105
- value = value.to_time if value.is_a?(Date) or value.is_a?(DateTime)
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 CMIS::CMISRequestError
40
+ rescue Exceptions::Constraint
41
+ # Check for specific constraint?
42
42
  nil
43
43
  end
44
44
 
45
- def set_content(stream, mime_type, filename)
46
- content = { stream: stream,
47
- mime_type: mime_type,
48
- filename: filename }
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(options = {})
20
- Children.new(self, options)
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 hash: #{r}"
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
@@ -1,11 +1,7 @@
1
1
  module CMIS
2
-
3
2
  class Item < Object
4
-
5
3
  def initialize(raw, repository)
6
4
  super
7
5
  end
8
-
9
6
  end
10
-
11
7
  end
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
- options = { repositoryId: repository.id,
74
- cmisaction: 'removeObjectFromFolder',
75
- objectId: cmis_object_id }
76
- options[:folderId] = folder.cmis_object_id if folder
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!(options)
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 excatly one folder'
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
@@ -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
- raise "Unexpected json: #{raw}"
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
@@ -1,6 +1,5 @@
1
1
  module CMIS
2
2
  class QueryResult
3
-
4
3
  attr_reader :results
5
4
  attr_reader :num_items
6
5
  attr_reader :has_more_items
@@ -10,6 +9,5 @@ module CMIS
10
9
  @num_items = num_items
11
10
  @has_more_items = has_more_items
12
11
  end
13
-
14
12
  end
15
13
  end
@@ -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
@@ -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 root
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
- types.map(&:id).include?(type_id)
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: MultiJson.dump(type.to_hash) })
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 query(statement, options = {})
97
- Query.new(self, statement, options)
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 "'service_url' must be set" unless service_url
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
- result = connection.execute!
38
-
39
- result.keys.include?(repository_id)
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 = {}, repository = nil)
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! ({ cmisaction: 'updateType',
50
- repositoryId: repository.id,
51
- type: MultiJson.dump(hash) })
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
@@ -1,3 +1,3 @@
1
1
  module CMIS
2
- VERSION = '0.2'
2
+ VERSION = '0.3'
3
3
  end
data/readme.md CHANGED
@@ -10,12 +10,8 @@ Running the tests requires a running CMIS server.
10
10
 
11
11
  ## TODO
12
12
 
13
- * query properties, not *
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
@@ -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'), 'text/plain', 'doc1.txt') # set content on detached doc
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'), 'text/plain', 'apple.txt')
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
@@ -23,5 +23,5 @@ end
23
23
 
24
24
  def delete_repository(id)
25
25
  META.object(id).delete
26
- rescue CMIS::CMISRequestError => ex
26
+ rescue CMIS::Exceptions::ObjectNotFound => ex
27
27
  end
@@ -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 = CMIS::Type.new
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
- @repo.create_type(type)
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 = CMIS::Type.new
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 = @repo.create_type(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.2'
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-23 00:00:00.000000000 Z
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: