Tuesday, December 20, 2011

The Parking Permit Demo (2)



I let you here #3 and #4 videos of the Parking Permit Demo with Oracle BPM/SOA suite.

- pp-03_Drilling_down_n_Identifying_Services_Candidates__Part2
  • Identifying the Electoral Register Verification Service & Residence Verification Service by dragging & dropping two service activities in the parallel gateway. Naming the service activities

- pp-04_Defining_Schema_Type_n_Element_for_Resident

  • Creating the parking_permit.xsd schema with target namespace http://ex.datys.cu/ParkingPermit/types
  • Defining XSD complexType & element for Resident


pp-03_Drilling_down_n_Identifying_Services_Candidates__Part2

pp-04_Defining_Schema_Type_n_Element_for_Resident

Monday, December 19, 2011

The Parking Permit Demo. A top-down approach with Oracle BPM-SOA Suite


I'd like to start a new series of posts dealing with BPM/SOA on Oracle Tech. I named it "The Parking Permit Demo. A top-down approach with Oracle BPM-SOA Suite", as the suggests it's a demonstrative use case extracted from Oracle Unified Method.
The whole purposed is prove (once again) how effective is to engage a top-down approach on the BPM - SOA synergy.

Various advantages are highlighted on the full trip of screencasts:  
  • use of standards
  • re-usability
  • the avoid unnecessary transformations
  • interoperability
  • test-driven-no-blocking design
  • flexibility of environments for different scenarios
  • smart label generation
  • process-driven, schema-centric & composite-supported 

The content is divided in various seasons according to specific areas or improvements of the solution. Each season contains a full-trip of webpisodies/screencasts with a short duration plus the resulting sources and other resources.

Here I let you the overall script.

Now I'd introduce the Season 1 “History of a Parking Lot. From the big-TOP to the black-DOWN.

I left you a couple of episodes here:

pp-01:
  • Creating an initial BPM/SOA application called TheParkingApplication with a
package's prefix cu.datys.examples and a project named ParkingPermitProject
  • Creating a Manual BPM Process named ParkingPermitProcess with a service
namespace http://ex.datys.cu/ParkingPermitProcess
  • Naming the user role Resident and the interactive activity Apply for Parking
Permit


pp-02:

  • Dragging  & dropping a Parallel Gateway to the BPM Process to call multiple verifications services simultaneously
  • Identifying the Vehicle Ownership Verification Service by dragging & dropping a service activity in the parallel gateway. Naming the service activity Verify Vehicle Ownership
  pp-01_Creating_new_BPM_App_n_Project



 pp-02_Drilling_down_n_Identifying_Services_Candidates__Part1






Thursday, October 6, 2011

Curso de Tecnología Java (Java Technology Course)

Java en Castellano
Aquí les brindo un modesto curso de la Tecnología Java, casi el 100% del contenido esta en español.

Espero que lo disfruten.

Wednesday, October 5, 2011

The apt keys, importing keys in batch mode

Why?
Sometimes a fresh Ubuntu or Debian install is mandatory or commanded, but we forget to export all GPG apt keys before the wipe. Once we made the installation we start to add our previously sources lists entries (hope you don't forget to save them first). In my case I use several entries many referencing some useful PPAs on Launchpad, this an excerpt:

deb http://archive.ubuntu.com/ubuntu natty-proposed main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu natty-security main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu natty-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu natty main restricted universe multiverse

deb http://archive.canonical.com/ubuntu natty partner
deb http://archive.canonical.com/ubuntu natty-backports partner

deb http://extras.ubuntu.com/ubuntu natty main

deb http://ppa.launchpad.net/stebbins/handbrake-releases/ubuntu natty main
deb-src http://ppa.launchpad.net/stebbins/handbrake-releases/ubuntu natty main

deb http://ppa.launchpad.net/tualatrix/ppa/ubuntu natty main 
deb http://ppa.launchpad.net/kiwixteam/ppa/ubuntu natty main
deb http://ppa.launchpad.net/pidgin-developers/ppa/ubuntu natty main

deb http://ppa.launchpad.net/rabbitvcs/ppa/ubuntu natty main
deb-src http://ppa.launchpad.net/rabbitvcs/ppa/ubuntu natty main

deb http://archive.cloudera.com/debian natty-cdh3 contrib
deb-src http://archive.cloudera.com/debian natty-cdh3 contrib

deb http://ppa.launchpad.net/ubuntu-x-swat/x-updates/ubuntu natty main
When we run then apt-get update in our fresh install we end with this annoying warning message:

W: A error occurred during the signature verification. The repository is not updated and the previous index files will be used.GPG error: ... Release: The following signatures were invalid: BADSIG 40976EAF437D05B5 Ubuntu Archive Automatic Signing Key <ftpmaster@ubuntu.com>

W: Failed to fetch ... 
W: Some index files failed to download, they have been ignored, or old ones used instead.


To avoid these warnings you shall to explicit import the public keys (40976EAF437D05B5) via Synaptic Package Manager or apt-key command.

How?
In my case, I keep a file (~/Sandbox/aptkeys/aptkeys) with a list of keys on my profile, one per line. Then, when a /etc/apt/sources.list archive get modified and the command apt-get update emits this kind of warning message, I append this key (40976EAF437D05B5) to the end of the file  ~/Sandbox/aptkeys/aptkeys using a text editor or cat command. Here is an excerpt of my aptkeys file:
DB141E2302FDF932
7FB8BEE0A1F196A8
5A9BF3BB4E5E17B5
2EBC26B60C5A2783
BE79FA4B705B7C13
E43D207C62D38753
C0B56813051D8B58
3B22AB97AF1CDFA9

The I use this script to make a batch import of all my approved keys:


$  cat ~/Sandbox/aptkeys/aptkeys  | importaptkeys


Hope that it will be useful for you.

Tuesday, October 4, 2011

Various Java VM on my Debian / Ubuntu. What can I do?

The situation
Many of us prefer Sun JVM (Oracle now) for historical or non-historical reasons. Many of us also prefer Debian, Ubuntu and/or even Red Hat. But when we go and install LibreOffice (for example), via apt-get other powerful player arrives: openjdk. I don't want to discuss which JVM implementation is the most "appropriate" for us, you or them. There is a fact, many JVM can and should coexists pacifically.

But the question persists
- After installing various Java-dependant packages on my GNU/Linux OS preferred distribution, and I issue the javac command, which JVM compiler is invoked? 
- How can I set my preferred Java implementation per command basis?

The solution
The Debian alternatives system is devoted to solve the problem of choosing the default preferred implementation of various kinds of programs: text editors, mail agents, JVM, etc.

The options are settled via update-alternatives in a terminal and there is also a graphical version called galternatives.


The Example
This script sets various' Sun JVM (Oracle now) commands as the default alternatives for: java packaging, java VM, java compiler, javadoc, etc. It runs update-alternatives command several times, one per java command.

Composing XML is easy

Intro
Sometimes we want to "modularize" some XML archive in some independent parts for a matter of clearness and manageability of simple documents instead of huge ones, lets say XHTML pages, XSLT, XSD, etc.

Many people don't know how to compose, in a generic manner, multiple XML (a no XML also) documents into a big one. It's easier to do, and the answer is XInclude.  Many XInclude examples reflect what I said: Its easy to use!

XInclude It's not a new invention at all, but surprisingly a bunch colleagues of mine don't know about its existence.

Example
Lets stop talking. I going to show you how you can freely merge varios XML (or text) documents into a more complex XML document with XInclude during a XSLT transformation. The example is very straightforward:

- input file: demoxi.html

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude">
  <head>Some title</head>
  <body>
    <p><xi:include href="license.txt" parse="text"/></p>
  </body>
</html>


- XSLT transformation: identity.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  xmlns:xi="http://www.w3.org/2001/XInclude">
   
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="no" />
 
  <xi:include href="copy_template.xml" parse="xml" />

</xsl:stylesheet>

- a text file to include: license.txt

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation Version 3 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See GNU General Public License <http://www.gnu.org/licenses/>.
- a XML file to include in the XSLT: copy_template.xml

<xsl:template match="*" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:element name="{fn:name(.)}" namespace="{fn:namespace-uri(.)}">
        <!-- copy attributes -->
        <xsl:for-each select="@*">
            <xsl:attribute name="{fn:node-name(.)}" select="." />
        </xsl:for-each>
        <xsl:apply-templates select="child::node()" />
    </xsl:element>
</xsl:template>

What's next?


Call an XSLT processor like Saxon in a XInclude aware manner.

$ exec java \
    -classpath saxon.jar \
    -Dorg.apache.xerces.xni.parser.XMLParserConfiguration=org.apache.xerces.parsers.XIncludeParserConfiguration \
    net.sf.saxon.Transform \
    -xi:on \

    -s:demoxi.html \
    -xsl:indentity.xsl

I provide this script to make things more easy. Enjoy it!

References:

Tiny: Extract all dependencies from Maven's POM recursively

A friend recently ask me: how can I extract all artifact dependencies from multiple POM files recursively into a single POM file?

Here is a simple answer using bash, libxml-xpath-perl and tidy.

What users can add?
- more XML processing instead of concatenating.
- extract properties values of non hardcoded dependencies.
- ensure uniqueness of dependencies.

Tuesday, July 5, 2011

An easy one with Symfony, MySql, Doctrine, PHPExcel and ExtJS

Codice Fiscale
The Italian fiscal code card, is an alphanumeric code of 16 characters with the purpose of unambiguously identify the residents on Italy. The page Codice_Fiscale clearly explains how the code is composed by the combination of the person's family name, name, birth date, sex and birth place. For example:

 The person:
  • Family name: Lago
  • Name: Eduardo
  • Birth date: November, 9 1980
  • Sex: Male
  • Birth place: Cuba
have a code:

  LGA DRD 80S09 ZCUB X



How to link each each part of the code with the corresponding person data?
  • Characters 1-3 come from the family name
  • Characters 4-6 come from the name
  • Characters 7-11 come from the birth date and the sex
  • Characters 12-15 come from the birth place
  • Character 16 is an especial character, it's a sort of checksum/parity control

The site http://www.codicefiscale.com/ is a very useful online tax code calculator.

The batch tax code validator
The presented application (ittaxcodevalidator) is PHP-based batch fiscal code validator that massively process citizens data in an Excel-spreadsheets, computes the tax code and compares it to the one supplied in the last column. The spreadsheet is supplied by an upload form.
Once the process is finished, then the application publish back a download link with a modified version of the spreadsheet with two additional columns added at the end, the first one with the calculated code, and the other indicating whether the tax code is compliant (OK/FAILED). Each row is also highlighted with red/green colour for not-compliant/compliant.

Input spreadsheet columns have the format:

NAME|FAMILY NAME|SEX|BIRTH DATE|BIRTH PLACE* (municipality)|BIRTH PLACE** (province)|TAX CODE
Eduardo | Lago | male | Nov 9, 80  | cuba   |        | LGADRD80S09ZCUBX
Mario     | Rossi | male | Jan 16, 60 | Roma | RM  |  RSSMRA60A15H501E   

The output spreadsheet columns have the format:


NAME|FAMILY NAME|SEX|BIRTH DATE|BIRTH PLACE* (municipality)|BIRTH PLACE** (province)|TAX CODE|VALIDATED TAX CODE|RESULT
Eduardo | Lago | male | Nov 9, 80  | cuba   |        | LGADRD80S09ZCUBX | LGADRD80S09ZCUBX | OK
Mario     | Rossi | male | Jan 16, 60 | Roma | RM  |  RSSMRA60A15H501E | RSSMRA60A16H501G | FAILED

* if the birth place is in a foreign Country, this field is filled with the name of the Country
** if the birth place is in a foreign Country, this field is not filled, this is the way to know it's a foreign country. If the birth place is on Italy, then use then inquiry the Belfiore code table (Spreadsheet located at extras/italian_municipalities_encoding/italian_municipalities_encoding.xls)

Sample spreadsheets can be found in directory data/xls/samples/ at: https://bitbucket.org/eduardo_lago_aguilar/ittaxcodevalidator 

The web application is fully developed with Symfony Web PHP-Framework v1.4.8 combined with Doctrine ORM and MySql Server. The PHPExcel v1.7.4 API is used for the spreadsheet loading/processing/saving. The user interface is built with the Sencha ExtJS AJAX framework.  
 
The algorithm
The rules for the tax code calculation are straightforward:
Characters 1-3
Use the first 3 consonants of the family name (or the family names if there are more than one, but in the exact order), if there are not enough consonants, always in the exact order, just after all the possible consonants already placed,  replace the missing consonant with the first vowel available and if the family name is so short that there are neither enough vowels, then replace every missing character with a 'X' character.

Characters 4-6
If the name has at least 4 consonants then take, as the chosen 3 consonants, 1st, 3rd and 4th consonant while, if there are not enough consonants, then take the first 3 in the exact order. If there are yet not enough consonants, always in the exact order, just after all the possible consonants already placed, then replace the missing consonant with the first vowel available and if the name is so short that there are neither enough vowels, then replace every missing character with a 'X' character.

Characters 7-11
The first 2 characters are the digits of the last two digits of the birth year (ex: 1960 is 60) and the 3rd character is the encoding of the birth month according to the following map:

A : january
B : february
C : march
D : april
E : may
H : june
L : july
M : august
P : september
R : october
S : november
T : december

the last 2 characters are the digits of the birth day, eventually filled with 0 if the birth day is just one digit. It's important to represent that the sex has to be taken in count cause if the person belongs to the female gender, it has to be added to the birth day the number 40 (ex: a woman born the 6 you will decode with 46, a woman born the 15 you will decode wih 55 and so on).

Characters 12-15
These characters are a simple translation of the Italian encoding for the municipalities by means of the inquiry of the Belfiore code table (Spreadsheet located at extras/italian_municipalities_encoding/italian_municipalities_encoding.xls), once found the proper birth place. The Province encoding (ex: the province code for Rome is 'RM') avoids the problem in having municipalities with the same name (there are no equal Municipality names in the same Province). If the birth place is in a foreign country, then encode with letter 'Z' followed by the 3 digits that represent the Country code according to the ISO 3166-1.

Character 16
The checksum-parity control is calculated this way:
  1. extract an ordered set from the rpevious 15 charatcers taking just the odd positions, in the above example the ordered set is 'LAR8S9CB'.
  2. extract an ordered set from the previous 15 charatcers taking just the even positions, in the above example the ordered set is 'GDD00ZU'.
  3. the "odd positions set" is decoded summing all the numbers that come from the encoding of each character presented in the table ODD ALPHANUMERIC CHARACTER.
  4. the "even positions set" is decoded summing all the numbers that come from the the encoding of each character presented in the table EVEN ALPHANUMERIC CHARACTER.
  5. then sum the both numbers that come from the previous two encodings and divide this number by 26. The rest of this operation is the target digit for as the last character of the tax code once decoded through the table REST.
  6. the previous steps don't guarantee that every single person gets a different code; there can be persons with the same name, born in the same day and in the same municipality and so, in such cases, it is applied a sort of "patch" that works this way: when a tax code is already existent it is changed the last numeric character starting from the right according to the table PATCH. However, this last case it's quite rare and it's not possible to prior know if this tax code is already existent or not, so when this case is presented it is just important to realize it's not a wrong format but it's a format that can be accepted because of the rule.
     
ODD ALPHANUMERIC CHARACTER
CharacterValueCharacterValueCharacterValueCharacterValue
1 0 A 1 J 21 S 12
2 5 B 0 K 2 T 14
3 7 C 5 L 4 U 16
4 9 D 7 M 18 V 10
5 13 E 9 N 20 W 22
6 15 F 13 O 11 X 25
7 17 G 15 P 3 Y 24
8 19 H 17 Q 6 Z 23
EVEN ALPHANUMERIC CHARACTER
CharacterValueCharacterValueCharacterValueCharacterValue
0 0 9 9 I 8 R 17
1 1 A 0 J 9 S 18
2 2 B 1 K 10 T 19
3 3 C 2 L 11 U 20
4 4 D 3 M 12 V 21
5 5 E 4 N 13 W 22
6 6 F 5 O 14 X 23
7 7 G 6 P 15 Y 24
8 8 H 7 Q 16 Z 25

REST
Rest Letter Rest Letter Rest Letter Rest Letter
0 A 7 H 14 O 21 V
1 B 8 I 15 P 22 W
2 C 9 J 16 Q 23 X
3 D 10 K 17 R 24 Y
4 E 11 L 18 S 25 Z
5 F 12 M 19 T

6 G 13 N 20 U



PATCH
Digit Letter Digit Letter Digit Letter
0 L 4 Q 8 U
1 M 5 R 9 V
2 N 6 S

3 P 7 T