HOWTO: stream response with struts 2 that works in IE6

Web browser
Image via Wikipedia

Sometimes I had to display a dinamically generated file to the browser without save it locally on the server where I produce it.

HTTP allows you all of this, but browsers implemented the feature in different ways, so here I will report a method for sending a stream of binary data to a browser that works for every browser, in particular IE6.

The environment I use for this example is:

The struts.xml fragment for the action that rertieves the bytes and send them to the browser is as follows:

<action name="getFile" class="my.app.ExportFileAction" method="getFile">
    <result type="stream" name="success">
        <param name="contentType">${mimeType}</param>
        <param name="inputName">exportStream</param>
        <param name="contentDisposition">attachment; filename=${fileName}</param>
    </result>
</action>

The getFile() method of the my.app.ExportFileAction class is as follows:

public String getFile() {
  try {
    exportStream = new ByteArrayInputStream(getFileContent());
    mimeType = "application/pdf"; // in this example I use PDF mime
    fileName = "ExportedFile.pdf"; // the name we want to be proposed in the Save as... dialog
  } catch (Exception e) {
    return ERROR;
  }
  return SUCCESS;
}

exportStream, mimeType and fileName are members of my JavaBean Action class, each of which must have its getter and setter:

 protected String mimeType;
 protected String fileName;
 protected InputStream exportStream;

getFileContent() will be the method that retrieves the bytes of your file to send to the browser; here I will report only the method signature:

 private byte[] getFileContent() {}

HOWTO: JS triggered link showing a DIV with LightBox

 Questo articolo è disponibile anche in italiano.

To use Lightbox to display the content of a DIV instead of an image can be not so straightforward.
In my example, to obtain the desired effect, I used the scsLightbox  jQuery plug-in. This makes easier to interact with page elements.
Here are brief instruction on how to do it:

  1. Download jQuery and the scsLightbox plug-in
  2. Link in your page the jQuery script of the desired version (I tested for this example the 1.4.2 and 1.5.2 releases), the plugin script, and the CSS bundled with the plug-in:
<script type="text/javascript"
     src="MyScripts/jquery/jquery-x.y.z.min.js"></script>
<script type="text/javascript"
     src="MyScripts/scsLightbox/jquery.scslightbox.js"></script>
<link rel="stylesheet" type="text/css" 
     href="MyStyles/scsLightbox/jquery.scslightbox.css">
  1. We want to activate the lightbox clicking a link, so we need the link, and the DIV with the content we want to disply in the LightBox; the link will not have a content because it will only be an anchor that we will activate it from JS:
<a id="link-content-div" href="#content-div"></a>
  <div id="content-div" style="display: none;">
    Il contenuto del nostro div.
  </div>
</div>
DIV is initially hidden. Note that the href link’s attribute point to the DIV’s selector: this is the same selector we would use in CSS to style the DIV.
  1. Now, we want to display the content-div in the LightBox and define the JS function we can call to activate the LighBox. To find DOM elements and activate the link we use jQuery:
<script type="text/javascript">
  $(function() {
    $('#link-content-div').scsLightbox();
  });
  function ShowContentDiv() {
    $('#link-content-div').trigger('click');
  }
</script>

This trick is quite simple and useful, because it allows you to display whatever HTML you want in a LightBox.

As an alternative you can try to use FancyBox to do the same work.

HOWTO: get a recordset result from a PL/SQL Function

 Questo articolo è disponibile anche in italiano.

How to get a recordset result from a parametric query in PL/SQL in one command?

At first, I thought:

  • It should be useful to use a view but…. We can’t “pass” parameters to a view; a view could read some information from the SYS_CONTEXT or from a table where to store the parameter, but in this way the commands used would be complicated ad we should involve a transaction, isolation of the parameter etc.
  • I may use a procedure but… A procedure can’t return a recordset; it can return a cursor, that cannot be directly “viewed” but rather used by another procedure or PL/SQL code that loops thorugh it.
