Monday, December 22, 2008
Friday, September 12, 2008
Rappresentazione di un numero in lettere
Oggi mi sono trovato a dover stampare un bollettino postale per un pagamento... per cui ho avuto il solito problema di rappresentare un valore numerico in lettere, cosa che serve anche per rappresentare l'importo su assegni bancari.
Ecco qua il codice Java che realizza la cosa...
Nota: la classe org.apache.commons.lang.StringUtils; e' fornita dalla libreria
di utilita' Apache Commons Lang (http://commons.apache.org/lang/)
per cui per compilare e eseguire la classe ricordatevi di aggiungere commons-lang.jar
al vostro classpath.
Ecco qua il codice Java che realizza la cosa...
Nota: la classe org.apache.commons.lang.StringUtils; e' fornita dalla libreria
di utilita' Apache Commons Lang (http://commons.apache.org/lang/)
per cui per compilare e eseguire la classe ricordatevi di aggiungere commons-lang.jar
al vostro classpath.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import org.apache.commons.lang.StringUtils;
public class CharsNumber {
private BigDecimal v;
public CharsNumber(BigDecimal v) {
super();
this.v = v;
}
@Override
public String toString() {
return toString(v);
}
private static String toString(BigDecimal Valore) {
String result = ""; // risultato
String[] lettere = { "", "uno", "due", "tre", "quattro", "cinque",
"sei", "sette", "otto", "nove", "dieci", "undici", "dodici",
"tredici", "quattordici", "quindici", "sedici", "diciassette",
"diciotto", "diciannove", "venti", "trenta", "quaranta",
"cinquanta", "sessanta", "settanta", "ottanta", "novanta" };
String valore = "" + Valore.abs();
String resto = "/00";
valore = valore.replace(',', '.');
int k = valore.indexOf('.');
if (k >= 0) // l'importo รจ decimale
{
resto = "/" + valore.substring(k + 1);
if (resto.length() == 2) resto += "0";
if (resto.length() > 3) resto = resto.substring(0, 3);
valore = valore.substring(0, k);
}
if (valore == "0") // importo zero finisce subito
{
result += "zero";
valore = "";
}
k = valore.length() % 3;
// normalizzo la cifra in modo da poter avere dei gruppi di tre
if (k > 0) {
valore = StringUtils.leftPad(valore, valore.length() + (3 - k), '0');
}
k = -1;
while (valore.length() > 0) {
String parziale = "";
// mangia tre caratteri a destra
char[] c = valore.substring(valore.length() - 3,valore.length()).toCharArray();
valore = valore.substring(0, valore.length() - 3);
k++;
for (int j = 0; j < 3; j++) {
int x = Integer.parseInt(new Character(c[j]).toString());
if (x != 0) {
if (j == 0)
parziale += (x == 1) ? "cento" : lettere[x] + "cento";
if (j == 1)
parziale += (x < 3) ? lettere[x * 10] : lettere[x + 18];
if (j == 2) {
boolean dieci = (!parziale.endsWith("dieci"));
if (!dieci) {
parziale = parziale.substring(0, parziale.length() - 5);
}
parziale += (dieci) ? lettere[x] : lettere[x + 10];
if (dieci) {
for (String s : new String[] { "ao", "au", "io",
"iu" }) {
int i = parziale.indexOf(s);
String t = s.substring(1);
while (i >= 0) {
parziale = parziale.substring(0, i)
+ parziale.substring(i + 1);
i = parziale.indexOf(s);
}
}
} // if (dieci)
} // if (j==2)
} // if (j != 0)
} // for j
if (parziale.length() > 0) {
String[] mille = { "uno", "mille", "unmilione", "unmiliardo",
"millemiliardi", "unmilionedimiliardi",
"unmiliardodimiliardi", "", "mila", "milioni",
"miliardi", "milamiliardi", "milionidimiliardi",
"miliardidimiliardi" };
int j = k + 7;
if (parziale.equals("uno")) {
parziale = "";
j = k;
}
if (j > mille.length - 1)
result = "valore fuori dei limiti";
else
result = (k == 0) ? mille[j] + parziale : parziale
+ mille[j] + result;
}
} // while
result += resto;
if (Valore.doubleValue() < 0)
result = "meno" + result;
return result;
}
public static void main(String[] args) throws Exception {
BufferedReader console = new BufferedReader(
new InputStreamReader(java.lang.System.in)
);
java.lang.System.out.println("Numero: ");
String line = "";
while ((line = console.readLine()) != null) {
BigDecimal d = new BigDecimal(line);
java.lang.System.out.println("Lettere: " + new CharsNumber(d));
java.lang.System.out.print("Numero: ");
}
}
}
Monday, July 28, 2008
JavaCC Maven Plugin and JJTree User definied Node Classes
Well I'm using JJTree (the Javacc preprocessor) to build a parsed tree model of the language that I'm implementing.
I also use maven to manage my project as usually and so I use the javacc maven plugin JavaCC Maven Plugin to integrate the jjtree and javacc commands into the project build lifecycle.
All worked fine until I start to provide my own defined node classes for the JJTree model.
In this case I experienced same unpleasant behaviors of jjtree about mixing generated and user provided java sources.
In fact I could not maintain well divided my sources implementing tree nodes from jjtree generated ones.
In particularity with the javacc maven plugin default configuration, the sources generation process ignores my java classes located in the default sources directory src/main/java and at the end of the process I obtain a compilation error of duplicate class. In fact for each classes I define I find also the generated one into the directory target/generated-sources/javacc.
So I decide to remove the java files from the generated sources directory in the case I had yet provided it.
Here the pom file with the ant code passed to maven-antrun-plugin to do this dirty work
I also use maven to manage my project as usually and so I use the javacc maven plugin JavaCC Maven Plugin to integrate the jjtree and javacc commands into the project build lifecycle.
All worked fine until I start to provide my own defined node classes for the JJTree model.
In this case I experienced same unpleasant behaviors of jjtree about mixing generated and user provided java sources.
In fact I could not maintain well divided my sources implementing tree nodes from jjtree generated ones.
In particularity with the javacc maven plugin default configuration, the sources generation process ignores my java classes located in the default sources directory src/main/java and at the end of the process I obtain a compilation error of duplicate class. In fact for each classes I define I find also the generated one into the directory target/generated-sources/javacc.
So I decide to remove the java files from the generated sources directory in the case I had yet provided it.
Here the pom file with the ant code passed to maven-antrun-plugin to do this dirty work
Wednesday, May 28, 2008
Blite-SE was just born!!
I have just founded a new project at Google Code, Blite-SE.
This new project aims to implement the Blite language as JBI component. The language has bean created at University of Florence by Prof. R. Pugliese and his research group.
In this project we chose as JBI target platform the Fuji implementation. Fuji is the new open source JBI enviroment based on OSGi, and it's the next JBI implemetation in the GlassFish v3.
Please check it out and report here your impression about the project and its intentions.
Thank you.
Panks
This new project aims to implement the Blite language as JBI component. The language has bean created at University of Florence by Prof. R. Pugliese and his research group.
In this project we chose as JBI target platform the Fuji implementation. Fuji is the new open source JBI enviroment based on OSGi, and it's the next JBI implemetation in the GlassFish v3.
Please check it out and report here your impression about the project and its intentions.
Thank you.
Panks
Tuesday, April 1, 2008
Linux File Locks: Java and the others...
Since Java 1.4, it's possible to locks file using the underline o.s. facilities through the standard API; in this way we can safe share external files with non-Java applications or among multiple Java applications (on different JVM) without writing native and unportable code.
The
To use file locking, you need to get a file channel, that is an instance of the FileChannel class. You can get a file channel through the
Here the Java code, it asks the user for a file to open and than it writes to it the successive user input lines. Before starting to write to the file the Java Program try to get an exclusive lock on the file.
Ok then let's try the program
oopss... we can access the locked file!! ... does it seam strange? Do worry your linux station is working perfectly and this the normal specificated behavior. In fact we have to remember normally file locks on unix operation system are advisory locks, then programs must collaborate to share files, they must use the same lock strategy to be blocked each others.
Ok, the try with and well advised startegy
Whats?!?! So... That seams really strange. Wait a moment try this
this return 1 because it can't lock the file.
Then the flock works fine, but it doesn't work with Java locks.
In this situation we have only one thing to do... "let's open the box and take a look inside"...
we need to directly explore our great resource... the LINUX KERNEL and his system calls .
Ok in the flock man 1 page we can read:
"This utility manages flock(2) locks from within shell scripts or the command line"
so the flock shell command use the flock syscall, in fact in man 2 flock we can read
"... Since kernel 2.0, flock() is implemented as a system call in its own right rather than being emulated in the GNU C library as a call to fcntl(2). This yields true BSD semantics: there is no interaction between the types of lock placed by flock() and fcntl(2), and flock() does not detect deadlock. ..."
Now the situation becomes to be clearer, probably the Java Api are implemented by fcntl and so they can't share locks with flock. By the way we can explore this possibility.
We start to write a simple C program that uses the flock syscall directly.
Ok now we test this program compiled to the executable file named as
In one terminal we execute:
We have the file file opened and locked in exclusive way and we are writing into it.
On one other terminal in the same dir we can try this:
the terminal is blocked because the flock can't acquire the lock the file.
If we go back to the first terminal and we give the Crt+D
on the second terminal we have
so our c program shares file lock with the shell command flock in the right way.
let's try it with the Java program.
I lock the file file and I start writing to it by Java code.
On the other terminal I try the c program
..mmm yes the two program seams absolutely ignore themselves...
The c program rewrote what Java one has written before...
Well now we can try using the
Here the exs program modified with fcntl.
ok now let's to try it with the Java one.
In the first terminal
we lock the file file by the c code using the
On the second terminal we execute the Java program:
YES!!!! IT WORKS... we synchronized the Java program with linux C native code on a file.
Same conclusions:
The
The
FileLock
class, which is part of the java.nio.channels
package, represents a file lock. You can use a file lock to restrict access to a file from multiple processes. In addition, you have the option of restricting access to an entire file or just a small region of it. A file lock is either shared or exclusive as usually. If you use a file lock in multiple threads, none of the threads would be restricted from accessing the file, because they run in the same VM and share the same system process. Only external processes are restricted.To use file locking, you need to get a file channel, that is an instance of the FileChannel class. You can get a file channel through the
getChannel
method of any of the following I/O classes:FileInputstream
FileOutputStream
RandomAccessFile
FileLock lock()
FileLock tryLock()
In this post I show an example how use this api to lock a file under Linux (Ubuntu 7.10) and to synchronize a Java program with C native program to access a shared file.Here the Java code, it asks the user for a file to open and than it writes to it the successive user input lines. Before starting to write to the file the Java Program try to get an exclusive lock on the file.
import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;
import java.util.regex.Pattern;
/**
* @author panks
*
*/
public class Main {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
RandomAccessFile file = null;
FileLock lock = null;
try {
BufferedReader console =
new BufferedReader(new InputStreamReader(System.in));
System.out.println("Inserisci nome file:");
String name = console.readLine();
file = new RandomAccessFile(name, "rwd");
System.out.println("locking file " + name);
lock = file.getChannel().tryLock();
if (lock == null) {
System.out.println("NO LOCK :( bye bye...");
return;
}
System.out.println("!!LOCKED!!");
String line = "";
while ((line = console.readLine()) != null) {
file.writeBytes(line + "\n");
}
} finally {
if (lock != null) lock.release();
if (file != null) file.close();
}
}
}
Ok then let's try the program
java Mainleave the program running and open a new console to the same working directory and try
Inserisci nome file:
file
locking file file
!!LOCKED!!
hello world!!
...
cat file
hello world!!
...
oopss... we can access the locked file!! ... does it seam strange? Do worry your linux station is working perfectly and this the normal specificated behavior. In fact we have to remember normally file locks on unix operation system are advisory locks, then programs must collaborate to share files, they must use the same lock strategy to be blocked each others.
Ok, the try with and well advised startegy
flock file ls
file Main.class
Whats?!?! So... That seams really strange. Wait a moment try this
open a new console to the same directory and type
flock file cat
blabla blabla
blabla blabla
uhuh uuhh uhh
uhuh uuhh uhh
flock -n file cat
this return 1 because it can't lock the file.
Then the flock works fine, but it doesn't work with Java locks.
In this situation we have only one thing to do... "let's open the box and take a look inside"...
we need to directly explore our great resource... the LINUX KERNEL and his system calls .
Ok in the flock man 1 page we can read:
"This utility manages flock(2) locks from within shell scripts or the command line"
so the flock shell command use the flock syscall, in fact in man 2 flock we can read
"... Since kernel 2.0, flock() is implemented as a system call in its own right rather than being emulated in the GNU C library as a call to fcntl(2). This yields true BSD semantics: there is no interaction between the types of lock placed by flock() and fcntl(2), and flock() does not detect deadlock. ..."
Now the situation becomes to be clearer, probably the Java Api are implemented by fcntl and so they can't share locks with flock. By the way we can explore this possibility.
We start to write a simple C program that uses the flock syscall directly.
#include
#include
#include
#include
#include
#include
#include
int main(void) {
char filepath[100];
puts("Please insert the file path:");
gets(filepath); //don't use gets, only here for simplicty ;)
int fd = open(filepath, O_CREAT | O_RDWR | O_SYNC
, S_IRUSR | S_IWUSR | S_IROTH | S_IRGRP);
if (fd < 0) perror("open");
printf("opened file %s \n", filepath);
puts("tring to lock file...");
if (flock(fd, LOCK_EX) < 0)
perror("fcntl");
else
puts("file !!LOCKED!!");
char line[1000];
while (fgets(line, 1000, stdin) != NULL) {
int n = write(fd, line, strlen(line));
if (n < 0) perror("write");
}
puts("release lock ...");
if (flock(fd, LOCK_UN) < 0)
perror("flock");
else
puts("file !!RELEASED!!");
puts("closing file...");
if (close(fd) < 0)
perror("close");
else
puts("file !!CLOSED!!");
return 0;
}
Ok now we test this program compiled to the executable file named as
exs
.In one terminal we execute:
./exs
Please insert the file path:
file
opened file file
tring to lock file...
file !!LOCKED!!
Hello Word!
:)
We have the file file opened and locked in exclusive way and we are writing into it.
On one other terminal in the same dir we can try this:
flock file cat file
the terminal is blocked because the flock can't acquire the lock the file.
If we go back to the first terminal and we give the Crt+D
release lock ...
file !!RELEASED!!
closing file...
file !!CLOSED!!
on the second terminal we have
Hello Word!
:)
so our c program shares file lock with the shell command flock in the right way.
let's try it with the Java program.
java Main
Inserisci nome file:
file
locking file file
!!LOCKED!!
Ciao
Mondo!
by panks
I lock the file file and I start writing to it by Java code.
On the other terminal I try the c program
./exs
Please insert the file path:
file
opened file file
tring to lock file...
file !!LOCKED!!
Bella
Ciao!
release lock ...
file !!RELEASED!!
closing file...
file !!CLOSED!!
..mmm yes the two program seams absolutely ignore themselves...
Inserisci nome file:
file
locking file file
!!LOCKED!!
Ciao
Mondo!
by panks
"CRTL+D"
cat file
Bella
Ciao!
by panks
The c program rewrote what Java one has written before...
Well now we can try using the
fcntl
syscall from our c code.Here the exs program modified with fcntl.
...
int main(void) {
char filepath[100];
puts("Please insert the file path:");
gets(filepath); //don't use gets, only here for simplicty ;)
struct flock lock;
/* Initialize the flock structure. */
memset (&lock, 0, sizeof(lock));
lock.l_type = F_WRLCK;
int fd = open(filepath, O_CREAT | O_RDWR | O_SYNC
, S_IRUSR | S_IWUSR | S_IROTH | S_IRGRP);
if (fd < 0) perror("open");
printf("opened file %s \n", filepath);
puts("tring to lock file...");
if (fcntl(fd, F_SETLKW, &lock) < 0)
perror("fcntl");
else
puts("file !!LOCKED!!");
char line[1000];
while (fgets(line, 1000, stdin) != NULL) {
int n = write(fd, line, strlen(line));
if (n < 0) perror("write");
}
puts("release lock ...");
lock.l_type = F_UNLCK;
if (fcntl(fd, F_SETLKW, &lock) < 0)
perror("fcntl");
else
puts("file !!RELEASED!!");
puts("closing file...");
if (close(fd) < 0)
perror("close");
else
puts("file !!CLOSED!!");
return 0;
}
ok now let's to try it with the Java one.
In the first terminal
./exs
Please insert the file path:
file
opened file file
tring to lock file...
file !!LOCKED!!
Come e' dura
l'avventura...
we lock the file file by the c code using the
fcntl
directly.On the second terminal we execute the Java program:
java Main
Inserisci nome file:
file
locking file file
NO LOCK :( bye bye...
YES!!!! IT WORKS... we synchronized the Java program with linux C native code on a file.
Same conclusions:
The
FileLock
class is absolutely useful but probably better to use it to synchronize Java Processes running on different JVM of the same version (in fact different implementations could give unexpected behaviour). When we really need to synchronize on a file a Java program with same native one probably better to use other strategy:- One of most appropriate enterprise scale mechanism, database lock, queues ecc...
- Advisory file locks by same external and well documented conventional mechanism, for example symbolic links in
/var/lock
as anyway all unix daemons usually do.
Subscribe to:
Posts (Atom)
Blog Archive
About Me
- Paolo Panconi alias Panks
- Milano, Italy
- Software Architect and Software Solution Advisor