Search This Blog

Tuesday, 15 December 2009

Open Office Macro

 Here comes a macro for Open Office Writer, written in StarBasic.
It aims at realizing a sort of constraint logic between controls in a form.

In the first part there is a data structure which specify all the constraints
on three controls, where the first two a comboboxes and the last is a text area.

In the second part there is the handler for the "onChange" event,
which loads data according to the specifications in the data structure.

REM  *****  BASIC  *****
'data block
' tabella dependenciesTable(objName, value, dependentObj, valueSetID)
' Primary Key: objName, value, dependentOb
' associa per ogni oggetto 'objName'
' un oggetto dipendente 'dependentObj' che assumerĂ 
' il set di valori identificato da 'valueSetID' (vedere tabella valueSets)
' quando l'oggetto 'objName' assumerĂ  il valore 'value'
Global dependenciesTable(2, 3) As String

' tabella valueSets(valueSetID, value)
' Primary Key: valueSetID, value
' associa per ogni valueSetID un set di valori
Global valueSets(6, 1) As String
Sub Init
    dependenciesTable(0, 0) = "cb1"
    dependenciesTable(0, 1) = "uno"
    dependenciesTable(0, 2) = "cb2"
    dependenciesTable(0, 3) = "1"
    dependenciesTable(1, 0) = "cb1"
    dependenciesTable(1, 1) = "due"
    dependenciesTable(1, 2) = "cb2"
    dependenciesTable(1, 3) = "2"
    dependenciesTable(2, 0) = "cb1"
    dependenciesTable(2, 1) = "tre"
    dependenciesTable(2, 2) = "cb3"
    dependenciesTable(2, 3) = "3"

    valueSets(0, 0) = "1"
    valueSets(0, 1) = "obj1ValPerUno1"
    valueSets(1, 0) = "1"
    valueSets(1, 1) = "obj1ValPerUno2"
    valueSets(2, 0) = "1"
    valueSets(2, 1) = "obj1ValPerUno3"
    valueSets(3, 0) = "2"
    valueSets(3, 1) = "obj1ValPerDue1"
    valueSets(4, 0) = "2"
    valueSets(4, 1) = "obj1ValPerDue2"
    valueSets(5, 0) = "2"
    valueSets(5, 1) = "obj1ValPerDue3"
    valueSets(6, 0) = "3"
    valueSets(6, 1) = "selezionato il valore tre"

End Sub
'end of data block

'engine block
Sub Main
End Sub
' ritorna nel parametro values il set dei valori
' da assegnare a un oggetto dependentObj
' quando l'oggetto ctrlName vale selectedVal
' il set di valori ritornati dipendono da che valore ha assunto il controllo che ha scatenato l'evento
' secondo le tabelle dependenciesTable e valueSets
Sub getValueSet(ctrlName As String, selectedVal As String, dependentObj As String, values)
    Dim valueId As String
    Dim firstTime As Integer
    firstTime = 1
    Dim last As Integer
    last = 0
    'selezione dell'id dei valori, nella tabella valueSets
    For I = 0 To UBound(dependenciesTable)
        If dependenciesTable(I, 0) = ctrlName AND dependenciesTable(I, 1) = selectedVal AND dependenciesTable(I, 2) = dependentObj Then
            valueId = dependenciesTable(I, 3) ' id dei valori selezionato
            Exit For
        End If

    ' ricerca dei valori in valueSets in base all'id
    For I = 0 To UBound(valueSets)
        If valueSets(I, 0) = valueId Then
            If FirstTime = 0 Then
                last = last + 1
                Redim Preserve values(last)
            End If
            values(last) = valueSets(I, 1)
        End If
        firstTime = 0
End Sub
' ritorna nel parametro res l'elenco degli oggetti dipendenti
' dal controllo ctrlName quando il suo valore è ctrlValue
' i controlli di questo elenco dipendono da che valore ha assunto il controllo che ha scatenato l'evento
' secondo la tabella dependenciesTable
Sub getDependentObjsId(ctrlName As String, ctrlValue As String, res)
    Dim firstTime As Integer
    firstTime = 1
    Dim last As Integer
    last = 0
    For I = 0 To UBound(dependenciesTable)
        If dependenciesTable(I, 0) = ctrlName AND dependenciesTable(I, 1) = ctrlValue AND res(last) <> dependenciesTable(I, 2) Then 'last clause helps in preventing from inserting duplicates (not guaranteeing)
            If FirstTime = 0 Then
                last = last + 1
                Redim Preserve res(last)
            End If
            res(last) = dependenciesTable(I, 2)
        End If
        firstTime = 0
