Java tutorial
/* * Copyright 2011-2012 Alfresco Software Limited. * * 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. * * This file is part of an unsupported extension to Alfresco. */ package org.alfresco.jive.cmis.dao; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.alfresco.cmis.client.AlfrescoDocument; import org.alfresco.cmis.client.auth.JiveToolkitCmisAuthenticationProvider; import org.alfresco.jive.cmis.manager.RemoteContainer; import org.alfresco.jive.cmis.manager.RemoteDocument; import org.alfresco.jive.community.impl.ConnectorConstants; 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.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.OperationContextImpl; 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.enums.BindingType; import org.apache.chemistry.opencmis.commons.enums.VersioningState; import org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException; import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException; import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl; import org.apache.log4j.Logger; import org.springframework.dao.EmptyResultDataAccessException; import com.jivesoftware.base.AuthToken; import com.jivesoftware.base.User; import com.jivesoftware.base.UserManager; import com.jivesoftware.base.UserNotFoundException; import com.jivesoftware.base.aaa.JiveAuthentication; import com.jivesoftware.base.database.dao.DAOException; import com.jivesoftware.base.database.dao.JiveJdbcDaoSupport; import com.jivesoftware.cache.Cache; import com.jivesoftware.community.JiveGlobals; import com.jivesoftware.community.aaa.SystemUser; import com.jivesoftware.community.lifecycle.JiveApplication; /** * TODO: Alfresco calls taking 1.5 seconds on average. Doing a count on the data * also takes 1.5 seconds, so calls are taking like 3 seconds. We can pull a * count in the same query perhaps to decrease amount of calls being made, * increasing performance. * * @author corey.ferguson */ public class AlfrescoNavigationDAOImpl extends JiveJdbcDaoSupport implements AlfrescoNavigationDAO { Logger log = Logger.getLogger(AlfrescoNavigationDAOImpl.class); private final SessionFactory sessionFactory; private UserManager userManager; protected Cache<Long, Session> userSessionCache; public static final int PAGINATE_MAX_ITEMS = 10; private OperationContext paginateContext; private static final String QUERY_SUBFOLDERS = "select f.cmis:name as name, " + "f.cmis:objectId as id " + "from cmis:folder as f " + "where in_folder('?')"; private static final String QUERY_SEARCH_FOLDERS = "select f.cmis:name as name, " + "f.cmis:objectId as id " + "from cmis:folder as f " + "where name like '%?%'"; private static final String QUERY_SEARCH_FILES = "select d.cmis:objectId as id, " + "d.cmis:name as name " + "from cmis:document d " + "where name like '%?%' "; /* private static final String QUERY_JIVE_ID = "select dv.internaldocid from jivedocumentprop dp, jivedocversion dv" + " where dp.name = 'cmisObject' and dp.propvalue = ? and" + " dp.internaldocid=dv.internaldocid and dp.versionid=dv.versionid and dv.state='published'"; */ public AlfrescoNavigationDAOImpl() { sessionFactory = SessionFactoryImpl.newInstance(); } @Override public Session getSession() { Session session = null; long userID = getAuthentication().getUserID(); session = userSessionCache.get(userID); User user = null; try { user = userManager.getUser(userID); } catch (UserNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (session == null) { session = createUserSession(user); userSessionCache.put(userID, session); } return session; } protected Session createUserSession(User user) throws CmisConnectionException { long startTime = System.currentTimeMillis(); HashMap<String, String> parameters = new HashMap<String, String>(); String sessionUser = JiveGlobals.getJiveProperty(ConnectorConstants.ALFRESCO_USER); String sessionPassword = JiveGlobals.getJiveProperty(ConnectorConstants.ALFRESCO_PASSWORD); // User credentials. if (sessionUser == null || sessionPassword == null) { throw new CmisConnectionException("Connection failed. " + ConnectorConstants.ALFRESCO_USER + " or " + ConnectorConstants.ALFRESCO_PASSWORD + " are not set."); } parameters.put(SessionParameter.USER, sessionUser); parameters.put(SessionParameter.PASSWORD, sessionPassword); // Connection settings. "http://localhost:8080/alfresco/service/cmis" String cmsBaseURL = JiveGlobals.getJiveProperty(ConnectorConstants.ALFRESCO_URL); if (cmsBaseURL == null) { throw new CmisConnectionException( "Connection failed. " + ConnectorConstants.ALFRESCO_URL + " is not set."); } parameters.put(SessionParameter.ATOMPUB_URL, cmsBaseURL + ConnectorConstants.ALFRESCO_ENDPOINT); // URL // parameters.put(SessionParameter.ATOMPUB_URL, // "http://localhost:8090/alfresco/service/cmis"); // parameter.put(SessionParameter.REPOSITORY_ID, "myRepository"); // // Only necessary if there is more than one repository. parameters.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value()); // set the custom AuthenticationProvider - see http://incubator.apache.org/chemistry/opencmis-client-bindings.html parameters.put(SessionParameter.AUTHENTICATION_PROVIDER_CLASS, "org.alfresco.cmis.client.auth.JiveToolkitCmisAuthenticationProvider"); // set the masquerade user id (same as whatever we login with HTTP Basic Auth above - this is adequate for unit testing) parameters.put(JiveToolkitCmisAuthenticationProvider.SESSION_KEY_USER_ID, getMasqueradedUser(user)); String sharedPassword = JiveGlobals.getJiveProperty(ConnectorConstants.USERNAME_ENCRYPTION_PASSWORD); if (sharedPassword == null) { throw new CmisConnectionException( "Connection failed. " + ConnectorConstants.USERNAME_ENCRYPTION_PASSWORD + " is not set."); } // set the encryption password for the masqueraded user id parameters.put(JiveToolkitCmisAuthenticationProvider.SESSION_KEY_SHARED_PASSWORD, sharedPassword); // set the object factory to the Alfresco extension - see http://code.google.com/a/apache-extras.org/p/alfresco-opencmis-extension/ parameters.put(SessionParameter.OBJECT_FACTORY_CLASS, "org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl"); // Session locale. parameters.put(SessionParameter.LOCALE_ISO3166_COUNTRY, ""); parameters.put(SessionParameter.LOCALE_ISO639_LANGUAGE, "en"); parameters.put(SessionParameter.LOCALE_VARIANT, "US"); // This supposes only one repository is available at the URL. Session session; try { Repository soleRepository = sessionFactory.getRepositories(parameters).get(0); log.info("Opening session to Alfresco repository for .... " + soleRepository.getName()); session = soleRepository.createSession(); log.info("Session opened .... "); } catch (Exception e) { // TODO Auto-generated catch block log.error("Session opened .... " + e.getLocalizedMessage()); throw new CmisConnectionException("Connection failed", e); } // Default Pagination paginateContext = new OperationContextImpl(); paginateContext.setMaxItemsPerPage(PAGINATE_MAX_ITEMS); paginateContext.setOrderBy("cmis:baseTypeId ASC"); long endTime = System.currentTimeMillis(); long processingTime = endTime - startTime; log.info("Creating connection to Alfresco repository took " + processingTime + " milliseconds."); return session; } private String getMasqueradedUser(User user) { if (SystemUser.SYSTEM_USER_ID == user.getID()) { return JiveGlobals.getJiveProperty(ConnectorConstants.ALFRESCO_USER, "admin"); } return user.getUsername(); } /** * {@inheritDoc} */ @Override public List<Object> getDirectories(RemoteContainer remoteContainer, Long firstRecord) { List<Object> returnResults = new ArrayList<Object>(); Session session = getSession(); long startTime = System.currentTimeMillis(); if (firstRecord == null) { firstRecord = 0L; } // Get parent folder Folder parentFolder; if (remoteContainer == null || remoteContainer.getId() == null) { parentFolder = session.getRootFolder(); } else { parentFolder = (Folder) session.getObject(remoteContainer); } log.info("Getting list of directories for parent folder " + parentFolder.getName()); String query = QUERY_SUBFOLDERS.replaceFirst("\\?", parentFolder.getId()); ItemIterable<QueryResult> results = session.query(query.toString(), false, paginateContext); ItemIterable<QueryResult> paginatedResults = results.skipTo(firstRecord).getPage(); List<RemoteContainer> remoteContainers = new ArrayList<RemoteContainer>(); for (QueryResult result : paginatedResults) { RemoteContainer folder = new RemoteContainer((String) result.getPropertyValueById("cmis:objectId"), (String) result.getPropertyValueById("cmis:name")); remoteContainers.add(folder); } long endTime = System.currentTimeMillis(); long processingTime = endTime - startTime; log.info("Getting list of directories took " + processingTime + " milliseconds."); returnResults.add(results.getTotalNumItems()); returnResults.add(remoteContainers); return returnResults; } /** * {@inheritDoc} */ @Override public List<Object> searchDirectories(String searchString, Long firstRecord) { List<Object> returnedResults = new ArrayList<Object>(); Session session = getSession(); long startTime = System.currentTimeMillis(); log.info("Searching for directories for the given searchString: " + searchString); if (firstRecord == null) { firstRecord = 0L; } String query = QUERY_SEARCH_FOLDERS.replaceFirst("\\?", searchString); ItemIterable<QueryResult> results = session.query(query, false, paginateContext); ItemIterable<QueryResult> paginatedResults = results.skipTo(firstRecord).getPage(); List<RemoteContainer> remoteContainers = new ArrayList<RemoteContainer>(); for (QueryResult result : paginatedResults) { RemoteContainer folder = new RemoteContainer((String) result.getPropertyValueById("cmis:objectId"), (String) result.getPropertyValueById("cmis:name")); remoteContainers.add(folder); log.info("Found folder: " + folder); } long endTime = System.currentTimeMillis(); long processingTime = endTime - startTime; log.info("Searching for directories took " + processingTime + " milliseconds."); returnedResults.add(results.getTotalNumItems()); returnedResults.add(remoteContainers); return returnedResults; } /** * {@inheritDoc} */ @Override public List<Object> getFiles(RemoteContainer remoteContainer, Long firstRecord) { List<Object> returnedResults = new ArrayList<Object>(); Session session = getSession(); long startTime = System.currentTimeMillis(); if (firstRecord == null) { firstRecord = 0L; } // Get parent folder Folder parentFolder; if (remoteContainer == null || remoteContainer.getId() == null) { parentFolder = session.getRootFolder(); } else { parentFolder = (Folder) session.getObject(remoteContainer); } ItemIterable<CmisObject> results = parentFolder.getChildren(paginateContext); ItemIterable<CmisObject> paginatedResults = results.skipTo(firstRecord).getPage(); List<RemoteContainer> remoteContainers = new ArrayList<RemoteContainer>(); for (CmisObject child : paginatedResults) { RemoteContainer container = new RemoteContainer(child.getId(), child.getName()); if ("cmis:folder".equals(child.getPropertyValue("cmis:baseTypeId"))) { container.setFile(false); remoteContainers.add(container); } else if ("cmis:document".equals(child.getPropertyValue("cmis:baseTypeId"))) { container.setFile(true); remoteContainers.add(container); } } long endTime = System.currentTimeMillis(); long processingTime = endTime - startTime; log.info("Getting list of directories took " + processingTime + " milliseconds."); returnedResults.add(results.getTotalNumItems()); returnedResults.add(remoteContainers); return returnedResults; } /** * {@inheritDoc} */ @Override public List<Object> searchFiles(String searchString, Long firstRecord) { List<Object> returnedResults = new ArrayList<Object>(); Session session = getSession(); long startTime = System.currentTimeMillis(); log.info("Searching for files for the given searchString: " + searchString); if (firstRecord == null) { firstRecord = 0L; } String query = QUERY_SEARCH_FILES.replaceFirst("\\?", searchString); ItemIterable<QueryResult> results = session.query(query, false, paginateContext); ItemIterable<QueryResult> paginatedResults = results.skipTo(firstRecord).getPage(); List<RemoteContainer> remoteContainers = new ArrayList<RemoteContainer>(); for (QueryResult result : paginatedResults) { RemoteContainer file = new RemoteContainer((String) result.getPropertyValueById("cmis:objectId"), (String) result.getPropertyValueById("cmis:name")); file.setFile(true); remoteContainers.add(file); } long endTime = System.currentTimeMillis(); long processingTime = endTime - startTime; log.info("Searching for directories took " + processingTime + " milliseconds."); returnedResults.add(results.getTotalNumItems()); returnedResults.add(remoteContainers); return returnedResults; } /** * {@inheritDoc} */ @Override public Document createDocument(RemoteContainer container, String fileName, String contentType, long size, InputStream data) throws CmisConstraintException { Document document = null; Session session = getSession(); try { Folder folder = (Folder) session.getObject(container); // Properties Map<String, Object> properties = new HashMap<String, Object>(); properties.put(PropertyIds.OBJECT_TYPE_ID, ObjectType.DOCUMENT_BASETYPE_ID + ",P:jive:socialized"); //properties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document"); properties.put(PropertyIds.NAME, fileName); // Content ContentStream cs = new ContentStreamImpl(fileName, BigInteger.valueOf(size), contentType, data); document = folder.createDocument(properties, cs, VersioningState.MAJOR); } finally { try { data.close(); } catch (IOException ex) { // Do nothing } } return document; } /** * {@inheritDoc} */ @Override public Document updateDocument(RemoteDocument doc, String fileName, String contentType, long size, InputStream data) throws CmisConstraintException { Document document = null; Session session = getSession(); try { document = (Document) session.getObject(doc); // Properties Map<String, Object> properties = new HashMap<String, Object>(); AlfrescoDocument alfDoc = (AlfrescoDocument) document; if (!alfDoc.hasAspect("P:jive:socialized")) { alfDoc.addAspect("P:jive:socialized"); } properties.put(PropertyIds.NAME, fileName); document.updateProperties(properties); // Content ContentStream cs = new ContentStreamImpl(fileName, BigInteger.valueOf(size), contentType, data); document.setContentStream(cs, true); } finally { try { data.close(); } catch (IOException ex) { // Do nothing } } return document; } /** * {@inheritDoc} */ @Override public Document updateDocument(RemoteDocument doc, String fileName) throws CmisConstraintException { Document document = null; Session session = getSession(); try { document = (Document) session.getObject(doc); // Properties Map<String, Object> properties = new HashMap<String, Object>(); AlfrescoDocument alfDoc = (AlfrescoDocument) document; if (!alfDoc.hasAspect("P:jive:socialized")) { alfDoc.addAspect("P:jive:socialized"); } properties.put(PropertyIds.NAME, fileName); document.updateProperties(properties); } finally { // Do nothing } return document; } /** * {@inheritDoc} */ @Override public Document deleteDocument(RemoteDocument doc) throws CmisConstraintException { Document document = null; Session session = getSession(); try { document = (Document) session.getObject(doc); AlfrescoDocument alfDoc = (AlfrescoDocument) document; if (alfDoc.hasAspect("P:jive:socialized")) { log.info("P:jive:socialized aspect found \n Removing ..."); alfDoc.removeAspect("P:jive:socialized"); } else { log.info("No P:jive:socialized aspect found"); } } finally { // Do nothing } return document; } /** * {@inheritDoc} */ @Override public InputStream getDocumentContent(String docId) throws CmisConnectionException, CmisConstraintException { Session session = getSession(); CmisObject object = session.getObject(session.createObjectId(docId)); Document document = (Document) object; InputStream stream = document.getContentStream().getStream(); return stream; } @Override public RemoteDocument getDocumentMetadata(String docId) throws CmisConnectionException, CmisConstraintException { RemoteDocument remoteDocument = null; Session session = getSession(); CmisObject object = session.getObject(session.createObjectId(docId)); Document document = (Document) object; String filename = document.getContentStreamFileName(); String mimeType = document.getContentStreamMimeType(); long size = document.getContentStreamLength(); remoteDocument = new RemoteDocument(docId, filename, filename, mimeType, intValue(size)); return remoteDocument; } private int intValue(long l) { if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) { throw new IllegalArgumentException(" Cannot cast long " + l + "to int."); } return (int) l; } /** * {@inheritDoc} */ @Override public RemoteContainer getRemoteObject(String remoteObjectId) { Session session = getSession(); CmisObject cmisObject = session.getObject(remoteObjectId); RemoteContainer remoteObject = new RemoteContainer(cmisObject.getId(), cmisObject.getName()); if ("cmis:folder".equals(cmisObject.getPropertyValue("cmis:baseTypeId"))) { remoteObject.setFile(false); } else if ("cmis:document".equals(cmisObject.getPropertyValue("cmis:baseTypeId"))) { remoteObject.setFile(true); } // TODO Auto-generated method stub return remoteObject; } public static AuthToken getAuthToken() { return JiveApplication.getEffectiveContext().getAuthenticationProvider().getAuthToken(); } public static JiveAuthentication getAuthentication() { return JiveApplication.getEffectiveContext().getAuthenticationProvider().getAuthentication(); } /** * @param usersRepCache the usersRepCache to set */ public void setUserSessionCache(Cache<Long, Session> userSessionCache) { this.userSessionCache = userSessionCache; } public void setUserManager(UserManager userManager) { this.userManager = userManager; } }