Пример #1
0
 /** Searches for the node or nodes that match the path element for the given parent node */
 private List<NodeRef> getDirectDescendents(NodeRef pathRootNodeRef, String pathElement) {
   if (logger.isDebugEnabled()) {
     logger.debug(
         "Getting direct descendents: \n"
             + "   Path Root: "
             + pathRootNodeRef
             + "\n"
             + "   Path Element: "
             + pathElement);
   }
   List<NodeRef> results = null;
   // if this contains no wildcards, then we can fasttrack it
   if (!WildCard.containsWildcards(pathElement)) {
     // a specific name is required
     NodeRef foundNodeRef = fileFolderService.searchSimple(pathRootNodeRef, pathElement);
     if (foundNodeRef == null) {
       results = Collections.emptyList();
     } else {
       results = Collections.singletonList(foundNodeRef);
     }
   } else {
     // escape for the Lucene syntax search
     String escapedPathElement = SearchLanguageConversion.convertCifsToLucene(pathElement);
     // do the lookup
     List<org.alfresco.service.cmr.model.FileInfo> childInfos =
         fileFolderService.search(pathRootNodeRef, escapedPathElement, false);
     // convert to noderefs
     results = new ArrayList<NodeRef>(childInfos.size());
     for (org.alfresco.service.cmr.model.FileInfo info : childInfos) {
       results.add(info.getNodeRef());
     }
   }
   // done
   return results;
 }
Пример #2
0
  @Override
  public void setUp() throws Exception {
    super.setUp();

    this.fileFolderService = (FileFolderService) ctx.getBean("FileFolderService");
    this.repositoryHelper = (Repository) ctx.getBean("repositoryHelper");
    this.nodeService = (NodeService) ctx.getBean("NodeService");
    this.transactionService = (TransactionService) ctx.getBean("transactionService");

    server.setServletAuthenticatorFactory(new LocalTestRunAsAuthenticatorFactory());

    NodeRef companyHomeNodeRef = repositoryHelper.getCompanyHome();
    String guid = GUID.generate();

    AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName());

    folderWithoutAspect =
        fileFolderService
            .create(companyHomeNodeRef, "folder_" + guid, ContentModel.TYPE_FOLDER)
            .getNodeRef();
    assertNotNull("Doesn't create folder", folderWithoutAspect);

    folderWithAspect =
        fileFolderService
            .create(companyHomeNodeRef, "folder_aspect_" + guid, ContentModel.TYPE_FOLDER)
            .getNodeRef();
    assertNotNull("Doesn't create folder", folderWithoutAspect);
    // add 'dublincore' aspect
    Map<QName, Serializable> aspectProps = new HashMap<QName, Serializable>(1);
    aspectProps.put(ContentModel.PROP_SUBJECT, "Test subject");
    nodeService.addAspect(folderWithAspect, ContentModel.ASPECT_DUBLINCORE, aspectProps);
  }
Пример #3
0
  @Override
  public void tearDown() {
    if (folderWithoutAspect != null && fileFolderService.exists(folderWithoutAspect)) {
      fileFolderService.delete(folderWithoutAspect);
    }

    if (folderWithAspect != null && fileFolderService.exists(folderWithAspect)) {
      fileFolderService.delete(folderWithAspect);
    }
  }
