Package org.pdfclown.samples.cli

Source Code of org.pdfclown.samples.cli.PageManagementSample

package org.pdfclown.samples.cli;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.pdfclown.documents.Document;
import org.pdfclown.documents.Page;
import org.pdfclown.documents.Pages;
import org.pdfclown.files.File;
import org.pdfclown.objects.PdfReference;
import org.pdfclown.tools.PageManager;

/**
  This sample demonstrates <b>how to manipulate the pages collection</b> within a PDF document,
  to perform page data size calculations, additions, movements, removals, extractions and
  splits of groups of pages.

  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
  @version 0.1.0
*/
public class PageManagementSample
  extends Sample
{
  private enum ActionEnum
  {
    PageDataSizeCalculation,
    PageAddition,
    PageMovement,
    PageRemoval,
    PageExtraction,
    DocumentMerge,
    DocumentBurst,
    DocumentSplitByPageIndex,
    DocumentSplitOnMaximumFileSize;

    public String getDescription(
      )
    {
      StringBuilder builder = new StringBuilder();
      for(char c : name().toCharArray())
      {
        if(Character.isUpperCase(c) && builder.length() > 0)
        {builder.append(" ");}

        builder.append(c);
      }
      return builder.toString();
    }
  }

  @Override
  public boolean run(
    )
  {
    final String mainFilePath = promptPdfFileChoice("Please select a PDF file");

    // Open the PDF file!
    final File mainFile;
    try
    {mainFile = new File(mainFilePath);}
    catch(Exception e)
    {throw new RuntimeException(mainFilePath + " file access error.",e);}

    final Document mainDocument = mainFile.getDocument();
    final Pages mainPages = mainDocument.getPages();
    final int mainPagesCount = mainPages.size();

    final ActionEnum action = promptAction();
    switch(action)
    {
      case PageDataSizeCalculation:
      {
        System.out.println("\nThis algorithm calculates the data size (expressed in bytes) of the selected document's pages.");
        System.out.println("Legend:");
        System.out.println(" * full: page data size encompassing all its dependencies (like shared resources) -- this is the size of the page when extracted as a single-page document;");
        System.out.println(" * differential: additional page data size -- this is the extra-content that's not shared with previous pages;");
        System.out.println(" * incremental: data size of the page sublist encompassing all the previous pages and the current one.\n");

        // Calculating the page data sizes...
        Set<PdfReference> visitedReferences = new HashSet<PdfReference>();
        long incrementalDataSize = 0;
        for(Page page : mainPages)
        {
          long pageFullDataSize = PageManager.getSize(page);
          long pageDifferentialDataSize = PageManager.getSize(page, visitedReferences);
          incrementalDataSize += pageDifferentialDataSize;

          System.out.println(
            "Page " + (page.getIndex()+1) + ": "
              + pageFullDataSize + " (full); "
              + pageDifferentialDataSize + " (differential); "
              + incrementalDataSize + " (incremental)"
            );
        }
      } break;
      case PageAddition:
      {
        // Source file.
        File sourceFile;
        {
          String sourceFilePath = promptPdfFileChoice("Select the source PDF file");
          try
          {sourceFile = new File(sourceFilePath);}
          catch(Exception e)
          {throw new RuntimeException(sourceFilePath + " file access error.",e);}
        }
        // Source page collection.
        Pages sourcePages = sourceFile.getDocument().getPages();
        // Source page count.
        int sourcePagesCount = sourcePages.size();

        // First page to add.
        int fromSourcePageIndex = promptPageChoice("Select the start source page to add", sourcePagesCount);
        // Last page to add.
        int toSourcePageIndex = promptPageChoice("Select the end source page to add", fromSourcePageIndex + 1, sourcePagesCount) + 1;
        // Target position.
        int targetPageIndex = promptPageChoice("Select the position where to insert the source pages", mainPagesCount + 1);

        // Add the chosen page range to the main document!
        new PageManager(mainDocument).add(
          targetPageIndex,
          sourcePages.subList(
            fromSourcePageIndex,
            toSourcePageIndex
            )
          );

        // Serialize the main file!
        serialize(mainFile, action);
      } break;
      case PageMovement:
      {
        // First page to move.
        int fromSourcePageIndex = promptPageChoice("Select the start page to move", mainPagesCount);
        // Last page to move.
        int toSourcePageIndex = promptPageChoice("Select the end page to move", fromSourcePageIndex + 1, mainPagesCount) + 1;
        // Target position.
        int targetPageIndex = promptPageChoice("Select the position where to insert the pages", mainPagesCount + 1);

        // Move the chosen page range!
        new PageManager(mainDocument).move(
          fromSourcePageIndex,
          toSourcePageIndex,
          targetPageIndex
          );

        // Serialize the main file!
        serialize(mainFile, action);
      } break;
      case PageRemoval:
      {
        // First page to remove.
        int fromPageIndex = promptPageChoice("Select the start page to remove", mainPagesCount);
        // Last page to remove.
        int toPageIndex = promptPageChoice("Select the end page to remove", fromPageIndex + 1, mainPagesCount) + 1;

        // Remove the chosen page range!
        new PageManager(mainDocument).remove(
          fromPageIndex,
          toPageIndex
          );

        // Serialize the main file!
        serialize(mainFile, action);
      } break;
      case PageExtraction:
      {
        // First page to extract.
        int fromPageIndex = promptPageChoice("Select the start page", mainPagesCount);
        // Last page to extract.
        int toPageIndex = promptPageChoice("Select the end page", fromPageIndex + 1, mainPagesCount) + 1;

        // Extract the chosen page range!
        Document targetDocument = new PageManager(mainDocument).extract(
          fromPageIndex,
          toPageIndex
          );

        // Serialize the target file!
        serialize(targetDocument.getFile(), action);
      } break;
      case DocumentMerge:
      {
        // Source file.
        File sourceFile;
        {
          String sourceFilePath = promptPdfFileChoice("Select the source PDF file");
          try
          {sourceFile = new File(sourceFilePath);}
          catch(Exception e)
          {throw new RuntimeException(sourceFilePath + " file access error.",e);}
        }

        // Append the chosen source document to the main document!
        new PageManager(mainDocument).add(sourceFile.getDocument());

        // Serialize the main file!
        serialize(mainFile, action);
      } break;
      case DocumentBurst:
      {
        // Split the document into single-page documents!
        List<Document> splitDocuments = new PageManager(mainDocument).split();

        // Serialize the split files!
        int index = 0;
        for(Document splitDocument : splitDocuments)
        {serialize(splitDocument.getFile(), action, ++index, false);}
      } break;
      case DocumentSplitByPageIndex:
      {
        // Number of splits to apply to the source document.
        int splitCount;
        try
        {splitCount = Integer.parseInt(promptChoice("Number of split positions: "));}
        catch(Exception e)
        {splitCount = 0;}

        // Split positions within the source document.
        int[] splitIndexes = new int[splitCount];
        {
          int prevSplitIndex = 0;
          for(int index = 0; index < splitCount; index++)
          {
            int splitIndex = promptPageChoice("Position " + (index + 1) + " of " + splitCount, prevSplitIndex + 1, mainPagesCount);
            splitIndexes[index] = splitIndex;
            prevSplitIndex = splitIndex;
          }
        }

        // Split the document at the chosen positions!
        List<Document> splitDocuments = new PageManager(mainDocument).split(splitIndexes);

        // Serialize the split files!
        int index = 0;
        for(Document splitDocument : splitDocuments)
        {serialize(splitDocument.getFile(), action, ++index, false);}
      } break;
      case DocumentSplitOnMaximumFileSize:
      {
        // Maximum file size.
        long maxDataSize;
        {
          long mainFileSize = new java.io.File(mainFilePath).length();
          int kbMaxDataSize;
          do
          {
            try
            {kbMaxDataSize = Integer.parseInt(promptChoice("Max file size (KB): "));}
            catch(Exception e)
            {kbMaxDataSize = 0;}
          } while(kbMaxDataSize == 0);
          maxDataSize = kbMaxDataSize << 10;
          if(maxDataSize > mainFileSize)
          {maxDataSize = mainFileSize;}
        }

        // Split the document on maximum file size!
        List<Document> splitDocuments = new PageManager(mainDocument).split(maxDataSize);

        // Serialize the split files!
        int index = 0;
        for(Document splitDocument : splitDocuments)
        {serialize(splitDocument.getFile(), action, ++index, false);}
      } break;
    }

    return true;
  }

  private ActionEnum promptAction(
    )
  {
    ActionEnum[] actions = ActionEnum.values();
    Map<String,String> options = new HashMap<String,String>();
    for(ActionEnum action : actions)
    {options.put(Integer.toString(action.ordinal()), action.getDescription());}

    try
    {return actions[Integer.parseInt(promptChoice(options))];}
    catch(Exception e)
    {return actions[0];}
  }

  /**
    Serializes the specified PDF file.

    @param file File to serialize.
    @param action Generator.
  */
  private void serialize(
    File file,
    ActionEnum action
    )
  {serialize(file, action, null, true);}

  /**
    Serializes the specified PDF file.

    @param file File to serialize.
    @param action Generator.
    @param index File index.
    @param chooseMode Whether to allow user choice of serialization mode.
  */
  private void serialize(
    File file,
    ActionEnum action,
    Integer index,
    boolean chooseMode
    )
  {
    serialize(
      file,
      getClass().getSimpleName() + "_" + action.name() + (index != null ? "." + index : ""),
      chooseMode
      );
  }
}
TOP

Related Classes of org.pdfclown.samples.cli.PageManagementSample

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.