Generating HTML tables with XSLT

The following code snippet is a relatively simple and reusable implementation for generating HTML table content.

    <!-- The number of columns in the generated table -->
    <xsl:variable name="nColumns" select="3" />

    <!--
        XPath indexes start at 1, not 0. 'row' and 'column' template
        parameters therefore default to 1
    -->
    
    <xsl:template name="tableRows">
        <!-- The table content node list -->
        <xsl:param name="items" />
        <!-- The current row index -->
        <xsl:param name="row" select="1" />
        <!--
            Calculate the total number of rows based on the number of
            items and the number of columns
        -->
        <xsl:variable name="nRows" select="ceiling(count($items) div $nColumns)"></xsl:variable>
        <xsl:element name="tr">
            <xsl:call-template name="tableColumns">
                <xsl:with-param name="items" select="$items" />
                <xsl:with-param name="row" select="$row" />
            </xsl:call-template>
        </xsl:element>
         <!--
              There's no loop construct in XSLT so we simply increment
              the row index and call the template again if the current
              row index is less than the total number of rows
         -->
        <xsl:if test="$nRows > $row">
            <xsl:call-template name="tableRows">
                <xsl:with-param name="items" select="$items" />
                <xsl:with-param name="row" select="$row + 1" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template name="tableColumns">
        <!-- The table content node list -->
        <xsl:param name="items" />
        <!-- The current row index -->
        <xsl:param name="row" />
        <!-- The current column index -->
        <xsl:param name="column" select="1" />
        <!--
            Calculate the item index based on the current row and
            column index
        -->
        <xsl:variable name="itemIndex" select="(($row - 1) * $nColumns) + $column" />
        <xsl:element name="td">
            <!-- Check the item index is 'in bounds' -->
            <xsl:if test="count($items) >= $itemIndex">
                <xsl:call-template name="tableCellContent">
                    <xsl:with-param name="item" select="$items[$itemIndex]" />
                </xsl:call-template>
            </xsl:if>
        </xsl:element>
         <!--
              There's no loop construct in XSLT so we simply increment
              the column index and call the template again if the current
              column index is less than the specified number of columns
         -->
        <xsl:if test="$nColumns > $column">
            <xsl:call-template name="tableColumns">
                <xsl:with-param name="items" select="$items" />
                <xsl:with-param name="row" select="$row" />
                <xsl:with-param name="column" select="$column + 1" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template name="tableCellContent">
        <xsl:param name="item" />
        <!-- Generate content for the current item -->
        ...
    </xsl:template>
Tagged with: , , ,
Posted in XSLT

Eclipse 4.4.0 – Tool bar item visibility based on the currently active perspective

Displaying trimmed window tool bar items based on the currently active perspective in an Eclipse 4.4.0 RCP application would seem like a straightforward task but it actually involves a fair bit of tinkering and there are a few not so obvious pitfalls along the way.

After reading section 31.2 of Lars Vogel’s Eclipse 4 RCP tutorial the obvious approach was to associate a ‘visible-when’ expression with each of my perspective-specific tool bar items. The first problem I encountered was the fact that expressions are not evaluated for items added directly to the main tool bar (see Bug 400217). By ‘added directly’ I mean added as children of the tool bar element in the e4xmi application model. Luckily, when added as ToolBar Contributions visible-when expressions are evaluated as expected.

The next problem I encountered was how to determine the currently active perspective from within a visible-when expression. I couldn’t find any up to date documentation regarding the names of predefined context variables and none of the variables listed in Command Core Expressions were available in my Eclipse Luna 4.4.0 RCP application. To determine which context variables were available I added the following @CanExecute method to one of my tool bar item command handlers:

@CanExecute
public boolean canExecute(final IEclipseContext ictx) {
    final EclipseContext ctx = (EclipseContext) ictx.getParent();
    System.out.println("### START ###");
    for (final Entry<String, Object> entry : ctx.localData().entrySet()) {
        System.out.println(String.format("Key: '%s', value: '%s'", entry.getKey(), entry.getValue()));
    }
    System.out.println("### END ###");
    return true;
}

