martedì 29 novembre 2011

Redirect automatico da una pagina con conto alla rovescia

E' molto utile utilizzare il tag
<META http-equiv="Refresh" content="10;URL=http://www.nuovaurl.it">
dentro la sezione <head> dell'html, in modo da effettuare un redirezionamento a tempo (in questo caso 10 secondi) di una pagina Web.

Vediamo come abbinarlo al classico "conto alla rovescia", supponiamo di avere una pagina che ci informi che avverrà la redirezione al sito www.corriere.it dopo X secondi e di avere un informazione sulla pagina in merito a quanti secondi mancano alla redirect.
Per ottenere questo risultato si utilizza nell'onload del body della pagina il metodo setInterval, che accetta 2 parametri:
  1. La funzione javascript da richiamare;
  2. Il tempo in millisecondi che deve trascorrere tra una chiamata e l'altra.
Vediamo il codice HTML e Javascript di questo semplice esempio:

<html>

<head>
<title>Pagina di autorefresh</title>
<META http-equiv="Refresh" content="10;URL=http://www.corriere.it">
</head>
<body onload="javascript:setInterval('go()',1000)">
Sarai redirezionato al sito in
<div id="mioDiv">10
</div> secondi
</body>
</html>

<script language="javascript">
function go(){
var valore=parseInt(document.getElementById("mioDiv").innerHTML);
valore=valore-1;
document.getElementById("mioDiv").innerHTML=valore;

}
</script>


venerdì 25 novembre 2011

Java calcolo piano ammortamento alla francese

Questa classe provvede a calcolare il piano ammortamento alla francese (rata costante, quota capitale crescente e quota interesse decrescente), tornando una lista di oggetti Rata con le seguenti proprietà:
  • Numero Rata
  • Data Scadenza
  • Importo Rata
  • Quota Interessi
  • Quota Capitale
  • Debito Residuo
Di seguito posto il codice della classe, con un main di esempio invocazione:


package it.test;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
enum PERIODICITA
{
    MENSILE(12),
    TRIMESTRALE(4),
    QUADRIMESTRALE(3),
    SEMESTRALE(2),
    ANNUALE(1);
    PERIODICITA(int n)
    {
        this.n=n;
    }
    private int n;
    public int getN() {
        return n;
    }
    public void setN(int n) {
        this.n = n;
    }
   
   
}
class Rata
{
    private Date dataScadenza;
    private int numeroRata;
    private double importoRata;
    private double quotaCapitale;
    private double quotaInteressi;
    private double debitoResiduo;
   
   
    public Date getDataScadenza() {
        return dataScadenza;
    }
    public void setDataScadenza(Date dataScadenza) {
        this.dataScadenza = dataScadenza;
    }
    public String toString(){
        StringBuilder sb=new StringBuilder();
        sb.append("[");
        sb.append(" Numero rata: ");
        sb.append(formatNumber(this.numeroRata));
        sb.append(" Data Scadenza: ");
        sb.append(formatDate(this.dataScadenza));
        sb.append(" Importo: ");
        sb.append(formatNumber(this.importoRata));
        sb.append(" Quota Capitale: ");
        sb.append(formatNumber(this.quotaCapitale));
        sb.append(" Quota Interesse: ");
        sb.append(formatNumber(this.quotaInteressi));
        sb.append(" Debito Residuo: ");
        sb.append(formatNumber(this.debitoResiduo));
        sb.append(" ]");
        sb.append("\n");
       
       
        return sb.toString();
    }
    public int getNumeroRata() {
        return numeroRata;
    }
    public void setNumeroRata(int numeroRata) {
        this.numeroRata = numeroRata;
    }
    public double getImportoRata() {
        return importoRata;
    }
    public void setImportoRata(double importoRata) {
        this.importoRata = importoRata;
    }
    public double getQuotaCapitale() {
        return quotaCapitale;
    }
    public void setQuotaCapitale(double quotaCapitale) {
        this.quotaCapitale = quotaCapitale;
    }
    public double getQuotaInteressi() {
        return quotaInteressi;
    }
    public void setQuotaInteressi(double quotaInteressi) {
        this.quotaInteressi = quotaInteressi;
    }
    public double getDebitoResiduo() {
        return debitoResiduo;
    }
    public void setDebitoResiduo(double debitoResiduo) {
        this.debitoResiduo = debitoResiduo;
    }
    private String formatNumber(double number){
        NumberFormat nf=NumberFormat.getInstance(Locale.ITALY);
        nf.setGroupingUsed(true);
        nf.setMaximumFractionDigits(2);
        nf.setMinimumFractionDigits(2);
        return nf.format(number);
        }
    private String formatDate(Date d){
        SimpleDateFormat sdf=new SimpleDateFormat("dd/MM/yyyy");
        return sdf.format(d);
    }
   
}
/**
 * Piano di ammortamento a rata costante <br>
 * La rata è divisa in quota interessi e quota capitale, la quota di capitale sarà <br>
 * crescente mentre la quota di interessi decrescente.<br>
 * La somma del totale delle quote capitale deve restituire il capitale prestato.<br>
 *
 *
 *
 * @author
 *
 */
