ReVo Blog


Friends

Friends Posts

profile for Marco Acierno at Stack Overflow, Q&A for professional and enthusiast programmers
profile for Marco Acierno on Stack Exchange, a network of free, community-driven Q&A sites
1 user(s) online
F_ACTIVE
1 guests
0 members
0 Anonymous Members
[ View Complete List ]


Last comments


Statistics
F_STATS
ReVo Blog have:
8 articles, 0 comments, 1 members,
167 total visits, 0 monthly visits

The newest member is .ReVo.


B_NORM    
view post Posted on 2/11/2014, 16:22 by: .ReVo. Reply
CODICE
private final static Pattern formatPattern = Pattern.compile("\\{(\\d+)\\}");
   public static String format(String string, Object... args) {
       Matcher matcher = formatPattern.matcher(string);
       StringBuffer builder = new StringBuffer();

       while (matcher.find()) {
           int index = Integer.parseInt(matcher.group(1));

           if (index < 0 || index > args.length) {
               continue;
           }

           matcher.appendReplacement(builder, args[index].toString());
       }
       matcher.appendTail(builder);

       return builder.toString();
   }


CODICE
System.out.println(format("Ciao {0}, come {1}?", "Mondo", "stai"));


Tags:
java
Comments: 0 | Views: 2Last Post by: .ReVo. (2/11/2014, 16:22)
 

B_NORM    
view post Posted on 13/10/2014, 19:26 by: .ReVo. Reply
Se state scrivendo il MANIFEST.MF per il vostro file .jar ricordatevi di aggiungere SEMPRE una nuova linea alla fine o la API Java non leggerà l'ultima chiave presente nel file.

Esempio, se avete questo nel file

CODICE
Manifest-Version: 1.0
Module-Class: com.module.SimpleModule


la classe Manifest conterrà soltando l'attributo Manifest-Version mentre con

CODICE
Manifest-Version: 1.0
Module-Class: com.module.SimpleModule
<spazio>


il vostro file sarà letto correttamente.

Esempio codice

CODICE
for (File file : files) {
           JarFile jarFile = null;

           try {
               jarFile = new JarFile(file);
               Manifest manifest = jarFile.getManifest();

               if (manifest == null) {
                   continue;
               }

               clazzes.add(manifest.getMainAttributes().getValue("Module-Class"));
               urls.add(file.toURI().toURL());
           } catch (IOException e) {
               /* log exception */
           } finally {
               try {
                   jarFile.close();
               } catch (IOException ignored) { }
           }
}


il consiglio è di inserire due spazi alla fine del file, esempio:

CODICE
Manifest-Version: 1.0
Module-Class: com.module.SimpleModule
<spazio>
<spazio>