The following entry was included in the output from this method:

 Key: 'org.eclipse.e4.ui.model.application.ui.advanced.MPerspective', value: 'org.eclipse.e4.ui.model.application.ui.advanced.impl.PerspectiveImpl@2d778add (elementId: my.example.perspective.Edit, tags: [], contributorURI: platform:/plugin/my.example.application) (widget: Composite {}, renderer: org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveRenderer@7fc44dec, toBeRendered: true, onTop: false, visible: true, containerData: null, accessibilityPhrase: null) (label: Edit, iconURI: null, tooltip: , context: PerspectiveImpl (my.example.perspective.Edit) Context, variables: [])'

Based on this output I wrote the following following Property Tester to query the elementId of the active perspective:

/**
 * Property tester that checks the <code>elementId</code> of the currently active perspective
 */
public class PerspectivePropertyTester extends PropertyTester {

    /**
     * @param receiver the currently active {@link MPerspective}
     * @param property the property to test, in this case 'elementId'
     * @param args additional arguments, in this case an empty array
     * @param expectedValue the expected value of {@link MPerspective#getElementId()}
     */
    @Override
    public boolean test(final Object receiver, final String property, final Object[] args, final Object expectedValue) {
        final MPerspective perspective = (MPerspective) receiver;
        return perspective.getElementId().equals(expectedValue);
    }
}

This was then configured in plugin.xml as follows:

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
   ...
   <extension point="org.eclipse.core.expressions.propertyTesters">
      <propertyTester class="my.example.application.propertytester.PerspectivePropertyTester"
            id="my.example.application.propertytester.PerspectivePropertyTester"
            namespace="my.example.property"
            properties="perspectiveId"
            type="org.eclipse.e4.ui.model.application.ui.advanced.MPerspective">
      </propertyTester>
   </extension>
   <extension point="org.eclipse.core.expressions.definitions">
      <definition id="my.example.expression.isEditPerspective">
         <with variable="org.eclipse.e4.ui.model.application.ui.advanced.MPerspective">
            <test forcePluginActivation="true"
                  property="my.example.property.perspectiveId"
                  value="my.example.perspective.Edit">
            </test>
         </with>
      </definition>
      <definition id="my.example.expression.isPreviewPerspective">
         <with variable="org.eclipse.e4.ui.model.application.ui.advanced.MPerspective">
            <test forcePluginActivation="true"
                  property="my.example.property.perspectiveId"
                  value="my.example.perspective.Preview">
            </test>
         </with>
      </definition>
   </extension>
   ...
</plugin>

As a footnote I should also note that subscribing to UIEvents.UILifeCycle.PERSPECTIVE_OPENED events does not work as expected (see Bug 408681) so the above approach is probably the best option. You could, of course, set the visibility of tool bar items programmatically when switching perspective but this is far from ideal.

Tagged with: , , , , , , ,
Posted in Eclipse RCP

Installing Squid 3.0 on Fredora 11

  1. Install Squid in the normal fashion using yum or System -> Administration -> Add/Remove Software.
  2. Open the Squid configuration file by executing the following command:
    sudo gedit /etc/squid/squid.conf
  3. Change the value of the error_directory property so that it points to an actual directory. For example:
    error_directory /usr/share/squid/errors/English

    As opposed to

    error_directory /usr/share/squid/errors/en

    which didn’t exist on my system after the install had completed.

  4. If your current SELinux enforcing mode is set to "Enforcing" you’ll also need to perform the following steps.
  5. Create the following Type Enforcement file (the remaining steps assume the file name local.te):
    module local 1.0;
    
    require {
    	type var_run_t;
    	type unconfined_t;
    	type squid_t;
    	class file {open read getattr};
    	class process signal;
    }
    
    #============= squid_t ==============
    allow squid_t var_run_t:file {open read getattr};
    allow squid_t unconfined_t:process signal;

    N.B. The following steps will overwrite any existing module with the same name. To check if you already have a policy module called local go to System -> Administration -> SELinux Management, select "Policy Module" from the left-hand menu and enter "local" into the filter field. If you’ve already got a module called local simply edit the Type Enforcement file accordingly. For example:

    module mysquid 1.0;
  6. Edit accordingly, then execute the following script:
    dir=<your-dir-path>;
    sudo checkmodule -M -m -o $dir/local.mod $dir/local.te;
    sudo semodule_package -o $dir/local.pp -m $dir/local.mod;
    sudo semodule -i $dir/local.pp;

    N.B. The checkmodule command takes the Type Enforcement file, local.te, created in step 5 as its input.

  7. Got to System -> Administration -> Services. Start Squid.
  8. Cleanup any unwanted files created in steps 5 and 6.