public class PianoAmmortamentoFrancese {
    private double rata;
    private double capitalePrestato;
    private double interesse;
    private PERIODICITA periodicita;
    private int durataMesiMutuo;
    private Date dataPrimaScadenza;
   
    public double getRata() {
        return rata;
    }
    public void setRata(double rata) {
        this.rata = rata;
    }
    public PianoAmmortamentoFrancese(double capitalePrestato,double interesse,PERIODICITA per,int durataMesiMutuo,Date dataPrimaScadenza){
        this.capitalePrestato=capitalePrestato;
        this.interesse=interesse;
        this.periodicita=per;
        this.durataMesiMutuo=durataMesiMutuo;
        this.dataPrimaScadenza=dataPrimaScadenza;
        calcolaImportoRata();
    }
    public List<Rata> getPianoAmmortamento(){
        List<Rata> myList=new LinkedList<Rata>();
        Rata rIn=new Rata();
        rIn.setDebitoResiduo(this.capitalePrestato);
        rIn.setDataScadenza(dataPrimaScadenza);
       
        Date dataScadenza=dataPrimaScadenza;
        int[] dati=getGiorniMesiAnnoFromDate(dataScadenza);
        int giorno=dati[0];
       
        double debitoResiduo=this.capitalePrestato;
        double quotaCapitale=0;
        double interesse=0;
        int numeroRata=0;
        myList.add(rIn);
        do
        {
            numeroRata++;
           
           
            dataScadenza=getDataSuccessiva(dataScadenza);
            int nuovoGiorno=getGiorniMesiAnnoFromDate(dataScadenza)[0];
            if(nuovoGiorno!=giorno){
                if(isGiornoAmmissibilePerData(dataScadenza, giorno)){
                    Calendar c=Calendar.getInstance();
                    c.setTime(dataScadenza);
                    c.set(Calendar.DAY_OF_MONTH, giorno);
                    dataScadenza=c.getTime();
                }
            }
            double[] quote=getQuoteDebito(debitoResiduo);
            Rata r=new Rata();
            quotaCapitale=quote[1];
            interesse=quote[0];
            debitoResiduo=debitoResiduo-quotaCapitale;
            r.setImportoRata(rata);
            r.setDataScadenza(dataScadenza);
            r.setDebitoResiduo(debitoResiduo);
            r.setQuotaCapitale(quotaCapitale);
            r.setQuotaInteressi(interesse);
            r.setNumeroRata(numeroRata);
            myList.add(r);
           
           
        }
        while((int)debitoResiduo!=0);
       
        return myList;
    }
    private void calcolaImportoRata(){

        rata= this.capitalePrestato*getFattoreA()*getFattoreB();
    }
    private double getFattoreB(){
        double numeratore=calcolaA()-(double)1;
        double denominatore=getFattoreA()-1;
        return numeratore/denominatore;
    }
    /**
     * Stiamo calcolando 1+ TA/PA dove TA è l'interesse e PA i periodi annui
     * @return
     */
    private double calcolaA(){
       
        return (double)1+this.interesse/(double)periodicita.getN();
       
    }
    private double esponenteA(){
        return (double)periodicita.getN()*anniRimborso();
       
    }
    private double getFattoreA(){
        return Math.pow(calcolaA(), esponenteA());
    }
   
