Need additional functionality for publications? Why not write your own custom publication extension?!
- 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.
Building and deploying custom post-processing (pre-delivery) publication extensions
Method | Description |
---|---|
handle |
This method is invoked one time for each destination and scope. It must return an IInfoObjects collection containing the artifacts created by the plugin that will be delivered to the recipients associated with the current destination and scope. The parameter is a com.businessobjects.publisher.postprocessing.IPublicationPostProcessingContext object, which contains information about the context, including the current scope and destination, and any parameters that were used to invoke the plugin.
|
getTargetDestinations |
This method must return a collection of com.businessobjects.publisher.postprocessing.PluginTargetDestination representing the destinations for which the plugin will be invoked.
|
Method | Description |
---|---|
getAdminLogAdapter() | This method returns a logger that can be used to log information during post-processing |
getDestination() | This method returns the current destination. |
getDocuments() | This method returns the static documents and schedulable document artifacts for the current scope and destination. |
getEnterpriseSession() | This method returns the session associated with the current user. |
getInfoStore() | This method returns an InfoStore object that can be used to query the BusinessObjects Enterprise repository. |
getOptions() | This method returns the generic parameter value, that was passed in through the CMC UI. |
getPluginArtifacts() | This method returns all artifacts that have been generated during the publishing process. |
getPublication() | This method returns the publication that invoked this plugin. |
getScopeFilter(IInfoObject doc) | This method returns IScopeFilter object that can be used to obtain personalization information |
getScopeID() | This method returns the ID of the current scope. |
getTempDirectory() | This method returns the path of the directory on the processing server that is used by BusinessObjects Enterprise for storing temporary files. |
The com.businessobjects.publisher.postprocessing.PostProcessingPluginHelper provides several static methods that can be used in post-processing plugins. For example, to add new artifacts, use createInfoObject method. The following code creates a text file info object.
ITxt textInfoObject = (ITxt) PostProcessingPluginHelper.createInfoObject(context, ITxt.PROGID, “text/plain”, null, null);
For detailed information on IPublicationPostProcessingPlugin, IPublicationPostProcessingContext, PluginTargetDestination, and PostProcessingPluginHelper, see the SAP BusinessObjects Business Intelligence Platform Java API Reference .
An example publication extension is posted at this blog post: Sample Publication Extension: Deliver shortcut to a BI platform folder based on personalization . This post processing publication extension creates a shortcut of the publication artifact in a folder based on the personalization. For example if you personalize on Country and have a folder for USA and Canada, then a shortcut for the publication artifact filtered to USA will be created in a USA folder, and a shortcut for the Canada document will be created in a Canada folder.
After the publication extension is built into a jar file, it needs to be deployed in the publication extensions directory. The default location of this directory is <Enterprise Dir>\java\lib\publishingPlugins. Once the extension was added, you have to restart the Adaptive Processing Server.
Adding a publication extensions to a publication
A publication extension can be added to a publication either programmatically or from the Central Management Console (CMC). The BI launch pad application does not allow you to specify publication extensions for a publication through the UI.
At this point it is assumed that you have already deployed the publication extension as described above on all computers that run the Adaptive Processing Server.
Below are the steps to add a publication extension via the CMC:
- Double-click a publication to open it. The “Properties” dialog box appears.
- Expand Additional Options, and click Publication Extension.
- In the Publication Extension Name box, type a name for the extension.
- In the Class Name box, type the fully qualified class name for the extension.
- (Optional) In the Parameter box, type a serialized string that your extension requires. What the parameter is would depend on how the extension was designed.
- To use the extension after processing but before delivery, above the Before Publication Delivery list, click the Add button. The extension is added to the Before Publication Delivery list.
- To use the extension after delivery, above the After Publication Delivery list, click the Add button. The extension is added to the After Publication Delivery list.
- Click Save.
- Repeat steps 2 to 8 for each extension you want to add.
To define the order in which to execute publication extensions, click Move Up or Move Down under the Before Publication Delivery list or the After Publication Delivery list.
As always great blog Christina, very useful and informative. Thanks a lot for sharing.
Regards,
Sohel
Thanks Sohel! this particular one was long over due ๐
The fruit of patience is sweet ๐
Excellent!!!
Thanks
Great and helpful article. I’ve created a basic publication extension that works. However, when I added additional functionality to it that requires external .JARs from a third-party, I can’t seem to get things to work. The publication log shows that it’s not able to find the necessary class. Short of putting the additional .JARs directly in to the <drive>\Program Files\Business Objects\common\4.0\java\lib\publishingPlugins directory I can’t seem to get it to work.
When I package my the third-party jars in my publishing plugin jar, it appears to ignore the class path and jars there. Is there any way to set the classpath for BO or have it find those jars without dumping them in the publishingPlugins directory?
It’s recommended to put all the custom jars (and dependencies) in <drive>\Program Files\Business Objects\common\4.0\java\lib\publishingPlugins because BOE will load all jars in that folder. This is how we avoid having to change the classpath.
Thanks,
Derrick
Also for the question on “When I package my the third-party jars in my publishing plugin jar, it appears to ignore the class path and jars there”, we only load classes inside jars inside the publishingPlugins folder. If you package 3rd party jars inside the publishing jars, it won’t be loaded. You can just put multiple jars (including the 3rd party ones) inside the publishingPlugins folder and it should work ๐ .
Cheers,
Derrick
Got a chance to check this only now. Amazing Christina.
In my publication I define output file name as %SI_NAME%_%SI_OWNER%.%EXT% . Please how do I capture SI_NAME, SI_OWNER (from profile) and EXT in publication extension? I already have a functional publication extension using online examples but these examples captures artifact titles internal to cms. I am interestes in the physical file names of the publications. Thanks.
Hi Christina,
We are in the process of updating our CE Enterprise ver 10 Server to BOBJ 4.1 SP2 (using BOE Xi 3.1 as the intermediate as one cannot migrate directly) and encountered a puzzling issue in the test environment when using BOBJ 4.1 SP2.
I am new to Crystal as a whole relatively speaking (~ 1 year) and so am finding this daunting, especially when I’m not familiar with java.
Here’s our issue:
A former staff many moons ago must have set up a custom SDK coding for the Crystal Enterprise ver 10 where there is a “hidden” parameter that would automatically pass the value of the User security groups (ie. If you belong to Security Group A), then “A” will pass to the “vUsername” parameter automatically when an individual runs a Crystal Report. The report would, based on this, only show Group A’s data. User belonging to Group B would then only see Group B’s data, etc. This is working fine in Crystal Enterprise ver 10, but on the newly set up BOBJ 4.1 SP2 CMS server, we could not get the value to pass automatically.
I’m assuming we need to add this with a publication extension somehow. Would you be able to assist or direct me on how to get this set up as we’ve been puzzling over this for awhile now and we need to get this resolved asap.
thx!
Hi Jeff,
I no longer work on this area. I suggest to contact support about this or post it as a discussion for others to see, not as a comment on a blog.
Thanks,
Christina
Am getting an error such as cannot instantiate the class. Class not found.
Any suggstions would be much appreciated.
Java Code:
import java.io.FileWriter;
import java.util.ArrayList;
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;
public class TestPublishingPostProcessingPlugin implements
IPublicationPostProcessingPlugin
{
public Collection getTargetDestinations() throws Exception
{
Collection pluginTargetDestinations = new ArrayList();
pluginTargetDestinations.add(new PluginTargetDestination(CeProgID.DISKUNMANAGED,
IDestinationPluginArtifactFormat.CeDistributionMode.FILTER_NONE));
pluginTargetDestinations.add(new PluginTargetDestination(null,
IDestinationPluginArtifactFormat.CeDistributionMode.FILTER_NONE));
return pluginTargetDestinations;
}
public IInfoObjects handle(IPublicationPostProcessingContext context) throws
Exception
{
FileWriter outFile = new FileWriter(“C:\\test\\PPLog” +
System.currentTimeMillis()+”.log”);
outFile.write(“hello!\n”);
ArrayList docs = context.getDocuments();
Iterator docIt = docs.iterator();
IInfoObjects objs = context.getInfoStore().newInfoObjectCollection();
while (docIt.hasNext())
{
IInfoObject obj = (IInfoObject)docIt.next();
outFile.write(obj.getTitle() + “\n”);
String newName = “Artifact – ” + System.currentTimeMillis();
outFile.write(“Renaming ‘” + obj.getTitle() + “‘ to ” + newName);
obj.setTitle(newName);
objs.add(obj);
}
outFile.close();
return objs;
}
}
Please referย 2386522 – Error: “Post-processing plugin failure! Cannot instantiate plugin class test.SafetyExtension. (FBE60208)” when scheduling publication with post processing plugin