cmis-ruby 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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