    private double anniRimborso()
    {
        return (double)this.durataMesiMutuo/(double)12;
    }
    public static void main(String[] args) throws Exception
    {
        Date dataPrimaScadenza= creaData(26, 12, 2011);
       PianoAmmortamentoFrancese p=new PianoAmmortamentoFrancese((double)100000, 0.05,PERIODICITA.MENSILE, 24,dataPrimaScadenza);
      System.out.println(p.getPianoAmmortamento());
      
    }
    private double[] getQuoteDebito(double capitaleResiduo){
        double[] retVal=new double[2];
        double quotaInteressi=(this.interesse/(double)periodicita.getN())*capitaleResiduo;
        double quotaCapitale=rata-quotaInteressi;
        retVal[0]=quotaInteressi;
        retVal[1]=quotaCapitale;
        return retVal;
    }
    private int[] getGiorniMesiAnnoFromDate(Date d){
        Calendar c=Calendar.getInstance();
        c.setTime(d);
        int anno=c.get(Calendar.YEAR);
        int mese=c.get(Calendar.MONTH);
        int giorno=c.get(Calendar.DAY_OF_MONTH);
        int[] lista=new int[3];
        lista[0]=giorno;
        lista[1]=mese;
        lista[2]=anno;
        return lista;
    }
    private Date getDataSuccessiva(Date d){
        int p=12/this.periodicita.getN();
        Calendar c=Calendar.getInstance();
        c.setTime(d);
        c.add(Calendar.MONTH, p);
        return c.getTime();
    }
   private static Date creaData(int giorno,int mese,int anno){
        Calendar c=Calendar.getInstance();
        c.set(Calendar.YEAR, anno);
        c.set(Calendar.MONTH, mese-1);
        c.set(Calendar.DAY_OF_MONTH, giorno);
        return c.getTime();
    }
   private boolean isGiornoAmmissibilePerData(Date d,int giorno){
       boolean retVal=false;
       if(giorno<=28){
           retVal=true;
       }
       else
       {
           int mese=getGiorniMesiAnnoFromDate(d)[1];
           if(mese==Calendar.FEBRUARY){
               if(isLeapYear(getGiorniMesiAnnoFromDate(d)[2]) && giorno==29){
                   retVal=true;
               }
               else
               {
                   retVal=false;
               }
           }
           else if(giorno==31 ){
               if(mese!=Calendar.APRIL && mese !=Calendar.JUNE && mese !=Calendar.SEPTEMBER && mese !=Calendar.NOVEMBER)
               {
                   retVal=true;
               }
               else
               {
                   retVal=false;
               }
           }
       }
       return retVal;
   }
  
   /**
     * Un anno è bisestile se:<br>
     * 1) divisibile per 4<br>
     * 2) non secolare (a parte i secolari divisibili per 400)<br>
     * @param anno
     * @return
     */
    private boolean isLeapYear(int anno){
        boolean retVal=false;
        int div4=anno%4;
        if(div4==0){
            //divisibile per quattro
            int div100=anno%100;
            if(div100==0){
                // è un anno "secolare"
                int div400=anno%400;
                if(div400==0){
                    // però è divisibile anche per 400
                    retVal=true;
                }
                else
                {
                    // anno secolare non divisibile per 400
                    // non è bisestile
                    retVal=false;
                }
            }
            else
            {
                // divisibile per 4 e non secolare è bisestile
                retVal=true;
            }
        }
        return retVal;
    }
}

Jboss .bat per cancellare tutti i file di log

@ERASE  /Q   C:\jboss-4.0.5.GA\server\default\log server.log.????-??-??


L'indicazione /Q indica di non chiedere conferma alla cancellazione,  questo script praticamente cancella sia il server.log sia tutti i back_up, che tipicamente hanno il formato server.log.AAAA-MM-GG.


MySql creare backUp con data usando mysqldump su Windows