So, here comes the solution. We may use OBJECT TYPES and PIPELINED FUNCTIONS.
A pipelined function, can return a collection of objects, each of which will be rendered as a record of a table in the resulting recordset; so we have to define this object and the relative collection object in PL/SQL:
    CREATE OR REPLACE
    TYPE O_MY_OBJECT AS OBJECT (
      MY_DATE                       DATE
    , MY_NUMBER                     NUMBER
    , MY_VARCHAR                    VARCHAR2(20)
    );

    CREATE OR REPLACE
    TYPE T_MY_OBJECT AS TABLE OF O_MY_OBJECT;
Then, we can declare a function as PIPELINED and say it will return the previously defined collection type and, in the function body, create the objects (the record) and send them to the output with PIPE ROW():
    FUNCTION MY_FUNCTION(V_MY_PARAM IN VARCHAR2)
      RETURN  T_MY_OBJECT
      PIPELINED
    AS
    V_MY_OBJ_VAR O_MY_OBJECT := O_MY_OBJECT(null, null, null);
    BEGIN
          SELECT
                SYSDATE
              , 10
              , 'CIAO MONDO! -> ' || V_MY_PARAM
          INTO
              V_MY_OBJ_VAR.MY_DATE
            , V_MY_OBJ_VAR.MY_NUMBER
            , V_MY_OBJ_VAR.MY_VARCHAR
          FROM
              DUAL;

          PIPE ROW(V_MY_OBJ_VAR);

      RETURN;
    END MY_FUNCTION;
Let’s go deep in some detail:
  • V_MY_OBJ_VAR O_MY_OBJECT := O_MY_OBJECT(null, null, null); => I define a variable and init it with the object’s default constructor
  • INTO clause => set the desired values (in this case some constant value) in my object’s properties
  • PIPE ROW(V_MY_OBJ_VAR) => send the object to output
If we have to work with rows returned by a parametric query that we want to execute inside the pipelined function, we can declare and LOOP through a cursor and, at every loop cycle, build a new object instance and send it to the output with PIPE ROW.
In the end, to call this function and get the final result, we must use the PL/SQL TABLE function:
     SELECT * FROM TABLE(MY_FUNCTION('SAMPLE VALUE'));
The result, will be a grid of results usable as a table or a view.

HOWTO: using multi column keys in MyBatis Sql maps

When you have to deal with a Third normal form (3NF) relational database, you almost always fall in two scenarios:

  • a DB with natural keys as the primary keys of your data
  • a DB with surrogate keys with auto generated integer identities or GUIDs
Said that I prefer to model with the “more normalized” first approach, this results in a more complicated way to query the DB with multiple condition ON clauses in Joins, more and best designed indexes to have good performance, higher skill to develop, maintain and query the DB.
With this approach you can however manage historical data (with the change of the date part of a composite key), you can easily implement inheritance and extension and so on.
Another issue to be aware of,  is that when you opt for the first approach you may have to deal with Object Relational libraries such as MyBatis(Net) I’m talking about here.
When you use MyBatis you can express your relation through the SELECT attribute in the RESULT tag of the RESULTMAP definition.
Suppose we have the following master/detail table definition:
MASTER(M_KEY1, M_KEY2, M_ATTR1, M_ATTR2)
DETAIL(D_KEY1, D_ATTR1, D_FK_M_KEY1, D_FK_M_KEY2)
And you have the following two mapping Classes:
class Master {
    string key1;
    string key2;
    string attr1;
    string attr2;
    List<Detail> details;
}
class Detail {
    string key1;
    string atttr1;
    Master master;
}
Then you can define two result maps:
<resultMaps>
  <resultMap id="masterResult" class="Master">
    <result property="key1" column="M_KEY1" />
    <result property="key2" column="M_KEY2" />
    <result property="attr1" column="M_ATTR1" />
    <result property="attr2" column="M_ATTR2" />
  </resultMap>
  <resultMap id="detailResult" class="Detail">
    <result property="key1" column="D_KEY1" />
    <result property="attr1" column="D_ATTR1" />
  </resultMap>