Пример #4
0
  protected void onSetUpInTransaction() throws Exception {
    System.err.println("onSetUpInTransaction");
    super.onSetUpInTransaction();
    this.nodeService = (NodeService) super.applicationContext.getBean("dbNodeService");
    assertNotNull(this.nodeService);
    final FileFolderService fileFolderService =
        (FileFolderService) super.applicationContext.getBean("fileFolderService");
    assertNotNull(fileFolderService);
    this.formsService = (FormsService) super.applicationContext.getBean("FormsService");
    assertNotNull(this.formsService);
    final MutableAuthenticationService authenticationService =
        (MutableAuthenticationService) applicationContext.getBean("authenticationService");
    authenticationService.clearCurrentSecurityContext();
    final MutableAuthenticationDao authenticationDAO =
        (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");

    // Create a workspace that contains the 'live' nodes
    final StoreRef testStoreRef =
        this.nodeService.createStore(
            StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());

    // Get a reference to the root node
    final NodeRef rootNodeRef = this.nodeService.getRootNode(testStoreRef);

    // Create an authenticate the user
    if (!authenticationDAO.userExists(AuthenticationUtil.getAdminUserName())) {
      authenticationService.createAuthentication(
          AuthenticationUtil.getAdminUserName(), "admin".toCharArray());
    }

    TestWithUserUtils.authenticateUser(
        AuthenticationUtil.getAdminUserName(), "admin", rootNodeRef, authenticationService);

    // set up a faces context
    final MockExternalContext ec =
        new MockExternalContext(
            new MockServletContext(), new MockHttpServletRequest(), new MockHttpServletResponse());
    final StaticWebApplicationContext ac = new StaticWebApplicationContext();
    ac.setParent(this.applicationContext);
    this.applicationContext = ac;
    ec.getApplicationMap()
        .put(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.applicationContext);
    new MockFacesContext(ec);

    final FileInfo folderInfo =
        fileFolderService.create(rootNodeRef, "test_form", WCMAppModel.TYPE_FORMFOLDER);
    final HashMap<QName, Serializable> props = new HashMap<QName, Serializable>();
    this.nodeService.addAspect(folderInfo.getNodeRef(), WCMAppModel.ASPECT_FORM, props);
    this.mockForm = new MockForm(folderInfo.getNodeRef(), this.formsService);
  }
  @Override
  public NodeRef createNode(
      Resource resource,
      RepositoryLocation targetLocation,
      String encoding,
      String mimetype,
      QName nodeType)
      throws IOException {
    NodeRef rootNode = nodeService.getRootNode(targetLocation.getStoreRef());
    final List<NodeRef> parentNodes =
        searchService.selectNodes(
            rootNode, targetLocation.getPath(), null, namespaceService, false);
    Assert.isTrue(parentNodes.size() == 1, "Target location leads to not 1 unique Node reference");

    final String fileName = resource.getFilename();
    final FileInfo fileInfo = fileFolderService.create(parentNodes.get(0), fileName, nodeType);
    final NodeRef nodeRef = fileInfo.getNodeRef();

    final ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
    writer.putContent(resource.getInputStream());

    if (mimetype == null) {
      mimetype = guessMimetype(resource);
    }

    if (encoding == null) {
      encoding = guessEncoding(resource.getInputStream(), mimetype);
    }

    writer.setMimetype(mimetype);
    writer.setEncoding(encoding);

    return nodeRef;
  }
Пример #6
0
  /**
   * 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);
    }
  }
Пример #7
0
  /**
   * @param ruleAction
   * @param filename
   * @return
   */
  protected NodeRef createDestinationNode(
      String filename, NodeRef destinationParent, NodeRef target) {
    NodeRef destinationNode;
    FileInfo fileInfo =
        fileFolderService.create(destinationParent, filename, ContentModel.TYPE_CONTENT);
    destinationNode = fileInfo.getNodeRef();

    return destinationNode;
  }
Пример #8
0
  /**
   * Check if the folder node is empty
   *
   * @param folderNode NodeRef
   * @return boolean
   */
  public boolean isFolderEmpty(NodeRef folderNode) {

    // Check if the node has any child files/folders

    List<FileInfo> filesAndFolders = fileFolderService.list(folderNode);
    if (filesAndFolders == null || filesAndFolders.size() == 0) {
      return true;
    }
    return false;
  }
  @Test
  public void canPutFileWithResourceTag() throws ServletException, IOException {
    String fileName = "test_ALF-18821.txt";
    // VtiIfHeaderAction PUT handler expects the file to have already been created (in most cases)
    FileInfo createdFile = fileFolderService.create(docLib, fileName, ContentModel.TYPE_CONTENT);

    request =
        new MockHttpServletRequest(
            "PUT", "/alfresco/" + shortSiteId + "/documentLibrary/" + fileName);
    String fileContent = "This is the test file's content.";
    request.setContent(fileContent.getBytes());
    request.addHeader("If", "(<rt:792589C1-2E8F-410E-BC91-4EF42DA88D3C@00862604462>)");

    dispatcher.service(request, response);

    assertEquals(HttpServletResponse.SC_OK, response.getStatus());
    String retContent = fileFolderService.getReader(createdFile.getNodeRef()).getContentString();
    assertEquals(fileContent, retContent);
  }
  /**
   * Test attachment extraction with a TNEF message
   *
   * @throws Exception
   */
  public void testAttachmentExtraction() throws Exception {
    AuthenticationUtil.setRunAsUserSystem();
    /** Load a TNEF message */
    ClassPathResource fileResource = new ClassPathResource("imap/test-tnef-message.eml");
    assertNotNull("unable to find test resource test-tnef-message.eml", fileResource);
    InputStream is = new FileInputStream(fileResource.getFile());
    MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), is);

    /** Create a test node containing the message */
    String storePath = "workspace://SpacesStore";
    String companyHomePathInStore = "/app:company_home";
    StoreRef storeRef = new StoreRef(storePath);
    NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);

    List<NodeRef> nodeRefs =
        searchService.selectNodes(
            storeRootNodeRef, companyHomePathInStore, null, namespaceService, false);
    NodeRef companyHomeNodeRef = nodeRefs.get(0);

    FileInfo f1 =
        fileFolderService.create(
            companyHomeNodeRef, "ImapServiceImplTest", ContentModel.TYPE_FOLDER);
    FileInfo d2 =
        fileFolderService.create(f1.getNodeRef(), "ImapServiceImplTest", ContentModel.TYPE_FOLDER);
    FileInfo f2 =
        fileFolderService.create(
            f1.getNodeRef(), "test-tnef-message.eml", ContentModel.TYPE_CONTENT);

    ContentWriter writer = fileFolderService.getWriter(f2.getNodeRef());
    writer.putContent(new FileInputStream(fileResource.getFile()));

    NodeRef folder = imapService.extractAttachments(f1.getNodeRef(), f2.getNodeRef(), message);
    assertNotNull(folder);

    List<FileInfo> files = fileFolderService.listFiles(folder);
    assertTrue("three files not found", files.size() == 3);
  }
