Java tutorial
/** * Copyright 2015 Esteban Luengo Simn * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package info.estebanluengo.alfrescoAPI; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.chemistry.opencmis.client.api.CmisObject; import org.apache.chemistry.opencmis.client.api.Document; import org.apache.chemistry.opencmis.client.api.Folder; import org.apache.chemistry.opencmis.client.api.ItemIterable; import org.apache.chemistry.opencmis.client.api.ObjectId; import org.apache.chemistry.opencmis.client.api.ObjectType; import org.apache.chemistry.opencmis.client.api.OperationContext; import org.apache.chemistry.opencmis.client.api.QueryResult; import org.apache.chemistry.opencmis.client.api.Repository; import org.apache.chemistry.opencmis.client.api.Session; import org.apache.chemistry.opencmis.client.api.SessionFactory; import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl; import org.apache.chemistry.opencmis.commons.PropertyIds; import org.apache.chemistry.opencmis.commons.SessionParameter; import org.apache.chemistry.opencmis.commons.data.ContentStream; import org.apache.chemistry.opencmis.commons.data.PropertyData; import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition; import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; import org.apache.chemistry.opencmis.commons.enums.BindingType; import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships; import org.apache.chemistry.opencmis.commons.enums.UnfileObject; import org.apache.chemistry.opencmis.commons.enums.VersioningState; import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException; import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException; import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException; import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException; import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * Utility class that encapsulates access to the Alfresco server and offers a set of high level operations to * work easily with Alfresco or another Cmis server. * <br> * I've received inspiration to build this class after reading the Jeff Potts tutorial * <a href="http://ecmarchitect.com/alfresco-developer-series-tutorials/content/tutorial/tutorial.html">Working With Custom Content Types in Alfresco</a> * * @author Esteban Luengo Simn * @version 1.0 11/May/2015 */ public class AlfrescoAPI { //https://logging.apache.org/log4j/2.0/manual/api.html private static final Logger logger = LogManager.getLogger(); public static String CUSTOM_ASSOCIATION = "R:cmiscustom:assoc"; //is a creatable sub-type of cmis:relationship public static String CUSTOM_DOCUMENT_TYPE = "D:cmiscustom:document"; //a subtype of cmis:document /** * Creates a new Session to allow access to the server. This method uses ATOMPUB binding type. * * @param user a String that contains the username * @param password a String that contains the password * @param url an URL to the server. The URL has to be atompub style: * <br>Example: <a href="http://host:port/alfresco/api/-default-/public/cmis/versions/1.1/atom">AtomPub url style</a> * * @return a Session object that allow access to the Alfresco Server or null if no session has been created */ public static Session createSession(String user, String password, String url) { // default factory implementation logger.debug("createSession called"); SessionFactory factory = SessionFactoryImpl.newInstance(); Map<String, String> parameter = new HashMap<>(); // user credentials parameter.put(SessionParameter.USER, user); parameter.put(SessionParameter.PASSWORD, password); // Specify the connection settings parameter.put(SessionParameter.ATOMPUB_URL, url); parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value()); //Another way. This way works with http://host:port/alfresco/cmis/ URL style // parameter.put(SessionParameter.BINDING_TYPE, BindingType.WEBSERVICES.value()); // String BASE_URL = url; // parameter.put(SessionParameter.WEBSERVICES_ACL_SERVICE, BASE_URL + "ACLService?wsdl"); // parameter.put(SessionParameter.WEBSERVICES_DISCOVERY_SERVICE, BASE_URL + "DiscoveryService?wsdl"); // parameter.put(SessionParameter.WEBSERVICES_MULTIFILING_SERVICE, BASE_URL + "MultiFilingService?wsdl"); // parameter.put(SessionParameter.WEBSERVICES_NAVIGATION_SERVICE, BASE_URL + "NavigationService?wsdl"); // parameter.put(SessionParameter.WEBSERVICES_OBJECT_SERVICE, BASE_URL + "ObjectService?wsdl"); // parameter.put(SessionParameter.WEBSERVICES_POLICY_SERVICE, BASE_URL + "PolicyService?wsdl"); // parameter.put(SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE, BASE_URL + "RelationshipService?wsdl"); // parameter.put(SessionParameter.WEBSERVICES_REPOSITORY_SERVICE, BASE_URL + "RepositoryService?wsdl"); // parameter.put(SessionParameter.WEBSERVICES_VERSIONING_SERVICE, BASE_URL + "VersioningService?wsdl"); // // set the alfresco object factory. Not for Alfresco 4.2, only for Alfresco 5.x // parameter.put(SessionParameter.OBJECT_FACTORY_CLASS, "org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl"); List<Repository> repositories = factory.getRepositories(parameter); logger.debug("getting repositories"); // create session Session session = repositories.get(0).createSession(); logger.debug("returning a session object"); return session; } /** * Retrieves the folder with the given name and exists under the parentFolder. * Returns null if the folder does not exist. * * @param session a Session object that is connected with the server * @param parentFolder a Folder object that represents parent folder where the folder to * retrieve exists * @param folderName a String that contains the folder name * * @return a Folder object that represent the folder in the Alfresco repository */ public static Folder getFolderByName(Session session, Folder parentFolder, String folderName) { logger.debug("getFolder called for folderName:" + folderName); ObjectType type = session.getTypeDefinition(BaseTypeId.CMIS_FOLDER.value()); PropertyDefinition<?> objectIdPropDef = type.getPropertyDefinitions().get(PropertyIds.OBJECT_ID); String objectIdQueryName = objectIdPropDef.getQueryName(); String query = "SELECT * FROM cmis:folder WHERE cmis:name='" + folderName + "' and IN_FOLDER('workspace://SpacesStore/" + parentFolder.getId() + "')"; ItemIterable<QueryResult> results = session.query(query, false); logger.debug("query executed:" + query); for (QueryResult qResult : results) { String objectId = qResult.getPropertyValueByQueryName(objectIdQueryName); logger.debug("ObjectId recovered from query:" + objectId); return (Folder) session.getObject(session.createObjectId(objectId)); } logger.debug("No results recover for query"); return null; } /** * Retrieves the folder with the given name. Returns null if the folder does * not exist. If there are more than one folder with the same name, the method * returns the first folder in the list * * @param session a Session object that is connected with the server * @param folderName a String that contains the folder name * * @return a Folder object that represent the folder in the Alfresco repository */ public static Folder getFolderByName(Session session, String folderName) { logger.debug("getFolder called for folderName:" + folderName); ObjectType type = session.getTypeDefinition(BaseTypeId.CMIS_FOLDER.value()); PropertyDefinition<?> objectIdPropDef = type.getPropertyDefinitions().get(PropertyIds.OBJECT_ID); String objectIdQueryName = objectIdPropDef.getQueryName(); String query = "SELECT * FROM cmis:folder WHERE cmis:name='" + folderName + "'"; ItemIterable<QueryResult> results = session.query(query, false); logger.debug("query executed:" + query); for (QueryResult qResult : results) { String objectId = qResult.getPropertyValueByQueryName(objectIdQueryName); logger.debug("ObjectId recovered from query:" + objectId); return (Folder) session.getObject(session.createObjectId(objectId)); } logger.debug("No results recover from query"); return null; } /** * Creates a new folder under the parentFolder. * * @param session a Session object that is connected with the server * @param parentFolder a Folder object where the new folder will be created * @param folderName a String that contains the name for the new folder * * @return a Folder object that represent the new folder created * @throws CmisContentAlreadyExistsException will be thrown if the folder to be created exists in the same parentFolder. */ public static Folder createFolder(Session session, Folder parentFolder, String folderName) throws CmisContentAlreadyExistsException { logger.debug("createFolder called"); Map<String, Object> folderProps = new HashMap<>(); folderProps.put(PropertyIds.NAME, folderName); folderProps.put(PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_FOLDER.value()); ObjectId folderObjectId = session.createFolder(folderProps, parentFolder, null, null, null); logger.debug("Folder created with id:" + folderObjectId); return (Folder) session.getObject(folderObjectId); } /** * Creates the folders under the parentFolder. The method creates the folders that don't exist in the * tree. Maybe if all folders exist under the parentFolder, no folder is created. * * @param session a Session object that is connected with the server * @param parentFolder a Folder object where the new folder will be created * @param foldersPath a String that contains the folders path to be created. For example: folder1/folder2 * * @return a Folder object that represent the last folder under the tree */ public static Folder createFolders(Session session, Folder parentFolder, String foldersPath) { logger.debug("createFolders called"); Folder folder = parentFolder; String[] folderList = foldersPath.split("/"); for (String f : folderList) { logger.debug(folder.getPath() + "/" + f); try { CmisObject objFolder = session.getObjectByPath(folder.getPath() + "/" + f); folder = (Folder) objFolder; } catch (CmisObjectNotFoundException e) { folder = createFolder(session, folder, f); } } return folder; } /** * Gets the folders that exits in the folder * * @param session a Session object that is connected with the server * @param parentFolder a Folder object where we want the children folders * @param cache a boolean. True indicates that cache is used and false indicates that the * folders are retrieved from the server * @return a List<org.apache.chemistry.opencmis.client.api.Folder> that contain the folder list */ public static List<Folder> getFolders(Session session, Folder parentFolder, boolean cache) { OperationContext oc = session.createOperationContext(); oc.setCacheEnabled(cache); ItemIterable<CmisObject> children = parentFolder.getChildren(oc); List<Folder> folderList = new ArrayList<>(); for (CmisObject obj : children) { if (obj instanceof Folder) { folderList.add((Folder) obj); } } return folderList; } /** * Creates a new Document in the folder with the name, content, and mimeType. * * @param session a Session object that is connected with the server * @param folder a Folder object where the new document will be created * @param fileName a String that contain the file name * @param content a byte array that contain the document * @param mimeType a String that represent the mime type of the document * * @return a Document object that represent the document that has just been created * @throws CmisContentAlreadyExistsException if the document to be created exists in the same folder */ public static Document createDocument(Session session, Folder folder, String fileName, byte[] content, String mimeType) throws CmisContentAlreadyExistsException { logger.debug("createDocument called for document name:" + fileName); Map<String, Object> docProps = new HashMap<>(); docProps.put(PropertyIds.NAME, fileName); docProps.put(PropertyIds.OBJECT_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value()); docProps.put(PropertyIds.CREATION_DATE, new Date()); ByteArrayInputStream in = new ByteArrayInputStream(content); ContentStream contentStream = new ContentStreamImpl(fileName, BigInteger.valueOf(content.length), mimeType, in); ObjectId documentId = session.createDocument(docProps, session.createObjectId((String) folder.getPropertyValue(PropertyIds.OBJECT_ID)), contentStream, null, null, null, null); logger.debug("Document created with id:" + documentId.getId()); Document document = (Document) session.getObject(documentId); return document; } /** * Creates a new Document in the folder with the name, content, and mimeType, docType and properties given in the method call * * @param session a Session object that is connected with the server * @param folder a Folder object where the new document will be created * @param fileName a String that contain the file name * @param content a byte array that contain the document * @param mimeType a String that represent the mime type of the document * @param docType a String that represent the document type. If it is null then CUSTOM_DOCUMENT_TYPE will be used * @param docProps a Map with the properties to are associated to the document. It may be null * * @return a Document object that represent the document that has just been created * @throws CmisContentAlreadyExistsException if the document to be created exists in the same folder */ public static Document createDocument(Session session, Folder folder, String fileName, byte[] content, String mimeType, String docType, Map<String, Object> docProps) throws CmisContentAlreadyExistsException { logger.debug("createDocument called for document name:" + fileName); if (docProps == null) { docProps = new HashMap<>(); } docProps.put(PropertyIds.NAME, fileName); docProps.put(PropertyIds.OBJECT_TYPE_ID, docType == null ? CUSTOM_DOCUMENT_TYPE : docType); ByteArrayInputStream in = new ByteArrayInputStream(content); ContentStream contentStream = new ContentStreamImpl(fileName, BigInteger.valueOf(content.length), mimeType, in); ObjectId documentId = session.createDocument(docProps, session.createObjectId((String) folder.getPropertyValue(PropertyIds.OBJECT_ID)), contentStream, VersioningState.MAJOR); logger.debug("Document created with id:" + documentId.getId()); Document document = (Document) session.getObject(documentId); return document; } /** * Relates the source document with the target document. After calling to this method you can access to * the target document from the source document but not viceversa * * @param session a Session object that is connected with the server * @param sourceDoc a Document that represent the source document. It can not be null * @param targetDoc a Document that represent the target document. It can not be null * @param associationName a String that represent the association name. If it is null then the method uses R:cmiscustom:assoc */ public static void relatedDocuments(Session session, Document sourceDoc, Document targetDoc, String associationName) { logger.debug("relatedDocument called"); String sourceId = sourceDoc.getId(); String targetId = targetDoc.getId(); Map<String, String> properties = new HashMap<>(); properties.put(PropertyIds.OBJECT_TYPE_ID, associationName == null ? CUSTOM_ASSOCIATION : associationName); properties.put(PropertyIds.SOURCE_ID, sourceId); properties.put(PropertyIds.TARGET_ID, targetId); session.createRelationship(properties); logger.debug("relationShip created between the two documents"); } /** * Updates the document that exits in the server and creates a new version. The method allows to update the content of the document, * the mimetype and the properties.<br> * In some circunstances a CmisStorageException could be thrown with the message "Expected x bytes but retrieved 0 bytes!". I Think * this is an issue in Alfresco Server and it can be resolved catching the exception and calling this method another time.<br> * <a href="https://issues.alfresco.com/jira/browse/ACE-2821">Link to the issue</a> * * @param session a Session object that is connected with the server * @param doc a Document object to be updated. * @param newContent a byte[] with the content of the document. It can not be null. * @param mimeType a String that represent the mime type of the document * @param docProps a Map object with the properties of the document. It can be null * @param majorVersion a boolean. true indicates that we want a major version and false a minor version. * @param checkinComment a String with the comments that are associated to the new version * * @return a Document that contains the new version created or null if it was not possible to make a new version. * Remember that every version of the document may has its own ID depending of the server. Alfresco uses alfhanumeric plus ;version */ public static Document updateDocument(Session session, Document doc, byte[] newContent, String mimeType, Map<String, Object> docProps, boolean majorVersion, String checkinComment) { logger.debug("updateDocument called for docId:" + doc.getId() + " length:" + newContent.length); Document updatedDocument = null; if (doc.getAllowableActions().getAllowableActions() .contains(org.apache.chemistry.opencmis.commons.enums.Action.CAN_CHECK_OUT)) { doc.refresh(); //make a checkout is mandatory for some repositories. ObjectId checkedOutDocument = doc.checkOut(); Document pwc = (Document) session.getObject(checkedOutDocument); ByteArrayInputStream in = new ByteArrayInputStream(newContent); ObjectId objectId; try { ContentStream contentStream = new ContentStreamImpl(doc.getName(), BigInteger.valueOf(newContent.length), mimeType, in); objectId = pwc.checkIn(majorVersion, docProps, contentStream, checkinComment); } catch (CmisStorageException e) { logger.error("Error trying to make a checkIn", e); pwc.delete(); return null; } updatedDocument = (Document) session.getObject(objectId); } return updatedDocument; } /** * Updates the document properties of the document that exist in the server * * @param session a Session object that is connected with the server * @param doc a Document object to be updated. * @param updateProperties a Map object with the new properties of the document. It can be null * @return a Document object with the new properties. This object is retrieved from the server and not from the cache */ public static Document updateDocumentProperties(Session session, Document doc, Map<String, Object> updateProperties) { logger.debug("updateDocumentProperties called"); ObjectId docReturned = doc.updateProperties(updateProperties, true); logger.debug("Document updated with id:" + doc.getId()); Document document = (Document) session.getObject(docReturned); return document; } /** * Deletes the document from the server * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id in the server * @param allVersions a boolean. True value indicates that all versions of the document will be deleted. False * indicates that only the version of the document will be deleted */ public static void deleteDocument(Session session, String docId, boolean allVersions) { logger.debug("deleteDocument called"); String repositoryId = session.getRepositoryInfo().getId(); session.getBinding().getObjectService().deleteObject(repositoryId, docId, allVersions, null); } /** * Deletes the version of the document from the server * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id in the server * @param version a String that represent the version of the document to be deleted */ public static void deleteDocumentByVersion(Session session, String docId, String version) { logger.debug("deleteDocumentByVersion called for docId:" + docId); List<Document> versions = getAllVersionsOfDocument(session, docId); for (Document doc : versions) { if (version.equals(doc.getVersionLabel())) { doc.delete(false); } } } /** * Deletes the folder from the server and all the documents that are under the folder. * * @param session a Session object that is connected with the server * @param folderId a String that represents the forlder Id to be deleted * @throws CmisConstraintException If the folder to be deleted contains other folders */ public static void deleteFolder(Session session, String folderId) throws CmisConstraintException { logger.debug("deleteFolder called"); session.delete(session.createObjectId(folderId), true); } /** * Deletes the folder from the server and all the documents that are under the folder. * * @param session a Session object that is connected with the server * @param folder a Folder object to be deleted * @throws CmisConstraintException If the folder to be deleted contains other folders */ public static void deleteFolder(Session session, Folder folder) throws CmisConstraintException { logger.debug("deleteFolder called"); session.delete(folder, true); } /** * Deletes the folder from the server and all the documents and subfolders that are under the folder. * * @param session a Session object that is connected with the server * @param folder a Folder object to be deleted * @param allVersions a boolean. True value indicates that all versions of the folder will be deleted. * False indicates that only this version of the folder will be deleted */ public static void deleteFolder(Session session, Folder folder, boolean allVersions) { logger.debug("deleteFolder called"); /** * Note that with the continueOnFailure parameter set to true, folders and documents are deleted individually. If a document or folder * cannot be deleted, the method moves to the next document or folder in the list. When the method completes, it returns a list of the document * IDs and folder IDs that were not deleted. * With the continueOnFailure parameter set to false, all of the folders and documents can be deleted in a single batch, which, depending on * the repository design, may improve performance. If a document or folder cannot be deleted, an exception is raised. Some repository implementations * will attempt the delete transactionally, so if it fails, no objects are deleted. In other repositories a failed delete may have deleted some, * but not all, objects in the tree. */ folder.deleteTree(allVersions, UnfileObject.DELETE, true); } /** * Deletes all subfolders and document from the folder * * @param session a Session object that is connected with the server * @param folder a Folder object where we want to delete all children * @param allVersions a boolean. True value indicates that all versions of the folder will be deleted. * False indicates that only this version of the folder will be deleted */ public static void deleteChildren(Session session, Folder folder, boolean allVersions) { logger.debug("deleteChildren called"); ItemIterable<CmisObject> children = folder.getChildren(); for (CmisObject obj : children) { if (obj instanceof Folder) { AlfrescoAPI.deleteFolder(session, (Folder) obj, allVersions); } else if (obj instanceof Document) { AlfrescoAPI.deleteDocument(session, ((Document) obj).getId(), allVersions); } } } /** * Gets the document from the server without using the cache system. * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id * @return a Document object with the document * @throws CmisObjectNotFoundException will be thrown if the document does not exist in the server */ public static Document getDocument(Session session, String docId) throws CmisObjectNotFoundException { return getDocument(session, docId, false); } /** * Gets the document from the server or from the cache. * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id * @param cache a boolean. True indicates that cache is used and false indicates that the * document is retrieved from the server * @return a Document object with the document * @throws CmisObjectNotFoundException will be thrown if the document does not exist in the server */ public static Document getDocument(Session session, String docId, boolean cache) throws CmisObjectNotFoundException { logger.debug("getDocument called for id:" + docId); OperationContext oc = session.createOperationContext(); oc.setCacheEnabled(cache); CmisObject object = session.getObject(docId, oc); logger.debug("document recovered"); return (Document) object; } /** * Gets a specific version of the document or null if does not exist this version. This method * does not use the cache. * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id * @param version a String that represent the version of the document to be retrieved * @return a Document object with the document */ public static Document getDocumentByVersion(Session session, String docId, String version) { return getDocumentByVersion(session, docId, version, false); } /** * Gets a specific version of the document or null if does not exist this version * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id * @param version a String that represent the version of the document to be retrieved * @param cache a boolean. True indicates that cache is used and false indicates that the * document is retrieved from the server * @return a Document object with the document */ public static Document getDocumentByVersion(Session session, String docId, String version, boolean cache) { logger.debug("getDocumentByVersion called for id:" + docId + " and version:" + version); List<Document> versions = getAllVersionsOfDocument(session, docId, cache); for (Document doc : versions) { if (version.equals(doc.getVersionLabel())) { logger.debug("Document recovered"); return doc; } } return null; } /** * Gets the content of the document * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id * @return a byte[] that represents the content of the document * @throws java.io.IOException if the content cannot be read from the document * @throws CmisObjectNotFoundException will be thrown if the document does not exist in the server */ public static byte[] getDocumentContent(Session session, String docId) throws CmisObjectNotFoundException, IOException { logger.debug("getDocumentContent called"); Document doc = getDocument(session, docId); if (doc.getContentStreamLength() == 0) { return null; } ContentStream contentStream = doc.getContentStream(); try (InputStream inputStream = contentStream.getStream()) { byte[] content = IOUtils.toByteArray(inputStream); logger.debug("Content recovered"); return content; } catch (IOException e) { throw e; } } /** * Gets the document and all its relationships from the server or from the cache. * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id * @param cache a boolean. True indicates that cache is used and false indicates that the * document is retrieved from the server * @return a Document object with the document * @throws CmisObjectNotFoundException if the document does not exist in the server */ public static Document getDocumentWithRelationShips(Session session, String docId, boolean cache) throws CmisObjectNotFoundException { logger.debug("getDocumentWithRelationShips called for id:" + docId); OperationContext oc = session.createOperationContext(); oc.setCacheEnabled(cache); oc.setIncludeRelationships(IncludeRelationships.SOURCE); Object object = session.getObject(session.createObjectId(docId), oc); logger.debug("document recovered"); return (Document) object; } /** * Gets all versions of the document from the server without using the cache * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id * @return a List<org.apache.chemistry.opencmis.client.api.Document> with all versions of the document * @throws CmisObjectNotFoundException if the document does not exist in the server */ public static List<Document> getAllVersionsOfDocument(Session session, String docId) throws CmisObjectNotFoundException { return getAllVersionsOfDocument(session, docId, false); } /** * Gets all versions of the document from the server or from the cache * * @param session a Session object that is connected with the server * @param docId a String that represent the document Id * @param cache a boolean. True indicates that cache is used and false indicates that the * document is retrieved from the server * @return a List<org.apache.chemistry.opencmis.client.api.Document> with all versions of the document * @throws CmisObjectNotFoundException if the document does not exist in the server */ public static List<Document> getAllVersionsOfDocument(Session session, String docId, boolean cache) throws CmisObjectNotFoundException { logger.debug("getAllVersionsOfDocument called for docId:" + docId); Document document = getDocument(session, docId, cache); return document.getAllVersions(); } /** * Executes a query in the server or in the cache to retrive a list of CmisObjects * * @param session a Session object that is connected with the server * @param query a String that contains the query to be executed * @param maxNumItems a int that represent the max number of items to be retrieved. If this value is equal to 0 then there * is no limitation. * @param cache a boolean. True indicates that cache is used and false indicates that the * query is executed in the server * @return a List<org.apache.chemistry.opencmis.client.api.CmisObject> that contains the list * of CmisObject to be returned */ public static List<CmisObject> executeQuery(Session session, String query, int maxNumItems, boolean cache) { logger.debug("getQueryResults called for query:" + query); List<CmisObject> objList = new ArrayList<>(); OperationContext context = session.createOperationContext(); context.setCacheEnabled(cache); // execute query ItemIterable<QueryResult> results = session.query(query, false, context); logger.debug("items:" + results.getPageNumItems()); if (maxNumItems == 0) { results = results.getPage(); } else { results = results.getPage(maxNumItems); } logger.debug("query executed"); for (QueryResult qResult : results) { String objectId; PropertyData<?> propData = qResult.getPropertyById("cmis:objectId"); // Atom Pub binding if (propData != null) { objectId = (String) propData.getFirstValue(); } else { objectId = qResult.getPropertyValueByQueryName("d.cmis:objectId"); // Web Services binding } logger.debug("Object recovered from query with id:" + objectId); CmisObject obj = session.getObject(session.createObjectId(objectId)); objList.add(obj); } return objList; } /** * Finds a list of documents that contain the keyword. This method makes a full scan. * * @param session a Session object that is connected with the server * @param keyword a String that represent the word to use in the full scan * @param maxNumItems a int that represent the max number of items to be retrieved. If this value is equal to 0 then there * is no limitation. * @param cache a boolean. True indicates that cache is used and false indicates that the * query is executed in the server * @return a List<org.apache.chemistry.opencmis.client.api.CmisObject> that contains the list * of CmisObject to be returned */ public static List<CmisObject> findDocumentsByText(Session session, String keyword, int maxNumItems, boolean cache) { logger.debug("getQueryResults called for keyword:" + keyword); return executeQuery(session, "select * from cmis:document where contains('" + keyword + "')", maxNumItems, cache); } /** * Finds the documents that are in the folder * * @param session a Session object that is connected with the server * @param folder a Folder object where we want to get the documents * @param maxNumItems a int that represent the max number of items to be retrieved. If this value is equal to 0 then there * is no limitation. * @param cacheEnable * @return a List<org.apache.chemistry.opencmis.client.api.CmisObject> that contains the list * of CmisObject to be returned */ public static List<CmisObject> findDocumentsInFolder(Session session, Folder folder, int maxNumItems, boolean cacheEnable) { logger.debug("getQueryResults called for folderName:" + folder.getName()); return executeQuery(session, "select * from cmis:document where IN_FOLDER('workspace://SpacesStore/" + folder.getId() + "')", maxNumItems, cacheEnable); } }