Tuesday, November 24, 2009

Common Header and Footer with Sub Template – Part 2

Construct Reference URI Dynamically

When you reference the Sub-Template from the main template you need to specify an absolute path to the Sub-Template file with either the http or file option in the Import syntax. This is easy when you are developing your reports at your local machine or the development instance. However, sometimes you don’t know where the Sub-Template files will end up being located. For example, your production environment probably will be a different server and have a different directory (or folder) structure. So you don’t want to hard-code the http or file path to the Sub-Template, which you don’t know where it will be at for your deployment. Otherwise, you need to go visit each single RTF template file to update the location path.

There is a limitation that you cannot get a value from the XML data and assign it to the Import syntax. However, you can assign values from BI Publisher’s pre-defined properties or custom properties that you can create both at a server and a report level.

Today, I will go through the steps to make your File or HTTP path dynamic so that the Sub-Template implementation can be independent from any instance and be easier to maintain.

How to Construct URI with Property

Here is the default ‘import’ syntax where you set the absolute path to the Sub-Template file as we saw yesterday.

<?import:http://knishida-lap.us.oracle.com:9704/bip/Header_Sub.rtf?>

Now, you don’t know where the Header_Sub.rtf file will be at a testing or production environment. Or you might need to change the above server location in future. So you want to make the above path dynamic.

This is where the custom property comes in to rescue. I will show you how to set the custom property later, but for now, let’s assume we have a custom property called, ‘HTTPSERVER’, and the value is ‘knishida-lap.us.oracle.com:9704/bip’.

You can use a dollar sign and surround the property name with curly brackets (e.g. ${HTTPSERVER}) and embed it into the path like below.

Example :

<?import:http://${HTTPSERVER}/Header_Sub.rtf?>

When a value of the property ‘HTTPSERVER’ is set to ‘knishida-lap.us.oracle.com:9704/bip’ the above ‘import’ syntax will be dynamically constructed as

<?import:http://knishida-lap.us.oracle.com:9704/bip/Header_Sub.rtf?>

at the report generation time.

How to Set Custom Property

Now how to set the custom property?

Here is a list of the step on how to set the custom properties at the BI Publisher server level.

1. Create a custom configuration file, xdo.cfg, if you don’t have it yet, and add the following line.

<config version="1.0.0" xmlns="http://xmlns.oracle.com/oxp/config/">

<!-- Properties -->

<properties>

<property name="xslt.HTTPSERVER">'knishida-lap.us.oracle.com:9704/bip'</property>

</properties>

</config>

2. Place the xdo.cfg under %BIP_REPOSITORY_HOME%/Admin/Configuration

If your BI Publisher Repository root is ‘C:\OracleBI\xmlp\XMLP’ the xdo.cfg file should be located at

C:\OracleBI\xmlp\XMLP\Admin\Configuration

3. Restart the Application Server (e.g. OC4J) to take the property setting in effect.

Additionally, you can also set this property at the report level. In this case you can locate the xdo.cfg file at the same folder where the BI Publisher report definition file (.xdo) is located.

That’s it, now you are set with the custom property so try testing it!

When you need to deploy your reports to another instance like Testing or Production then you need to make sure that the custom property is set at the server level. Once the property is set then all the reports using the property in the Sub-Template import syntax should work without any hassle!

Lastly, there are some pre-defined properties that you can use in the import syntax. This can be useful especially when you have a different set of Sub-Template files for each language and you want to import an appropriate template based on the user’s session language setting.

Pre-Defined BI Publisher Property List

Here is a list of the BI Publisher’s pre-defined properties.

  • _XDOCALENDAR
  • _XDOLOCALE
  • _XDOTIMEZONE
  • _XDODFOVERRIDE
  • _XDOCURMASKS
  • _XDONFSEPARATORS
  • _XDOCHARTTYPE
  • _XDOOUTPUTFORMAT
  • _XDOSVGFONTEMBED
  • _XDOCTX

All the locale related properties values are coming from the user’s preference setting at the BI Publisher Server.

That’s it for today. Happy Thanks Giving!

24 comments:

  1. Doesn't work for me.

    At runtime, the variable is not converted.

    I get the message :
    java.io.FileNotFoundException: /{$HTTPSERVER}/Reports/eCad/Physician/headerFooter/headerFooter_fr.rtf (No such file or directory)

    What's the problem please?

    ReplyDelete
  2. Check if the variable is set correctly and the values is passed to your RTF template by following the 'How to See What Property Values are Passed in RTF Template?' section at this post.
    http://bipconsulting.blogspot.com/2010/01/bi-publisher-logging-debugging-part-4.html

    ReplyDelete
  3. We are getting an error when trying this method. Could you please tell us what we are doing wrong?



    Servers xdo.cfg:
    ================



    false
    'C:/Tools/oc4j_extended_101350/XMLP/Reports'
    C:/Tools/oc4j_extended_101350/XMLP/Reports



    ******
    Case 1
    ******

    TestVariables rtf template file contains:
    =========================================

    Test Guy variables:



    Bip Result:
    ===========

    Test Guy variables:

    xslt.CURRENT_SERVER_SCHEME='http'
    xslt.BIP_REPORT_HOME_Q='C:/Tools/oc4j_extended_101350/XMLP/Reports'
    html-image-dir=C:\Tools\oc4j_extended_101350\j2ee\home\applications\BiPublisher\xmlpserver\xdo/tmp/
    fo-external-link-target=_blank
    html-css-dir=C:\Tools\oc4j_extended_101350\j2ee\home\applications\BiPublisher\xmlpserver\xdo/tmp/
    system-temp-dir=C:\Tools\oc4j_extended_101350\j2ee\home\applications\BiPublisher\xmlpserver\xdo/tmp/
    xslt.XDO_USER_ROLES='XMLP_TEMPLATE_DESIGNER,XMLP_ANALYZER_EXCEL,XMLP_ADMIN,XMLP_ANALYZER_ONLINE,XMLP_DEVELOPER,XMLP_SCHEDULER'
    xslt.CURRENT_SERVER_PORT='8888'
    xdk-secure-io-mode=false
    xslt.CURRENT_SERVER_URL='http://ict-0225:8888/xmlpserver/'
    fo-external-link-base-url='http://ict-0225:8888/xmlpserver/'
    xslt.XDO_USER_NAME='administrator'
    xslt._XDOCHARTTYPE='image/png'
    xslt.CURRENT_SERVER_CONTEXT_PATH='xmlpserver'
    xslt._XDOOUTPUTFORMAT='text/html'
    html-css-base-uri=http://ict-0225:8888/xmlpserver/xdo/tmp
    xslt._FURL='http://ict-0225:8888/xmlpserver/~administrator/Test/'
    xslt._xdo_user='administrator'
    xslt._xt='Template1'
    html-image-base-uri=http://ict-0225:8888/xmlpserver/xdo/tmp/
    xslt.CURRENT_SERVER_NAME='ict-0225'
    xslt.BIP_REPORT_HOME=C:/Tools/oc4j_extended_101350/XMLP/Reports
    xslt._xf='html'
    xslt._XDOLOCALE='en-US'
    xdodebug.LogDir=C:/Tmp/Log


    ******
    Case 2
    ******

    TestHeaderSub rtf template file contains:
    =========================================


    Bip error message:
    ==================

    [011410_023813741][oracle.apps.xdo.common.xml.XSLTWrapper][ERROR] XSL error:

    : XML-22002: (Fatal Error) Error while processing include XSL file (rtf2xsl://file_//${BIP_REPORT_HOME}/Header_Su
    b.rtf?sid=1&eaf=3).

    ReplyDelete
  4. Almost, your variable name is wrong. Looks you used BIP_REPORT_HOME_Q to set the path. Change your template to use BIP_REPORT_HOME_Q.

    ReplyDelete
  5. Ok, I had defined 2 variables:
    BIP_REPORT_HOME with a value of c:/Tools/...
    and a variable BIP_REPORT_HOME_Q with a value of 'c:/Tools/...'
    They both look to have the same value, but one is single quoted and the other one is not. They both do not work.

    <?import:file://${BIP_REPORT_HOME}/Header_Sub.rtf?>

    <?import:file://${BIP_REPORT_HOME_Q}/Header_Sub.rtf?>


    Is there some other setting that I should/could verify?

    ReplyDelete
  6. Since my rtf file is stored in the database, I try to use a servlet here to pull the file. I did,



    However, BI Publisher gives back a error message as follows,

    oracle.xdoparser.v2.XMLParseException: start of root element expected

    It seems like that BI Publisher is not happy with ? used in URL. Do you know what the correct way is to do this?

    ReplyDelete
  7. Since my rtf file is stored in Oracle database, I used a servlet to pull the file. I did



    However, BI Publisher gives back an error as follows,

    oracle.xdoparser.v2.XMLParseException: start of root element expected

    It seems like BI Publisher doesn't like ? in the URL. Do you know what the correct way is to do this? Thanks.

    ReplyDelete
  8. Hi Anonymous, just realized that your syntax is missing one slash. It should be

    import:file:///${BIP_REPORT_HOME}/Header_Sub.rtf

    ReplyDelete
  9. Hi Mommy,

    I also had a same situation some time back and had to get a RTF template from a blog column in the database. It worked fine, I don't think I needed to do anything extra. Make sure it works fine with the file on a http server first. Then make sure you can get the RTF file from the db correctly. Also test with not using the variable in the import clause.

    ReplyDelete
  10. Hello,

    We are using BIP 10.1.3.4.1. We would like to use subtemplates to define common features across most of our reports. To implement this, we created one dummy report and added template rtf. We started (using absolute path) referring this rtf location (hardcoded path) in all of our other BIP reports.

    But, instead of hard coding the whole path, we wanted to use variables to define the report path (like BIP_RPT_HOME) in the server settings (xdo.cfg) and use it in all our reports.

    Step 1:

    'C:\OracleBI\XMLP\Reports'


    Step 2:


    This does not seem to work because of the following two reasons.

    1) Per BIP documentation, "import" statement should be the first statement in the rtf or xsl.
    2) We can't use parameters/variables until we define it in the template. Here we are trying to use BIP_RPT_HOME which is not declared/defined yet in the rtf (because of above point)

    Any help will be highly appreciated.

    Thanks,
    Ashok

    ReplyDelete
  11. hmm... this is exactly I'm talking about at this post. Please read this post again.

    ReplyDelete
  12. Hi Kan,
    Thanks for reply! I read the blog again. I am not sure where and what I miss.

    I have defined the custom Property in xdo.cfg. Following is my xdo.cfg (since I am not able to enter comments in the blog with xml tags, I have added extra spaces in the tag)

    < properties >
    < property name="xslt.BIP_RPT_HOME">'C:\OracleBI\XMLP\Reports'< /property >
    < property name="xdk-secure-io-mode" >false< /property >< /properties >


    2) I am using an import statement as a first element in the rtf file. Following is the statement I have used.

    < ?import:file:///${BIP_RPT_HOME}\Points Table\Points Table.rtf ? >

    Note: I dint define any variable for BIP_RPT_HOME in the RTF file.

    3) I restarted the OC4J Server. When I ran the report, I get the following error.

    [031910_083212737][oracle.apps.xdo.template.FOProcessor][STATEMENT] Start Memory: max=508MB, total=37MB, free=13MB
    [031910_083212737][oracle.apps.xdo.template.FOProcessor][STATEMENT] FOProcessor.generate() called.
    [031910_083212752][oracle.apps.xdo.template.FOProcessor][STATEMENT] createFO(Object, Object) is called.
    [031910_083212768][][STATEMENT] WARNING: Found undetermined AttrKey: style-name
    [031910_083212877][oracle.apps.xdo.common.xml.XSLT10gR1][STATEMENT] Oracle XML Developers Kit 10.1.0.5.0 - Production
    [031910_083212877][oracle.apps.xdo.common.xml.XSLT10gR1][STATEMENT] Scalable Feature Disabled
    [031910_083212955][oracle.apps.xdo.common.xml.XSLTWrapper][ERROR] XSL error:

    : XML-22002: (Fatal Error) Error while processing include XSL file (rtf2xsl://file_///${BIP_RPT_HOME}\Points Table\Points Table.rtf?sid=1&eaf=3).

    [031910_083212955][oracle.apps.xdo.template.FOProcessor][STATEMENT] clearInputs(Object) is called.
    [031910_083212955][oracle.apps.xdo.template.FOProcessor][STATEMENT] clearInputs(Object) done. All inputs are cleared.
    ....
    at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
    at java.lang.Thread.run(Thread.java:619)
    aused by: java.io.FileNotFoundException: \${BIP_RPT_HOME}\Points Table\Points Table.rtf (The system cannot find the path specified)
    at oracle.xdo.parser.v2.XSLProcessor.reportException(XSLProcessor.java:806)
    at oracle.xdo.parser.v2.XSLProcessor.newXSLStylesheet(XSLProcessor.java:571)
    ... 33 more

    From the error, it is clear that BIP_RPT_HOME is not resolved to C:\OracleBI\XMLP\Reports.

    Please let me know which piece from this blog I am missing? Appreciate your time.

    Thanks,
    Ashok

    ReplyDelete
  13. Hi Kan,
    Thanks for reply! I read the blog again. I am not sure where and what I miss.

    I have defined the custom Property in xdo.cfg. Following is my xdo.cfg

    Note: I have padded with spaces (in the following list) since I could not post the XML tags in this blog.

    < config version="1.0.0" xmlns="http://xmlns.oracle.com/oxp/config/ ">
    < !-- Properties -- >
    < properties >
    < property name="xslt.BIP_RPT_HOME" >'C:\OracleBI\XMLP\Reports'< /property >
    < property name="xdk-secure-io-mode">false< /properties >
    < /config >


    2) I am using an import statement as a first element in the rtf file. Following is the statement I have used.

    < ?import:file:///${BIP_RPT_HOME}\Points Table\Points Table.rtf? >

    Note: I dint define any variable for BIP_RPT_HOME in the RTF file.

    3) I restarted the OC4J Server. When I ran the report, I get the following error.

    [031910_083212737][oracle.apps.xdo.template.FOProcessor][STATEMENT] Start Memory: max=508MB, total=37MB, free=13MB
    [031910_083212737][oracle.apps.xdo.template.FOProcessor][STATEMENT] FOProcessor.generate() called.
    [031910_083212752][oracle.apps.xdo.template.FOProcessor][STATEMENT] createFO(Object, Object) is called.
    [031910_083212768][][STATEMENT] WARNING: Found undetermined AttrKey: style-name
    [031910_083212877][oracle.apps.xdo.common.xml.XSLT10gR1][STATEMENT] Oracle XML Developers Kit 10.1.0.5.0 - Production
    [031910_083212877][oracle.apps.xdo.common.xml.XSLT10gR1][STATEMENT] Scalable Feature Disabled
    [031910_083212955][oracle.apps.xdo.common.xml.XSLTWrapper][ERROR] XSL error:

    : XML-22002: (Fatal Error) Error while processing include XSL file (rtf2xsl://file_///${BIP_RPT_HOME}\Points Table\Points Table.rtf?sid=1&eaf=3).

    [031910_083212955][oracle.apps.xdo.template.FOProcessor][STATEMENT] clearInputs(Object) is called.
    [031910_083212955][oracle.apps.xdo.template.FOProcessor][STATEMENT] clearInputs(Object) done. All inputs are cleared.
    ....
    at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
    at java.lang.Thread.run(Thread.java:619)
    aused by: java.io.FileNotFoundException: \${BIP_RPT_HOME}\Points Table\Points Table.rtf (The system cannot find the path specified)
    at oracle.xdo.parser.v2.XSLProcessor.reportException(XSLProcessor.java:806)
    at oracle.xdo.parser.v2.XSLProcessor.newXSLStylesheet(XSLProcessor.java:571)
    ... 33 more

    From the error, it is clear that BIP_RPT_HOME is not resolved to C:\OracleBI\XMLP\Reports.

    Please let me know which piece from this blog I am missing? Appreciate your time.

    Thanks,
    Ashok

    ReplyDelete
  14. Try the following command in your RTF template to see what value is exactly returned for your variable.

    < ? xdoxslt:getXDOProperties($_XDOCTX)? >

    Check this post for the detail of the command.
    http://bipconsulting.blogspot.com/2010/01/bi-publisher-logging-debugging-part-4.html

    Also, you might want to start with something simple, e.g. just use a report name for the variable.

    ReplyDelete
  15. I put the custom property definition to where BI Publisher report definition file is located (like /server/Report_name/xdo.cfg), but I get an error saying that the variable is not defined. When I but it in the report folder do I still have to restart the server? Or am I missing something else?

    ReplyDelete
  16. Evelyn, as mentioned in this post you need to place the xdo.cfg file under %BIP_REPOSITORY_HOME%/Admin/Configuration and need to restart.

    ReplyDelete
  17. But you also said "Additionally, you can also set this property at the report level. In this case you can locate the xdo.cfg file at the same folder where the BI Publisher report definition file (.xdo) is located." Is there any difference when I set the property on server or report level? I'm asking because I can't access the admin part of it all, but I do have access to my report folders.

    ReplyDelete
  18. Hi!

    I have put the property in the server level into xdo.cfg file, restarted the server and with < ? xdoxslt:getXDOProperties($_XDOCTX)? >
    it shows me that the xslt.HTTPSERVER has the right path (the path is correct, cause the import with that path works fine). But when I but the ${HTTPSERVER} to the import statement it is giving me an error. It seems that it is not taking the property into account in the import. I'm not sure what i'm missing here...

    ReplyDelete
  19. Should this approach also work with BIP Desktop?

    I have tried the import statement using a custom property and the ${property} syntax. It appears that BIP Desktop is not expanding the value and is taking it as a literal. I know my property is being read as I can output it I have tested with both BIP Desktop 10.1.3.4 and 10.1.3.4.1 with the same result. Built-in properties such as _XDOTIMEZONE are also not expanded.

    I am using embedded BIP in JD Edwards with BIP Desktop as the design tool. As the JDE Embedded version is 10.1.3.3.2 I understand that this feature may not be present. However I am puzzled that it doesn't work in the latest BIP Desktop.

    Can you point to a document that states from what releases parameter expansion in the import statement is supported?

    ReplyDelete
  20. Those parameters only work with the online mode, those values are directly coming from BIP Server.

    ReplyDelete
  21. For some reason an error is thrown if you use the full "http://knishida-lap.us.oracle.com:9704/bip/" in lieu of "knishida-lap.us.oracle.com:9704/bip/" to define HTTPSERVER. I would have liked the import to look like this: .

    ReplyDelete
  22. Thanks your blog has been tons of help in the past.

    On this issue I am unable to get this to work. I have defined the variable in xdo.cfg and restarted the server. I used < ? xdoxslt:getXDOProperties($_XDOCTX)? > to get the list of properties and it returned the property I set.

    xslt.REPORTREPOSITORYPATH='\\\XMLP\Reports\SiebelCRMReports'
    xslt._xf='rtf'
    xslt.XDO_USER_NAME='us95707'
    xslt.XDO_USER_ROLES='Siebel Administrator,XMLP_ADMIN,XMLP_SCHEDULER,XMLP_DEVELOPER,Premera New Views,Premera Admin Change Role'
    xslt._xdo_user=''
    xslt._XDOOUTPUTFORMAT='text/html'
    html-css-dir=D:\OraHome_1\oc4j_bi\j2ee\home\applications\xmlpserver\xmlpserver\xdo/tmp/
    xslt._XDOLOCALE='en-US'
    xslt._xt='SiebelTemplate'
    system-temp-dir=D:\OraHome_1\oc4j_bi\j2ee\home\applications\xmlpserver\xmlpserver\xdo/tmp/
    html-image-dir=D:\OraHome_1\oc4j_bi\j2ee\home\applications\xmlpserver\xmlpserver\xdo/tmp/
    xslt._XDOCHARTTYPE='image/png'
    fo-external-link-target=_blank
    xdk-secure-io-mode=false
    xdodebug.LogDir=D:\OraHome_1\oc4j_bi\log\xdo

    When I try to use


    it fails with the following error:
    : XML-22002: (Fatal Error) Error while processing include XSL file (rtf2xsl://file_///${REPORTREPOSITORYPATH}\importfile\importfile.rtf?sid=1&eaf=3).

    Any help would be great.

    Is there a way to just print one property not all the properties?

    Thanks,
    Justin

    ReplyDelete
  23. Hello Kanichiro,

    I am working conditional templates logic in header, boday and footer. It is working fine for me. the only issue i have is it prints a blank page at the end. i adjusted margins, header and footer but unable to figure why a blank page is generated. Thak you in advance for your help.

    ReplyDelete
  24. Hi,
    first i would like to thank you as this blog is helping us a lot. I am able to call sub templates with the static URl in Import statement but after applying HTTPserver property statement in xdo.cfg file and then applying in import statement it is ending with an error. for checking i have applied
    in template and i am able to get same response for HTTPSERVER as that of static URL. so could you please help me out if some thing else need to be done.

    ReplyDelete