Per effettuare un back up di un db con una data (in questo caso con l'indicazione di giorno e ora) su windows si può creare un .bat di questo tipo:  

set giorno=%date:~0,2%
set mese=%date:~3,2%
set anno=%date:~6,4%
set ora=%time:~0,2%_%time:~3,2%_%time:~6,2%
set miadata=%giorno%_%mese%_%anno%_Ore_%ora%
mysqldump -uroot -proot test>c:\test_%miadata%.sql



Il risultato sarà un file di back up di questo tipo:test_25_11_2011_Ore_10_18_34.sql

domenica 20 novembre 2011

Javascript show/hide div

Spesso è utile visualizzare del testo statico on demand su pagina Web, il classico esempio è quello della visualizzazione di informazioni cliccando su un pulsante e poi farlo scomparire di nuovo ricliccando.
Il metodo Javascript è il seguente:

function showhide(id) {
    var state = document.getElementById(id).style.display;
        if (state == 'block') {
            document.getElementById(id).style.display = 'none';
            document.getElementById('spiega').value="Mostra Guida";
        } else {
            document.getElementById(id).style.display = 'block';
           
            document.getElementById('spiega').value="Nascondi Guida";
           
        }
    }

 Al caricamento vogliamo che non si veda il testo del div, quindi definiamo

<style type="text/css">
<!--

#spiegazioni {
   
    display: none;
}
-->
</style>

Sulla pagina HTML abbiamo

<form name="caricaBilancio" id="caricaBilancio" ENCTYPE="multipart/form-data" action="CaricaBilancio" method="post">

<input class="inputButton" id="spiega"    type="button" name="Guida"  title="Guida"  value="Mostra guida" onclick="javascript:showhide('spiegazioni')"/>

<div id="spiegazioni">
/// qui il nostro testo
Prova prova
</div>
Vediamo l'esempio cliccando sul pulsante


// qui il nostro testo Prova prova

Upload di un file via Web

Per effettuare l'upload di File via Web è molto utile utilizzare la libreria commons-fileupload-1.2.2.jar (per usarla c'è bisogno di avere nel classpath anche commons-io.jar.

Bisogna ricordarsi di scrivere dentro il tag Form ENCTYPE="multipart/form-data" altrimenti la chiamata al metodo isMultipartContent(request) torna false.

Ecco il form

<form name="caricaBilancio" id="caricaBilancio" ENCTYPE="multipart/form-data" action="CaricaBilancio" method="post">
<div class="contentResultCol" id="contentResultCol_M1472946676">
<div class="resultBodyObject" id="resultBodyObject_M1472946676">

<table  class="filterTable">
<tr class="filterTr"><td>Acquisisci *: </td>

<td>
<select id="ddlScelta" name="ddlScelta" class="input">
            <option value="B" selected="selected">Bilancio Azienda</option>
            <option value="V">Votazione Azienda</option>
        </select>


</td>
</tr>
<tr class="filterTr">
<td class="filterLabelTd" id="filterLabelTd_M994447656" valign="top">

        <span id="FormModifica_dataCostituzione_label">File Excel *</span>
        </td>
        <td class="filterInputTd" valign="top"><!-- CalendarField#input -->
        <span id="span_FormModifica_dataCostituzione"> <!-- FormField#boundedField -->
        <span class="" alt="" title=""> <input id="fileExcel"
            name="fileExcel" class="input" type="file" value="" size="100" width="100" title="FileExcel"/> </span> </span></td>
</tr>
</table>
<table class="buttonTable" align="left">
    <tr>
        <td><input class="inputButton" id="annulla"    type="button" name="Annulla"  title="Annulla"  value="Annulla" onclick="javascript:self.close();"/></td>
        <td><input class="inputButton" id="salva"   type="button" name="btnInvio" value="Invia Richiesta"    title="Invia Richiesta" onclick="javascript:validateForm()  "  /></td>
        <td><input class="inputButton" id="reset"   type="reset"  name="Cancella" title="Cancella" value="Cancella" /></td>
        <td><input class="inputButton" id="spiega"    type="button" name="Guida"  title="Guida"  value="Mostra guida" onclick="javascript:showhide('spiegazioni')"/></td>
      
   
    </tr>
</table>
</form>


Ecco il codice della Servlet che  effettuare la lettura

