martedì 20 settembre 2011

jboss 7: non ci sono i quartz mdb..ma c'è @Schedule

come dicono sul forum ufficiale, " TimerService is already available in 7.0.1 "

http://community.jboss.org/thread/172213?tstart=60

I would suggest to change the MDBs to singletons (EJB3.1) and use the EJB3.1 Timer Service of JEE6. The migration should be quite simple if you do not rely too much on quartz


Per chi non avesse mai provato i nuovi timer in jee6:
http://blogs.oracle.com/arungupta/entry/totd_146_understanding_the_ejb

provare!!!

jboss7: creare servizi rest - json

In jboss7 è semplice creare servizi rest!

Per iniziare basta dare un okkio al progetto di esempio distribuito come applicazione di esempio:
https://docs.jboss.org/author/display/AS7/Kitchensink+quickstart

L'unica difficoltà incontrata, nasce nel voler generare contenuti di tipo json, ovvero segnando i metodi con: @Produces("application/json")
Il problema riscontrato nasce nel mapping di relazioni di tipo @OneToMany, o meglio nell'escludere queste relazioni dal mapping del risultato (evitando l'errore:
org.codehaus.jackson.map.JsonMappingException: failed to lazily initialize a collection of role
date un okkio a questo post sul jbo7 forum: http://community.jboss.org/thread/169352 )

Facciamo un esempio pratico...
Immaginiamo di avere due entity Percorso, Punto (un percorso ha una relazione @OneToMany con i punti che lo costituiscono).

@Table(name = "percorsi")
@Entity
@XmlRootElement
public class Percorso implements Serializable {
private Long id;
private String nome;
        private List<Punto> punti;
.....

        @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getNome() {
return nome;
}

public void setNome(String nome) {
this.nome = nome;
}

       @OneToMany(fetch = FetchType.LAZY, mappedBy = "percorso")
@XmlTransient
@JsonIgnore
public List<Punto> getPunti() {
if (punti == null)
this.punti = new ArrayList<Punto>();
return this.punti;
}

public void setPunti(List<Punto> punti) {
this.punti = punti;
}
}

@Table(name = "punti")
@Entity
@XmlRootElement
public class Punto implements Serializable {
private Long id;
private Percorso percorso;


       @Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}


        @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_percorso")
@XmlTransient
@JsonIgnore
public Percorso getPercorso() {
return percorso;
}

public void setPercorso(Percorso percorso) {
this.percorso = percorso;
}
}

Immaginiamo di generare un servizio rest,

@Path("/v1/percorsi")
@RequestScoped
public class PercorsiREST {

.....

che permette di recuperare un percorso:

        // repository che gestisce il caricamento da db dei dati
        @Inject
PercorsiRepository percorsiRepository;

@GET
@Path("/{id:[0-9][0-9]*}")
@Produces("application/json")
public Percorso getPercorsoById(@PathParam("id") long id) {
Percorso percorso = percorsiRepository.fetch(id);
if (percorso == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return percorso;
}

Saremo in grado di invocarlo all'indirizzo: http://localhost:8080/primetracks/rest/v1/percorsi/3 e restituirà una risposta json del tipo:
 
 [{"id":3,"nome":"04-08-2011"}]

Dato che la collezione di punti è stata annotata con @JsonIgnore i punti non verranno restituiti nel corpo della risposta.
Conoscendo l'id del percorso andremo ad invocare un secondo metodo, che fornisce i punti che lo compongono:

        @GET
@Path("/{id:[0-9][0-9]*}/punti")
@Produces("application/json")
public List<Punto> getPuntiByPercorsoId(@PathParam("id") long id) {
Percorso percorso = percorsiRepository.fetch(id);
if (percorso == null) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return percorso.getPunti();
}
Che invocheremo all'indirizzo: http://localhost:8080/primetracks/rest/v1/percorsi/3/punti e restituirà una risposta json del tipo:

[{"id":130}, {"id":131}]

Do notare come l'annotazione @XmlTransient , svolge la stessa funzione nel caso si voglia mostrare il risultato in formato xml, usando @Produces("text/xml") al posto  di @Produces("application/json").

Ultima nota, per usare l'annotazione @JsonIgnore va aggiunto in maven:
                 <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.6.3</version>
</dependency>
Inoltre per usare a runtime questa libreria, presente tra i moduli di jboss7, va aggiunto nel META-INF/MANIFEST.MF:
Dependencies: org.codehaus.jackson.jackson-core-asl


Provate!!



sabato 10 settembre 2011

recupero files eliminati

se vi capita di cancellare dei files per sbaglio, date un okkio qui:

http://ubuntumanual.org/posts/357/recover-your-deleted-files-in-ubuntu

io non ci sono riuscito..e alla fine mi sono riscritto il codice perso...

comunque provate questo:
Photorec


Scaricato il tar.gz, usate il comando:
./photorec_static


seguendo il wizard e l'artcioletto citato sopra, si riesce a lanciare il recupero che produce una serie di cartelline, da setacciare per recuperare il/i file perso/i. I files vengono ripristinati in ordine non ben definito nelle cartelline, e diventa difficila recuperare un file/un tipo di files...


andate di shell con qualche comando simile a questo (immaginate di avere nella cartella test5 il risultato del ripristino e di copiare i file .java in una cartella .java):

find test5 -name \*.java -exec  cp {} test_java/ \;



in bocca al lupoo!

cercare data più vicina in una lista di date

Immaginate di avere una lista ordinata di date.
Immaginate di dover trovare la data nella lista + vicina alla data proposta.


  • Utilizziamo un TreeSet per le funzioni lower e higher (per trovare la data nella lista che la precede e la data nella lista successiva) e joda-time per calcolare gli intervalli tra le date
  • calcoliamo la distanza tra la data  proposta e le due date precedente e successivo
  • restituiamo come risultato la data che genera intervallo di minore durata.
Ecco l'esempio intero...si capisce al volo.. [nel codice vanno gestite le eccezioni ...es. lista date vuota...]



package by.giava.mytrips.test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TreeSet;

import org.joda.time.DateTime;
import org.joda.time.Interval;

public class DateTree {
private TreeSet<Date> treeset;

public DateTree() {
this.treeset = new TreeSet<Date>();
}

public void reset() {
this.treeset = new TreeSet<Date>();
}

public void add(Date data) {
getTreeset().add(data);
}

public TreeSet<Date> getTreeset() {
return treeset;
}

public void setTreeset(TreeSet<Date> treeset) {
this.treeset = treeset;
}

public Date nearest(Date data) {
DateTime dataF = new DateTime(data);

Date dataMin = getTreeset().lower(data);
DateTime dataMinJ = new DateTime(dataMin);

Date dataMax = getTreeset().higher(data);
DateTime dataMaxJ = new DateTime(dataMax);

Interval periodMin = new Interval(dataMinJ, dataF);
Interval periodMax = new Interval(dataF, dataMaxJ);

if (periodMin.toDurationMillis() <= periodMax.toDurationMillis()) {
return dataMin;
} else {
return dataMax;
}
}

public static void main(String[] args) throws ParseException {
SimpleDateFormat form = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
DateTree dat = new DateTree();
dat.add(form.parse("01-01-2011 10:30:00"));
dat.add(form.parse("01-01-2011 10:50:00"));
dat.add(form.parse("01-01-2011 11:00:00"));

Date result = dat.nearest(form.parse("01-01-2011 10:56:00"));
System.out.println(result);
}
}