/**
   * Streams content back to client from a given resource path.
   *
   * @param req The request
   * @param res The response
   * @param resourcePath The classpath resource path the content is required for.
   * @param attach Indicates whether the content should be streamed as an attachment or not
   * @param attachFileName Optional file name to use when attach is <code>true</code>
   * @throws IOException
   */
  protected void streamContent(
      WebScriptRequest req,
      WebScriptResponse res,
      String resourcePath,
      boolean attach,
      String attachFileName,
      Map<String, Object> model)
      throws IOException {
    if (logger.isDebugEnabled())
      logger.debug(
          "Retrieving content from resource path " + resourcePath + " (attach: " + attach + ")");

    // get extension of resource
    String ext = "";
    int extIndex = resourcePath.lastIndexOf('.');
    if (extIndex != -1) {
      ext = resourcePath.substring(extIndex);
    }

    // We need to retrieve the modification date/time from the resource itself.
    StringBuilder sb = new StringBuilder("classpath:").append(resourcePath);
    final String classpathResource = sb.toString();

    long resourceLastModified = resourceLoader.getResource(classpathResource).lastModified();

    // create temporary file
    File file = TempFileProvider.createTempFile("streamContent-", ext);

    InputStream is = resourceLoader.getResource(classpathResource).getInputStream();
    OutputStream os = new FileOutputStream(file);
    FileCopyUtils.copy(is, os);

    // stream the contents of the file, but using the modifiedDate of the original resource.
    streamContent(req, res, file, resourceLastModified, attach, attachFileName, model);
  }
  @Override
  public void setUp() throws Exception {
    super.setUp();

    // create a store that uses a subdirectory of the temp directory
    File tempDir = TempFileProvider.getTempDir();
    store = new FileContentStore(ctx, tempDir.getAbsolutePath() + File.separatorChar + getName());
    // disallow random access
    store.setAllowRandomAccess(false);
  }
 /**
  * Returns a writer to a thread-unique file. It's always the same file per thread so you must
  * use and close the writer before getting another.
  */
 @Override
 protected ContentWriter getWriterInternal(
     ContentReader existingContentReader, String newContentUrl) {
   File file = hammeredFile.get();
   if (file == null) {
     file = TempFileProvider.createTempFile("NullContentStore", ".txt");
     hammeredFile.set(file);
   }
   return new FileContentWriter(file);
 }
 private TFile getFile(String extension, String location) {
   File file = TempFileProvider.createTempFile("moduleManagementToolTest-", extension);
   InputStream is = this.getClass().getClassLoader().getResourceAsStream(location);
   assertNotNull(is);
   OutputStream os;
   try {
     os = new FileOutputStream(file);
     FileCopyUtils.copy(is, os);
   } catch (IOException error) {
     error.printStackTrace();
   }
   return new TFile(file);
 }
  @Override
  protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache) {
    // Check we got a valid Multi-Part Form Upload
    FormData form = (FormData) req.parseContent();
    if (form == null || !form.getIsMultiPart()) {
      throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Bad Upload");
    }

    // Look for a file, we're quite flexible!
    File spreadsheet = null;
    for (FormData.FormField field : form.getFields()) {
      if (field.getIsFile()) {
        String ext = ".xls";
        if (field.getFilename() != null && field.getFilename().endsWith(".xlsx")) {
          ext = ".xlsx";
        }

        try {
          spreadsheet = TempFileProvider.createTempFile("spreadsheet", ext);
          FileOutputStream sout = new FileOutputStream(spreadsheet);
          IOUtils.copy(field.getInputStream(), sout);
          sout.close();
        } catch (IOException e) {
          throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Upload Failed");
        }

        break;
      }
    }

    // Process
    String[] sheetnames = null;
    if (spreadsheet != null) {
      try {
        sheetnames = excerpter.getSheetNames(spreadsheet);
      } catch (IOException e) {
        throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Spreadsheet Corrupt", e);
      }
    } else {
      throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Spreadsheet Missing");
    }

    // Report
    Map<String, Object> model = new HashMap<String, Object>();
    model.put("file", spreadsheet.getName());
    model.put("sheets", sheetnames);
    return model;
  }
  private File convertPdfToPdfA(final InputStream source) throws IOException, DocumentException {

    final File pdfAFile =
        TempFileProvider.createTempFile("digitalSigning-" + System.currentTimeMillis(), ".pdf");

    // Reads a PDF document.
    PdfReader reader = new PdfReader(source);
    // PdfStamper: Applies extra content to the pages of a PDF document. This extra content can be
    // all the objects allowed in
    // PdfContentByte including pages from other Pdfs.
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(pdfAFile));
    // A generic Document class.
    Document document = new Document();
    // we create a writer that listens to the document
    PdfWriter writer = stamper.getWriter();
    int numberPages = reader.getNumberOfPages();
    writer.setPDFXConformance(PdfWriter.PDFA1A);
    document.open();

    // PdfDictionary:A dictionary is an associative table containing pairs of objects.
    // The first element of each pair is called the key and the second  element is called the value
    // <CODE>PdfName</CODE> is an object that can be used as a name in a PDF-file
    PdfDictionary outi = new PdfDictionary(PdfName.OUTPUTINTENT);
    outi.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString("sRGB IEC61966-2.1"));
    outi.put(PdfName.INFO, new PdfString("sRGB IEC61966-2.1"));
    outi.put(PdfName.S, PdfName.GTS_PDFA1);
    writer.getExtraCatalog().put(PdfName.OUTPUTINTENTS, new PdfArray(outi));

    // Add pages
    PdfImportedPage p = null;
    Image image;
    for (int i = 0; i < numberPages; i++) {
      p = writer.getImportedPage(reader, i + 1);
      image = Image.getInstance(p);
      document.add(image);
    }
    writer.createXmpMetadata();

    document.close();

    // Add Metadata from source pdf
    HashMap<String, String> info = reader.getInfo();
    stamper.setMoreInfo(info);
    stamper.close();

    return pdfAFile;
  }
  public static File copy(InputStream inputStream) {
    ParameterCheck.mandatory("inputStream", inputStream);

    File tempFile = TempFileProvider.createTempFile("acav_tempfile_", ".tmp");

    OutputStream outputStream = null;

    try {
      outputStream = new FileOutputStream(tempFile);

      IOUtils.copy(inputStream, outputStream);

      return tempFile;
    } catch (Exception ex) {
      tempFile.delete();

      throw new AlfrescoRuntimeException(ex.getMessage(), ex);
    } finally {
      IOUtils.closeQuietly(inputStream);
      IOUtils.closeQuietly(outputStream);
    }
  }
 private File tempfile() {
   File file = TempFileProvider.createTempFile("cached-content", ".bin");
   file.deleteOnExit();
   return file;
 }
 @Before
 public void setUp() throws Exception {
   contentCache = new ContentCacheImpl();
   contentCache.setMemoryStore(lookupTable);
   contentCache.setCacheRoot(TempFileProvider.getTempDir());
 }
  /**
   * @see
   *     org.alfresco.repo.content.transform.AbstractContentTransformer2#transformInternal(org.alfresco.service.cmr.repository.ContentReader,
   *     org.alfresco.service.cmr.repository.ContentWriter,
   *     org.alfresco.service.cmr.repository.TransformationOptions)
   */
  @Override
  public void transformInternal(
      ContentReader reader, ContentWriter writer, TransformationOptions options) throws Exception {
    final String outputMimetype = writer.getMimetype();
    final String outputFileExt = getMimetypeService().getExtension(outputMimetype);

    // We need to keep a reference to thrown exceptions as we're going to catch them and
    // then move on to the next transformer. In the event that they all fail, we will throw
    // the final exception.
    Exception transformationException = null;

    for (int i = 0; i < transformers.size(); i++) {
      int oneBasedCount = i + 1;
      ContentTransformer transf = transformers.get(i);
      ContentWriter currentWriter = null;
      File tempFile = null;
      try {
        if (logger.isDebugEnabled()) {
          logger.debug(
              "Transformation attempt "
                  + oneBasedCount
                  + " of "
                  + transformers.size()
                  + ": "
                  + transf);
        }

        if (!transf.isTransformable(
            reader.getMimetype(), reader.getSize(), outputMimetype, options)) {
          throw new UnsupportedTransformationException(
              "Unsupported transformation: " + reader.getMimetype() + " to " + outputMimetype);
        }

        // We can't know in advance which transformer in the sequence will work - if any.
        // Therefore we can't write into the ContentWriter stream.
        // So make a temporary file writer with the current transformer name.
        tempFile =
            TempFileProvider.createTempFile(
                "FailoverTransformer_intermediate_" + transf.getClass().getSimpleName() + "_",
                "." + outputFileExt);
        currentWriter = new FileContentWriter(tempFile);
        currentWriter.setMimetype(outputMimetype);
        currentWriter.setEncoding(writer.getEncoding());

        // attempt to transform
        transf.transform(reader, currentWriter, options);

        // TODO Could add a check for zero-length output and treat that as a failure
        // final long writtenSize = currentWriter.getSize();
      } catch (Exception are) {
        if (transformationException == null) {
          transformationException = are;
        }

        if (logger.isDebugEnabled()) {
          logger.debug("Transformation " + oneBasedCount + " was unsuccessful.");
          if (i != transformers.size() - 1) {
            // We don't log the last exception as we're going to throw it.
            logger.debug("The below exception is provided for information purposes only.", are);
          }
        }

        // Set a new reader to refresh the input stream.
        reader = reader.getReader();
        // and move to the next transformer
        continue;
      }
      // No need to close input or output streams

      // At this point the current transformation was successful i.e. it did not throw an exception.

      // Now we must copy the content from the temporary file into the ContentWriter stream.
      if (tempFile != null) {
        writer.putContent(tempFile);
      }

      if (logger.isInfoEnabled()) {
        logger.info("Transformation was successful");
      }
      return;
    }
    // At this point we have tried all transformers in the sequence without apparent success.
    if (transformationException != null) {
      transformerDebug.debug("          No more transformations to failover to");
      if (logger.isDebugEnabled()) {
        logger.debug(
            "All transformations were unsuccessful. Throwing first exception.",
            transformationException);
      }
      throw transformationException;
    }
  }
  /**
   * Sign file.
   *
   * @param signingDTO sign informations
   * @param pdfSignedFile signed pdf returned
   */
  public void sign(final DigitalSigningDTO signingDTO) {
    if (signingDTO != null) {

      try {
        Security.addProvider(new BouncyCastleProvider());
        final File alfTempDir = TempFileProvider.getTempDir();

        if (alfTempDir != null) {
          final String keyType =
              (String) nodeService.getProperty(signingDTO.getKeyFile(), SigningModel.PROP_KEYTYPE);

          if (SigningConstants.KEY_TYPE_X509.equals(keyType)) {
            // Sign the file
            final KeyStore ks = KeyStore.getInstance("pkcs12");
            final ContentReader keyContentReader = getReader(signingDTO.getKeyFile());

            if (keyContentReader != null && ks != null && signingDTO.getKeyPassword() != null) {

              final List<AlfrescoRuntimeException> errors =
                  new ArrayList<AlfrescoRuntimeException>();

              // Get crypted secret key and decrypt it
              final Serializable encryptedPropertyValue =
                  nodeService.getProperty(
                      signingDTO.getKeyFile(), SigningModel.PROP_KEYCRYPTSECRET);
              final Serializable decryptedPropertyValue =
                  metadataEncryptor.decrypt(
                      SigningModel.PROP_KEYCRYPTSECRET, encryptedPropertyValue);

              // Decrypt key content
              InputStream decryptedKeyContent;
              try {
                decryptedKeyContent =
                    CryptUtils.decrypt(
                        decryptedPropertyValue.toString(),
                        keyContentReader.getContentInputStream());
              } catch (Throwable e) {
                log.error(e);
                throw new AlfrescoRuntimeException(e.getMessage(), e);
              }

              ks.load(
                  new ByteArrayInputStream(IOUtils.toByteArray(decryptedKeyContent)),
                  signingDTO.getKeyPassword().toCharArray());

              final String alias =
                  (String)
                      nodeService.getProperty(signingDTO.getKeyFile(), SigningModel.PROP_KEYALIAS);

              final PrivateKey key =
                  (PrivateKey) ks.getKey(alias, signingDTO.getKeyPassword().toCharArray());
              final Certificate[] chain = ks.getCertificateChain(alias);

              final Iterator<NodeRef> itFilesToSign = signingDTO.getFilesToSign().iterator();
              while (itFilesToSign.hasNext()) {
                final NodeRef nodeRefToSign = itFilesToSign.next();
                final AlfrescoRuntimeException exception =
                    signFile(nodeRefToSign, signingDTO, alfTempDir, alias, ks, key, chain);
                if (exception != null) {
                  // Error on the file process
                  errors.add(exception);
                }
              }

              if (errors != null && errors.size() > 0) {
                final StringBuffer allErrors = new StringBuffer();
                final Iterator<AlfrescoRuntimeException> itErrors = errors.iterator();
                if (errors.size() > 1) {
                  allErrors.append("\n");
                }
                while (itErrors.hasNext()) {
                  final AlfrescoRuntimeException alfrescoRuntimeException = itErrors.next();
                  allErrors.append(alfrescoRuntimeException.getMessage());
                  if (itErrors.hasNext()) {
                    allErrors.append("\n");
                  }
                }
                throw new RuntimeException(allErrors.toString());
              }

            } else {
              log.error("Unable to get key content, key type or key password.");
              throw new AlfrescoRuntimeException(
                  "Unable to get key content, key type or key password.");
            }
          }
        } else {
          log.error("Unable to get temporary directory.");
          throw new AlfrescoRuntimeException("Unable to get temporary directory.");
        }
      } catch (KeyStoreException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      } catch (NoSuchAlgorithmException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      } catch (CertificateException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      } catch (IOException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      } catch (UnrecoverableKeyException e) {
        log.error(e);
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      }
    } else {
      log.error("No object with signing informations.");
      throw new AlfrescoRuntimeException("No object with signing informations.");
    }
  }
  /**
   * @param reader
   * @param writer
   * @param options
   * @throws Exception
   */
  protected final void action(
      Action ruleAction,
      NodeRef actionedUponNodeRef,
      ContentReader reader,
      Map<String, Object> options) {
    PDDocument pdf = null;
    InputStream is = null;
    File tempDir = null;
    ContentWriter writer = null;

    try {
      // Get the split frequency
      int splitFrequency = 0;

      String splitFrequencyString = options.get(PARAM_SPLIT_AT_PAGE).toString();
      if (!splitFrequencyString.equals("")) {
        try {
          splitFrequency = Integer.valueOf(splitFrequencyString);
        } catch (NumberFormatException e) {
          throw new AlfrescoRuntimeException(e.getMessage(), e);
        }
      }

      // Get contentReader inputStream
      is = reader.getContentInputStream();
      // stream the document in
      pdf = PDDocument.load(is);
      // split the PDF and put the pages in a list
      Splitter splitter = new Splitter();
      // Need to adjust the input value to get the split at the right page
      splitter.setSplitAtPage(splitFrequency - 1);

      // Split the pages
      List<PDDocument> pdfs = splitter.split(pdf);

      // Start page split numbering at
      int page = 1;

      // build a temp dir, name based on the ID of the noderef we are
      // importing
      File alfTempDir = TempFileProvider.getTempDir();
      tempDir = new File(alfTempDir.getPath() + File.separatorChar + actionedUponNodeRef.getId());
      tempDir.mkdir();

      // FLAG: This is ugly.....get the first PDF.
      PDDocument firstPDF = (PDDocument) pdfs.remove(0);

      int pagesInFirstPDF = firstPDF.getNumberOfPages();

      String lastPage = "";
      String pg = "_pg";

      if (pagesInFirstPDF > 1) {
        pg = "_pgs";
        lastPage = "-" + pagesInFirstPDF;
      }

      String fileNameSansExt = getFilenameSansExt(actionedUponNodeRef, FILE_EXTENSION);
      firstPDF.save(
          tempDir
              + ""
              + File.separatorChar
              + fileNameSansExt
              + pg
              + page
              + lastPage
              + FILE_EXTENSION);

      try {
        firstPDF.close();
      } catch (IOException e) {
        throw new AlfrescoRuntimeException(e.getMessage(), e);
      }

      // FLAG: Like I said: "_UGLY_" ..... and it gets worse
      PDDocument secondPDF = null;

      Iterator<PDDocument> its = pdfs.iterator();

      int pagesInSecondPDF = 0;

      while (its.hasNext()) {
        if (secondPDF != null) {
          // Get the split document and save it into the temp dir with
          // new name
          PDDocument splitpdf = (PDDocument) its.next();

          int pagesInThisPDF = splitpdf.getNumberOfPages();
          pagesInSecondPDF = pagesInSecondPDF + pagesInThisPDF;

          PDFMergerUtility merger = new PDFMergerUtility();
          merger.appendDocument(secondPDF, splitpdf);
          merger.mergeDocuments();

          try {
            splitpdf.close();
          } catch (IOException e) {
            throw new AlfrescoRuntimeException(e.getMessage(), e);
          }

        } else {
          secondPDF = (PDDocument) its.next();

          pagesInSecondPDF = secondPDF.getNumberOfPages();
        }
      }

      if (pagesInSecondPDF > 1) {

        pg = "_pgs";
        lastPage = "-" + (pagesInSecondPDF + pagesInFirstPDF);

      } else {
        pg = "_pg";
        lastPage = "";
      }

      // This is where we should save the appended PDF
      // put together the name and save the PDF
      secondPDF.save(
          tempDir
              + ""
              + File.separatorChar
              + fileNameSansExt
              + pg
              + splitFrequency
              + lastPage
              + FILE_EXTENSION);

      for (File file : tempDir.listFiles()) {
        try {
          if (file.isFile()) {
            // Get a writer and prep it for putting it back into the
            // repo
            NodeRef destinationNode =
                createDestinationNode(
                    file.getName(),
                    (NodeRef) ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER),
                    actionedUponNodeRef);
            writer =
                serviceRegistry
                    .getContentService()
                    .getWriter(destinationNode, ContentModel.PROP_CONTENT, true);

            writer.setEncoding(reader.getEncoding()); // original
            // encoding
            writer.setMimetype(FILE_MIMETYPE);

            // Put it in the repo
            writer.putContent(file);

            // Clean up
            file.delete();
          }
        } catch (FileExistsException e) {
          throw new AlfrescoRuntimeException("Failed to process file.", e);
        }
      }
    } catch (COSVisitorException e) {
      throw new AlfrescoRuntimeException(e.getMessage(), e);
    } catch (IOException e) {
      throw new AlfrescoRuntimeException(e.getMessage(), e);
    } finally {
      if (pdf != null) {
        try {
          pdf.close();
        } catch (IOException e) {
          throw new AlfrescoRuntimeException(e.getMessage(), e);
        }
      }
      if (is != null) {
        try {
          is.close();
        } catch (IOException e) {
          throw new AlfrescoRuntimeException(e.getMessage(), e);
        }
      }

      if (tempDir != null) {
        tempDir.delete();
      }
    }
  }