RequestDispatcher rd=request.getRequestDispatcher("jsp/CaricaBilancio.jsp");
        try
        {
        String valoreRichiesta="";
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if(isMultipart){
            // Create a factory for disk-based file items
            FileItemFactory factory = new DiskFileItemFactory();

            // Create a new file upload handler
            ServletFileUpload upload = new ServletFileUpload(factory);
            List<FileItem> items=upload.parseRequest(request);
            Iterator iter = items.iterator();
            while (iter.hasNext()) {
                FileItem item = (FileItem) iter.next();

                if (item.isFormField()) {
                    String name = item.getFieldName();
                   valoreRichiesta = item.getString();
                } else {
                    String fieldName = item.getFieldName();
                    String fileName = item.getName();
                    String contentType = item.getContentType();
                    boolean isInMemory = item.isInMemory();
                    long sizeInBytes = item.getSize();
                    log.info(String.format("Upload di file %s di tipo %s e di size %d", fileName,contentType,sizeInBytes));
                    if("B".equals(valoreRichiesta)){
                   
                    InputStream is=item.getInputStream();
                    ExcelCaricamentoDao ed=ExcelCaricamentoDaoImpl.getInstance();
                    BilancioExcel bil= ed.getBilancioFromExcel(is);
                    ed.persistBilancio(bil);
                    request.setAttribute("ok", "Inserimento del bilancio terminato correttamente");
                    }
                    else
                    {
                        InputStream is=item.getInputStream();
                        ExcelCaricamentoDao ed=ExcelCaricamentoDaoImpl.getInstance();
                        VotazioneExcel v=ed.getVotazioniFromExcel(is);
                        ed.persistVotazione(v);
                       
                        request.setAttribute("ok", "Inserimento della votazione terminato correttamente");
                    }
                   
                }
            }
           
        }
        }
        catch(Exception fex){
            String messaggio="";
            if(fex instanceof SQLException){
                if(fex.getMessage().startsWith("Duplicate entry"))
                {
                    messaggio="Attenzione nel foglio caricato sono presenti dei dati che non rispettano i vincoli di univocità del database. " +
                            " Si consiglia di ricontrollare di aver rispettato tutte le regole di caricamento. <br> Dettaglio Messaggio:";
                    messaggio=messaggio+fex.getMessage();
                }
                else
                {
                    messaggio="Attenzione si sono verificati dei problemi nell'inserimento dati sul db. <br>" +
                            "Si consiglia di ricontrollare di aver rispettato tutte le regole di caricamento. Dettaglio Messaggio: ";
                    messaggio=messaggio+fex.getMessage();
                }
            }
            if(messaggio.equals(""))
            {
                messaggio=fex.getMessage();
            }
            request.setAttribute("error", messaggio);
        }
        finally{
            rd.forward(request, response);
        }

Per la lettura del file Excel è molto utile utilizzare Apache POI (vedi post precedenti).

lunedì 14 novembre 2011

Apache Poi esempio lettura cella e riga generica da un xls

Un semplice metodo per prendere da un excel il valore di una certa cella.
La libreria utilizzata è Apache POI 3.7, il metodo accetta come parametri l'oggetto HSSFWorkBook, il nome del foglio Excel su cui ricercare e la riga e colonna esatta dove farlo.
Per istanziare l'oggetto basta la seguente new

HSSFWorkbook wb = new HSSFWorkbook(new FileOutputStream(new File("test.xls")));

private String getContenutoCella(HSSFWorkbook wb,String nomeFoglio,int riga,int colonna){
        String retVal="";
        HSSFSheet sheet=wb.getSheet(nomeFoglio);
        Iterator rows = sheet.rowIterator();
        int rigCont=0;
        while(rows.hasNext()){
            HSSFRow row = (HSSFRow) rows.next();
            rigCont++;
            if(rigCont==riga){
                Iterator cells=row.cellIterator();
                int cellCont=0;
                while(cells.hasNext()){
                    HSSFCell cella=(HSSFCell)cells.next();
                    cellCont++;
                    if(cellCont==colonna){
                        retVal=cella.getRichStringCellValue().getString();
                    }
                   
                }
            }
        }
        return retVal;
    }

venerdì 11 novembre 2011

Maven, installare un jar nel repository locale

Vediamo in questo post come installare un jar creato da noi nel repository locale di maven, in modo da poterlo poi allegare ad altri progetti semplicemente aggiungendo la dipendenza sul file pom (senza quindi aggiungerlo noi ogni volta tra le lib di progetto).