Personalmente ho deciso di scrivere questo post come promemoria in caso mi succeda di nuovo in futuro. (p.s questo bug è abbastanza strano, ma non mi sono informato molto onli...

Read the whole post...



Tags:
java
Comments: 0 | Views: 3Last Post by: .ReVo. (13/10/2014, 19:26)
 

B_NORM    
view post Posted on 27/8/2014, 14:19 by: .ReVo. Reply
Passato a format la stringa da formttare e in variables le variabili con cui bisogna sostituire le corrispondenze.

CODICE
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* La classe ti permette di formattare una stringa X
* e di sostituire dei blocchi con valori di variabili.
*
* @author Marco Acierno
*/
public class Template {
   private final Pattern pattern;

   public Template(String start, String end) {
       pattern = Pattern.compile(Pattern.quote(start) + "([^}]+)" + Pattern.quote(end));
   }

   public Template() {
       this("{", "}");
   }

   public String format(String text, Map<String, String> variables) {
       Matcher matcher = pattern.matcher(text);
       /* appendReplacement e appendTail accettano solo StringBuffer */
       StringBuffer buffer = new StringBuffer();

       while (matcher.find()) {
           String key = matcher.group(1);
           String value = variables.get(key);

           if (value == null) {
               matcher.appendReplacement(buffer, "{" + key + "}");
               continue;
           }

           matcher.appendReplacement(buffer, value);
       }

       matcher.appendTail(buffer);
       return buffer.toString();
   }
}


Alcuni test-cases per capire come funziona:

CODICE
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.junit.Assert.*;

public class TemplateTest {

   @Test
   public void testFormat() throws Exception {
       Template template = new Template();

       String text = "Hello {who}, {saluto}";
       String result = "Hello ReVo_, ok?";

     ...

Read the whole post...



Tags:
java,
jbucket-api
Comments: 0 | Views: 4Last Post by: .ReVo. (27/8/2014, 14:19)
 

B_NORM    
view post Posted on 19/8/2014, 14:45 by: .ReVo. Reply
Sembra che per Java 9 sarà integrato un parser JSON all'interno del framework stesso, ottima notizia no?

Beh, no.

Lo scopo di questo parser è quello di offrire un soluzione leggera e semplice per JSON e la frase

CITAZIONE
There are existing JSON APIs for Java. The most popular of these generally offer more functionality than the planned API and/or don't take advantage of Java 8/9 language and library features.

lo conferma. Le alternative di cui parla sono (le più famose): Gson e Jackson.

Leggendo la pagina ufficiale qui possiamo farci un'idea di come vorrebbero realizzarlo.

La mia domanda è: Perché?

Perché aggiungere un'altra alternativa al parsing JSON quando Gson e Jackson fanno già un ottimo lavoro? Certo, avere una soluzione integrata rimuovere la necessità di utilizzare una libreria esterna, ma perché realizzarla partendo già con l'idea che sarà inferiore alle alternative? Al momento, Gson fa un ottimo lavoro quando c'è bisogno di lavorare con JSON semplici:

CODICE
User user = new Gson().fromJson(json/reader, User.class);


Fatto! Il JSON è stato convertito nell'oggetto User senza fare altro!

È possibile realizzare un API che renda questo passaggio ancora più semplice?

E se i nomi dei campi JSON sono diversi da quelli della classe?

Basta mettere

CODICE
@SerializedName(nome_nel_json)


sopra il nostro campo ed il problema è risolto! (per non parlare delle altre annotazioni come Since, Until, Expose)

E se il vostro JSON diventa sempre più complesso, lavorare direttamente con il deserializer è praticamente un gioco da ragazzi!

Personalmente spero che non venga realizzato sulla stessa linea dei parser XML come SAX (ad eventi, come parla anche la pagina sul JSON) o DOM (che io apprezzo) in modo da evitare di dover aggiungere altra spazzatura all'interno della JDK (e poi essere costretti a mantenerla viva).

Ma dai, mancano ancora molti anni prima che potremmo avere Java 9 quindi speriamo bene.

Edited by .ReVo. - 19/8/2014, 18:06

Tags:
java,
java9
Comments: 0 | Views: 16Last Post by: .ReVo. (19/8/2014, 14:45)
 

B_NORM    
view post Posted on 1/8/2014, 17:12 by: .ReVo. Reply
Prima o poi capita a tutti di voler lavorare con un Database per salvare i dati degli utenti online, e all'inizio siamo tutti tentati dal realizzare le connessioni, le richieste e la gestione dei dati nella pagina PHP stessa e con codice del genere:

CODICE
$connessione = new MySQLi("localhost", "root", "hello", "world");
$result = $connessione->query("SELECT nome, cognome FROM users");
while ($row = $result->fetch_row()) {
  echo "Utente - Nome: " . $row[0] " . - " . $row[1] . ";<br />";
}
$result->close();
$connessione->close();


In effetti questo codice funziona, ottimo!

Ora immaginiamo che la nostra applicazione stia diventando sempre più grande (yup!): i file PHP aumentano, i dati da leggere e scrivere aumentano, le query diventano più lunghe e faticose ed un semplice errore può causare gravi danni!

La nostra applicazione è diventata cosi grande e fa qualcosa di utile che la vogliamo hostare su altervista (o dove volete) e prima mazzata:

CITAZIONE
Warning: mysqli_connect() [function.mysqli-connect]: Can't connect to MySQL server on 'localhost' (10061) in \myhost\index.php on line 2 Could not connect: Can't connect to MySQL server on 'localhost' (10061)

(l'errore sarà simile a questo, ho preso il primo che è capitato!)

Boom! Vediamo questo errore PHP ovunque, in ogni pagina e non funziona più niente!

Perchè? Beh, i nostri dati connessione

CODICE
$connessione = new MySQLi("localhost", "root", "hello", "world");


(questa parte!)

andavano bene per il nostro server casalingo, ma il nostro hosting online ci ha fornito altri dati per connetterci e per colpa di questo adesso vi ritrovare a modificare ben 40 file php! (numero a caso, potrebbero essere di più!).

Aiuto!



Questa faticata si poteva evitare con una piccola accortezza: avete mai provato a girare per il sorgente di WordPress? C'è un piccolo file (config.php) che viene creato dall'installer di WordPress e contiene 4 linee che potevano salvarci la faticata:

Comments: 0 | Views: 8Last Post by: .ReVo. (1/8/2014, 17:12)
 

B_NORM    
view post Posted on 25/7/2014, 13:50 by: .ReVo. Reply
In questi ultimi giorni mi sono dedicato ad un piccolo progetto "casalingo"... PHPMarkdoc.

PHPMarkdoc



Lo scopo è quello di generare documentazione PHP nel formato Markdown in modo da poterlo usare per inserire la documentazione di una classe in un Wiki di Bitbucket o Github.
L'idea mi è venuta quando dovevo scrivere la documentazione online di alcune classi che avevo creato per un progetto e vedendo che tutti i generatori automatici erano tutti per HTML ho pensato di crearne una mia versione che scrivesse tutto in Markdown.

Il progetto utilizza Java, mentre per legge i file da analizzare viene usato il PHP (php-cgi -f <file_name>). Il file source.php utilizza le API Reflection del PHP per leggere i dati delle classi dell'utente e le memorizza in una struttura Json che sarà letta e convertita in un oggetto FileDoc da Java.

Il codice dell'utente viene iniettato da Java utilizzato un file di "passaggio" che ho chiamato source_injector.php infatti, questo file viene creato da Java ogni volta che è necessario analizzare un file e contiene una singola linea:

CODICE
require_once("URL_DEL_FILE_PHP");


In questo modo, all'interno di source.php è presente il codice PHP della classe (p.s al momento non è presente nessun algoritmo che "blocca" output diversi dal Json di source.php).

Le funzioni get_declared_classes, get_declared_interfaces, get_defined_functions e get_declared_traits si occuperanno di leggere i nomi delle classi dell'utente.

Va notato che, prima di require_once("source_injector.php"); troviamo:

CODICE
$default_classes = get_declared_classes();
$default_interfaces = get_declared_interfaces();
$default_traits = get_declared_traits();


Con questo "trucco", possiamo fare in modo di isolare le classi di PHP da quelle dell'utente utilizzando array_diff.

Non c'è nulla del genere per le funzioni perchè il PHP già fa la divisione con un array interno con [internal] e [user] per differenziare i due tipi, eseguire un array_filter su questo array è obbligatorio per rimuovere da questo elenco le funzioni del parser (infatti, anche se get_defined_functions() viene eseguito prima che il source.php definisca una funzione, il PHP fa una prima l...

Read the whole post...



Tags:
java,
php,
phpmarkdoc
Comments: 0 | Views: 7Last Post by: .ReVo. (25/7/2014, 13:50)
 

B_NORM    
view post Posted on 13/7/2014, 13:24 by: .ReVo. Reply
Questa è una piccola lista di tutti i miei profili online:

Stackoverflow e CodeReview sono i due account dove sono più attivo. I tag che seguo con interesse sono Java, Android e Guava.

Edited by .ReVo. - 13/7/2014, 20:20

Tags:
generale
Comments: 0 | Views: 6Last Post by: .ReVo. (13/7/2014, 13:24)
 

B_NORM    
view post Posted on 13/7/2014, 13:17 by: .ReVo. Reply
Ciao a tutti!

Ho deciso di creare questo blog per "divertimento", credo che posterò qualche immagine divertente e post riguardo alla programmazione (Java, Android e C#, se leggete post che parlano di PHP o Javascript fidatevi che sarà un post pieno di offese verso questi linguaggi).

Posterò anche qualche news riguardo a mie applicazioni a cui sto lavorando o novità sempre riguardo ai miei lavori.

Grazie, ci vediamo. :)

P.S Per i vecchi post, leggere revonline.

Tags:
generale
Comments: 0 | Views: 1Last Post by: .ReVo. (13/7/2014, 13:17)
 

Search: