27.4. Custom images, JSP files, and other resources

27.4.1. Javascript and stylesheets
27.4.2. X-JSP files

Some times your extension may need other resources. It can for for example be an icon, a javascript file, a JSP file or something else. Fortunately this is very easy. You need to put the extension in a JAR file. As usual the extension definition XML file should be at META-INF/extensions.xml. Everything you put in the JAR file inside the resources/ directory will automatically be extracted by the extension system to a directory on the web server. Here is another "Hello world" example which uses a custom JSP file to display the message. There is also a custom icon.


<extensions xmlns="http://base.thep.lu.se/extensions.xsd">
   <extension
      id="net.sf.basedb.clients.web.menu.extensions.hellojspworld"
      extends="net.sf.basedb.clients.web.menu.extensions"
      >
      <index>4</index>
      <about safe-scripts="1" safe-resources="1">
         <name>Hello JSP world</name>
         <description>
            This example uses a custom JSP file to display the
            "Hello world" message instead of a javascript popup.
         </description>
      </about>
      <action-factory>
         <factory-class>
            net.sf.basedb.clients.web.extensions.menu.FixedMenuItemFactory
         </factory-class>
         <parameters>
            <title>Hello JSP world!</title>
            <tooltip>Opens a JSP file with the message</tooltip>
            <data-url>$HOME$/hello_world.jsp?ID=$SESSION-ID$</data-url>
            <data-popup>HelloJspWorld, 400, 300</data-popup>
            <icon>~/images/world.png</icon>
         </parameters>
      </action-factory>
   </extension>
</extensions>

The JAR file should have have the following contents:

META-INF/extensions.XML
resources/hello_world.jsp
resources/images/world.png

When this extension is installed the hello_world.jsp and world.png files are automatically extracted to the web servers file system. Each extension is given a unique HOME directory to make sure that extensions doesn't interfere with each other. The URL to the home directory is made available in the $HOME$ variable. All factory settings that have been annotated with the VariableSetter will have their values scanned for $HOME$ which is replaced with the real URL. It is also possible to use the $ROOT$ variable to get the root URL for the BASE web application. Never use /base/... since users may install BASE into another path.

The tilde (~) in the <icon> tag value is also replaced with the HOME path. Note that this kind of replacement is only done on factory settings that have been annotated with the PathSetter annotation and is only done on the first character.

The safe-resources="1" attribute in the <about> tag is used to tell BASE that all resource files doesn't use inline scripts or event handlers. This is the default setting and don't have to be included. On the other hand, if safe-resources="0" is specified BASE uses a less restrictive content security policy for that extension that allows the use of inline scripts. This setting is not recommended but can be useful during a transition phase while the extensions code is being updated.

[Note] Note

Unfortunately, the custom JSP file can't use classes that are located in the extension's JAR file. The reason is that the JAR file is not known to Tomcat and Tomcat will not look in the plugins.dir folder to try to find classes. There are currently two possible workarounds:

  • Place classes needed by JSP files in a separate JAR file that is installed into the WEB-INF/lib folder. The drawback is that this requires a restart of Tomcat.

  • Use an X-JSP file instead. This is an experimental feature. See Section 27.4.2, “X-JSP files” for more information.

27.4.1. Javascript and stylesheets

It is possible for an extension to use a custom javascript or stylesheet. However, this doesn't happen automatically and may not be enabled for all extension points. If an extension needs this functionality the action factory or renderer factory must call JspContext.addScript() or JspContext.addStylesheet() from the prepareContext() method.

The AbstractJspActionFactory and AbstractJspRendererFactory factory can do this. All factories shipped with BASE extends one of those classes and we recommend that custom-made factories also does this.

Factories that are extending one of those two classes can use <script> and <stylesheet> tags in the <parameters> section for an extensions. Each tag may be used more than one time. The values are subject to path and variable substitution.


<action-factory>
   <factory-class>
      ... some factory class ...
   </factory-class>
   <parameters>
      <script>~/scripts/custom.js</script>
      <stylesheet>~/css/custom.css</stylesheet>
      ... other parameters ...
   </parameters>
</action-factory>

If scripts and stylesheets has been added to the JSP context the extension system will, in most cases, include the proper HTML to link in the requested scripts and/or stylesheet.

[Note] Use UTF-8 character encoding

The script and stylesheet files should use use UTF-8 character encoding. Otherwise they may not work as expected in BASE.

[Note] All extension points doesn't support custom scripts/stylesheets

In some cases the rendering of the HTML page has gone to far to make is possible to include custom scripts and stylesheets. This is for example the case with the extensions menu. Always check the documentation for the extension point if scripts and stylesheets are supported or not.

27.4.2. X-JSP files

The drawback with a custom JSP file is that it is not possible to use classes from the extension's JAR file in the JSP code. The reason is that the JAR file is not known to Tomcat and Tomcat will not look in the plugins.dir folder to try to find classes.

One workaround is to place classes that are needed by the JSP files in a separate JAR file that is placed in WEB-INF/lib. The drawback with this is that it requires a restart of Tomcat. It is also a second step that has to be performed manually by the person installing the extension and is maybe forgotten when doing an update.

Another workaround is to use an X-JSP file. This is simply a regular JSP file that has a .xjsp extension instead of .jsp. The .xjsp extension will trigger the use of a different compiler that knows how to include the extension's JAR file in the class path.

[Note] X-JSP is experimental

The X-JSP compiler depends on functionality that is internal to Tomcat. The JSP compiler is not part of any open specification and the implementation details may change at any time. This means that the X-JSP compiler may or may not work with future versions of Tomcat. We have currently tested it with Tomcat 8.0.21 only. It will most likely not work with other servlet containers.

Adding support for X-JSP requires that a JAR file with the X-JSP compiler is installed into Tomcat's internal /lib directory. It is an optional step and not all BASE installations may have the compiler installed. See Section 22.1.4, “Installing the X-JSP compiler”.