End Sub
 Sub OnChangeValue(oEvent)
    oControl = oEvent.Source.Model
     oForm = oControl.Parent
    Dim valueId As String
    Dim depObjs(0) As String
    'popola l'array depObjs con l'elenco dei controlli dipendenti dall'evento corrente
    getDependentObjsId(oControl.Name,  oControl.Text, depObjs)
    Dim textVar As String
    For I = 0 To UBound(depObjs) ' per ogni elemento dipendente
        Dim listValues(0)
        listValues(0) = ""
        getValueSet(oControl.Name, oControl.Text, depObjs(I), listValues) 'valori
        For K = 0 to oForm.Count - 1
            If oForm.getByIndex(K).Name = depObjs(I) Then
                If hasProperty(oForm.getByIndex(K), "StringItemList") = 1 Then 'ComboBox
                    oForm.getByIndex(K).StringItemList = listValues
                    oForm.getByIndex(K).Text = ""
                Else 'altro caso
                    textVar = ""
                    For valIdx = 0 To UBound(listValues)
                        textVar = "" & textVar & listValues(valIdx)
                    oForm.getByIndex(K).Text = textVar
                End If
                Exit For
        Next K

 End Sub
 Function hasProperty( oObj, prop )
   oIntrospection = createUnoService( "" )
   oObjInfo = oIntrospection.inspect( oObj )
   oProperties = oObjInfo.getProperties( )
   For i = LBound( oProperties ) To UBound( oProperties )
      oProperty = oProperties( i )
      cPropertyName = oProperty.Name
      If cPropertyName = prop Then
          hasProperty() = 1
          Exit Function
      End If
   hasProperty() = 0
End Function
'end of engine block

Saturday, 12 December 2009

Linux keyboard remapping on X server

  • use xev to retrieve keycodes
  • use xmodmap  to load a remapping file
  • use the command setxkbmap to restore a keyboard setting, ex.
    the command "setxkbmap it" restore the it keyboard

Thursday, 10 December 2009

Oracle parse number

how to parse as a number the string 1670.0000

note that the substring ., is enclosed within single quotes

Wednesday, 9 December 2009

inspect Oracle db

to get a full list of all the objects in the data dictionary:

select * from dictionary order by table_name

show database version and parameters
select * from v$version
select * from nls_database_parameters

V$ Views

Thursday, 3 December 2009

Linux, information about the distribution

suppose you are asked to take care of a Linux system you've never seen before, and nobody is able to tell anything about it, at first you can get some information about the distribution and the kernel by using the commands