Per prima cosa dobbiamo assegnare un nome a:
  • groupId: di solito qui si specifica il package del nostro jar, comunque la scelta è libera;
  • artifactId: indica il nome univoco da assegnare all'artefatto, il nome deve essere univoco all'interno del groupId;
  • version;
  • packaging (es JAR,WAR, specifica l'output prodotto da Maven);
 Il jar sarà installato nel percorso M2_REPO/goupId/artifactId/version
Quindi specificare dove è presente il nostro jar file con l'opzione -Dfile=e, in alcuni casi (esempio con Maven 2.2) specificare anche l'opzione

-DgeneratePom=true

In modo da assicurarci che il POM sia generato.

Ipotizzando quindi di avere un progetto Java con una sola classe Test così creata, in un package it.prova:

package it.prova;
public class Test {

      public static void main(String[] args) {
        String v=args[0];
       
        int val=Integer.valueOf(v);
        System.out.println("Il fattoriale è "+getFattoriale((long)val)+"");
    }
    public static long getFattoriale(long n){
        if(n==1 || n==0){
            return 1;
        }
        else
        {
            return n*getFattoriale(n-1);
        }       
    }
}

Da eclipse creiamo il jar test.jar

Quindi da console digitiamo:

C:\>mvn install:install-file -Dfile=c:\test.jar -DgroupId=it.prova -DartifactId=myTest -Dversion=1.0 -Dpackaging=jar  -DgeneratePom=true

La console di esecuzione ci darà un messaggio di questo tipo:

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'install'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [install:install-file] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [install:install-file {execution: default-cli}]
[INFO] Installing c:\test.jar to C:\Documents and Settings\user\.m2\repos
itory\it\prova\myTest\1.0\myTest-1.0.jar

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: < 1 second
[INFO] Finished at: Fri Nov 11 13:06:55 CET 2011
[INFO] Final Memory: 3M/15M
[INFO] ------------------------------------------------------------------------

Quindi è possibile verificare che a livello di repository Maven locale è presente la directory evidenziata sopra in grassetto.


Il contenuto della directory è il seguente:


Come possiamo vedere è stato generato anche il pom che è così composto:

<?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>it.prova</groupId>
  <artifactId>myTest</artifactId>
  <version>1.0</version>
  <description>POM was created from install:install-file</description>
</project>


lunedì 7 novembre 2011

NullPointerException su com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack durante parsing Xml con JAX-B

Stavo effettuando il parsing di un xml utilizzando JAXB.

L'xml aveva una struttura di questo tipo

<root>
<lista>
<classpathentry kind="var" path="M2_REPO/javax/transaction/jta/1.0.1B/jta-1.0.1B.jar"/>
.......
</lista>
</root>

La classe JAXB era definita così:

package it.eng.classpathreader;
import java.util.Collection;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="root")
public class MyXml {
    private Collection<ClassPathElement> lista;
    @XmlElementWrapper(name="lista",nillable=true,required=false)
    @XmlElement(name="classpathentry",nillable=true,required=false)
    public Collection<ClassPathElement> getListaElementi() {
          return lista;
    }
    public void setListaUtenti(Collection<ClassPathElement> listaEl) {
          this.lista = listaEl;
    }
    public String toString(){
        StringBuilder sb=new StringBuilder();
        for(ClassPathElement i : lista){
            sb.append(i);
            sb.append("\n");
        }
        return sb.toString();
    }
}

Andando a parsare l'Xm l ho avuto questo errore:



