cmis 0.1.0-java

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.
Files changed (38) hide show
  1. data/.gitignore +21 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +212 -0
  6. data/Rakefile +6 -0
  7. data/cmis.gemspec +20 -0
  8. data/lib/cmis/version.rb +3 -0
  9. data/lib/cmis.rb +115 -0
  10. data/pom.xml +19 -0
  11. data/samples.rb +112 -0
  12. data/spec/cmis_spec.rb +274 -0
  13. data/spec/fixtures/document.pdf +0 -0
  14. data/spec/fixtures/text_file.txt +1 -0
  15. data/spec/fixtures/text_file2.txt +1 -0
  16. data/spec/spec_helper.rb +31 -0
  17. data/target/dependency/activation-1.1.jar +0 -0
  18. data/target/dependency/chemistry-opencmis-client-api-0.8.0.jar +0 -0
  19. data/target/dependency/chemistry-opencmis-client-bindings-0.8.0.jar +0 -0
  20. data/target/dependency/chemistry-opencmis-client-impl-0.8.0.jar +0 -0
  21. data/target/dependency/chemistry-opencmis-commons-api-0.8.0.jar +0 -0
  22. data/target/dependency/chemistry-opencmis-commons-impl-0.8.0.jar +0 -0
  23. data/target/dependency/jaxb-api-2.1.jar +0 -0
  24. data/target/dependency/jaxb-impl-2.1.11.jar +0 -0
  25. data/target/dependency/jaxws-api-2.1.jar +0 -0
  26. data/target/dependency/jaxws-rt-2.1.7.jar +0 -0
  27. data/target/dependency/junit-3.8.jar +0 -0
  28. data/target/dependency/mimepull-1.3.jar +0 -0
  29. data/target/dependency/org.osgi.core-1.0.0.jar +0 -0
  30. data/target/dependency/resolver-20050927.jar +0 -0
  31. data/target/dependency/saaj-api-1.3.jar +0 -0
  32. data/target/dependency/saaj-impl-1.3.3.jar +0 -0
  33. data/target/dependency/slf4j-api-1.6.6.jar +0 -0
  34. data/target/dependency/stax-api-1.0-2.jar +0 -0
  35. data/target/dependency/stax-ex-1.2.jar +0 -0
  36. data/target/dependency/streambuffer-0.9.jar +0 -0
  37. data/target/dependency/wstx-asl-3.2.3.jar +0 -0
  38. metadata +107 -0
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ TODO.txt
20
+
21
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cmis.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Richard Nyström
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # CMIS
2
+
3
+ CMIS client for JRuby. This gem uses the Apache Chemistry OpenCMIS Java libraries under the hood.
4
+
5
+ More information about Apache Chemistry can be found here: http://chemistry.apache.org/
6
+
7
+ ## What is CMIS
8
+
9
+ Content Management Interoperability Services (CMIS) is an open standard that defines an abstraction layer for controlling diverse document management systems and repositories using web protocols. CMIS defines a domain model plus Web Services and Restful AtomPub (RFC5023) bindings that can be used by applications.
10
+
11
+ Here are a few CMIS-compliant content repositories:
12
+
13
+ * [Alfresco](http://www.alfresco.com)
14
+ * [Nuxeo](http://www.nuxeo.com)
15
+ * [EMC Documentum](http://www.emc.com/domains/documentum/index.htm)
16
+ * [Sharepoint](http://sharepoint.microsoft.com/en-us/Pages/default.aspx)
17
+ * [IBM FileNet Content Manager](http://www-01.ibm.com/software/data/content-management/filenet-content-manager/)
18
+ * [KnowledgeTree](https://www.knowledgetree.com/)
19
+
20
+ ## Installation
21
+
22
+ Add this line to your application's Gemfile:
23
+
24
+ gem 'cmis'
25
+
26
+ And then execute:
27
+
28
+ $ bundle
29
+
30
+ Or install it yourself as:
31
+
32
+ $ gem install cmis
33
+
34
+ ## Usage
35
+
36
+ This guide is for JRuby developers who want to access CMIS-compliant content repositories from JRuby. The examples has been tested with Alfresco Community Edition 4.2.c which is one of the most feature complete CMIS content repository.
37
+
38
+ If you want to run the code snippets below you can download and install Alfresco. You can find the version that fits your platform here: http://wiki.alfresco.com/wiki/Download_and_Install_Alfresco
39
+
40
+ You can also run the examples using the Public Alfresco CMIS server. More information can be found here: http://cmis.alfresco.com. The atom url for the public
41
+ server is http://cmis.alfresco.com/cmisatom.
42
+
43
+ Nuxeo also provides a demo server. More information can be found here: http://doc.nuxeo.com/display/NXDOC/CMIS+for+Nuxeo#CMISforNuxeo-Onlinedemo .
44
+
45
+ ## Connecting to a CMIS repository
46
+
47
+ To be able to do anything useful on a CMIS repository, you must first find a repository, and create a session with it:
48
+
49
+ ```ruby
50
+ require 'cmis'
51
+ atom_url = "http://localhost:8080/alfresco/service/cmis"
52
+ user = "admin"
53
+ password = "admin"
54
+ @session = CMIS::create_session(atom_url, user, password)
55
+
56
+ ```
57
+ Most CMIS servers only provides one repository by default that you can connect to and the code above automatically connects to the first repository that it finds.
58
+ If you want to connect to a specific repository you can do it like this:
59
+
60
+ ```ruby
61
+ available_repos = CMIS::repositories(atom_url, user, password)
62
+ puts "Trying to connect to a repository with id #{available_repos[0].id}"
63
+ @session = CMIS::create_session(atom_url, user, password, available_repos[0].id)
64
+
65
+ ```
66
+
67
+ ## Working with folders and documents
68
+
69
+ Finding the contents of the root folder:
70
+
71
+ ```ruby
72
+ root = @session.root_folder
73
+ children = root.children
74
+
75
+ # Prints out all children objects name found in the root folder
76
+ children.each do |o|
77
+ puts o.name
78
+ end
79
+ ```
80
+
81
+ ### Creating folders
82
+
83
+ Create a folder the simple way. The create_cmis_folder method is a convenient method implemented in the JRuby CMIS library.
84
+
85
+ ```ruby
86
+ root.create_cmis_folder("My new folder")
87
+ ```
88
+
89
+ Create a folder the hard way:
90
+
91
+ ```ruby
92
+ folder_props = { CMIS::PropertyIds::OBJECT_TYPE_ID => "cmis:folder", CMIS::PropertyIds::NAME => "Another folder" }
93
+ root.create_folder(folder_props)
94
+ ```
95
+
96
+ ### Creating/Uploading documents
97
+
98
+ The create_cmis_document method is a convenient method implemented in the JRuby CMIS Library.
99
+ This method takes a name and a file path and uploads the file to the repository. The document will be saved as a major version.
100
+
101
+ ```ruby
102
+ id = root.create_cmis_document("cmis_logo.png", "/Users/ricn/cmis_logo.png")
103
+ doc = @session.get_object(id)
104
+ puts doc.name
105
+ ```
106
+
107
+ #### Create a document the hard way (but with more flexibility)
108
+
109
+ ```ruby
110
+ content_stream = CMIS::create_content_stream("/Users/ricn/cmis_logo.png", @session)
111
+ props = { CMIS::PropertyIds::OBJECT_TYPE_ID => "cmis:document", CMIS::PropertyIds::NAME => "cmis_logo.png" }
112
+ id = root.create_document(props, content_stream, CMIS::VersioningState::MAJOR)
113
+ doc = @session.get_object(id)
114
+ ```
115
+
116
+ #### Download a document to your local disk
117
+
118
+ ```ruby
119
+ doc = @session.get_object(id)
120
+ file = "/Users/ricn/" + doc.name
121
+ doc.download(file)
122
+ ```
123
+
124
+ ### Updating a document
125
+
126
+ ```ruby
127
+ id = root.create_cmis_document("cmis_logo_original.png", "/Users/ricn/cmis_logo.png")
128
+ doc = @session.get_object(id)
129
+ puts "Original name: #{doc.name}"
130
+ props = { CMIS::PropertyIds::NAME => "cmis_logo_renamed.png"}
131
+ id = doc.update_properties(props)
132
+ doc = @session.get_object(id)
133
+ puts "New name: #{doc.name}"
134
+ ```
135
+
136
+ ### Deleting a document
137
+
138
+ ```ruby
139
+ doc = @session.get_object(id)
140
+ doc.delete # Yay, that was easy!
141
+ ```
142
+
143
+ ### Deleting a folder tree
144
+
145
+ ```ruby
146
+ # First we need to create a folder tree
147
+ folder1 = root.create_cmis_folder("folder1")
148
+ folder11 = folder1.create_cmis_folder("Folder11")
149
+ folder12 = folder1.create_cmis_folder("Folder12")
150
+ # Delete it
151
+ folder1.delete_tree(true, CMIS::UnfileObject::DELETE, true) # parameter explanation: boolean allversions, UnfileObject unfile, boolean continueOnFailure
152
+ ```
153
+
154
+ ## Working with CMIS Properties
155
+
156
+ ```ruby
157
+ ### Displaying the properties of an object
158
+ props = @session.root_folder.properties
159
+ props.each do |p|
160
+ display_name = p.definition.display_name
161
+ value = p.value_as_string
162
+ if display_name != nil && value != nil
163
+ puts p.definition.display_name + ": " + p.value_as_string
164
+ end
165
+ end
166
+ ```
167
+
168
+ ### Getting a property explicitly
169
+
170
+ Each object type has a known set of properties, and you can retrieve these explicitly. For example, the document type has a set of properties described by the [DocumentProperties](http://chemistry.apache.org/java/0.8.0/maven/apidocs/org/apache/chemistry/opencmis/client/api/DocumentProperties.html) interface, and you can use the methods on this interface to retrieve the value a property.
171
+
172
+ ```ruby
173
+ # For root folder
174
+ puts "Is root folder? " + root.is_root_folder.to_s
175
+ puts "Path: " + root.path
176
+
177
+ # For a document
178
+ id = root.create_cmis_document("cmis.png", "/Users/ricn/cmis_logo.png")
179
+ doc = @session.get_object(id)
180
+ puts "Name: " + doc.name
181
+ puts "Version label: " + doc.version_label
182
+ puts "Content stream file name: " + doc.content_stream_file_name
183
+ puts "Content stream mime type: " + doc.content_stream_mime_type
184
+ ```
185
+
186
+ ## Working with CMIS Queries
187
+
188
+ ```ruby
189
+ query = "SELECT * FROM cmis:document WHERE cmis:name LIKE 'cmis%'"
190
+ q = @session.query(query, false) # true means search all versions
191
+
192
+ q.each do |result|
193
+ puts result.property_value_by_query_name("cmis:name")
194
+ end
195
+ ```
196
+
197
+ ## DOCUMENTION TODO:
198
+ * Add Multi-filing and Unfiling examples
199
+ * Add Relationships examples
200
+ * Add Access control examples
201
+ * Add OperationContext examples
202
+ * Add Advanced types usage examples
203
+ * Add Performance notes
204
+ * Add Troubleshooting notes
205
+
206
+ ## Contributing
207
+
208
+ 1. Fork it
209
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
210
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
211
+ 4. Push to the branch (`git push origin my-new-feature`)
212
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ desc 'Download jars'
4
+ task :download_jars do
5
+ system "mvn dependency:copy-dependencies"
6
+ end
data/cmis.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cmis/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "cmis"
8
+ gem.version = Cmis::VERSION
9
+ gem.authors = ["Richard Nyström"]
10
+ gem.email = ["ricny046@gmail.com"]
11
+ gem.description = %q{A thin JRuby wrapper for the Apache Chemistry OpenCMIS client.}
12
+ gem.summary = %q{A thin JRuby wrapper for the Apache Chemistry OpenCMIS client.}
13
+ gem.homepage = "https://github.com/ricn/cmis"
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+ gem.add_development_dependency "rspec"
19
+ gem.platform = "java"
20
+ end
@@ -0,0 +1,3 @@
1
+ module Cmis
2
+ VERSION = "0.1.0"
3
+ end
data/lib/cmis.rb ADDED
@@ -0,0 +1,115 @@
1
+ raise "You need to run JRuby to use CMIS" unless RUBY_PLATFORM =~ /java/
2
+
3
+ require "cmis/version"
4
+ require 'java'
5
+
6
+ Dir[File.join(File.dirname(__FILE__), "../target/dependency/*.jar")].each do |jar|
7
+ require jar
8
+ end
9
+
10
+ module CMIS
11
+ import org.apache.chemistry.opencmis.client.api.Session
12
+ import org.apache.chemistry.opencmis.client.api.SessionFactory
13
+ import org.apache.chemistry.opencmis.client.api.OperationContext
14
+ import org.apache.chemistry.opencmis.client.util.FileUtils
15
+ import org.apache.chemistry.opencmis.client.runtime.OperationContextImpl
16
+ import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl
17
+ import org.apache.chemistry.opencmis.commons.SessionParameter
18
+ import org.apache.chemistry.opencmis.commons.PropertyIds
19
+ import org.apache.chemistry.opencmis.commons.impl.MimeTypes
20
+
21
+ import org.apache.chemistry.opencmis.commons.enums.Action
22
+ import org.apache.chemistry.opencmis.commons.enums.BaseTypeId
23
+ import org.apache.chemistry.opencmis.commons.enums.CapabilityAcl
24
+ import org.apache.chemistry.opencmis.commons.enums.VersioningState
25
+ import org.apache.chemistry.opencmis.commons.enums.UnfileObject
26
+ import org.apache.chemistry.opencmis.commons.enums.BindingType
27
+ import org.apache.chemistry.opencmis.commons.enums.CapabilityChanges
28
+ import org.apache.chemistry.opencmis.commons.enums.CapabilityContentStreamUpdates
29
+ import org.apache.chemistry.opencmis.commons.enums.CapabilityJoin
30
+ import org.apache.chemistry.opencmis.commons.enums.CapabilityQuery
31
+ import org.apache.chemistry.opencmis.commons.enums.CapabilityRenditions
32
+ import org.apache.chemistry.opencmis.commons.enums.Cardinality
33
+ import org.apache.chemistry.opencmis.commons.enums.ChangeType
34
+ import org.apache.chemistry.opencmis.commons.enums.ContentStreamAllowed
35
+ import org.apache.chemistry.opencmis.commons.enums.DateTimeResolution
36
+ import org.apache.chemistry.opencmis.commons.enums.DecimalPrecision
37
+ import org.apache.chemistry.opencmis.commons.enums.ExtensionLevel
38
+ import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships
39
+ import org.apache.chemistry.opencmis.commons.enums.PropertyType
40
+ import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection
41
+ import org.apache.chemistry.opencmis.commons.enums.SupportedPermissions
42
+ import org.apache.chemistry.opencmis.commons.enums.UnfileObject
43
+ import org.apache.chemistry.opencmis.commons.enums.Updatability
44
+
45
+ FolderImpl = org.apache.chemistry.opencmis.client.runtime.FolderImpl
46
+ DocumentImpl = org.apache.chemistry.opencmis.client.runtime.DocumentImpl
47
+
48
+ class DocumentImpl
49
+ def download(destination_path)
50
+ FileUtils.download(self, destination_path)
51
+ end
52
+ end
53
+
54
+ class FolderImpl
55
+ def create_cmis_folder(name, props = nil)
56
+ folder_props = { PropertyIds::OBJECT_TYPE_ID => "cmis:folder", PropertyIds::NAME => name }
57
+ folder_props.merge!(props) if props != nil && props.is_a?(Hash)
58
+ self.create_folder(java.util.HashMap.new(folder_props))
59
+ end
60
+
61
+ def create_cmis_document(name, filename, props = nil)
62
+ if filename != nil && filename.length > 0
63
+ file = java.io.File.new(filename)
64
+ stream = java.io.BufferedInputStream.new(java.io.FileInputStream.new(file))
65
+ content = session.object_factory.create_content_stream(file.name, file.length, CMIS::MimeTypes.getMIMEType(file), stream)
66
+ doc_props = { CMIS::PropertyIds::OBJECT_TYPE_ID => "cmis:document", CMIS::PropertyIds::NAME => name }
67
+ doc_props.merge!(props) if props != nil && props.is_a?(Hash)
68
+ self.create_document(doc_props, content, CMIS::VersioningState::MAJOR)
69
+ end
70
+ end
71
+
72
+ def create_text_doc(name, content)
73
+ FileUtils.create_text_document(self.id, name, content, "cmis:document", CMIS::VersioningState::MAJOR, session)
74
+ end
75
+ end
76
+
77
+ def self.create_session(url, user, password, repo_id = nil)
78
+ session_factory = SessionFactoryImpl.new_instance
79
+ repo_id = self.repositories(url, user, password)[0].id if repo_id == nil
80
+
81
+ parameters = {
82
+ SessionParameter::ATOMPUB_URL => url,
83
+ SessionParameter::BINDING_TYPE => BindingType::ATOMPUB.value,
84
+ SessionParameter::USER => user,
85
+ SessionParameter::PASSWORD => password,
86
+ SessionParameter::REPOSITORY_ID => repo_id
87
+ }
88
+
89
+ session_factory.create_session(parameters)
90
+ end
91
+
92
+ def self.repositories(url, user, password)
93
+ session_factory = SessionFactoryImpl.new_instance
94
+ parameters = {
95
+ SessionParameter::ATOMPUB_URL => url,
96
+ SessionParameter::BINDING_TYPE => BindingType::ATOMPUB.value,
97
+ SessionParameter::USER => user,
98
+ SessionParameter::PASSWORD => password
99
+ }
100
+
101
+ session_factory.get_repositories(parameters)
102
+ end
103
+
104
+ def self.create_content_stream(filename, session)
105
+ content = nil
106
+
107
+ if filename != nil && filename.length > 0
108
+ file = java.io.File.new(filename)
109
+ stream = java.io.BufferedInputStream.new(java.io.FileInputStream.new(file))
110
+ content = session.object_factory.create_content_stream(file.name, file.length, CMIS::MimeTypes.getMIMEType(file), stream)
111
+ end
112
+
113
+ content
114
+ end
115
+ end
data/pom.xml ADDED
@@ -0,0 +1,19 @@
1
+ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
+ <modelVersion>4.0.0</modelVersion>
4
+
5
+ <name>CMIS</name>
6
+
7
+ <groupId>org.cmis</groupId>
8
+ <artifactId>CMIS</artifactId>
9
+ <version>1.0-SNAPSHOT</version>
10
+ <packaging>jar</packaging>
11
+
12
+ <dependencies>
13
+ <dependency>
14
+ <groupId>org.apache.chemistry.opencmis</groupId>
15
+ <artifactId>chemistry-opencmis-client-impl</artifactId>
16
+ <version>0.8.0</version>
17
+ </dependency>
18
+ </dependencies>
19
+ </project>
data/samples.rb ADDED
@@ -0,0 +1,112 @@
1
+ require 'cmis'
2
+
3
+ ## Connecting to a CMIS repository (the simple way)
4
+ # To be able to do anything useful on a CMIS repository, you must first find a repository, and create a session with it:
5
+
6
+ atom_url = "http://localhost:8181/alfresco/service/cmis"
7
+ user = "admin"
8
+ password = "admin"
9
+ @session = CMIS::create_session(atom_url, user, password)
10
+
11
+ # Most CMIS servers only provides one repository by default that you can connect to and the code above automatically connects to the first repository that it finds.
12
+ # If you want to connect to a specific repository you can do it like this:
13
+
14
+ available_repos = CMIS::repositories(atom_url, user, password)
15
+ puts "Trying to connect to repository with id #{available_repos[0].id}"
16
+ @session = CMIS::create_session(atom_url, user, password, available_repos[0].id)
17
+
18
+ ## Working with folders and documents
19
+
20
+ ### Finding the contents of the root folder
21
+
22
+ root = @session.root_folder
23
+ children = root.children
24
+
25
+ children.each do |o|
26
+ puts o.name # Prints out all children objects found in the root folder
27
+ end
28
+
29
+ ### Creating folders
30
+
31
+ # Create a folder the simple way. This is a convenient method implemented in the JRuby CMIS library.
32
+ root.create_cmis_folder("My new folder")
33
+
34
+ # Create a folder the hard way:
35
+ folder_props = { CMIS::PropertyIds::OBJECT_TYPE_ID => "cmis:folder", CMIS::PropertyIds::NAME => "Another folder" }
36
+ root.create_folder(folder_props)
37
+
38
+ ## Creating/Uploading documents
39
+
40
+ ### Create a document object the simple way. This is a convenient method implemented in the JRuby CMIS Library.
41
+
42
+ # This method takes a name and a file path and uploads the file to the repository. The document will be saved as a major version.
43
+ id = root.create_cmis_document("cmis_logo.png", "/Users/ricn/cmis_logo.png")
44
+ doc = @session.get_object(id)
45
+ puts doc.name
46
+
47
+ ### Create a document object the hard way:
48
+ # TODO
49
+
50
+ ### Download a document to your local disk:
51
+ # TODO
52
+
53
+ ### Updating a document
54
+ id = root.create_cmis_document("cmis_logo_original.png", "/Users/ricn/cmis_logo.png")
55
+ doc = @session.get_object(id)
56
+ puts "Original name: #{doc.name}"
57
+ props = { CMIS::PropertyIds::NAME => "cmis_logo_renamed.png"}
58
+ id = doc.update_properties(props)
59
+ doc = @session.get_object(id)
60
+ puts "New name: #{doc.name}"
61
+
62
+ ### Deleting a document
63
+ doc = @session.get_object(id)
64
+ doc.delete # Yay, that was easy!
65
+
66
+ ### Deleting a folder tree
67
+
68
+ # First we need to create a folder tree
69
+ folder1 = root.create_cmis_folder("folder1")
70
+ folder11 = folder1.create_cmis_folder("Folder11")
71
+ folder12 = folder1.create_cmis_folder("Folder12")
72
+ # Delete it
73
+ folder1.delete_tree(true, CMIS::UnfileObject::DELETE, true) # parameter explanation: boolean allversions, UnfileObject unfile, boolean continueOnFailure
74
+
75
+ ## CMIS Properties
76
+
77
+ ### Displaying the properties of an Object
78
+ props = @session.root_folder.properties
79
+ props.each do |p|
80
+ display_name = p.definition.display_name
81
+ value = p.value_as_string
82
+ if display_name != nil && value != nil
83
+ puts p.definition.display_name + ": " + p.value_as_string
84
+ end
85
+ end
86
+
87
+ ### Getting a property explicitly
88
+ # Each object type has a known set of properties, and you can retrieve these explicitly.
89
+ # For example, the document type has a set of properties described by the DocumentProperties
90
+ # (http://chemistry.apache.org/java/0.8.0/maven/apidocs/org/apache/chemistry/opencmis/client/api/DocumentProperties.html) interface,
91
+ # and you can use the methods on this interface to retrieve the value a property
92
+
93
+ # For root folder
94
+ puts "Is root folder? " + root.is_root_folder.to_s
95
+ puts "Path: " + root.path
96
+
97
+ # For a document
98
+ id = root.create_cmis_document("cmis_logo_original.png", "/Users/ricn/cmis_logo.png")
99
+ doc = @session.get_object(id)
100
+ puts "Name: " + doc.name
101
+ puts "Version label: " + doc.version_label
102
+ puts "Content stream file name: " + doc.content_stream_file_name
103
+ puts "Content stream mime type: " + doc.content_stream_mime_type
104
+
105
+ ## Working with CMIS Queries. NOT WORKING :-(
106
+
107
+ query = "SELECT * FROM cmis:document WHERE cmis:name LIKE 'cmis%'"
108
+ q = @session.query(query, false) # true means search all versions
109
+
110
+ q.each do |result|
111
+ puts result.property_value_by_query_name("cmis:name").inspect
112
+ end
data/spec/cmis_spec.rb ADDED
@@ -0,0 +1,274 @@
1
+ require 'spec_helper'
2
+
3
+ describe "CMIS" do
4
+ shared_examples_for "a CMIS repository" do |atom_url, user, password|
5
+
6
+ before(:all) do
7
+ @atom_url = atom_url
8
+ @user = user
9
+ @password = password
10
+ @repos = CMIS::repositories(@atom_url, @user, @password)
11
+ @session = CMIS::create_session(@atom_url, @user, @password, @repos[0].id)
12
+ @test_folder_name = "JRUBY_CMIS_TEST_" + random_name
13
+ @test_folder = @session.root_folder.create_cmis_folder(@test_folder_name)
14
+ end
15
+
16
+ after(:all) do
17
+ @test_folder.delete_tree(true, CMIS::UnfileObject::DELETE, true)
18
+ end
19
+
20
+ describe "Repository functionality" do
21
+ it "should create a session" do
22
+ @session.is_a?(Java::OrgApacheChemistryOpencmisClientRuntime::SessionImpl).should be_true
23
+ end
24
+
25
+ it "should create a session against the first repository" do
26
+ @simple_session = CMIS::create_session(@atom_url, @user, @password)
27
+ @simple_session.is_a?(Java::OrgApacheChemistryOpencmisClientRuntime::SessionImpl).should be_true
28
+ end
29
+
30
+ it "should retrieve all available repositories" do
31
+ @repos.is_a?(Java::JavaUtil::ArrayList).should be_true
32
+ end
33
+
34
+ it "should have one repository with a name" do
35
+ repo = @repos[0]
36
+ repo.name.should_not be_empty
37
+ end
38
+
39
+ it "should be possible to read the repository info" do
40
+ rep_info = @session.repository_info
41
+ cap = rep_info.capabilities
42
+
43
+ # Just testing a few of them
44
+ cap.is_get_descendants_supported.should == true
45
+ cap.is_get_folder_tree_supported.should == true
46
+ cap.changes_capability.value.should_not be_empty
47
+ cap.query_capability.value.should_not be_empty
48
+ cap.join_capability.value.should_not == be_empty
49
+ end
50
+ end
51
+
52
+ describe "Reading objects" do
53
+ it "should be possible to find the contents of the root folder" do
54
+ root = @session.root_folder
55
+ children = root.children
56
+ children.map(&:name).should include(@test_folder_name)
57
+ end
58
+
59
+ it "should display the properties of an object" do
60
+ props = @session.root_folder.properties
61
+ props.each do |p|
62
+ disp_name = p.definition.display_name
63
+ p.value_as_string.should == "/" if disp_name == "Path"
64
+ p.value_as_string.should == "cmis:folder" if disp_name == "Type-Id"
65
+ p.value_as_string.should_not be_nil if disp_name == "Name"
66
+ p.value_as_string.should be_nil if disp_name == "Parent Id"
67
+ end
68
+ end
69
+
70
+ it "should be possible to get a property explicitly" do
71
+ # A couple of folder specific props that we can access explicitly
72
+ root = @session.root_folder
73
+ root.is_root_folder.should == true
74
+ root.path.should == "/"
75
+ end
76
+
77
+ it "should retrieve allowable actions for an object" do
78
+ allowed_actions = @session.root_folder.allowable_actions.allowable_actions # Are you kidding me!!?
79
+ allowed_actions.to_a.should include(CMIS::Action::CAN_GET_PROPERTIES)
80
+ end
81
+
82
+ it "should be possible to check if a document is versionable" do
83
+ doc = create_random_doc(@test_folder)
84
+ doc.type.is_versionable.should == true
85
+ end
86
+
87
+ it "should be possible to access information about renditions" do
88
+ file = file_path("document.pdf")
89
+ file_name = random_name + ".pdf"
90
+ id = @test_folder.create_cmis_document(file_name, file)
91
+ context = @session.create_operation_context
92
+ context.rendition_filter_string = "cmis:thumbnail"
93
+ @session.clear
94
+ doc = @session.get_object(id, context)
95
+
96
+ renditions = doc.renditions
97
+ # TODO: Fix this test.
98
+ #renditions.size.should >= 1
99
+ renditions.each do |r|
100
+ r.kind.should_not be_empty
101
+ r.mime_type.should_not be_empty
102
+ end
103
+ end
104
+
105
+ it "should be possible to download document" do
106
+ doc = create_random_doc(@test_folder)
107
+ file = Dir.tmpdir + doc.name
108
+ doc.download(file)
109
+ File.exists?(file).should == true
110
+ File.delete(file)
111
+ end
112
+ end
113
+
114
+ describe "Writing objects" do
115
+ it "should create a folder" do
116
+ name = random_name
117
+ new_folder_props = { CMIS::PropertyIds::OBJECT_TYPE_ID => "cmis:folder", CMIS::PropertyIds::NAME => name }
118
+ @test_folder.create_folder(new_folder_props)
119
+ @test_folder.children.map(&:name).should include(name)
120
+ end
121
+
122
+ it "should create a folder using convenient method" do
123
+ name = random_name
124
+ @test_folder.create_cmis_folder(name)
125
+ @test_folder.children.map(&:name).should include(name)
126
+ end
127
+
128
+ it "should create document" do
129
+ content_stream = CMIS::create_content_stream(file_path("text_file.txt"), @session)
130
+ text_file = random_name + ".txt"
131
+ props = { CMIS::PropertyIds::OBJECT_TYPE_ID => "cmis:document", CMIS::PropertyIds::NAME => text_file }
132
+ id = @test_folder.create_document(props, content_stream, CMIS::VersioningState::MAJOR)
133
+ doc = @session.get_object(id)
134
+
135
+ doc.properties.each do |p|
136
+ p.value.should == 16 if p.definition.id == "cmis:contentStreamLength"
137
+ end
138
+ end
139
+
140
+ it "should create document using convenient method" do
141
+ file = file_path("text_file.txt")
142
+ file_name = random_name + ".txt"
143
+ id = @test_folder.create_cmis_document(file_name, file)
144
+ doc = @session.get_object(id)
145
+
146
+ doc.properties.each do |p|
147
+ p.value.should == 16 if p.definition.id == "cmis:contentStreamLength"
148
+ end
149
+ end
150
+
151
+ it "should create document by specifying a string as content" do
152
+ content = "Please, save me!"
153
+ file_name = random_name + ".txt"
154
+ id = @test_folder.create_text_doc(file_name, content)
155
+ doc = @session.get_object(id)
156
+
157
+ doc.properties.each do |p|
158
+ p.value.should == content.size if p.definition.id == "cmis:contentStreamLength"
159
+ end
160
+ end
161
+ end
162
+
163
+ describe "Updating objects" do
164
+ it "should rename a document" do
165
+ doc = create_random_doc(@test_folder)
166
+ renamed_file_name = "renamed_" + doc.name
167
+ props = { CMIS::PropertyIds::OBJECT_TYPE_ID => "cmis:document",
168
+ CMIS::PropertyIds::NAME => renamed_file_name }
169
+ doc.update_properties(props)
170
+
171
+ doc.name.should == renamed_file_name
172
+ end
173
+
174
+ it "should update the content of a document (versioning)" do
175
+ doc = create_random_doc(@test_folder)
176
+
177
+ content_stream = CMIS::create_content_stream(file_path("text_file2.txt"), @session)
178
+ working_copy = @session.get_object(doc.check_out)
179
+ id = working_copy.check_in(false, nil, content_stream, "minor version")
180
+ doc = @session.get_object(id)
181
+
182
+ doc.properties.each do |p|
183
+ p.value.should == 17 if p.definition.id == "cmis:contentStreamLength"
184
+ p.value.should == "1.1" if p.definition.id == "cmis:versionLabel"
185
+ end
186
+
187
+ versions = doc.all_versions
188
+ versions.size.should == 2
189
+ end
190
+ end
191
+
192
+ describe "Deleting objects" do
193
+ it "should delete a document" do
194
+ content_stream = CMIS::create_content_stream(file_path("text_file.txt"), @session)
195
+ text_file = random_name + ".txt"
196
+ props = { CMIS::PropertyIds::OBJECT_TYPE_ID => "cmis:document",
197
+ CMIS::PropertyIds::NAME => text_file }
198
+ id = @test_folder.create_document(props, content_stream, CMIS::VersioningState::MAJOR)
199
+
200
+ doc = @session.get_object(id)
201
+
202
+ doc.delete(true)
203
+ children = @test_folder.children
204
+ children.map(&:name).should_not include(text_file)
205
+ end
206
+
207
+ it "should delete a folder tree" do
208
+ root = @test_folder
209
+ random_folder_name = random_name
210
+ folder1 = root.create_cmis_folder(random_folder_name)
211
+ folder11 = folder1.create_cmis_folder("Folder11")
212
+ folder12 = folder1.create_cmis_folder("Folder12")
213
+ @test_folder.children.map(&:name).should include(random_folder_name)
214
+ folder1.delete_tree(true, CMIS::UnfileObject::DELETE, true)
215
+ @test_folder.children.map(&:name).should_not include(random_folder_name)
216
+ end
217
+ end
218
+
219
+ describe "Querying and navigating objects" do
220
+ it "should be possible to navigate through a folder tree" do
221
+ root = @session.root_folder
222
+ # just making sure it can be executed
223
+ root.descendants(-1).count.should > 0 # get folders and documents
224
+ root.folder_tree(-1).count.should > 0 # get folders only
225
+ end
226
+
227
+ it "should be possible to execute a simple query" do
228
+ query = "SELECT cmis:name FROM cmis:folder WHERE cmis:name = 'Company Home'"
229
+ q = @session.query(query, false)
230
+
231
+ q.each do |result|
232
+ result.get_property_value_by_query_name("cmis:name").should == "Company Home"
233
+ end
234
+ end
235
+
236
+ it "should be possible to use paging" do
237
+ @sub_folder = @test_folder.create_cmis_folder("Paging")
238
+
239
+ 5.times do
240
+ @sub_folder.create_cmis_folder(random_name)
241
+ end
242
+
243
+ oc = CMIS::OperationContextImpl.new
244
+ oc.max_items_per_page = 3
245
+ @sub_folder.children(oc).skip_to(0).page.map(&:name).size.should == 3
246
+ @sub_folder.children.map(&:name).size.should == 5
247
+ end
248
+ end
249
+ end
250
+
251
+ describe "Local Alfresco" do
252
+ atom_url = "http://localhost:8181/alfresco/service/cmis"
253
+ user = "admin"
254
+ password = "admin"
255
+
256
+ #it_behaves_like "a CMIS repository", atom_url, user, password
257
+ end
258
+
259
+ describe "Alfresco" do
260
+ atom_url = "http://cmis.alfresco.com/cmisatom"
261
+ user = "admin"
262
+ password = "admin"
263
+
264
+ it_behaves_like "a CMIS repository", atom_url, user, password
265
+ end
266
+
267
+ describe "Nuxeo" do
268
+ atom_url = "http://cmis.demo.nuxeo.org/nuxeo/atom/cmis"
269
+ user = "Administrator"
270
+ password = "Administrator"
271
+
272
+ it_behaves_like "a CMIS repository", atom_url, user, password
273
+ end
274
+ end
Binary file
@@ -0,0 +1 @@
1
+ This is content.
@@ -0,0 +1 @@
1
+ This is content!!
@@ -0,0 +1,31 @@
1
+ require 'cmis'
2
+ require 'tmpdir'
3
+ def file_path( *paths )
4
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', *paths))
5
+ end
6
+
7
+
8
+ def random_name
9
+ rand(16**16).to_s(16)
10
+ end
11
+
12
+ def create_random_doc(parent)
13
+ file = file_path("text_file.txt")
14
+ file_name = random_name + ".txt"
15
+ id = parent.create_cmis_document(file_name, file)
16
+
17
+ parent.session.get_object(id)
18
+ end
19
+
20
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
+ RSpec.configure do |config|
22
+ config.treat_symbols_as_metadata_keys_with_true_values = true
23
+ config.run_all_when_everything_filtered = true
24
+ config.filter_run :focus
25
+
26
+ # Run specs in random order to surface order dependencies. If you find an
27
+ # order dependency and want to debug it, you can fix the order by providing
28
+ # the seed, which is printed after each run.
29
+ # --seed 1234
30
+ config.order = 'random'
31
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cmis
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: java
7
+ authors:
8
+ - Richard Nyström
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: !binary |-
21
+ MA==
22
+ none: false
23
+ requirement: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ! '>='
26
+ - !ruby/object:Gem::Version
27
+ version: !binary |-
28
+ MA==
29
+ none: false
30
+ prerelease: false
31
+ type: :development
32
+ description: A thin JRuby wrapper for the Apache Chemistry OpenCMIS client.
33
+ email:
34
+ - ricny046@gmail.com
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - .gitignore
40
+ - .rspec
41
+ - Gemfile
42
+ - LICENSE.txt
43
+ - README.md
44
+ - Rakefile
45
+ - cmis.gemspec
46
+ - lib/cmis.rb
47
+ - lib/cmis/version.rb
48
+ - pom.xml
49
+ - samples.rb
50
+ - spec/cmis_spec.rb
51
+ - spec/fixtures/document.pdf
52
+ - spec/fixtures/text_file.txt
53
+ - spec/fixtures/text_file2.txt
54
+ - spec/spec_helper.rb
55
+ - target/dependency/activation-1.1.jar
56
+ - target/dependency/chemistry-opencmis-client-api-0.8.0.jar
57
+ - target/dependency/chemistry-opencmis-client-bindings-0.8.0.jar
58
+ - target/dependency/chemistry-opencmis-client-impl-0.8.0.jar
59
+ - target/dependency/chemistry-opencmis-commons-api-0.8.0.jar
60
+ - target/dependency/chemistry-opencmis-commons-impl-0.8.0.jar
61
+ - target/dependency/jaxb-api-2.1.jar
62
+ - target/dependency/jaxb-impl-2.1.11.jar
63
+ - target/dependency/jaxws-api-2.1.jar
64
+ - target/dependency/jaxws-rt-2.1.7.jar
65
+ - target/dependency/junit-3.8.jar
66
+ - target/dependency/mimepull-1.3.jar
67
+ - target/dependency/org.osgi.core-1.0.0.jar
68
+ - target/dependency/resolver-20050927.jar
69
+ - target/dependency/saaj-api-1.3.jar
70
+ - target/dependency/saaj-impl-1.3.3.jar
71
+ - target/dependency/slf4j-api-1.6.6.jar
72
+ - target/dependency/stax-api-1.0-2.jar
73
+ - target/dependency/stax-ex-1.2.jar
74
+ - target/dependency/streambuffer-0.9.jar
75
+ - target/dependency/wstx-asl-3.2.3.jar
76
+ homepage: https://github.com/ricn/cmis
77
+ licenses: []
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: !binary |-
87
+ MA==
88
+ none: false
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: !binary |-
94
+ MA==
95
+ none: false
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 1.8.24
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: A thin JRuby wrapper for the Apache Chemistry OpenCMIS client.
102
+ test_files:
103
+ - spec/cmis_spec.rb
104
+ - spec/fixtures/document.pdf
105
+ - spec/fixtures/text_file.txt
106
+ - spec/fixtures/text_file2.txt
107
+ - spec/spec_helper.rb