cat /etc/*-release
uname -a

Friday, 27 November 2009

OpenOffice API, a generic document inspector

Here comes a useful program to inspect the content of a document (Open Office .odt or Microsoft Word .doc) in order to read paragraphs, text sections, bookmarks, text fields, forms and tables.

package docreader;

import java.util.ArrayList;

import org.apache.log4j.Logger;


public class DocReaderParser {

    private static Logger logger = Logger.getLogger(DocReaderParser.class);

    public DocReaderParser() {

    private String classifyFormComponentType(XPropertySet xComponent,
            String name, DocumentModel documentModel) throws Exception {
        String sType = "";
        XServiceInfo xSI = (XServiceInfo) UnoRuntime.queryInterface(
                XServiceInfo.class, xComponent);
        XPropertySetInfo xPSI = null;
        if (null != xComponent) {
            xPSI = xComponent.getPropertySetInfo();
             * Property ps[] = xPSI.getProperties(); for (int i = 0; i <
             * ps.length; i++) { logger.debug("ps " + ps[i].Name); }

        XPropertySet xCompProps = (XPropertySet) UnoRuntime.queryInterface(
                XPropertySet.class, xComponent);

        if ((null != xPSI) && xPSI.hasPropertyByName("ClassId")) {
            // get the ClassId property
            Short nClassId = (Short) xCompProps.getPropertyValue("ClassId");
            switch (nClassId.intValue()) {
            case FormComponentType.COMMANDBUTTON:
                sType = "Command button";
            case FormComponentType.RADIOBUTTON:
                sType = "Radio button";
            case FormComponentType.IMAGEBUTTON:
                sType = "Image button";
            case FormComponentType.CHECKBOX:
                sType = "Check Box";
            case FormComponentType.LISTBOX:
                sType = "List Box";
                short[] selectedItems = (short[]) xCompProps
                String[] items = (String[]) xCompProps
                if (items != null && items.length > 0) {
                    ArrayList selectedItemsModelList = new ArrayList();
                    for (int item_idx = 0; item_idx < selectedItems.length; item_idx++) {
                        if (selectedItems[item_idx] > -1
                                && selectedItems[item_idx] < items.length) {
                            logger.debug("property SelectedItems[" + item_idx
                                    + "]: " + items[selectedItems[item_idx]]);
                        }// if
                    }// for
                    if (selectedItemsModelList.size() > 0) {
            case FormComponentType.COMBOBOX:
                sType = "Combo Box";
            case FormComponentType.GROUPBOX:
                sType = "Group Box";
            case FormComponentType.FIXEDTEXT:
                sType = "Fixed Text";
            case FormComponentType.GRIDCONTROL:
                sType = "Grid Control";
            case FormComponentType.FILECONTROL:
                sType = "File Control";
            case FormComponentType.HIDDENCONTROL:
                sType = "Hidden Control";
            case FormComponentType.IMAGECONTROL:
                sType = "Image Control";
            case FormComponentType.DATEFIELD:
                sType = "Date Field";
            case FormComponentType.TIMEFIELD:
                sType = "Time Field";
            case FormComponentType.NUMERICFIELD:
                sType = "Numeric Field";
            case FormComponentType.CURRENCYFIELD:
                sType = "Currency Field";
            case FormComponentType.PATTERNFIELD:
                sType = "Pattern Field";
            case FormComponentType.TEXTFIELD:
                // there are two known services with this class id: the usual
                // text field,
                // and the formatted field
                sType = "Text Field";
                logger.debug("property Text: "
                        + xCompProps.getPropertyValue("Text"));
                documentModel.addFormElement(name, ""
                        + xCompProps.getPropertyValue("Text"));
                if ((null != xSI)
                        && xSI
                                .supportsService("")) {
                    sType = "Formatted Field";
        } else {
            if ((null != xSI)
                    && xSI
                            .supportsService("")) {
                sType = "Form";
        return sType;

    private XDrawPage getDocumentDrawPage(XComponent m_xDocument)
            throws java.lang.Exception {
        XModel s_aDocument = (XModel) UnoRuntime.queryInterface(XModel.class,
        XDrawPage xReturn;
        // in case of a Writer document, this is rather easy: simply ask the
        // XDrawPageSupplier
        XDrawPageSupplier xSuppPage = (XDrawPageSupplier) UnoRuntime
                .queryInterface(XDrawPageSupplier.class, s_aDocument);
        xReturn = xSuppPage.getDrawPage();
        if (null == xReturn) {
            // the model itself is no draw page supplier - then it may be an
            // Impress or Calc
            // (or any other multi-page) document
            XDrawPagesSupplier xSuppPages = (XDrawPagesSupplier) UnoRuntime
                    .queryInterface(XDrawPagesSupplier.class, s_aDocument);
            XDrawPages xPages = xSuppPages.getDrawPages();
            xReturn = (XDrawPage) UnoRuntime.queryInterface(XDrawPage.class,
            // Note that this is not really error-proof code: If the document
            // model does not support the
            // XDrawPagesSupplier interface, or if the pages collection returned
            // is empty, this will break.
        return xReturn;

    private XNameContainer getFormComponentTreeRoot(
            throws java.lang.Exception {
        XFormsSupplier xSuppForms = (XFormsSupplier) UnoRuntime.queryInterface(
                XFormsSupplier.class, getDocumentDrawPage(m_xDocument));
        XNameContainer xFormsCollection = null;
        if (null != xSuppForms) {
            xFormsCollection = xSuppForms.getForms();
        return xFormsCollection;

    private void enumerateFormComponents(XNameAccess xContainer,
            String sPrefix, DocumentModel documentModel)
            throws java.lang.Exception {
        // loop through all the element names
        String aNames[] = xContainer.getElementNames();

        for (int i = 0; i < aNames.length; ++i) {
            // print the child name
                    + " recognized element, name: " + sPrefix + aNames[i]);

            XPropertySet xModelProps = (XPropertySet) UnoRuntime
                    .queryInterface(XPropertySet.class, xContainer
            logger.debug("classifyFormComponentType: "
                    + classifyFormComponentType(xModelProps, aNames[i],

            // check if it is a FormComponents component itself
            XServiceInfo xSI = (XServiceInfo) UnoRuntime.queryInterface(
                    XServiceInfo.class, xContainer.getByName(aNames[i]));
            if (xSI.supportsService("")) {
                XNameAccess xChildContainer = (XNameAccess) UnoRuntime
                        .queryInterface(XNameAccess.class, xSI);
                enumerateFormComponents(xChildContainer, new String(" ")
                        + sPrefix, documentModel);

    private void enumerateTextComponents(XComponent xComp,
            DocumentModel documentModel) throws NoSuchElementException,
            WrappedTargetException, UnknownPropertyException {
        // query the new document for the XTextDocument interface
        XTextDocument xTextDocument = (XTextDocument) UnoRuntime
                .queryInterface(XTextDocument.class, xComp);
        XText xText = xTextDocument.getText();
        // Get Access to the TextFields in the document
        XTextFieldsSupplier xTextFieldsSupplier = (XTextFieldsSupplier) UnoRuntime
                .queryInterface(XTextFieldsSupplier.class, xComp);
        XEnumerationAccess xEnumeratedFields = xTextFieldsSupplier
        XEnumeration enumeration = xEnumeratedFields.createEnumeration();
        // Loop through the TextFields
        while (enumeration.hasMoreElements()) {
            Object field = enumeration.nextElement();
            XDependentTextField dependentTextField = (XDependentTextField) UnoRuntime
                    .queryInterface(XDependentTextField.class, field);
            XPropertySet propertySet = dependentTextField.getTextFieldMaster();
            String name = (String) propertySet.getPropertyValue("Name");
            logger.debug("textfield name name " + name);
            XPropertySetInfo propertysetInfo = propertySet.getPropertySetInfo();
            Property properties[] = propertysetInfo.getProperties();
            for (int i = 0; i < properties.length; i++) {
                logger.debug("prop " + properties[i].Name);
        // enumerate paragraphs
        logger.debug("create an enumeration of all paragraphs");
        XEnumeration xParagraphEnumeration = null;
        XEnumerationAccess xParaEnumerationAccess = null;
        XEnumeration xTextPortionEnum;
        XTextContent xTextElement = null;
        // create an enumeration access of all paragraphs of a document
        XEnumerationAccess xEnumerationAccess = (XEnumerationAccess) UnoRuntime
              , xText);
        xParagraphEnumeration = xEnumerationAccess.createEnumeration();

        // Loop through all paragraphs of the document
        while (xParagraphEnumeration.hasMoreElements()) {
            logger.debug("------------------------------- new paragraph");

            xTextElement = (XTextContent) UnoRuntime.queryInterface(
                    XTextContent.class, xParagraphEnumeration.nextElement());

            XServiceInfo xServiceInfo = (XServiceInfo) UnoRuntime
                    .queryInterface(XServiceInfo.class, xTextElement);

            String[] services = xServiceInfo.getSupportedServiceNames();
            for (int si = 0; si < services.length; si++) {
                logger.debug("service " + services[si]);

            // check if the current paragraph is really a paragraph or an
            // anchor of a frame or picture
            if (xServiceInfo.supportsService("")) {
                XTextRange xTextRange = xTextElement.getAnchor();
                logger.debug("This is a Paragraph");

                // create another enumeration to get all text portions of
                // the paragraph
                xParaEnumerationAccess = (XEnumerationAccess) UnoRuntime
                        .queryInterface(XEnumerationAccess.class, xTextElement);
                xTextPortionEnum = xParaEnumerationAccess.createEnumeration();

                while (xTextPortionEnum.hasMoreElements()) {
                    XTextRange xTextPortion = (XTextRange) UnoRuntime
                            .queryInterface(XTextRange.class, xTextPortionEnum
                    logger.debug("Text from the portion : "
                            + xTextPortion.getString());

                    XPropertySet xPropertySet = (XPropertySet) UnoRuntime
                            .queryInterface(XPropertySet.class, xTextPortion);
                    logger.debug("font name: "
                            + xPropertySet.getPropertyValue("CharFontName"));

                    // PropertyState status of each text portion.
                    XPropertyState xPropertyState = (XPropertyState) UnoRuntime
                            .queryInterface(XPropertyState.class, xTextPortion);

                    if (xPropertyState.getPropertyState("CharWeight").equals(
                                .debug("-  The text range contains more than one different attributes");

                    if (xPropertyState.getPropertyState("CharWeight").equals(
                        logger.debug(" - The text range contains hard formats");

                    if (xPropertyState.getPropertyState("CharWeight").equals(
                                .debug(" - The text range doesn't contains hard formats");
            } else if (xServiceInfo
                    .supportsService("")) {
                logger.debug("this is a table");
            } else {
                logger.debug("The text portion isn't a text paragraph");
        }// while

    private void enumerateBookmarks(XComponent xComp,
            DocumentModel documentModel) throws NoSuchElementException,
            WrappedTargetException {
        // accessing the bookmark collection of the document
        XBookmarksSupplier xBookmarksSupplier = (XBookmarksSupplier) UnoRuntime
                .queryInterface(XBookmarksSupplier.class, xComp);
        if (xBookmarksSupplier != null) {
            XNameAccess xNamedBookmarks = xBookmarksSupplier.getBookmarks();
            String bookmarks[] = xNamedBookmarks.getElementNames();
            Object bookmark = null, previousBookmark = null;
            for (int b = 0; b < bookmarks.length; b++) {
                if (bookmark != null) {
                    previousBookmark = bookmark;
                bookmark = xNamedBookmarks.getByName(bookmarks[b]);

                // we need its XTextRange which is available from
                // getAnchor(),
                // so query for XTextContent
                XTextContent xBookmarkContent = (XTextContent) UnoRuntime
                        .queryInterface(XTextContent.class, bookmark);
                // get the anchor of the bookmark (its XTextRange)
                XTextRange xBookmarkRange = xBookmarkContent.getAnchor();

                if (previousBookmark != null) {
                    XTextRange x_previousBookmarkRange = ((XTextContent) UnoRuntime

                // set the bookmark text
                // xBookmarkRange.setString("test");

                logger.debug("bookmark " + bookmarks[b] + ", text "
                        + xBookmarkRange.getString());
                documentModel.addBookmark(bookmarks[b], xBookmarkRange

    private void enumerateTables(XComponent xComp, DocumentModel documentModel)
            throws IndexOutOfBoundsException, WrappedTargetException,
            UnknownPropertyException {
        // first query the XTextTablesSupplier interface from our document
        XTextTablesSupplier xTablesSupplier = (XTextTablesSupplier) UnoRuntime
                .queryInterface(XTextTablesSupplier.class, xComp);
        // get the tables collection
        XNameAccess xNamedTables = xTablesSupplier.getTextTables();
        // now query the XIndexAccess from the tables collection
        XIndexAccess xIndexedTables = (XIndexAccess) UnoRuntime.queryInterface(
                XIndexAccess.class, xNamedTables);
        // we need properties
        XPropertySet xTableProps = null;
        // get the tables
        for (int i = 0; i < xIndexedTables.getCount(); i++) {
            Object table = xIndexedTables.getByIndex(i);
            logger.debug("------------------------- recognized table ");

            // the properties
            xTableProps = (XPropertySet) UnoRuntime.queryInterface(
                    XPropertySet.class, table);
            Property props[] = xTableProps.getPropertySetInfo().getProperties();
            for (int props_idx = 0; props_idx < props.length; props_idx++) {
                // logger.debug("table props " + props[props_idx].Name + ", "
                // + xTableProps.getPropertyValue(props[props_idx].Name));

            XTextTable xTextTable = (XTextTable) UnoRuntime.queryInterface(
                    XTextTable.class, table);

            XTableRows rows = xTextTable.getRows();
            XTableColumns columns = xTextTable.getColumns();

            XCellRange cellRange = (XCellRange) UnoRuntime.queryInterface(
                    XCellRange.class, table);

            ArrayList righe = new ArrayList();

            for (int row_idx = 0; row_idx < rows.getCount(); row_idx++) {
                logger.debug("scanning row# " + row_idx);
                String colonna[] = new String[columns.getCount()];
                for (int col_idx = 0; col_idx < columns.getCount(); col_idx++) {

                    // WARNING: the first parameter is the column, the
                    // second
                    // parameter is the row
                    XCell xCell = cellRange.getCellByPosition(col_idx, row_idx);
                    XText xCellText = (XText) UnoRuntime.queryInterface(
                            XText.class, xCell);
                    logger.debug("cell (" + col_idx + "," + row_idx + "): "
                            + xCellText.getText().getString());
                    colonna[col_idx] = xCellText.getText().getString();

                    + xTableProps.getPropertyValue("LinkDisplayName"), righe);


    public DocumentModel parse(String sUrl) throws Exception {

        DocumentModel documentModel = new DocumentModel();
        DocConnection docConnection = new DocConnection();

        XComponent xComp = null;

        Exception ex = null;

        try {
            // open connection
            xComp =;

            // parse
            parse(xComp, documentModel);

        } catch (Exception e) {
            logger.error(e, e);
            ex = e;
        } finally {

        if (ex != null) {
            throw ex;

        return documentModel;

    public DocumentModel parse(XComponent xComp, DocumentModel documentModel)
            throws Exception {
        // enumerateTextComponents(xComp, documentModel);
        enumerateFormComponents(getFormComponentTreeRoot(xComp), " ",
        enumerateBookmarks(xComp, documentModel);
        enumerateTables(xComp, documentModel);
        return documentModel;



// the previous code can be tested with the following class

package docreader;

public class TestDocReader {
    public static void main(String args[]) {
        DocReaderParser parser = new DocReaderParser();
        DocumentModel documentModel = parser
        try {
        } catch (Exception e) {

Wednesday, 18 November 2009

monitoring dependencies between jar files

a script to use the jarjar utility on Windows

Make sure to run the dos console with the delayed environment variable expansion option enable, that is cmd /V:ON

echo off
FOR /F %%G IN ('DIR /S /B %1\*.jar') DO (
java -jar jarjar-1.0.jar find jar %CP%

the script has to be called with an argument specifying the directory containing the set of jar files

Monday, 16 November 2009

session management on WebSphere

WebSphere adds a prefix to the session identifiers, which will not be included by the getId method of the HttpSession object.

This would cause problems in such cases when you need to enable a process external to the browser to work inside an already existing session created by an user logged on the web interface.

HttpSession session = request.getSession(true);
String standardSessionID = session.getId();
//standardSessionID does not contain the cache prefix

String header = request.getHeader("Cookie");
//header contains the string "JSESSIONID="

String fromHeaderSessionID = header.substring(11);
//fromHeaderSessionID contains the WebSphere cache prefix
//and can be sent to the server as a JSESSIONID cookie or as a part of the url,
//as in the string 
Strig url = ";jsessionid=" + fromHeaderSessionID;

Thursday, 12 November 2009

load balance on Tomcat 5.5 with Apache web server

a very interesting post on how to set up a farm environment
with different instances of Tomcat 5.5 and an Apache web server


Wednesday, 11 November 2009

retrieve the HttpServletRequest on an Axis server object

MessageContext context = org.apache.axis.MessageContext.getCurrentContext();
request = (HttpServletRequest)context.getProperty(

Monday, 9 November 2009

debug the network activity of a process on Windows

find the process (service) id with
tasklist /SVC

then type

netstat -aovn | findstr <processid>

where <processid> is the process id found by tasklist.

Saturday, 7 November 2009


how to sync (in simulation mode) the folder myRootPackage under /http/www/myWebapp/WEB-INF/classes on the host "hostname", in the folder /http/lib/myWebapp/WEB-INF/classes/ on the local host

rsync --rsh="/usr/bin/ssh -l username" -avzn --size-only

Friday, 6 November 2009

tar gz

to create a tar.gz file
tar -czvf archive.tgz directory --exclude "file"
to extract a tar.gz file
tar xvzf file.tar.gz

on Solaris:
tar cf tomcat7.tar /tomcat7 | gzip -f tomcat7.tar

Wednesday, 4 November 2009

log swallowing on Tomcat

In order to split the catalina.out across multiple files, each one of which created every day, it's useful to configure the context xml descriptor as below (tested on Tomcat 5.0.28)

<context path="/myWebApp" swallowOutput="true">
<logger directory="logs"

which will create every day a new file called
containing the daily ouput

This technique is referred to as "output swallowing" on Tomcat
(note the swallowOutput="true")


articles on Datawarehouse

What's blocking my lock?

Here comes an extremely clear and interesting article, written by Natalka Roshalk, about Oracle locks and how to monitor what's going on when a lock is blocking a session

read the article

Friday, 30 October 2009

script to delete recursively all the CVS folders from a directory on Windows

Here comes a useful script to be run on the root folder of a CVS checked out project, in order to recursively delete all the CVS system folders named "CVS".

This comes useful when I need to copy some folders directly from a CVS project to another file systems without the need to export the project from the CVS.

FOR /F "tokens=*" %%G IN ('DIR /B /A:D /S *CVS') DO rmdir /S /Q %%G

If you paste the script directly in the Windows console, replace %%G with %G.

batch script on Windows to get the current date

I've come across the need of getting the current date,
inside a batch file on Windows, here's how to do it:

FOR /f "tokens=1,2,3,4 delims=/ " %%a IN ('date /t') DO (
SET FileDate=%%c-%%b-%%a

echo executing backup in date %FileDate%

Subversion resources

I've found a complete and interesting description of the Subversion system, at

Intervals intersection in SQL

An interesting problem, elegantly solved with the use of language SQL, is the calculation of intersections between sets of intervals.

An example of this problem is: arrange a meeting for a group of people who express availability of different times.

In that case you must calculate the time slots in which all persons of the group are able to participate at that meeting.


1 3 5 12 20 21
A ---- -------------- ----
B -------- ------
C --------------------

the solution is the following set of intervals
{[5,6], [10,12]}

Let's create the table TIMESLOTS (uid, start, end) whose rows contain for each person, identified by uid, timeslots which fit. They are defined by the start and end column.
The table in our example would be populated as follows
person start end
A 1 3
A 5 12
A 20 21
B 2 6
B 10 13
C 4 14

Assuming that in the table TIMESLOTS for each person timeslots are disjoint, that is they don't overlap (this is a non-restrictive assumption, in general) we can solve the problem of the intersection by mean of the following considerations:

the solution contains intervals whose delimiters are delimiters of some intervals in TIMESLOTS: actually, for example, the solution interval [5, 6] is delimited by the point 5, being a delimiter for the interval [5, 12] belonging to the A person, and by the point 6, being a delimiter for the interval [2, 6] belonging to the person B.

Considering the Cartesian product of the table TIMESLOTS, we get couples of the form ([fst.start, fst.end], [lst.start, lst.end]) representing all the possible combinations of delimiters for the intervals included in the table. The solution will then contain intervals of the form [fst.start, lst.end]. Among all these couples, those that concern us are the ones for which it holds fst.start<lst.end, namely the left delimiter is less than the right one, and for which every person has a suitable time availability, that is for every person it exists a "covering" interval.

The reasoning may translate in SQL query:

SELECT DISTINCT fst.start, lst.end
FROM timeslots fst, timeslots lst
WHERE fst.start<lst.end
( -- number of intervals covering [fst.start, lst.end]
FROM timeslots t
WHERE t.start<=fst.start AND t.end>=lst.end
) <=
( -- number of persons in the table
FROM timeslots

the hypothesis that the intervals of a single person must be separated, in TIMESLOTS, is justified by the subquery

FROM timeslots t
WHERE t.start<=fst.start AND t.end>=lst.end

that only under such circumstances makes it possible to count the number of people who have time availability compatible with the time interval [fst.start, lst.end].

Bibliography: Vadim Tropashko, "SQL Design Patterns: Expert Guide to SQL Programming", Rampant Techpress

A minimal microcontroller based project involving serial port communication

link to a pdf file explaining a minimal microcontroller based project involving serial port communication.

how to find a Java class inside a set of jar files

These are commands to be run from the shell to locate a Java class into a set of jar files, usually in a WEB-INF/lib directory in a J2EE application server.

On Windows
Make sure to run the script from a dos console with the delayed environment variable expansion option enable, that is cmd /V:ON

The script is to be called with two arguments, the first is the folder where to search in, the second is the class name

echo off
FOR /F %%G IN ('DIR /S /B /S %1\*.jar') DO (
echo %%G
jar -tf %%G | findstr %2

On *nix
find -ls -exec sh -c '/usr/jdk1.5.0_07/bin/jar tf $1 | 
grep JavaClass.class' {} {} \;

where /usr/jdk1.5.0_07 is the path where the JDK resides and JavaClass.class is the class name to be searched