</resultMaps>
Now you should use the SELECT attribute of the RESULT tag to make MyBatis automatically load the detail list related to a master or a master related to a details and eventually use the LAZYLOAD attribute to defer the execution of the subquery.
The SELECT attribute is used in conjunction with a COLUMN attribute in which you can specify the column to use as the parameter for selection; in our case we have TWO columns, so how this affect the use of SELECT, COLUMN and PARAMETERCLASS?
The multi column mapping of SELECT subqueries is based on Maps/Dictionaries so the mechanism is to build a Map/Dictionary from more than one column to use as a parameter for another query; to the masterResult map we can add:
<result property="details" column="MAP_KEY1=M_KEY1,MAP_KEY2=M_KEY2" select="details.byMaster" />
And in the detailResult map we can similarly add:
<result property="master" column="MAP_KEY1=D_FK_M_KEY1,MAP_KEY2=D_FK_M_KEY2" select="master.byKey" />
The two select statements master.byKey and details.byMaster should be something like this:
<select id="master.byKey" resultMap="masterRes" { parameterClass="System.Collections.IDictionary" (for .NET) OR parameterClass="java.util.Map" (for Java) } >
  SELECT *
  FROM MASTER
  WHERE M_KEY1=#MAP_KEY1# AND M_KEY2=#MAP_KEY2#
</select>
<select id="details.byMaster" resultMap="detailRes" { parameterClass="System.Collections.IDictionary" (for .NET) OR parameterClass="java.util.Map" (for Java) } >
  SELECT *
  FROM DETAIL
  WHERE D_FK_M_KEY1=#MAP_KEY1# AND D_FK_M_KEY2=#MAP_KEY2#
</select>
And that’s it!
Hope some of you may find this helpful.

HOWTO: using ServingXML in a Maven project

ServingXML is a powerful library to transform data from one format to another format by using a XML resource to define the transformation.

ServingXML comes with a console app, and also documents an API for embedding the software in a standard Java or J2EE application.

Apache Maven logo.
Image via Wikipedia

So, I decided to use this library in an enterprise integration application where normally I use Apache Maven for the Lifecycle Management. In the public Maven repos I couldn’t find the ServingXML dependency so I built a POM by myself tring to find which dependencies of ServingXML are present on public Maven repos and which are not.

Firstly I downloaded the latest version of ServingXML and extracted it on a local directory.

I adjusted the build-extensions.xml file as follows to obtain a minimal version of the library:

<project basedir="." default="build.extensions">
  <target name="build.extensions">
    <ant antfile="build.xml" dir="servingxml-msv" target="${ext.target}"/>
    <ant antfile="build.xml" dir="servingxml-saxon" target="${ext.target}"/>
    <ant antfile="build.xml" dir="servingxmlx" target="${ext.target}"/>
  </target>
</project>

So I had in my target/servingxml directory the built binary with dependenies in the lib folder. I figured out that some jar was the result of a transitive dependency so I decided to add progressively the libraries to my project using the install goal and then build and run tests to see if it worked.

Finally I obtained this POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.servingxml</groupId>
  <artifactId>servingxml</artifactId>
  <version>1.1.2</version>
  <description>Artifactory auto generated POM</description>
<dependencies>
        <dependency>
           <groupId>net.sourceforge.saxon</groupId>
           <artifactId>saxon</artifactId>
           <version>9.1.0.8</version>
        </dependency>
        <dependency>
            <groupId>isorelax</groupId>
            <artifactId>isorelax</artifactId>
            <version>20030108</version>
        </dependency>
        <dependency>
            <groupId>com.sun.msv.datatype.xsd</groupId>
            <artifactId>xsdlib</artifactId>
            <version>2011.1</version>
        </dependency>
        <dependency>
            <groupId>com.servingxml</groupId>
            <artifactId>msv</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.servingxml</groupId>
            <artifactId>saxon</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.servingxml</groupId>
            <artifactId>x</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>
</project>