Пример #11
0
  /**
   * Creates a file or directory using the given paths.
   *
   * <p>If the directory path doesn't exist, then all the parent directories will be created. If the
   * file path is <code>null</code>, then the file will not be created
   *
   * @param rootNodeRef the root node of the path
   * @param path the path to a node
   * @param typeQName type of fole
   * @return Returns a newly created file or folder node
   * @throws FileExistsException if the file or folder already exists
   */
  public NodeRef createNode(NodeRef rootNodeRef, String path, QName typeQName)
      throws FileExistsException {
    // split the path up into its constituents
    StringTokenizer tokenizer = new StringTokenizer(path, FileName.DOS_SEPERATOR_STR, false);
    List<String> folderPathElements = new ArrayList<String>(10);
    String name = null;
    while (tokenizer.hasMoreTokens()) {
      String pathElement = tokenizer.nextToken();

      if (!tokenizer.hasMoreTokens()) {
        // the last token becomes the name
        name = pathElement;
      } else {
        // add the path element to the parent folder path
        folderPathElements.add(pathElement);
      }
    }
    // ensure that the folder path exists
    NodeRef parentFolderNodeRef = rootNodeRef;
    if (folderPathElements.size() > 0) {
      parentFolderNodeRef =
          FileFolderUtil.makeFolders(
                  fileFolderService, rootNodeRef, folderPathElements, ContentModel.TYPE_FOLDER)
              .getNodeRef();
    }
    try {
      NodeRef nodeRef = fileFolderService.create(parentFolderNodeRef, name, typeQName).getNodeRef();

      // done
      if (logger.isDebugEnabled()) {
        logger.debug(
            "Created node: \n"
                + "   device root: "
                + rootNodeRef
                + "\n"
                + "   path: "
                + path
                + "\n"
                + "   type: "
                + typeQName
                + "\n"
                + "   new node: "
                + nodeRef);
      }
      return nodeRef;
    } catch (org.alfresco.service.cmr.model.FileExistsException e) {
      throw new FileExistsException(path);
    }
  }