java.lang.NullPointerException
    at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Scope.add(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty$ReceiverImpl.receive(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.endElement(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown Source)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
    at it.eng.classpathreader.Reader.main(Reader.java:21)



Dopo qualche "googlata" ho trovato il problema: la Collection rappresentante la lista di nodi di tipo classpathentry va inizializzata.
Quindi invece di
private Collection<ClassPathElement> lista;
ho scritto
private Collection<ClassPathElement> lista=new ArrayList<ClassPathElement>();
e tutto ha funzionato a dovere.

domenica 6 novembre 2011

Maven per Eclipse

Utilizzando Maven è possibile dato il file pom.xml generare il workspace eclipse direttamente da linea di comando posizionandosi sulla directory contenente il file pom.xml e quindi digitando:

mvn eclipse:eclipse

Viceversa per cancellare il tutto è sufficiente digitare

mvn eclipse:clear

sabato 5 novembre 2011

Verificare se un numero è intero

Un metodo per verificare se il numero dato in input è un intero:

public static boolean checkIfInt(double d){
        boolean retVal=false;
        int v=(int)d;
        if((double)v==d){
            retVal=true;
        }
        return retVal;
    }


martedì 1 novembre 2011

Java Web Services su Tomcat

Di seguito un esempio di WS deployato su tomcat ed invocato da client Java.
Per effettuare il deploy su Tomcat per prima cosa ho dovuto scaricare da qui l'ultima versione di JAX/WS.
Una volta scompattato lo zip ho messo tutti i jar dentro la directory lib di Tomcat 7.
Ho quindi creato un progetto Web da Eclipse.
Ho definito quindi la seguente interfaccia:

package it.ws;
import java.math.BigInteger;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;
@WebService
@SOAPBinding(style=Style.DOCUMENT,use=Use.LITERAL)
public interface FattorialeInt {
public BigInteger getFattoriale(long n);
}

Implementata dalla seguente classe:

package it.ws;
import java.math.BigInteger;
import javax.jws.WebService;
@WebService(endpointInterface="it.ws.FattorialeInt")
public class FattorialeImpl implements FattorialeInt {

    @Override
    public BigInteger getFattoriale(long n) {
        BigInteger fatt=new BigInteger("1");
        for(long i=1;i<=n;i++){
            fatt=fatt.multiply(new BigInteger(String.valueOf(i)));
        }
        return fatt;
    }
   

}

A questo punto, poichè lo style di binding è DOCUMENT e non RPC ho dovuto lanciare dalla console il comando wsgen per generarmi gli artefatti software necessari.
Quindi dalla directory dove sono i .class (quindi in build/class/it/ws, proprio a livello dei file .class)  ho digitato il seguente comando:

wsgen -keep -cp . it.ws.FattorialeImpl

In questo modo sono state generate le seguenti classi
1) GetFattoriale.java
2) GetFattorialeResponse.java

Codice 1

package it.ws.jaxws;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "getFattoriale", namespace = "http://ws.it/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getFattoriale", namespace = "http://ws.it/")
public class GetFattoriale {

    @XmlElement(name = "arg0", namespace = "")
    private long arg0;

    /**
     *
     * @return
     *     returns long
     */
    public long getArg0() {
        return this.arg0;
    }

    /**
     *
     * @param arg0
     *     the value for the arg0 property
     */
    public void setArg0(long arg0) {
        this.arg0 = arg0;
    }

}
Codice 2
package it.ws.jaxws;
import java.math.BigInteger;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement(name = "getFattorialeResponse", namespace = "http://ws.it/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getFattorialeResponse", namespace = "http://ws.it/")
public class GetFattorialeResponse {

    @XmlElement(name = "return", namespace = "")
    private BigInteger _return;

    /**
     *
     * @return
     *     returns BigInteger
     */
    public BigInteger getReturn() {
        return this._return;
    }

    /**
     *
     * @param _return
     *     the value for the _return property
     */
    public void setReturn(BigInteger _return) {
        this._return = _return;
    }

}

A questo punto bisogna effettuare delle configurazioni sul file Web Xml, in particolare bisogna dichiarare

1) la servlet com.sun.xml.ws.transport.http.servlet.WSServlet ;
2) il Listener com.sun.xml.ws.transport.http.servlet.WSServletContextListener

NOTA: per questo serve copiare quei jar dentro la lib di Tomcat
Quindi nel web.xml avremo:

 <servlet>
    <description></description>
    <display-name>WsTest</display-name>
    <servlet-name>FattConvert</servlet-name>
    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>FattConvert</servlet-name>
    <url-pattern>/FattConvert</url-pattern>
  </servlet-mapping>
  <listener>
  <listener-class>
  com.sun.xml.ws.transport.http.servlet.WSServletContextListener
  </listener-class>
  </listener>

Il listener dichiarato ha bisogno del seguente file xml sun-jaxws.xml dove è dichiarato l'endpoint:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint name="FattConvert" implementation="it.ws.FattorialeImpl" url-pattern="/FattConvert"/>
</endpoints>

Notare che bisogna fare in modo che nell'endpoint il name sia uguale al servlet name, l'implementation sia la classe del web service e l'url-pattern sia l'url-pattern della servlet.

Una volta effettuato il deploy il WS è richiamabile al seguente url:

http://localhost:8080/TestWs/FattConvert?wsdl

Per richiamare il Web Service è possibile come sempre generare un client tramite l'utility wsimport (già analizzato in un precedente POST).