This, properly uploaded in my Artifactory toghether with the deployment of all Ant generated jars, gave me the opportunity to build with Maven “minimal embedded ServingXML” applications within my organization.

HOWTO: using a java regex to match XML processing instructions

Some days ago, searching for a regex pattern to match a XML processing instruction, I found a nice tool that helped me to build one (increasingly often I’m so lazy that I don’t want to open a regex reference and build & test it myself, but I want to be spoon-fed…).

So, the nice tool is Regex Magic; nice interface to build and test regural expression strings…

Uh, and finally, the Java regex to match the XML PI I used is as follows:


"<\\?xml[^>?]+\\?>"

Cheers!

Ottenere un recordset da una Function PL/SQL

 This article is available in english language too.

Tempo fa sono incappato in un problema con Oracle. Come ottenere un recordset da una query parametrica in PL/SQL in un solo comando?

Le prime risposte cui si potrebbe pensare sono:

  • Uso una vista a cui passo un paramtero: non si possono passare parametri ad una vista; una vista potrebbe al massimo leggere un parametro dal SYS_CONTEXT o da una tabella di appoggio, ma in questo modo non si riuscirebbe in un solo comando ad ottenere il risultato
  • Uso una procedure; una procedure non può restituire un recordset; l’unico oggetto simile che può restituire è un cursore, che più che essere “visualizzato” dovrebbe essere poi utilizzato da una qualche altra procedura (PL/SQL o client che sia)
La tipologia di oggetto che risolve questo specifico problema è l’uso degli OBJECT TYPES e delle FUNCTION PIPELINED.
Una funzione pipelined può restituire una collezione di oggetti ognuno dei quali verrà restituito come un record nel recordset risultante; per definire un nuovo oggetto e la relativa collezione in PL/SQL avremo:
    CREATE OR REPLACE
    TYPE O_MY_OBJECT AS OBJECT (
      MY_DATE                       DATE
    , MY_NUMBER                     NUMBER
    , MY_VARCHAR                    VARCHAR2(20)
    );

    CREATE OR REPLACE
    TYPE T_MY_OBJECT AS TABLE OF O_MY_OBJECT;
Quindi, una volta definiti questi due tipi, si può dichiarare una funzione PIPELINED che restituisca il tipo collezione e nel suo body creare gli oggetti (i record) e mandarli in output con l’istruzione PIPE ROW():
    FUNCTION MY_FUNCTION(V_MY_PARAM IN VARCHAR2)
      RETURN  T_MY_OBJECT
      PIPELINED
    AS
    V_MY_OBJ_VAR O_MY_OBJECT := O_MY_OBJECT(null, null, null);
    BEGIN
          SELECT
                SYSDATE
              , 10
              , 'CIAO MONDO! -> ' || V_MY_PARAM
          INTO
              V_MY_OBJ_VAR.MY_DATE
            , V_MY_OBJ_VAR.MY_NUMBER
            , V_MY_OBJ_VAR.MY_VARCHAR
          FROM
              DUAL;

          PIPE ROW(V_MY_OBJ_VAR);

      RETURN;
    END MY_FUNCTION;
Vediamo i particolari della funzione:
  • V_MY_OBJ_VAR O_MY_OBJECT := O_MY_OBJECT(null, null, null); => Definisco una variabile e la inizializzo con il costruttore dell’oggetto
  • Parte INTO => inserisco i valori desiderati (in questo caso delle costanti) nelle proprietà del mio oggetto
  • PIPE ROW(V_MY_OBJ_VAR) => mando in output al recordset il mio oggetto
Per avere righe che vengono da una query parametrica, è sufficiente costruire un cursore e in un LOOP costruire le istanze di oggetti di cui si farà il PIPE ROW.
Infine per richiamare la funzione così costruita ed avere il risultato finale, è necessario utilizzare la funzione TABLE di PL/SQL:
     SELECT * FROM TABLE(MY_FUNCTION('SAMPLE VALUE'));
Il risultato, sarà una griglia in tutto e per tutto utilizzabile come una tabella, o una vista.