Пример #12
0
 /**
  * Rename a node
  *
  * @deprecated - not used by live code - exception handling is too severe
  * @param nodeToRenameRef Node to be renamed
  * @param newName New name for the node
  * @throws FileExistsException
  */
 public void rename(NodeRef nodeToRenameRef, String newName) throws FileExistsException {
   try {
     fileFolderService.rename(nodeToRenameRef, newName);
   } catch (org.alfresco.service.cmr.model.FileExistsException e) {
     throw new FileExistsException(newName);
   } catch (Throwable e) {
     throw new AlfrescoRuntimeException(
         "Rename failed: \n"
             + "   node to rename: "
             + nodeToRenameRef
             + "\n"
             + "   new name: "
             + newName,
         e);
   }
 }
Пример #13
0
  private NodeRef getEmailTemplateNodeRef() {
    List<NodeRef> nodeRefs =
        searchService.selectNodes(
            repository.getRootHome(),
            "app:company_home/app:dictionary/app:email_templates/cm:invite/cm:invite-email.html.ftl",
            null,
            this.namespaceService,
            false);

    if (nodeRefs.size() == 1) {
      // Now localise this
      NodeRef base = nodeRefs.get(0);
      NodeRef local = fileFolderService.getLocalizedSibling(base);
      return local;
    } else {
      throw new InvitationException("Cannot find the email template!");
    }
  }