Tagged with: , , , ,
Posted in Fedora

Unit Testing HTTPS Clients with a Self-signed Certificate

Overview

A quick and easy way to eliminate javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target without making dangerous changes to your default trust store.

Steps

  1. Create a new keystore and associated key entry by executing the following command (N.B. The password values for the -keypass and -storepass options must be identical for Tomcat to work):
    keytool -genkey -alias tomcat -keyalg RSA -keypass <password> -keystore <user-home>/tomcat.jks -storepass <password>
    
  2. Enter and confirm your details.
  3. Uncomment the “SSL HTTP/1.1 Connector” entry in $CATALINA_BASE/conf/server.xml.
  4. Add keystoreFile and keystorePass attributes with the appropriate values. The result should now resemble the following:
    <!-- Define a SSL HTTP/1.1 Connector on port 8443
    	This connector uses the JSSE configuration, when using APR, the
    	connector should be using the OpenSSL style configuration
    	described in the APR documentation -->
    
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
    	maxThreads="150" scheme="https" secure="true"
    	keystoreFile="${user.home}/tomcat.jks" keystorePass="<password>"
    	clientAuth="false" sslProtocol="TLS" />
    
  5. Restart Tomcat and deploy your HTTPS constrained resources.
  6. Add a @BeforeClass method to any tests generating HTTPS requests. Use this method to set the javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword system properties. For example:
    @BeforeClass
    public static void setUp() {
    	System.setProperty("javax.net.ssl.trustStore", "<user-home>/tomcat.jks");
    	System.setProperty("javax.net.ssl.trustStorePassword", "<password>");
    }
    
  7. JSSE now uses the new keystore created in steps 1 and 2 as opposed to the default, <java-home>/jre/lib/security/cacerts, trust store.
Tagged with: , , , , , , ,
Posted in Java EE Development

Scraping Sun Microsystems’ CertManager

Waiting for SCJD or SCEA results can be a bit of a pain. The lucky amongst you may get them in a couple of weeks. On the other hand, you could face a wait of up to six weeks.

To make life a little easier I decided to cobble together an HTML scraper to automate the checking process.

Figure 1. Screenshot

Although there are no binaries at this point in time, you can checkout the source code from SourceForge. For SVN details click the Develop tab.

Usage

According to the CertManager Test History page "tests are imported during regular business hours (GMT -07:00)".

Extending it

Adding your own service listener should be a pretty straightforward task: simply implement PropertyChangeListener and register with the service. As an example; if you live in a timezone other than GMT -07:00, and want to get notified ASAP, you could implement a listener to send an email, or SMS, once the specified test result has been found.

Tagged with: , , , , ,
Posted in Uncategorized

Rational Software Architect – Nested Node Instances

Section 10.3.7, Device (from Nodes), in the UML 2.2 specification contains the following deployment diagram (see page 206).

Figure 1 – Notation for a Device

Notation for a Device

Clearly, all the nodes in this diagram are instances. With this in mind, let’s try and recreate a similar diagram using Rational Software Architect 7.5.

Creating the AppServer and J2EEServer elements is pretty straightforward. A graphical representation of the model looks something like the following. In the example below I’ve added some attributes to the AppServer device to highlight the fact it’s an element specification, not an instance.

Figure 2 – Deployment Model

Deployment Model

