/** * Actualitza el tamany de la sèrie. * * @param nodeRef * @param parentNodeRef */ private void updateSerie(NodeService nodeService, NodeRef nodeRef, NodeRef serieNodeRef) { System.out.println( DateFormat.getInstance().format(new Date()) + " START: Recalcular tamany sèrie."); int tamany = 0; List<ChildAssociationRef> children = nodeService.getChildAssocs(serieNodeRef); for (ChildAssociationRef childAssoc : children) { NodeRef childNodeRef = childAssoc.getChildRef(); if (nodeService.hasAspect(childNodeRef, expedientRM)) { Serializable tamanySerial = nodeService.getProperty(childNodeRef, tamanyExpedientRM); if (tamanySerial != null) { tamany = tamany + (Integer.parseInt((String) tamanySerial)); } } else if (nodeService.hasAspect(childNodeRef, agregacioRM)) { Serializable tamanySerial = nodeService.getProperty(childNodeRef, tamanyAgregacioRM); if (tamanySerial != null) { tamany = tamany + (Integer.parseInt((String) tamanySerial)); } } } nodeService.setProperty(serieNodeRef, tamanySerieRM, String.valueOf(tamany)); Date now = new Date(); System.out.println( DateFormat.getInstance().format(now) + " Update tamany sèrie: " + serieNodeRef); System.out.println(DateFormat.getInstance().format(now) + " END: Recalcular tamany sèrie."); }
/** * @see CheckOutCheckInService#getWorkingCopy(NodeRef) * @see CheckOutCheckInService#getCheckedOut(NodeRef) */ public void testBidirectionalReferences() { final NodeRef origNodeRef = nodeService .createNode( this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("test2"), ContentModel.TYPE_CONTENT) .getChildRef(); NodeRef wk1 = cociService.getWorkingCopy(origNodeRef); assertNull(wk1); // Check the document out final NodeRef workingCopy = cociService.checkout(origNodeRef); assertTrue( "Expect cm:workingcopy aspect", nodeService.hasAspect(workingCopy, ContentModel.ASPECT_WORKING_COPY)); assertTrue( "Expect cm:checkedOut aspect", nodeService.hasAspect(origNodeRef, ContentModel.ASPECT_CHECKED_OUT)); List<AssociationRef> targetAssocs = nodeService.getTargetAssocs(origNodeRef, ContentModel.ASSOC_WORKING_COPY_LINK); assertEquals("Expect a 1:1 relationship", 1, targetAssocs.size()); List<AssociationRef> sourceAssocs = nodeService.getSourceAssocs(workingCopy, ContentModel.ASSOC_WORKING_COPY_LINK); assertEquals("Expect a 1:1 relationship", 1, sourceAssocs.size()); // Need to commit the transaction in order to get the indexer to run setComplete(); endTransaction(); final NodeRef finalNodeRef = origNodeRef; this.transactionService .getRetryingTransactionHelper() .doInTransaction( new RetryingTransactionCallback<Object>() { public Object execute() { NodeRef wk2 = cociService.getWorkingCopy(finalNodeRef); assertNotNull(wk2); assertEquals(workingCopy, wk2); NodeRef orig2 = cociService.getCheckedOut(wk2); assertNotNull(orig2); assertEquals(origNodeRef, orig2); cociService.cancelCheckout(workingCopy); return null; } }); NodeRef wk3 = cociService.getWorkingCopy(this.nodeRef); assertNull(wk3); }
/** @return */ private NodeRef checkout() { // Check out the node NodeRef workingCopy = cociService.checkout( this.nodeRef, this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("workingCopy")); assertNotNull(workingCopy); // System.out.println(NodeStoreInspector.dumpNodeStore(this.nodeService, this.storeRef)); // Ensure that the working copy and copy aspect has been applied assertTrue(nodeService.hasAspect(workingCopy, ContentModel.ASPECT_WORKING_COPY)); assertTrue(nodeService.hasAspect(workingCopy, ContentModel.ASPECT_COPIEDFROM)); // Check that the working copy owner has been set correctly assertEquals( this.userNodeRef, nodeService.getProperty(workingCopy, ContentModel.PROP_WORKING_COPY_OWNER)); // Check that the working copy name has been set correctly String name = (String) this.nodeService.getProperty(this.nodeRef, PROP_NAME_QNAME); String expectedWorkingCopyLabel = I18NUtil.getMessage("coci_service.working_copy_label"); String expectedWorkingCopyName = ((CheckOutCheckInServiceImpl) this.cociService) .createWorkingCopyName(name, expectedWorkingCopyLabel); String workingCopyName = (String) this.nodeService.getProperty(workingCopy, PROP_NAME_QNAME); assertEquals(expectedWorkingCopyName, workingCopyName); // Check a record has been kept of the working copy label used to create the working copy name assertEquals( "No record of working copy label kept", expectedWorkingCopyLabel, nodeService.getProperty(workingCopy, ContentModel.PROP_WORKING_COPY_LABEL)); // Ensure that the content has been copied correctly ContentReader contentReader = this.contentService.getReader(this.nodeRef, ContentModel.PROP_CONTENT); assertNotNull(contentReader); ContentReader contentReader2 = this.contentService.getReader(workingCopy, ContentModel.PROP_CONTENT); assertNotNull(contentReader2); assertEquals( "The content string of the working copy should match the original immediatly after checkout.", contentReader.getContentString(), contentReader2.getContentString()); return workingCopy; }
/** Check that an event without instructions throws an exception. */ @Test(expected = MissingDowngradeInstructions.class) public void testCheckConsistencyOfProperties_eventMissingInstructions() { when(mockNodeService.hasAspect(NODE_REF, ASPECT_CLASSIFIED)).thenReturn(true); when(mockNodeService.getProperty(NODE_REF, PROP_DOWNGRADE_DATE)).thenReturn(null); when(mockNodeService.getProperty(NODE_REF, PROP_DOWNGRADE_EVENT)).thenReturn("Event"); when(mockNodeService.getProperty(NODE_REF, PROP_DOWNGRADE_INSTRUCTIONS)).thenReturn(null); classifiedAspect.checkConsistencyOfProperties(NODE_REF); }
/** Check that omitting all downgrade fields is valid. */ @Test public void testCheckConsistencyOfProperties_notSpecified() { when(mockNodeService.hasAspect(NODE_REF, ASPECT_CLASSIFIED)).thenReturn(true); when(mockNodeService.getProperty(NODE_REF, PROP_DOWNGRADE_DATE)).thenReturn(null); when(mockNodeService.getProperty(NODE_REF, PROP_DOWNGRADE_EVENT)).thenReturn(null); when(mockNodeService.getProperty(NODE_REF, PROP_DOWNGRADE_INSTRUCTIONS)).thenReturn(null); classifiedAspect.checkConsistencyOfProperties(NODE_REF); }
// note: active or inactive public List<NodeRef> getModelRefs() { List<NodeRef> modelRefs = new ArrayList<NodeRef>(); for (RepositoryLocation repositoryLocation : this.repositoryModelsLocations) { StoreRef storeRef = repositoryLocation.getStoreRef(); if (!nodeService.exists(storeRef)) { logger.info("StoreRef '" + storeRef + "' does not exist"); continue; // skip this location } if (repositoryLocation.getQueryLanguage().equals(RepositoryLocation.LANGUAGE_PATH)) { List<NodeRef> nodeRefs = getNodes(storeRef, repositoryLocation, ContentModel.TYPE_DICTIONARY_MODEL); if (nodeRefs.size() > 0) { for (NodeRef dictionaryModel : nodeRefs) { try { // Ignore if the node is a working copy or archived if (!(nodeService.hasAspect(dictionaryModel, ContentModel.ASPECT_WORKING_COPY) || nodeService.hasAspect(dictionaryModel, ContentModel.ASPECT_ARCHIVED))) { modelRefs.add(dictionaryModel); } } catch (InvalidNodeRefException inre) { // ignore - model no longer exists if (logger.isDebugEnabled()) { logger.debug("getModelRefs: " + inre + " (assume concurrently deleted)"); } continue; } } } } else { logger.error( "Unsupported query language for models location: " + repositoryLocation.getQueryLanguage()); } } return modelRefs; }
@Override protected void executeImpl(Action action, NodeRef nodeRef) { String usernameAuth = authenticate(); NodeService nodeService = serviceRegistry.getNodeService(); NodeRef parentNodeRef = nodeService.getPrimaryParent(nodeRef).getParentRef(); if (nodeService.hasAspect(nodeRef, documentSimpleRM)) { if (nodeService.hasAspect(parentNodeRef, expedientRM)) { updateExpedient(nodeService, nodeRef, parentNodeRef); } else if (nodeService.hasAspect(parentNodeRef, agregacioRM)) { updateAgregacio(nodeService, nodeRef, parentNodeRef); } } else if (nodeService.hasAspect(nodeRef, expedientRM)) { updateSerie(nodeService, nodeRef, parentNodeRef); } else if (nodeService.hasAspect(nodeRef, agregacioRM)) { updateSerie(nodeService, nodeRef, parentNodeRef); } else if (nodeService.hasAspect(nodeRef, serieRM)) { updateFons(nodeService, nodeRef, parentNodeRef); } AuthenticationUtil.setRunAsUser(usernameAuth); AuthenticationUtil.setFullyAuthenticatedUser(usernameAuth); }
/** * Removes unwanted aspects * * @param nodeService * @param nodeRef */ protected void cleanDisposableItem(NodeService nodeService, NodeRef nodeRef) { // Remove unwanted aspects for (QName aspect : unwantedAspects) { if (nodeService.hasAspect(nodeRef, aspect)) { nodeService.removeAspect(nodeRef, aspect); } } // remove the current disposition action (if there is one) DispositionAction dispositionAction = dispositionService.getNextDispositionAction(nodeRef); if (dispositionAction != null) { nodeService.deleteNode(dispositionAction.getNodeRef()); } }
/** * 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; }
/** Perform the actual repository access, checking for the existence of a valid transaction */ private void onDictionaryInitInTxn() { if (AlfrescoTransactionSupport.getTransactionReadState() == TxnReadState.TXN_NONE) { throw new IllegalStateException( "The Repository-based dictionary initialization has to be done in the context of a transaction."); } long startTime = System.currentTimeMillis(); if (logger.isTraceEnabled()) { String tenantDomain = tenantAdminService.getCurrentUserDomain(); logger.trace( "onDictionaryInit: [" + Thread.currentThread() + "]" + (tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: " + tenantDomain + ")")); } Collection<QName> modelsBefore = dictionaryDAO.getModels(true); // note: re-entrant int modelsBeforeCnt = (modelsBefore != null ? modelsBefore.size() : 0); List<String> loadedModels = new ArrayList<String>(); if (this.repositoryModelsLocations != null) { // URI to model map Map<String, DynamicModelInfo> modelMap = new HashMap<String, DynamicModelInfo>(); if (logger.isTraceEnabled()) { logger.trace("onDictionaryInit: locations=" + this.repositoryModelsLocations); } // Register the models found in the repository for (RepositoryLocation repositoryLocation : this.repositoryModelsLocations) { StoreRef storeRef = repositoryLocation.getStoreRef(); if (!nodeService.exists(storeRef)) { logger.info("StoreRef '" + storeRef + "' does not exist"); continue; // skip this location } List<NodeRef> nodeRefs = null; if (repositoryLocation.getQueryLanguage().equals(RepositoryLocation.LANGUAGE_PATH)) { nodeRefs = getNodes(storeRef, repositoryLocation, ContentModel.TYPE_DICTIONARY_MODEL); if (nodeRefs.size() > 0) { for (NodeRef dictionaryModel : nodeRefs) { try { // Ignore if the node is a working copy or archived, or if its inactive if (!(nodeService.hasAspect(dictionaryModel, ContentModel.ASPECT_WORKING_COPY) || nodeService.hasAspect(dictionaryModel, ContentModel.ASPECT_ARCHIVED))) { Boolean isActive = (Boolean) nodeService.getProperty(dictionaryModel, ContentModel.PROP_MODEL_ACTIVE); if ((isActive != null) && (isActive.booleanValue() == true)) { M2Model model = createM2Model(dictionaryModel); if (model != null) { if (logger.isTraceEnabled()) { logger.trace( "onDictionaryInit: " + model.getName() + " (" + dictionaryModel + ")"); } for (M2Namespace namespace : model.getNamespaces()) { modelMap.put( namespace.getUri(), new DynamicModelInfo(repositoryLocation, model, dictionaryModel)); } } } } } catch (InvalidNodeRefException inre) { // ignore - model no longer exists if (logger.isDebugEnabled()) { logger.debug("onDictionaryInit: " + inre + " (assume concurrently deleted)"); } continue; } } } } else { logger.error( "Unsupported query language for models location: " + repositoryLocation.getQueryLanguage()); } } // Load the models ensuring that they are loaded in the correct order for (Map.Entry<String, DynamicModelInfo> entry : modelMap.entrySet()) { RepositoryLocation importedLocation = entry.getValue().location; M2Model importedModel = entry.getValue().model; loadModel(modelMap, loadedModels, importedModel, importedLocation); notifyDynamicModelLoaded(entry.getValue()); } } Collection<QName> modelsAfter = dictionaryDAO.getModels(true); int modelsAfterCnt = (modelsAfter != null ? modelsAfter.size() : 0); if (logger.isDebugEnabled()) { String tenantDomain = tenantAdminService.getCurrentUserDomain(); logger.debug( "Model count: before=" + modelsBeforeCnt + ", load/update=" + loadedModels.size() + ", after=" + modelsAfterCnt + " in " + (System.currentTimeMillis() - startTime) + " msecs [" + Thread.currentThread() + "] " + (tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: " + tenantDomain + ")")); } }
@Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { if (tracer.isDebugEnabled()) tracer.debug("DocumentAcquiring action, execution init"); // the document has already the documentAcquiring aspect? if yes, nothing to do if (nodeService.hasAspect(actionedUponNodeRef, SinekartaModel.ASPECT_QNAME_DOCUMENT_ACQUIRING)) return; // the document has the timestamp mark aspect? if yes, nothing to do if (nodeService.hasAspect(actionedUponNodeRef, SinekartaModel.ASPECT_QNAME_TIMESTAMP_MARK)) return; // the node to add is an archive, we don't need any acquire processing if (nodeService.getType(actionedUponNodeRef).equals(SinekartaModel.TYPE_QNAME_ARCHIVE)) return; // Someone is rendering the document (by ie in share), the document must not be acquired // if the document is a child of an acquired document and is not to render, it's a working copy // for displaying if (nodeService.hasAspect( nodeService.getPrimaryParent(actionedUponNodeRef).getParentRef(), SinekartaModel.ASPECT_QNAME_DOCUMENT_ACQUIRING)) return; // && // nodeService.hasAspect(actionedUponNodeRef, // org.alfresco.model.RenditionModel.ASPECT_HIDDEN_RENDITION)) Integer documentTypeId = (Integer) action.getParameterValue(PARAM_DOCUMENT_TYPE); DocumentType documentType = null; if (documentTypeId != null) { try { documentType = sinekartaDao.getDocumentType(documentTypeId); } catch (Exception e) { tracer.error("wrong documentType for mark folder prepare.", e); throw new DocumentAcquiringException("wrong documentType for mark folder prepare.", e); } } Date documentDate = (Date) action.getParameterValue(PARAM_DOCUMENT_DATE); String documentLanguage = (String) action.getParameterValue(PARAM_DOCUMENT_LANGUAGE); // getting sinekarta admin user String sinekartaAdminUserId = NodeTools.getSinekartaAdminUserId(nodeService, searchService, companyHomePath); DocumentAcquiringWorker execAsSinekartaAdmin = new DocumentAcquiringWorker( nodeService, contentService, actionedUponNodeRef, actionService, documentType, documentDate, documentLanguage); // running core of action as sinekarta admin Boolean result = AuthenticationUtil.runAs(execAsSinekartaAdmin, sinekartaAdminUserId); if (!result) { tracer.error( "document acquiring failed, please verify if the document already exists on archive : " + execAsSinekartaAdmin.getKoReason()); throw new DocumentAcquiringException( "document acquiring failed, please verify if the document already exists on archive : " + execAsSinekartaAdmin.getKoReason()); } if (tracer.isDebugEnabled()) tracer.debug("DocumentAcquiring action, execution end"); }
public void onCopyComplete( QName classRef, NodeRef sourceNodeRef, NodeRef targetNodeRef, boolean copyToNewNode, Map<NodeRef, NodeRef> copyMap) { Set<NodeRef> workingCopyNodeRefs = TransactionalResourceHelper.getSet(KEY_WORKING_COPIES); if (!workingCopyNodeRefs.contains(sourceNodeRef)) { // This is not one of the nodes that needs to have discussions copied over return; } // First check that the source node has forums NodeRef sourceForumNodeRef = getForum(sourceNodeRef); if (sourceForumNodeRef == null) { // Missing! Clean the source node up! nodeService.removeAspect(sourceNodeRef, ForumModel.ASPECT_DISCUSSABLE); return; } // The aspect may or may not exist on the target node if (!nodeService.hasAspect(targetNodeRef, ForumModel.ASPECT_DISCUSSABLE)) { // Add the aspect nodeService.addAspect(targetNodeRef, ForumModel.ASPECT_DISCUSSABLE, null); } // Get the forum node NodeRef targetForumNodeRef = getForum(targetNodeRef); // Merge the forum topics List<ChildAssociationRef> topicAssocRefs = nodeService.getChildAssocs( sourceForumNodeRef, Collections.singleton(ForumModel.TYPE_TOPIC)); int copied = 0; for (ChildAssociationRef topicAssocRef : topicAssocRefs) { NodeRef topicNodeRef = topicAssocRef.getChildRef(); try { // work out the name for the copied topic String topicName; String topicNodeName = nodeService.getProperty(topicNodeRef, ContentModel.PROP_NAME).toString(); Serializable labelProp = nodeService.getProperty(targetNodeRef, ContentModel.PROP_VERSION_LABEL); if (labelProp == null) { SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss"); topicName = topicNodeName + " - " + dateFormat.format(new Date()); } else { topicName = topicNodeName + " (" + labelProp.toString() + ")"; } if (fileFolderService.searchSimple(targetForumNodeRef, topicName) != null) { // A topic with that name already exists continue; } fileFolderService.copy(topicNodeRef, targetForumNodeRef, topicName); copied++; } catch (FileExistsException e) { // We checked for this, so this is a concurrency condition throw new ConcurrencyFailureException("Target topic exists: " + e.getMessage(), e); } catch (FileNotFoundException e) { // The node was there, but now it's gone throw new ConcurrencyFailureException("Forum was deleted: " + e.getMessage(), e); } } }
/** * @return Returns <tt>true</tt> if the data is a NodeRef and it represents a fileplan component */ public boolean isSupported(Serializable data) { if (data == null || !(data instanceof NodeRef)) { return false; } return nodeService.hasAspect((NodeRef) data, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT); }
public void testCheckOutPermissions_ALF7680_ALF535() { /* * Testing working copy creation in folder of source node. * User has no permissions to create children in this folder. * User has permissions to edit document. * Expected result: working copy should be created. */ NodeRef folder1 = createFolderWithPermission(rootNodeRef, userName, PermissionService.CONSUMER); NodeRef node = createNodeWithPermission(folder1, userName, PermissionService.EDITOR); // Check out the node NodeRef workingCopy = cociService.checkout( node, folder1, ContentModel.ASSOC_CHILDREN, QName.createQName("workingCopy")); // Ensure that the working copy was created and current user was set as owner assertNotNull(workingCopy); assertTrue(nodeService.hasAspect(workingCopy, ContentModel.ASPECT_WORKING_COPY)); assertEquals( this.userNodeRef, nodeService.getProperty(workingCopy, ContentModel.PROP_WORKING_COPY_OWNER)); cociService.cancelCheckout(workingCopy); /* * Testing working copy creation in a different folder. * User has permissions to create children in this folder. * User has permissions to edit document. * Expected result: working copy should be created. */ NodeRef folder2 = createFolderWithPermission(rootNodeRef, userName, PermissionService.ALL_PERMISSIONS); // Check out the node workingCopy = cociService.checkout( node, folder2, ContentModel.ASSOC_CHILDREN, QName.createQName("workingCopy")); // Ensure that the working copy was created and current user was set as owner assertNotNull(workingCopy); assertTrue(nodeService.hasAspect(workingCopy, ContentModel.ASPECT_WORKING_COPY)); assertEquals( this.userNodeRef, nodeService.getProperty(workingCopy, ContentModel.PROP_WORKING_COPY_OWNER)); cociService.cancelCheckout(workingCopy); /* * Testing working copy creation in a different folder. * User has no permissions to create children in this folder. * User has permissions to edit document. * Expected result: exception. */ NodeRef folder3 = createFolderWithPermission(rootNodeRef, userName, PermissionService.CONSUMER); try { // Check out the node workingCopy = cociService.checkout( node, folder3, ContentModel.ASSOC_CHILDREN, QName.createQName("workingCopy")); // Ensure that the working copy was not created and exception occurs fail("Node can't be checked out to folder where user has no permissions to create children"); } catch (Exception e) { // Exception is expected } /* * Testing working copy creation in a different folder. * User has permissions to create children in this folder. * User has no permissions to edit document. * Expected result: exception. */ NodeRef node2 = createNodeWithPermission(folder3, userName, PermissionService.CONSUMER); try { // Check out the node workingCopy = cociService.checkout( node2, folder3, ContentModel.ASSOC_CHILDREN, QName.createQName("workingCopy")); // Ensure that the working copy was not created and exception occurs fail("Node can't be checked out if user has no permissions to edit document"); } catch (Exception e) { // Exception is expected } }
private AlfrescoRuntimeException signFile( final NodeRef nodeRefToSign, final DigitalSigningDTO signingDTO, final File alfTempDir, final String alias, final KeyStore ks, final PrivateKey key, final Certificate[] chain) { final String fileNameToSign = fileFolderService.getFileInfo(nodeRefToSign).getName(); File fileConverted = null; File tempDir = null; try { ContentReader fileToSignContentReader = getReader(nodeRefToSign); if (fileToSignContentReader != null) { String newName = null; // Check if document is PDF or transform it if (!MimetypeMap.MIMETYPE_PDF.equals(fileToSignContentReader.getMimetype())) { // Transform document in PDF document final ContentTransformer tranformer = contentTransformerRegistry.getTransformer( fileToSignContentReader.getMimetype(), fileToSignContentReader.getSize(), MimetypeMap.MIMETYPE_PDF, new TransformationOptions()); if (tranformer != null) { tempDir = new File(alfTempDir.getPath() + File.separatorChar + nodeRefToSign.getId()); if (tempDir != null) { tempDir.mkdir(); fileConverted = new File(tempDir, fileNameToSign + "_" + System.currentTimeMillis() + ".pdf"); if (fileConverted != null) { final ContentWriter newDoc = new FileContentWriter(fileConverted); if (newDoc != null) { newDoc.setMimetype(MimetypeMap.MIMETYPE_PDF); tranformer.transform(fileToSignContentReader, newDoc); fileToSignContentReader = new FileContentReader(fileConverted); final String originalName = (String) nodeService.getProperty(nodeRefToSign, ContentModel.PROP_NAME); newName = originalName.substring(0, originalName.lastIndexOf(".")) + ".pdf"; } } } } else { log.error( "[" + fileNameToSign + "] No suitable converter found to convert the document in PDF."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] No suitable converter found to convert the document in PDF."); } } // Convert PDF in PDF/A format final File pdfAFile = convertPdfToPdfA(fileToSignContentReader.getContentInputStream()); final PdfReader reader = new PdfReader(new FileInputStream(pdfAFile)); if (nodeRefToSign != null) { tempDir = new File(alfTempDir.getPath() + File.separatorChar + nodeRefToSign.getId()); if (tempDir != null) { tempDir.mkdir(); final File file = new File(tempDir, fileNameToSign); if (file != null) { final FileOutputStream fout = new FileOutputStream(file); final PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0'); if (stp != null) { final PdfSignatureAppearance sap = stp.getSignatureAppearance(); if (sap != null) { sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED); sap.setReason(signingDTO.getSignReason()); sap.setLocation(signingDTO.getSignLocation()); sap.setContact(signingDTO.getSignContact()); sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED); sap.setImageScale(1); // digital signature if (signingDTO.getSigningField() != null && !signingDTO.getSigningField().trim().equalsIgnoreCase("")) { Image img = null; if (signingDTO.getImage() != null) { final ContentReader imageContentReader = getReader(signingDTO.getImage()); final AcroFields af = reader.getAcroFields(); if (af != null) { final List<FieldPosition> positions = af.getFieldPositions(signingDTO.getSigningField()); if (positions != null && positions.size() > 0 && positions.get(0) != null && positions.get(0).position != null) { final BufferedImage newImg = scaleImage( ImageIO.read(imageContentReader.getContentInputStream()), BufferedImage.TYPE_INT_RGB, Float.valueOf(positions.get(0).position.getWidth()).intValue(), Float.valueOf(positions.get(0).position.getHeight()).intValue()); img = Image.getInstance(newImg, null); } else { log.error( "[" + fileNameToSign + "] The field '" + signingDTO.getSigningField() + "' doesn't exist in the document."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] The field '" + signingDTO.getSigningField() + "' doesn't exist in the document."); } } if (img == null) { img = Image.getInstance( ImageIO.read(imageContentReader.getContentInputStream()), null); } sap.setImage(img); } sap.setVisibleSignature(signingDTO.getSigningField()); } else { int pageToSign = 1; if (DigitalSigningDTO.PAGE_LAST.equalsIgnoreCase( signingDTO.getPages().trim())) { pageToSign = reader.getNumberOfPages(); } else if (DigitalSigningDTO.PAGE_SPECIFIC.equalsIgnoreCase( signingDTO.getPages().trim())) { if (signingDTO.getPageNumber() > 0 && signingDTO.getPageNumber() <= reader.getNumberOfPages()) { pageToSign = signingDTO.getPageNumber(); } else { throw new AlfrescoRuntimeException("Page number is out of bound."); } } if (signingDTO.getImage() != null) { final ContentReader imageContentReader = getReader(signingDTO.getImage()); // Resize image final BufferedImage newImg = scaleImage( ImageIO.read(imageContentReader.getContentInputStream()), BufferedImage.TYPE_INT_RGB, signingDTO.getSignWidth(), signingDTO.getSignHeight()); final Image img = Image.getInstance(newImg, null); sap.setImage(img); } if (signingDTO.getPosition() != null && !DigitalSigningDTO.POSITION_CUSTOM.equalsIgnoreCase( signingDTO.getPosition().trim())) { final Rectangle pageRect = reader.getPageSizeWithRotation(1); sap.setVisibleSignature( positionSignature( signingDTO.getPosition(), pageRect, signingDTO.getSignWidth(), signingDTO.getSignHeight(), signingDTO.getxMargin(), signingDTO.getyMargin()), pageToSign, null); } else { sap.setVisibleSignature( new Rectangle( signingDTO.getLocationX(), signingDTO.getLocationY(), signingDTO.getLocationX() + signingDTO.getSignWidth(), signingDTO.getLocationY() - signingDTO.getSignHeight()), pageToSign, null); } } stp.close(); NodeRef destinationNode = null; NodeRef originalDoc = null; boolean addAsNewVersion = false; if (signingDTO.getDestinationFolder() == null) { destinationNode = nodeRefToSign; nodeService.addAspect(destinationNode, ContentModel.ASPECT_VERSIONABLE, null); addAsNewVersion = true; } else { originalDoc = nodeRefToSign; destinationNode = createDestinationNode( file.getName(), signingDTO.getDestinationFolder(), nodeRefToSign); } if (destinationNode != null) { final ContentWriter writer = contentService.getWriter(destinationNode, ContentModel.PROP_CONTENT, true); if (writer != null) { writer.setEncoding(fileToSignContentReader.getEncoding()); writer.setMimetype("application/pdf"); writer.putContent(file); file.delete(); if (fileConverted != null) { fileConverted.delete(); } nodeService.addAspect( destinationNode, SigningModel.ASPECT_SIGNED, new HashMap<QName, Serializable>()); nodeService.setProperty( destinationNode, SigningModel.PROP_REASON, signingDTO.getSignReason()); nodeService.setProperty( destinationNode, SigningModel.PROP_LOCATION, signingDTO.getSignLocation()); nodeService.setProperty( destinationNode, SigningModel.PROP_SIGNATUREDATE, new java.util.Date()); nodeService.setProperty( destinationNode, SigningModel.PROP_SIGNEDBY, AuthenticationUtil.getRunAsUser()); if (newName != null) { nodeService.setProperty(destinationNode, ContentModel.PROP_NAME, newName); } final X509Certificate c = (X509Certificate) ks.getCertificate(alias); nodeService.setProperty( destinationNode, SigningModel.PROP_VALIDITY, c.getNotAfter()); nodeService.setProperty( destinationNode, SigningModel.PROP_ORIGINAL_DOC, originalDoc); if (!addAsNewVersion) { if (!nodeService.hasAspect(originalDoc, SigningModel.ASPECT_ORIGINAL_DOC)) { nodeService.addAspect( originalDoc, SigningModel.ASPECT_ORIGINAL_DOC, new HashMap<QName, Serializable>()); } nodeService.createAssociation( originalDoc, destinationNode, SigningModel.PROP_RELATED_DOC); } } } else { log.error("[" + fileNameToSign + "] Destination node is not a valid NodeRef."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] Destination node is not a valid NodeRef."); } } else { log.error("[" + fileNameToSign + "] Unable to get PDF appearance signature."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] Unable to get PDF appearance signature."); } } else { log.error("[" + fileNameToSign + "] Unable to create PDF signature."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] Unable to create PDF signature."); } } } } else { log.error("[" + fileNameToSign + "] Unable to get document to sign content."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] Unable to get document to sign content."); } if (pdfAFile != null) { pdfAFile.delete(); } return null; } else { log.error("[" + fileNameToSign + "] The document has no content."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] The document has no content."); } } catch (KeyStoreException e) { log.error("[" + fileNameToSign + "] " + e); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + e.getMessage(), e); } catch (ContentIOException e) { log.error("[" + fileNameToSign + "] " + e); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + e.getMessage(), e); } catch (IOException e) { log.error("[" + fileNameToSign + "] " + e); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + e.getMessage(), e); } catch (DocumentException e) { log.error("[" + fileNameToSign + "] " + e); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + e.getMessage(), e); } finally { if (tempDir != null) { try { tempDir.delete(); } catch (Exception ex) { log.error("[" + fileNameToSign + "] " + ex); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + ex.getMessage(), ex); } } } }
public void testVersioning() throws Exception { WikiPageInfo wikiInfo; JSONObject page; JSONArray versions; String name; // Create a page page = createOrUpdatePage(PAGE_TITLE_TWO, PAGE_CONTENTS_ONE, null, Status.STATUS_OK); name = PAGE_TITLE_TWO.replace(' ', '_'); assertEquals("Incorrect JSON: " + page.toString(), true, page.has("title")); // Check it was versioned by default wikiInfo = wikiService.getWikiPage(SITE_SHORT_NAME_WIKI, name); assertNotNull(wikiInfo); assertEquals( true, nodeService.hasAspect(wikiInfo.getNodeRef(), ContentModel.ASPECT_VERSIONABLE)); // Check the JSON for versioning page = getPage(name, Status.STATUS_OK); assertEquals("Incorrect JSON: " + page.toString(), true, page.has("versionhistory")); versions = page.getJSONArray("versionhistory"); assertEquals(1, versions.length()); assertEquals("1.0", versions.getJSONObject(0).get("version")); assertEquals(USER_ONE, versions.getJSONObject(0).get("author")); // Fetch it at this version String content = getPageAtVersion(name, "1.0", Status.STATUS_OK); assertEquals(PAGE_CONTENTS_ONE, content); // Upload a new copy without a version flag, denied createOrUpdatePage(PAGE_TITLE_TWO, "Changed Contents", "none", Status.STATUS_CONFLICT); // Upload a new copy with the appropriate version, allowed String PAGE_CONTENTS_CHANGED = "Changed Contents 2"; page = createOrUpdatePage(PAGE_TITLE_TWO, PAGE_CONTENTS_CHANGED, "1.0", Status.STATUS_OK); page = getPage(name, Status.STATUS_OK); assertEquals("Incorrect JSON: " + page.toString(), true, page.has("versionhistory")); versions = page.getJSONArray("versionhistory"); assertEquals(2, versions.length()); assertEquals("1.1", versions.getJSONObject(0).get("version")); assertEquals(USER_ONE, versions.getJSONObject(0).get("author")); assertEquals("1.0", versions.getJSONObject(1).get("version")); assertEquals(USER_ONE, versions.getJSONObject(1).get("author")); // Check the version contents content = getPageAtVersion(name, "1.1", Status.STATUS_OK); assertEquals(PAGE_CONTENTS_CHANGED, content); content = getPageAtVersion(name, "1.0", Status.STATUS_OK); assertEquals(PAGE_CONTENTS_ONE, content); // Upload a new copy with the force flag, allowed String PAGE_CONTENTS_CHANGED3 = "Changed Contents 3"; page = createOrUpdatePage(PAGE_TITLE_TWO, PAGE_CONTENTS_CHANGED3, "force", Status.STATUS_OK); page = getPage(name, Status.STATUS_OK); assertEquals("Incorrect JSON: " + page.toString(), true, page.has("versionhistory")); versions = page.getJSONArray("versionhistory"); assertEquals(3, versions.length()); assertEquals("1.2", versions.getJSONObject(0).get("version")); assertEquals(USER_ONE, versions.getJSONObject(0).get("author")); assertEquals("1.1", versions.getJSONObject(1).get("version")); assertEquals(USER_ONE, versions.getJSONObject(1).get("author")); assertEquals("1.0", versions.getJSONObject(2).get("version")); assertEquals(USER_ONE, versions.getJSONObject(2).get("author")); // Check the version contents content = getPageAtVersion(name, "1.2", Status.STATUS_OK); assertEquals(PAGE_CONTENTS_CHANGED3, content); content = getPageAtVersion(name, "1.1", Status.STATUS_OK); assertEquals(PAGE_CONTENTS_CHANGED, content); content = getPageAtVersion(name, "1.0", Status.STATUS_OK); assertEquals(PAGE_CONTENTS_ONE, content); // You get an empty string back for invalid versions content = getPageAtVersion(name, "1.4", Status.STATUS_OK); assertEquals("", content); }