Пример #14
0
 /**
  * Move a node
  *
  * @deprecated - not used by live code - exception handling is too severe
  * @param nodeToMoveRef Node to be moved
  * @param newParentNodeRef New parent folder node
  * @param newName New name for the moved node
  * @throws FileExistsException
  */
 public void move(
     NodeRef nodeToMoveRef, NodeRef oldParent, NodeRef newParentNodeRef, String newName)
     throws FileExistsException {
   try {
     fileFolderService.moveFrom(nodeToMoveRef, oldParent, newParentNodeRef, newName);
   } catch (org.alfresco.service.cmr.model.FileExistsException e) {
     throw new FileExistsException(newName);
   } catch (Throwable e) {
     throw new AlfrescoRuntimeException(
         "Move failed: \n"
             + "   node to move: "
             + nodeToMoveRef
             + "\n"
             + "   new parent: "
             + newParentNodeRef
             + "\n"
             + "   new name: "
             + newName,
         e);
   }
 }
  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);
      }
    }
  }
  /**
   * @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;
  }
Пример #17
0
  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);
        }
      }
    }
  }
Пример #18
0
  /**
   * 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;
  }
  /**
   * Send an email message
   *
   * @throws AlfrescoRuntimeExeption
   */
  @SuppressWarnings("unchecked")
  @Override
  protected void executeImpl(final Action ruleAction, final NodeRef actionedUponNodeRef) {
    try {
      MimeMessage message = javaMailSender.createMimeMessage();
      // use the true flag to indicate you need a multipart message
      MimeMessageHelper helper = new MimeMessageHelper(message, true);

      // set recipient
      String to = (String) ruleAction.getParameterValue(PARAM_TO);
      if (to != null && to.length() != 0) {
        helper.setTo(to);
      } else {
        // see if multiple recipients have been supplied - as a list of
        // authorities
        Serializable toManyMails = ruleAction.getParameterValue(PARAM_TO_MANY);
        List<String> recipients = new ArrayList<String>();
        if (toManyMails instanceof List) {
          for (String mailAdress : (List<String>) toManyMails) {
            if (validateAddress(mailAdress)) {
              recipients.add(mailAdress);
            }
          }
        } else if (toManyMails instanceof String) {
          if (validateAddress((String) toManyMails)) {
            recipients.add((String) toManyMails);
          }
        }
        if (recipients != null && recipients.size() > 0) {
          helper.setTo(recipients.toArray(new String[recipients.size()]));
        } else {
          // No recipients have been specified
          logger.error("No recipient has been specified for the mail action");
        }
      }

      // set subject line
      helper.setSubject((String) ruleAction.getParameterValue(PARAM_SUBJECT));

      // See if an email template has been specified
      String text = null;
      NodeRef templateRef = (NodeRef) ruleAction.getParameterValue(PARAM_TEMPLATE);
      if (templateRef != null) {
        // build the email template model
        Map<String, Object> model = createEmailTemplateModel(actionedUponNodeRef, ruleAction);

        // process the template against the model
        text = templateService.processTemplate("freemarker", templateRef.toString(), model);
      }

      // set the text body of the message
      if (text == null) {
        text = (String) ruleAction.getParameterValue(PARAM_TEXT);
      }
      // adding the boolean true to send as HTML
      helper.setText(text, true);
      FileFolderService fileFolderService = serviceRegistry.getFileFolderService();
      /* add inline images.
       * "action.parameters.images is a ,-delimited string, containing a map of images and resources, from this example:
      message.setText("my text <img src='cid:myLogo'>", true);
      message.addInline("myLogo", new ClassPathResource("img/mylogo.gif"));
      so the "images" param can look like this: headerLogo|images/headerLogoNodeRef,footerLogo|footerLogoNodeRef
       */
      String imageList = (String) ruleAction.getParameterValue(PARAM_IMAGES);
      System.out.println(imageList);
      String[] imageMap = imageList.split(","); // comma no spaces
      Map<String, String> images = new HashMap<String, String>();
      for (String image : imageMap) {
        System.out.println(image);
        String map[] = image.split("\\|");
        for (String key : map) {
          System.out.println(key);
        }

        System.out.println(map.length);

        images.put(map[0].trim(), map[1].trim());
        System.out.println(images.size());
        System.out.println("-" + map[0] + " " + map[1] + "-");
      }
      NodeRef imagesFolderNodeRef = (NodeRef) ruleAction.getParameterValue(PARAM_IMAGES_FOLDER);
      if (null != imagesFolderNodeRef) {
        ContentService contentService = serviceRegistry.getContentService();
        System.out.println("mapping");
        for (Map.Entry<String, String> entry : images.entrySet()) {
          System.out.println(
              entry.getKey()
                  + " "
                  + entry.getValue()
                  + " "
                  + ruleAction.getParameterValue(PARAM_IMAGES_FOLDER));
          NodeRef imageFile = fileFolderService.searchSimple(imagesFolderNodeRef, entry.getValue());
          if (null != imageFile) {
            ContentReader reader = contentService.getReader(imageFile, ContentModel.PROP_CONTENT);
            ByteArrayResource resource =
                new ByteArrayResource(IOUtils.toByteArray(reader.getContentInputStream()));
            helper.addInline(entry.getKey(), resource, reader.getMimetype());

          } else {
            logger.error("No image for " + entry.getKey());
          }
        }
      } else {
        logger.error("No images folder");
      }

      // set the from address
      NodeRef person = personService.getPerson(authService.getCurrentUserName());

      String fromActualUser = null;
      if (person != null) {
        fromActualUser = (String) nodeService.getProperty(person, ContentModel.PROP_EMAIL);
      }
      if (fromActualUser != null && fromActualUser.length() != 0) {
        helper.setFrom(fromActualUser);
      } else {
        String from = (String) ruleAction.getParameterValue(PARAM_FROM);
        if (from == null || from.length() == 0) {
          helper.setFrom(fromAddress);
        } else {
          helper.setFrom(from);
        }
      }
      NodeRef attachmentsFolder = (NodeRef) ruleAction.getParameterValue(PARAM_ATTCHMENTS_FOLDER);
      if (attachmentsFolder != null) {

        List<FileInfo> attachFiles = fileFolderService.listFiles(attachmentsFolder);
        if (attachFiles != null && attachFiles.size() > 0) {
          for (FileInfo attachFile : attachFiles) {
            ContentReader contentReader = fileFolderService.getReader(attachFile.getNodeRef());
            ByteArrayResource resource =
                new ByteArrayResource(IOUtils.toByteArray(contentReader.getContentInputStream()));
            helper.addAttachment(attachFile.getName(), resource, contentReader.getMimetype());
          }
        }
      }

      // Send the message unless we are in "testMode"
      javaMailSender.send(message);
    } catch (Exception e) {
      String toUser = (String) ruleAction.getParameterValue(PARAM_TO);
      if (toUser == null) {
        Object obj = ruleAction.getParameterValue(PARAM_TO_MANY);
        if (obj != null) {
          toUser = obj.toString();
        }
      }

      logger.error("Failed to send email to " + toUser, e);

      throw new AlfrescoRuntimeException("Failed to send email to:" + toUser, e);
    }
  }