If you selected the "Blank Deployment Package" template and default model capabilities in the model creation wizard, the ability to add node instances will be disabled. To remedy this you need to select the capabilities tab in the model properties panel and select the "UML Specific Instance Type 1" and "UML Specific Instance Type 2" options.

Figure 3 – Enabling Node Instances

Enabling Node Instances

Once this is done you can starting adding node instances to your deployment diagram. For example.

Figure 4 – Deployment Diagram

Deployment Diagram

The problems arise when you try and add nested nodes to the diagram because, basically, you can’t. As the following figure shows, the properties panel appearance tab options for showing textual and/or graphical nested node compartments are absent for node instances.

Figure 5 – Node Instance Properties

Node Instance Properties

Unfortunately, the help documentation is totally unhelpful as it contains the following section

Nesting nodes inside other nodes

In UML modelling, you can nest nodes within nodes to represent the hardware and software components in a system that contains other components.

A diagram must be open in the diagram editor, and the diagram must contain at least two nodes. The Nested Nodes compartment of the container node must be visible.

To nest a node in another node, in the diagram editor, click one node and drag it into the Nested Node compartment of another node.

As the following figure illustrates, a node named Node2 is displayed in the Nested Nodes Textual and Nested Nodes Graphical compartments of another node, named Node1.

Figure 6 – Rational Software Architect Help

Figure from Rational Software Architect Help

What they fail to mention is that none of this applies to node instances. I raised this with Rational Support and after a month’s deliberation they finally confirmed that nested node instances are not currently supported.

Tagged with: , , , , , , , , ,
Posted in UML

Rational Software Architect – Java to UML Transformations

Over the past few weeks I’ve been evaluating IBM’s Rational Software Architect (RSA) for WebSphere 7.5 . Whilst RSA is an incredibly powerful piece of software, there are a number of features that are conspicuous by their absence. Perhaps the most prominent of these is the inability of the Java to UML transformation to generate relationships other than Generalisation or Realisation. For example, it won’t generate Association or Usage elements. This makes it pretty useless when it comes to visualising the structure of existing code

You could argue that RSA’s raison d’etre is not the reverse engineering of UML models from Java code, but rather the architecture and development of new applications. This is true, but it misses the point as a number of RSA’s design contract management protocols (notably, "Reconciled Modelling" and "Conceptual Models Drive Development") rely on the reverse transformation of Java code.

According to Rational Support this issue has been logged as a request for enhancement, but when or if it makes it into a future release is anyone’s guess. In the meantime here’s an illustration of the problem.

Step 1 – Create a simple UML model with a composite aggregation navigable from both ends

Figure 1. Class diagram view

Class Diagram 1

Figure 2. Project explorer view

Model 1

Step 2 – Run a reconciled UML to Java transformation on the model

This produces the following java classes (minus the auto-generated comments):

Whole.java

package uml;

import java.util.Set;

public class Whole {

	private Set part;
}

Part.java

package uml;

public class Part {

	private Whole whole;
}

Step 3 – Comment out both private fields in the generated source and run the reverse transformation

As you’d expect, the composite aggregation relationship has now been deleted from the model.

Figure 3. Class diagram view

Class Diagram 2

Figure 4. Project explorer view

Model 2

Step 4 – Uncomment both fields and rerun the reverse transformation

Unfortunately this doesn’t produce the results you’d expect. Rather than explicitly creating an Association element in the UML model, the composite aggregation becomes implicit via the generated attributes for each class. By itself this isn’t a major drama, but it does introduce an inconsistency in your model if you have existing relationships that are modelled explicitly, as was originally the case. To visualise the recreated association you have to filter the attributes to "show as association". However, this only produces uni-directional associations which results in difficult to read diagrams full of unnecessary clutter and noise. The only workaround is to manually recreate the association in the model, which at best wastes time and at worst introduces errors.

Figure 4. Class diagram view (show as attribute)

Class Diagram 3

Figure 4. Class diagram view (show as association)

Class Diagram 4

Figure 5. Project explorer view

Model 3

Tagged with: , , , , , , ,
Posted in UML
Follow

Get every new post delivered to your Inbox.