/* (non-Javadoc) * @see org.alfresco.service.cmr.view.Exporter#content(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.InputStream) */ public void content( NodeRef nodeRef, QName property, InputStream content, ContentData contentData, int index) { try { byte[] data = new byte[1048576]; // 1MB int read = content.read(data); ArrayList<Byte> total = new ArrayList<Byte>(); while (read > -1) { for (int i = 0; i < read; i++) { total.add(data[i]); } read = content.read(data); } byte[] toEncode = new byte[total.size()]; for (int i = 0; i < toEncode.length; i++) { toEncode[i] = total.get(i).byteValue(); } String temp = Base64.encodeBytes(toEncode); String ptemp = contentData.getMimetype() + "|" + contentData.getSize() + "|" + contentData.getEncoding() + "|"; contentHandler.characters(ptemp.toCharArray(), 0, ptemp.length()); contentHandler.characters(temp.toCharArray(), 0, temp.length()); } catch (Exception e) { throw new ExporterException("Failed to process export of base64 content: " + e.getMessage()); } }
public void testImmediateRemoval() throws Exception { eagerCleaner.setEagerOrphanCleanup(false); final StoreRef storeRef = nodeService.createStore("test", getName() + "-" + GUID.generate()); RetryingTransactionCallback<ContentData> testCallback = new RetryingTransactionCallback<ContentData>() { public ContentData execute() throws Throwable { // Create some content NodeRef rootNodeRef = nodeService.getRootNode(storeRef); Map<QName, Serializable> properties = new HashMap<QName, Serializable>(13); properties.put(ContentModel.PROP_NAME, (Serializable) "test.txt"); NodeRef contentNodeRef = nodeService .createNode( rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTENT, properties) .getChildRef(); ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.putContent("INITIAL CONTENT"); ContentData contentData = writer.getContentData(); // Delete the first node nodeService.deleteNode(contentNodeRef); // Done return contentData; } }; ContentData contentData = transactionService.getRetryingTransactionHelper().doInTransaction(testCallback); // Make sure that the content URL still exists ContentReader reader = contentService.getRawReader(contentData.getContentUrl()); assertNotNull(reader); assertTrue("Content should not have been eagerly deleted.", reader.exists()); // fire the cleaner cleaner.setProtectDays(0); cleaner.execute(); reader = contentService.getRawReader(contentData.getContentUrl()); // the content should have disappeared as it is not in the database assertFalse("Unprotected content was not deleted", reader.exists()); assertTrue("Content listener was not called", deletedUrls.contains(reader.getContentUrl())); }
/** * Relink the content data from a new node to an existing node to preserve the version history. * * @param tempNodeRef temp nodeRef * @param nodeToMoveRef NodeRef * @param newParentNodeRef NodeRef * @param newName new name */ public void relinkNode( NodeRef tempNodeRef, NodeRef nodeToMoveRef, NodeRef newParentNodeRef, String newName) throws FileNotFoundException, FileExistsException { // Get the properties for the old and new nodes org.alfresco.service.cmr.model.FileInfo tempFileInfo = fileFolderService.getFileInfo(tempNodeRef); org.alfresco.service.cmr.model.FileInfo fileToMoveInfo = fileFolderService.getFileInfo(nodeToMoveRef); // Save the current name of the old node String tempName = tempFileInfo.getName(); try { // Rename operation will add or remove the sys:temporary aspect appropriately // rename temp file to the new name fileFolderService.rename(tempNodeRef, newName); // rename new file to old name fileFolderService.rename(nodeToMoveRef, tempName); } catch (org.alfresco.service.cmr.model.FileNotFoundException e) { throw new FileNotFoundException(e.getMessage()); } catch (org.alfresco.service.cmr.model.FileExistsException e) { throw new FileExistsException(e.getMessage()); } if (!tempFileInfo.isFolder() && !fileToMoveInfo.isFolder()) { // swap the content between the two ContentData oldContentData = tempFileInfo.getContentData(); if (oldContentData == null) { String mimetype = mimetypeService.guessMimetype(tempName); oldContentData = ContentData.setMimetype(null, mimetype); } ContentData newContentData = fileToMoveInfo.getContentData(); // Reset the mime type // TODO Pass the content along when guessing the mime type, so we're more accurate String mimetype = mimetypeService.guessMimetype(newName); newContentData = ContentData.setMimetype(newContentData, mimetype); nodeService.setProperty(tempNodeRef, ContentModel.PROP_CONTENT, newContentData); nodeService.setProperty(nodeToMoveRef, ContentModel.PROP_CONTENT, oldContentData); } }
/** * Helper method to extract file info from a specific node. * * <p>This method goes direct to the repo for all information and no data is cached here. * * @param nodeRef the node * @param readOnly, should the file be shown as "read only", regardless of its permissions? * @param lockedFilesAsOffline should a locked file be marked as offline * @return Returns the file information pertinent to the node * @throws FileNotFoundException if the path refers to a non-existent file */ private ContentFileInfo getFileInformationImpl( NodeRef nodeRef, boolean readOnly, boolean lockedFilesAsOffline) throws FileNotFoundException { // get the file info org.alfresco.service.cmr.model.FileInfo fileFolderInfo = fileFolderService.getFileInfo(nodeRef); // retrieve required properties and create new JLAN file info ContentFileInfo fileInfo = new ContentFileInfo(nodeRef); // Set the file id from the node's DBID long id = DefaultTypeConverter.INSTANCE.convert( Long.class, nodeService.getProperty(nodeRef, ContentModel.PROP_NODE_DBID)); fileInfo.setFileId((int) (id & 0xFFFFFFFFL)); // unset all attribute flags int fileAttributes = 0; fileInfo.setFileAttributes(fileAttributes); if (fileFolderInfo.isFolder()) { // add directory attribute fileAttributes |= FileAttribute.Directory; fileInfo.setFileAttributes(fileAttributes); fileInfo.setFileType(FileType.Directory); } else { Map<QName, Serializable> nodeProperties = fileFolderInfo.getProperties(); // Get the file size from the content ContentData contentData = (ContentData) nodeProperties.get(ContentModel.PROP_CONTENT); long size = 0L; if (contentData != null) { size = contentData.getSize(); } fileInfo.setSize(size); // Set the allocation size by rounding up the size to a 512 byte block boundary if (size > 0) { fileInfo.setAllocationSize((size + 512L) & 0xFFFFFFFFFFFFFE00L); } // Check whether the file is locked if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_LOCKABLE)) { LockType lockType = lockService.getLockType(nodeRef); int attr = fileInfo.getFileAttributes(); if (lockType != null) { switch (lockType) { case NODE_LOCK: if ((attr & FileAttribute.ReadOnly) == 0) attr += FileAttribute.ReadOnly; break; case WRITE_LOCK: LockStatus lockStatus = lockService.getLockStatus(nodeRef); if (lockStatus == LockStatus.LOCK_OWNER) { } else { if ((attr & FileAttribute.ReadOnly) == 0) { attr += FileAttribute.ReadOnly; } if (lockedFilesAsOffline) { attr += FileAttribute.NTOffline; } } break; case READ_ONLY_LOCK: if ((attr & FileAttribute.ReadOnly) == 0) { attr += FileAttribute.ReadOnly; } if (lockedFilesAsOffline) { attr += FileAttribute.NTOffline; } break; } fileInfo.setFileAttributes(attr); } } // Check if it is a link node if (fileFolderInfo.isLink()) { fileInfo.setLinkNodeRef(fileFolderInfo.getLinkNodeRef()); } } // created Date createdDate = fileFolderInfo.getCreatedDate(); if (createdDate != null) { long created = DefaultTypeConverter.INSTANCE.longValue(createdDate); fileInfo.setCreationDateTime(created); } // modified Date modifiedDate = fileFolderInfo.getModifiedDate(); if (modifiedDate != null) { long modified = DefaultTypeConverter.INSTANCE.longValue(modifiedDate); fileInfo.setModifyDateTime(modified); fileInfo.setAccessDateTime(modified); fileInfo.setChangeDateTime(modified); } // name String name = fileFolderInfo.getName(); if (name != null) { fileInfo.setFileName(name); // Check for file names that should be hidden if (hiddenAspect.getVisibility(Client.cifs, fileInfo.getNodeRef()) == Visibility.HiddenAttribute) { // Add the hidden file attribute int attr = fileInfo.getFileAttributes(); if ((attr & FileAttribute.Hidden) == 0) { attr += FileAttribute.Hidden; fileInfo.setFileAttributes(attr); } } } // Read/write access if (!fileFolderInfo.isFolder() || isReadOnlyFlagOnFolders) { boolean deniedPermission = permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED; if (readOnly || deniedPermission) { int attr = fileInfo.getFileAttributes(); if ((attr & FileAttribute.ReadOnly) == 0) { attr += FileAttribute.ReadOnly; fileInfo.setFileAttributes(attr); } } } // Set the normal file attribute if no other attributes are set if (fileInfo.getFileAttributes() == 0) fileInfo.setFileAttributes(FileAttribute.NTNormal); // Debug if (logger.isDebugEnabled()) { logger.debug("Fetched file info: \n" + " info: " + fileInfo); } // Return the file information return fileInfo; }
/** * @see * org.alfresco.repo.version.operations.VersionOperationsService#checkin(org.alfresco.repo.ref.NodeRef, * Map<String,Serializable>, java.lang.String, boolean) */ public NodeRef checkin( NodeRef workingCopyNodeRef, Map<String, Serializable> versionProperties, String contentUrl, boolean keepCheckedOut) { NodeRef nodeRef = null; // Check that we have been handed a working copy if (this.nodeService.hasAspect(workingCopyNodeRef, ContentModel.ASPECT_WORKING_COPY) == false) { // Error since we have not been passed a working copy throw new AspectMissingException(ContentModel.ASPECT_WORKING_COPY, workingCopyNodeRef); } // Check that the working node still has the copy aspect applied if (this.nodeService.hasAspect(workingCopyNodeRef, ContentModel.ASPECT_COPIEDFROM) == true) { // Invoke policy invokeBeforeCheckIn(workingCopyNodeRef, versionProperties, contentUrl, keepCheckedOut); Map<QName, Serializable> workingCopyProperties = nodeService.getProperties(workingCopyNodeRef); // Try and get the original node reference nodeRef = (NodeRef) workingCopyProperties.get(ContentModel.PROP_COPY_REFERENCE); if (nodeRef == null) { // Error since the original node can not be found throw new CheckOutCheckInServiceException(MSG_ERR_BAD_COPY); } try { // Release the lock this.lockService.unlock(nodeRef); } catch (UnableToReleaseLockException exception) { throw new CheckOutCheckInServiceException(MSG_ERR_NOT_OWNER, exception); } if (contentUrl != null) { ContentData contentData = (ContentData) workingCopyProperties.get(ContentModel.PROP_CONTENT); if (contentData == null) { throw new AlfrescoRuntimeException( MSG_ERR_WORKINGCOPY_HAS_NO_MIMETYPE, new Object[] {workingCopyNodeRef}); } else { contentData = new ContentData( contentUrl, contentData.getMimetype(), contentData.getSize(), contentData.getEncoding()); } // Set the content url value onto the working copy this.nodeService.setProperty(workingCopyNodeRef, ContentModel.PROP_CONTENT, contentData); } // Copy the contents of the working copy onto the original this.copyService.copy(workingCopyNodeRef, nodeRef); // Handle name change on working copy (only for folders/files) if (fileFolderService.getFileInfo(workingCopyNodeRef) != null) { String origName = (String) this.nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); String name = (String) this.nodeService.getProperty(workingCopyNodeRef, ContentModel.PROP_NAME); if (hasWorkingCopyNameChanged(name, origName)) { // ensure working copy has working copy label in its name to avoid name clash if (!name.contains(" " + getWorkingCopyLabel())) { try { fileFolderService.rename(workingCopyNodeRef, createWorkingCopyName(name)); } catch (FileExistsException e) { throw new CheckOutCheckInServiceException( e, MSG_ERR_CANNOT_RENAME, name, createWorkingCopyName(name)); } catch (FileNotFoundException e) { throw new CheckOutCheckInServiceException( e, MSG_ERR_CANNOT_RENAME, name, createWorkingCopyName(name)); } } try { // rename original to changed working name fileFolderService.rename(nodeRef, getNameFromWorkingCopyName(name)); } catch (FileExistsException e) { throw new CheckOutCheckInServiceException( e, MSG_ERR_CANNOT_RENAME, origName, getNameFromWorkingCopyName(name)); } catch (FileNotFoundException e) { throw new CheckOutCheckInServiceException( e, MSG_ERR_CANNOT_RENAME, name, getNameFromWorkingCopyName(name)); } } } if (versionProperties != null && this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true) { // Create the new version this.versionService.createVersion(nodeRef, versionProperties); } if (keepCheckedOut == false) { // Delete the working copy this.nodeService.deleteNode(workingCopyNodeRef); } else { // Re-lock the original node this.lockService.lock(nodeRef, LockType.READ_ONLY_LOCK); } // Invoke policy invokeOnCheckIn(nodeRef); } else { // Error since the copy aspect is missing throw new AspectMissingException(ContentModel.ASPECT_COPIEDFROM, workingCopyNodeRef); } return nodeRef; }
/** * Create ContentData set it on a Node, delete the Node, then set the ContentData on a new node * and check that the content is preserved during eager cleanup. */ public void testEagerCleanupDereferencing() throws Exception { eagerCleaner.setEagerOrphanCleanup(true); final StoreRef storeRef = nodeService.createStore("test", getName() + "-" + GUID.generate()); RetryingTransactionCallback<ContentData> testCallback = new RetryingTransactionCallback<ContentData>() { public ContentData execute() throws Throwable { // Create some content NodeRef rootNodeRef = nodeService.getRootNode(storeRef); Map<QName, Serializable> properties = new HashMap<QName, Serializable>(13); properties.put(ContentModel.PROP_NAME, (Serializable) "test.txt"); NodeRef contentNodeRef = nodeService .createNode( rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTENT, properties) .getChildRef(); ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.putContent("INITIAL CONTENT"); ContentData contentData = writer.getContentData(); // Delete the first node nodeService.deleteNode(contentNodeRef); ContentReader reader = contentService.getRawReader(contentData.getContentUrl()); assertNotNull(reader); assertTrue("Content was cleaned before end of transaction", reader.exists()); // Make a new copy using the same ContentData properties.put(ContentModel.PROP_NAME, (Serializable) "test2.txt"); properties.put(ContentModel.PROP_CONTENT, contentData); contentNodeRef = nodeService .createNode( rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTENT, properties) .getChildRef(); reader = contentService.getRawReader(contentData.getContentUrl()); assertNotNull(reader); assertTrue("Content was cleaned before end of transaction", reader.exists()); // Done return contentData; } }; ContentData contentData = transactionService.getRetryingTransactionHelper().doInTransaction(testCallback); // Make sure that the content URL still exists ContentReader reader = contentService.getRawReader(contentData.getContentUrl()); assertNotNull(reader); assertTrue( "Content was cleaned despite being re-referenced in the transaction", reader.exists()); }