Publication extensions let you customize the publication process. For example, you can use a post-delivery publication extension to clean up scope batches for high-volume publications. Or you can use a pre-delivery publication extension to include additional artifacts in the personalized publication content. An introduction to publication extension can be found in this blog post  by Christina Obry

There are three types of publication extensions:

  • Dynamic recipient data providers, which allow you to add publication recipients from an external data source.
  • Post-processing (pre-delivery) plugins, which allow you to add processing logic after publication contents have been personalized.
  • Distribution complete (post-delivery) plugins, which allow you to add processing logic after publication contents have been delivered. 

In this blog, I will demonstrate a post-processing (pre-delivery) plugin to password protect publication articrafts (pdf & excel). As it is a post processing plugin, it will encrypt the pdf and excel documents generated by a publication and will return the encrypted documents back to the publication for delivery. The recipients will get the password protected documents.

Below are the pre-requisites to implement this publication extension:

  • You need to have at least one other destination other than default destination selected in order to have the publication extension executed.
  • On the BOE server you need to have a D:\PubDemo\logs\ folder. If this folder is not there then the publication will fail as this is a hardcoded value.
  • The publication extension jar file need to be added in the BOE server in the following directory <Enterprise Dir> \java\lib\publishingPlugins. SIA has to be restarted after dropping the jar file.
  • IText: Java API to manipulate pdf Format Files. The required files are available here
  • POI-XSSF – Java API to manipulate Microsoft Excel Format Files. The required files are available here

Below is the source code for publication extension:


