cmis-ruby 0.2

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.
@@ -0,0 +1,15 @@
1
+ module CMIS
2
+ class QueryResult
3
+
4
+ attr_reader :results
5
+ attr_reader :num_items
6
+ attr_reader :has_more_items
7
+
8
+ def initialize(results, num_items, has_more_items)
9
+ @results = results
10
+ @num_items = num_items
11
+ @has_more_items = has_more_items
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module CMIS
2
+ class Relationship < Object
3
+
4
+ def initialize(raw, repository)
5
+ super
6
+ cmis_properties %w( cmis:sourceId cmis:targetId )
7
+ end
8
+
9
+ def source
10
+ repository.object(source_id)
11
+ end
12
+
13
+ def target
14
+ repository.object(target_id)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,112 @@
1
+ module CMIS
2
+ class Repository
3
+
4
+ attr_reader :connection
5
+
6
+ def initialize(raw, connection)
7
+ @hash = raw
8
+ @hash.each_key do |key|
9
+ class_eval "def #{key.underscore};@hash['#{key}'];end"
10
+ class_eval "def #{key.gsub('repository', '').underscore};@hash['#{key}'];end" if key =~ /^repository/
11
+ end
12
+
13
+ @connection = connection
14
+ end
15
+
16
+ def new_document
17
+ Document.new({}, self)
18
+ end
19
+
20
+ def new_folder
21
+ Folder.new({}, self)
22
+ end
23
+
24
+ def new_relationship
25
+ Relationship.new({}, self)
26
+ end
27
+
28
+ def new_item
29
+ Item.new({}, self)
30
+ end
31
+
32
+ def new_policy
33
+ Policy.new({}, self)
34
+ end
35
+
36
+ def root
37
+ result = connection.execute!({ cmisselector: 'object',
38
+ repositoryId: id,
39
+ objectId: root_folder_id })
40
+
41
+ ObjectFactory.create(result, self)
42
+ end
43
+
44
+ def object(cmis_object_id)
45
+ result = connection.execute!({ cmisselector: 'object',
46
+ repositoryId: id,
47
+ objectId: cmis_object_id })
48
+
49
+ ObjectFactory.create(result, self)
50
+ end
51
+
52
+ def types
53
+ result = connection.execute!({ cmisselector: 'typeDescendants',
54
+ repositoryId: id,
55
+ includePropertyDefinitions: true })
56
+
57
+ construct_types(result)
58
+ end
59
+
60
+ def type(type_id)
61
+ result = connection.execute!({ cmisselector: 'typeDefinition',
62
+ repositoryId: id,
63
+ typeId: type_id })
64
+
65
+ Type.new(result, self)
66
+ end
67
+
68
+ def has_type?(type_id)
69
+ types.map(&:id).include?(type_id)
70
+ end
71
+
72
+ def create_type(type)
73
+ result = connection.execute!({ cmisaction: 'createType',
74
+ repositoryId: id,
75
+ type: MultiJson.dump(type.to_hash) })
76
+
77
+ Type.new(result, self)
78
+ end
79
+
80
+ def create_relationship(object)
81
+ raise 'Object is not a Relationship' unless object.is_a?(Relationship)
82
+
83
+ result = connection.execute!({ cmisaction: 'createRelationship',
84
+ repositoryId: id,
85
+ properties: object.properties })
86
+
87
+ ObjectFactory.create(result, self)
88
+ end
89
+
90
+ def content_changes(change_log_token)
91
+ connection.execute!({ cmisselector: 'contentChanges',
92
+ repositoryId: id,
93
+ changeLogToken: change_log_token })
94
+ end
95
+
96
+ def query(statement, options = {})
97
+ Query.new(self, statement, options)
98
+ end
99
+
100
+ private
101
+
102
+ def construct_types(a)
103
+ types = []
104
+ a.each do |t|
105
+ types << Type.new(t['type'], self)
106
+ types << construct_types(t['children']) if t.has_key?('children')
107
+ end
108
+ types.flatten
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,43 @@
1
+ require 'active_support/core_ext/hash/indifferent_access'
2
+
3
+ module CMIS
4
+ class Server
5
+
6
+ attr_reader :connection
7
+
8
+ def initialize(options = {})
9
+ options.stringify_keys!
10
+
11
+ service_url = options['service_url'] || ENV['CMIS_BROWSER_URL']
12
+ username = options['username'] || ENV['CMIS_USER']
13
+ password = options['password'] || ENV['CMIS_PASSWORD']
14
+ headers = options['headers']
15
+
16
+ raise "'service_url' must be set" unless service_url
17
+
18
+ @connection = Connection.new(service_url, username, password, headers)
19
+ end
20
+
21
+ def repositories
22
+ result = connection.execute!
23
+
24
+ result.values.map do |r|
25
+ Repository.new(r, connection)
26
+ end
27
+ end
28
+
29
+ def repository(repository_id)
30
+ result = connection.execute!({ cmisselector: 'repositoryInfo',
31
+ repositoryId: repository_id })
32
+
33
+ Repository.new(result[repository_id], connection)
34
+ end
35
+
36
+ def has_repository?(repository_id)
37
+ result = connection.execute!
38
+
39
+ result.keys.include?(repository_id)
40
+ end
41
+
42
+ end
43
+ end
data/lib/cmis/type.rb ADDED
@@ -0,0 +1,106 @@
1
+ require 'active_support/core_ext'
2
+
3
+ module CMIS
4
+ class Type
5
+
6
+ attr_accessor :connection
7
+ attr_accessor :repository
8
+
9
+ def initialize(hash = {}, repository = nil)
10
+ @repository = repository
11
+ @connection = repository.connection if repository
12
+
13
+ @hash = hash.with_indifferent_access
14
+
15
+ properties = %w( id localName localNamespace queryName displayName baseId
16
+ parentId description creatable fileable queryable
17
+ controllablePolicy controllableACL fulltextIndexed
18
+ includedInSupertypeQuery propertyDefinitions versionable
19
+ contentStreamAllowed allowedSourceTypes allowedTargetTypes )
20
+
21
+ properties.each do |key|
22
+ class_eval "def #{key.underscore};@hash['#{key}'];end"
23
+ class_eval "def #{key.underscore}=(value);@hash['#{key}']=value;end"
24
+ end
25
+
26
+ @hash['propertyDefinitions'] ||= ActiveSupport::HashWithIndifferentAccess.new
27
+ @hash['propertyDefinitions'].each do |key, value|
28
+ @hash['propertyDefinitions'][key] = PropertyDefinition.new(value)
29
+ end
30
+ end
31
+
32
+ def add_property_definition(property)
33
+ property_definitions[property[:id]] = property
34
+ end
35
+
36
+ def create
37
+ repository.create_type(self)
38
+ end
39
+
40
+ def update(changed_property_defs)
41
+ new_defs = changed_property_defs.map(&:to_hash).reduce({}) do |result, element|
42
+ result[element[:id]] = element
43
+ result
44
+ end
45
+
46
+ hash = to_hash
47
+ hash['propertyDefinitions'] = new_defs
48
+
49
+ result = connection.execute! ({ cmisaction: 'updateType',
50
+ repositoryId: repository.id,
51
+ type: MultiJson.dump(hash) })
52
+
53
+ Type.new(result, repository)
54
+ end
55
+
56
+ def delete
57
+ connection.execute!({ cmisaction: 'deleteType',
58
+ repositoryId: repository.id,
59
+ typeId: id })
60
+ end
61
+
62
+ def document_type?
63
+ base_id == 'cmis:document'
64
+ end
65
+
66
+ def folder_type?
67
+ base_id == 'cmis:folder'
68
+ end
69
+
70
+ def relationship_type?
71
+ base_id == 'cmis:relationship'
72
+ end
73
+
74
+ def policy_type?
75
+ base_id == 'cmis:policy'
76
+ end
77
+
78
+ def item_type?
79
+ base_id == 'cmis:item'
80
+ end
81
+
82
+ def new_object
83
+ object = case base_id
84
+ when 'cmis:document'
85
+ Document.new({}, repository)
86
+ when 'cmis:folder'
87
+ Folder.new({}, repository)
88
+ when 'cmis:relationship'
89
+ Relationship.new({}, repository)
90
+ when 'cmis:policy'
91
+ Policy.new({}, repository)
92
+ when 'cmis:item'
93
+ Item.new({}, repository)
94
+ else
95
+ raise "Unsupported base type: #{base_id}"
96
+ end
97
+ object.object_type_id = id
98
+ object
99
+ end
100
+
101
+ def to_hash
102
+ @hash
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,3 @@
1
+ module CMIS
2
+ VERSION = '0.2'
3
+ end
data/readme.md ADDED
@@ -0,0 +1,23 @@
1
+ # cmis-ruby
2
+
3
+ **cmis-ruby** is a [CMIS](http://chemistry.apache.org/project/cmis.html) client library, using the the CMIS browser binding ([CMIS 1.1](http://docs.oasis-open.org/cmis/CMIS/v1.1/CMIS-v1.1.html)) for Ruby.
4
+
5
+ ## Running Test
6
+
7
+ Running the tests requires a running CMIS server.
8
+
9
+ rake
10
+
11
+ ## TODO
12
+
13
+ * query properties, not *
14
+ * string / symbol consistency
15
+ * better exceptions and handling
16
+ * headers / params in low level (options)
17
+ * facilitate copy between servers (make a flow)
18
+ * improve exists for repo / type
19
+ * caching
20
+
21
+ ## Contributing
22
+
23
+ Write some code. Run tests. Open a pull request.
@@ -0,0 +1,45 @@
1
+ require_relative './helper'
2
+
3
+ describe CMIS::Document do
4
+
5
+ before :all do
6
+ @repo = create_repository('test')
7
+ end
8
+
9
+ after :all do
10
+ delete_repository('test')
11
+ end
12
+
13
+ it 'create_in_folder with content' do
14
+ new_object = @repo.new_document
15
+ new_object.name = 'doc1'
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
18
+ doc = new_object.create_in_folder(@repo.root)
19
+ doc.name.should eq 'doc1'
20
+ doc.content_stream_mime_type.should eq 'text/plain'
21
+ doc.content_stream_file_name.should eq 'doc1.txt'
22
+ doc.content.should eq 'content1'
23
+ doc.delete
24
+ end
25
+
26
+ it 'create_in_folder without content' do
27
+ new_object = @repo.new_document
28
+ new_object.name = 'doc2'
29
+ new_object.object_type_id = 'cmis:document'
30
+ doc = new_object.create_in_folder(@repo.root)
31
+ doc.name.should eq 'doc2'
32
+ doc.content.should be nil
33
+ doc.delete
34
+ end
35
+
36
+ # it 'set content - attached' do
37
+ # new_object = @repo.new_document
38
+ # new_object.name = 'doc3'
39
+ # new_object.object_type_id = 'cmis:document'
40
+ # doc = @repo.root.create(new_object)
41
+ # doc.set_content(StringIO.new('content3'), 'text/plain', 'doc3.txt') # set content on attached doc
42
+ # doc.content.should eq 'content3'
43
+ # doc.delete
44
+ # end
45
+ end
@@ -0,0 +1,75 @@
1
+ require_relative './helper'
2
+
3
+ describe CMIS::Folder do
4
+
5
+ before :all do
6
+ @repo = create_repository('test')
7
+ end
8
+
9
+ after :all do
10
+ delete_repository('test')
11
+ end
12
+
13
+ it 'parent - root' do
14
+ @repo.root.parent.should be_nil
15
+ end
16
+
17
+ it 'parent - root child' do
18
+ new_object = @repo.new_folder
19
+ new_object.name = 'folder1'
20
+ new_object.object_type_id = 'cmis:folder'
21
+ folder = @repo.root.create(new_object)
22
+ folder.parent.cmis_object_id.should eq @repo.root_folder_id
23
+ folder.delete
24
+ end
25
+
26
+ it 'create document' do
27
+ new_object = @repo.new_document
28
+ new_object.name = 'doc1'
29
+ new_object.object_type_id = 'cmis:document'
30
+ new_object.set_content(StringIO.new('apple is a fruit'), 'text/plain', 'apple.txt')
31
+ object = @repo.root.create(new_object)
32
+ object.should be_a_kind_of CMIS::Document
33
+ object.name.should eq 'doc1'
34
+ object.content_stream_mime_type.should eq 'text/plain'
35
+ object.content_stream_file_name.should eq 'apple.txt'
36
+ object.content.should eq 'apple is a fruit'
37
+ object.delete
38
+ end
39
+
40
+ it 'create folder' do
41
+ new_object = @repo.new_folder
42
+ new_object.name = 'folder1'
43
+ new_object.object_type_id = 'cmis:folder'
44
+ object = @repo.root.create(new_object)
45
+ object.should be_a_kind_of CMIS::Folder
46
+ object.name.should eq 'folder1'
47
+ object.delete
48
+ end
49
+
50
+ it 'create relationship' do
51
+ new_object = @repo.new_relationship
52
+ new_object.name = 'rel1'
53
+ new_object.object_type_id = 'cmis:relationship'
54
+ lambda { @repo.root.create(new_object) }.should raise_exception
55
+ end
56
+
57
+ it 'create item' do
58
+ begin
59
+ new_object = @repo.new_item
60
+ new_object.name = 'item1'
61
+ new_object.object_type_id = 'cmis:item'
62
+ object = @repo.root.create(new_object)
63
+ object.should be_a_kind_of CMIS::Item
64
+ object.name.should eq 'item1'
65
+ object.delete
66
+ end unless @repo.cmis_version_supported < '1.1'
67
+ end
68
+
69
+ it 'create object' do
70
+ new_object = CMIS::Object.new({}, @repo)
71
+ new_object.name = 'object1'
72
+ new_object.object_type_id = 'cmis:folder'
73
+ lambda { @repo.root.create(new_object) }.should raise_exception
74
+ end
75
+ end