import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import com.businessobjects.publisher.postprocessing.IPublicationPostProcessingContext;
import com.businessobjects.publisher.postprocessing.IPublicationPostProcessingPlugin;
import com.businessobjects.publisher.postprocessing.PluginTargetDestination;
import com.crystaldecisions.sdk.occa.infostore.IDestinationPluginArtifactFormat;
import com.crystaldecisions.sdk.occa.infostore.IInfoObject;
import com.crystaldecisions.sdk.occa.infostore.IInfoObjects;
import com.crystaldecisions.sdk.plugin.CeProgID;
import com.crystaldecisions.sdk.occa.infostore.*;
import java.io.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.*;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import com.crystaldecisions.sdk.plugin.desktop.pdf.*;
import com.crystaldecisions.sdk.occa.infostore.*;
import java.io.IOException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class PasswordProtection implements IPublicationPostProcessingPlugin
{
public Collection getTargetDestinations() throws Exception
{
PluginTargetDestination inboxDestination = new PluginTargetDestination(CeProgID.MANAGED_DEST,
IDestinationPluginArtifactFormat.CeDistributionMode.FILTER_EXCLUDE_SOURCE_DOCUMENTS);
         PluginTargetDestination smtpDestination = new PluginTargetDestination(CeProgID.SMTP,
IDestinationPluginArtifactFormat.CeDistributionMode.FILTER_EXCLUDE_SOURCE_DOCUMENTS);
         PluginTargetDestination diskDestination = new PluginTargetDestination(CeProgID.DISKUNMANAGED,
IDestinationPluginArtifactFormat.CeDistributionMode.FILTER_EXCLUDE_SOURCE_DOCUMENTS);
         PluginTargetDestination ftpDestination = new PluginTargetDestination(CeProgID.FTP,
IDestinationPluginArtifactFormat.CeDistributionMode.FILTER_EXCLUDE_SOURCE_DOCUMENTS);
         PluginTargetDestination[] destinations = { inboxDestination, smtpDestination, diskDestination, ftpDestination };
         return Arrays.asList(destinations);
}
public IInfoObjects handle(IPublicationPostProcessingContext context) throws Exception
{
//Below line retrieves the password text specified while creating the publication
String password = context.getOptions().toString();
//Below is the path to log file for this plugin on BO server
FileWriter outFile = new FileWriter("D:\\PubDemo\\logs\\" + System.currentTimeMillis()+".log");
outFile.write("hello!\n");
ArrayList docs = context.getDocuments();
Iterator docIt = docs.iterator();
IInfoObjects objs = context.getInfoStore().newInfoObjectCollection();
outFile.write("hello1!\n");
while (docIt.hasNext())
{
IInfoObject obj = (IInfoObject)docIt.next();
outFile.write("next step is get kind!\n");
String kind=obj.getKind();
outFile.write(kind);
if(kind.equals("Pdf"))
{
outFile.write("inside if and pdf!\n");
IFiles files = (IFiles)obj.getFiles();
IFile file2=(IFile) files.get(0);
InputStream iStream = ((IRemoteFile)files.get(0)).getInputStream();
//Path to create a copy of original excel document in publication. This will create a temp excel file on BO server in order to enable password protection.
    OutputStream file = new FileOutputStream("D:\\12345678.pdf");
    PdfReader reader = new PdfReader(iStream);
    PdfStamper stamper=new PdfStamper(reader,file);
//Below line of code sets the password for temp pdf document
    stamper.setEncryption(password.getBytes(), password.getBytes(),PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
  stamper.close();
  reader.close();
  file.close();
/*Below line of code replaces the original pdf document with the password protected pdf document in temp directory and deletes the document in temp directory
after successfully replacing the original pdf file*/
file2=(IFile)files.replace(0,"D:\\12345678.pdf",true);
outFile.write(obj.getTitle() + "\n");
String newName = "Artifact - " + System.currentTimeMillis();
outFile.write("Renaming '" + obj.getTitle() + "' to " + newName);
}
else if (kind.equals("Excel"))
{
outFile.write("inside elseif and excel!\n");
IFiles files = (IFiles)obj.getFiles();
IFile file2=(IFile) files.get(0);
InputStream iStream = ((IRemoteFile)files.get(0)).getInputStream();
    POIFSFileSystem poiFileSystem = new POIFSFileSystem();
  EncryptionInfo info = new EncryptionInfo(poiFileSystem, EncryptionMode.standard);
  Encryptor enc = info.getEncryptor();
  enc.confirmPassword(password);
    OPCPackage opc = OPCPackage.open(iStream);
  OutputStream os = enc.getDataStream(poiFileSystem);
  opc.save(os);
  opc.close();
  //Path to create a copy of original excel document in publication. This will create a temp excel file on BO server in order to enable password protection.
    FileOutputStream fileOut = new FileOutputStream("D:\\12345678.xlsx");
  poiFileSystem.writeFilesystem(fileOut);
  fileOut.close();
/* Below line of code replaces the original excel document with the password protected pdf document in temp directory and deletes the document in temp directory
after successfully replacing the original excel file*/
    file2=(IFile)files.replace(0,"D:\\12345678.xlsx",true);
  outFile.write(obj.getTitle() + "\n");
  String newName = "Artifact - " + System.currentTimeMillis();
  }
objs.add(obj);
}
outFile.close();
//return method returns the password protected pdf, excel documents
return objs;
}
}

  • Copy the above code into a text file and save it as PasswordProtection.java. Please make sure that your java class name and file name should exactly be the same (case sensitive).
  • Compile the above java class by having all the jars required to run the file in the classpath. You can also use eclipse IDE to compile and create jar file. The list of jars can be found from the developers guide available at below links:
    • For BI 4.0:

               http://help.sap.com/businessobject/product_guides/boexir4/en/xi4_boejava_dg_en.zip

    • For XI 3.1

               http://help.sap.com/businessobject/product_guides/boexir31/en/boesdk_java_dg_12_en.zip

  • Refer to the section ‘JAR files needed for deployment of Business Objects Software’ from the above guides to get the list of jar files.
  • You would specifically need the jar files listed under ‘BusinessObjects Enterprise Java SDK’
  • Also, you would need  to add third party jar files IText and POI-XSSF jars to the classpath in order to compile above code.
  • Once you have compiled the code, create a jar file for the generated PasswordProtection.class file


For reference, I have attached encryption.jar file with this blog. However the file is attached with extension as .txt. You can download the file and then can change the extension to .jar.


Deployment Instructions:

  • Once we have created a jar file (Encryption.jar) using the above code, place Encryption.jar along with the third party jar files to the below mentioned path on BO server:

        <BOBJ_INST_DIR>\SAP BusinessObjects\SAP BusinessObjects EnterpriseXI 4.0 \ java\lib\publishingPlugins

         Note: In a clustered environment, jar files are required to be placed on each node in BO cluster at the mentioned path.

  • For your reference, here is the consolidated list of jar files that are required to be copied along with ‘Encryption.jar’ to the provided path:
    • IText Jars:
      • bcmail-jdk16-1.46.jar

      • bcprov-jdk16-1.46.jar

      • bctsp-jdk16-1.46.jar
      • itextpdf-5.2.1.jar

    • POI-XSSF Jars:
      • poi-3.12-20150511.jar

      • poi-ooxml-3.12-20150511.jar

      • poi-ooxml-schemas-3.12-20150511.jar

      • poi-scratchpad-3.12-20150511.jar

  • Restart Server Intelligence Agent (SIA)

         Note: In a clustered environment, all SIA’s in the cluster are required to be restarted


How to enable password protection plugin for an existing or new publication:

  • Login to CMC and navigate to the folder where the publication is located. Right click on the publication and click on properties.
  • Click on Additional options and select ‘Publication Extension’ in the left window pane as shown below:

         encryption.PNG

  • Below mentioned fields needs to be specified as:
    • Publication Extension Name: Enter text as per the business requirement (e.g. Test)
    • Class Name: PasswordProtection (Note: Copy and Paste the Exact text to this text box. Please do not specify any other text string in this text box as it will fail the publication schedule)
    • Parameter (optional): The text enter in this text box will act as password (case sensitive) for the generated pdf and excel documents

       After specifying text in the above highlighted fields, click on ‘Add’ Button for ‘Before Publication Delivery’ as highlighted in the above snapshot

       Click on Save & Close to save the changes to publication.

       Note: The option ”Publication Extension’ to integrate publication extension with a publication is only available in CMC and not BI Launchpad.

To report this post you need to login first.

3 Comments

You must be Logged on to comment or reply to a post.

  1. Amirul Hussain

    Hi Anchal,

    Currently i’m working to implement the project with the client that need to do the password encryption to pdf when publish the webi / crystal report.

    I’m refering this article here to to do the post-processing encryption method, however i’m encounter the error when trying to compile the above code.

    Below is the error that i had encounter

    error compile.png

    And below is the list of JAR file that i had use as the reference

    jar file.PNG

    FYI, currently i’m using the BO 4.1.

    I’m not sure either i had this error because there are some jar file missing or what,because i’m also could not found the pub_common.jar file in C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib.

    Hope you could tell me what i can do to eliminate the error above.

    Thanks

    (0) 

Leave a Reply