Visualizzazione post con etichetta Java. Mostra tutti i post
Visualizzazione post con etichetta Java. Mostra tutti i post

mercoledì 26 giugno 2013

Java: CLI arguments [ENG]

Something useful for when you have to juggle command line parameters in Java.

mercoledì 8 agosto 2012

Java Strings

An interesting article on Javalobby about Java and Strings.

martedì 11 gennaio 2011

Java: Reflect on this [ENG]

Reflection in Java is a powerful tool, expecially useful when your code must get in touch with the outer world (configuration files, database, http protocol...). Here's an example, a simple parser for a CSV string where every value has a tag:

id=1112396889697; t=22740834120; 
x=184549969; y=8389273; f=89; 
q0=0.18810; q1=0.07500; q2=-0.23573; q3=0.96616

What I would like to do here is parsing the data into an object with (a subset of) the fields in each line. The solution is overly simplified, but it just works:

import java.lang.reflect.Field;

public class Sample
{

    class SampleData
    {
        public Long t = new Long(0);
    
        public Long x = new Long(0);
        public Long y = new Long(0);
        public Long f = new Long(0);
    
        public Double q0 = new Double(0);
        public Double q1 = new Double(0);
        public Double q2 = new Double(0);
        public Double q3 = new Double(0);
    }

    private SampleData data = new SampleData();
    
    public Sample(String taggedCsv)
    {
        if (taggedCsv != null && !"".equals(taggedCsv))
        {
            String[] chunks = taggedCsv.split(";");
            for (String chunk : chunks)
            {
                chunk = chunk.trim();
                String[] parts = chunk.split("=");
                String tag = parts[0].trim();
                String value = parts[1].trim();
                try
                {
                    Class<? extends SampleData> class1 = data.getClass();
                    Field f = class1.getField(tag);
                    if (f!=null)
                    {
                        if (f.getType().equals(java.lang.Double.class))
                        {
                            f.set(data, new Double(value));
                        }
                        else
                        if (f.getType().equals(java.lang.Long.class))
                        {
                            f.set(data, new Long(value));
                        }
                    }
                }
                catch (Exception e)
                {
                    System.out.println(e.getMessage());
                }
            }
        }
    }

    public long getT()
    {
        return data.t.longValue();
    }

    public double getX()
    {
        return data.x.longValue();
    }

    public double getY()
    {
        return data.y.longValue();
    }

    public double getF()
    {
        return data.f.longValue();
    }

    public double getQ0()
    {
        return data.q0.doubleValue();
    }

    public double getQ1()
    {
        return data.q1.doubleValue();
    }

    public double getQ2()
    {
        return data.q2.doubleValue();
    }

    public double getQ3()
    {
        return data.q3.doubleValue();
    }

}

It seems like it's doing its job just fine:

    @Test
    public void firstTest()
    {
        Sample a = new Sample(
"id=1112396889697; t=22740834120; " + 
"x=184549969; y=8389273; f=89; " +
"q0=0.18810; q1=0.07500; q2=-0.23573; q3=0.96616"); 
        assertTrue(22740834120L==a.getT());
        assertTrue(184549969L==a.getX());
        assertTrue(8389273L==a.getY());
        
    }

NOTE: there is an awkward thing in the code up there. To obtain encapsulation I had to use a PRIVATE class (DataSample) with PUBLIC fields because getField() can not access PRIVATE fields. There are other ways round, but they are not as lean. Still don't like it, though.

venerdì 6 novembre 2009

Java: reading & writing files [ENG]

Since I can NEVER remember... here's the (very) quick and dirty code to read & write from text files.

private String readFile(String fileName)
  {
    if (fileName==null || "".equals(fileName))
    {
      return null;
    }
    try
    {
      FileReader reader = new FileReader(fileName);
      int next = -1;
      StringBuffer s = new StringBuffer();
      do 
      {
          next = reader.read();  
          if (next != -1) 
          {
              s.append((char)next); 
          }

      } while (next != -1);

      reader.close();  
      return s.toString();
    }
    catch (Exception e)
    {
      log(e.getMessage(), Project.MSG_ERR);
      throw new BuildException(e);
    }
  }
// --------------------------------------------------------

BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) 
{
   // process the line.
}
br.close();  

// --------------------------------------------------------
  private void writeFile(String content, String fileName)
  {
    try
    {
      FileWriter writer = new FileWriter(fileName, false);
      writer.write(content);
      writer.close();
    }
    catch (Exception e)
    {
      log(e.getMessage(), Project.MSG_ERR);
      throw new BuildException(e);
    }
  }

venerdì 17 aprile 2009

mercoledì 26 novembre 2008

Struts2 and WTF8 [ENG]

Struts 2 is, overall, a good piece of software, but as many other frameworks has its annoying shortcomings. For example: it doesn't deal well with UTF8 encoding at all. The solution - found by my colleague Leonardo A. (second name omitted for privacy's sake) - is to use a filter that will set the request encoding.
The source of the workaround is Ian Purton's Blog.
Hope this helps since it was not so easy to smoke out.

martedì 9 settembre 2008

Hibernate Tools: Custom Reverse Engineering/2

Gli Hibernate Tools fanno un discreto lavoro per il reverse Engineering del database, e già personalizzare i modelli usati per la generazione automatica del codice permette di incrementare la produttività.

Si può anche personalizzare la naming convention. Di default infatti una tabella t_utenti verrebbe mappata come TUtenti; se volessimo modificare questo comportamento (magari per togliere il prefisso "T" convenzionale nel database ma abbastanza inutile nel contesto OOP) dovremmo creare una nostra classe che faccia l'override del metodo tableToClassName:

package reveng;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.TableIdentifier;

public class CustomReverseEngineeringStrategy extends DelegatingReverseEngineeringStrategy
{

  private static final String TABLE_PREFIX = "t_";

  private Properties properties = null;
  
  public CustomReverseEngineeringStrategy(ReverseEngineeringStrategy delegate)
  {
    super(delegate);
    try
    {
      properties = getPropertiesFromClasspath("reveng.properties");
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  public static Properties getPropertiesFromClasspath(String propFileName) throws IOException
  {
    
    if (propFileName==null || "".equals(propFileName)) return null;
    
    Properties props = new Properties();
    InputStream inputStream = getInputStreamFromClasspath(propFileName);

    if (inputStream != null)
    {
      props.load(inputStream);
      return props;     
    }

    else
    {
      return null;
    }
  }

  public static InputStream getInputStreamFromClasspath(String resourceFileName)
  {
    return CustomReverseEngineeringStrategy.class.getResourceAsStream(resourceFileName);
  }
  
  @Override
  /**
   * Genera il nome della classe a partire dal nome della tabella, ignorando il prefisso "t_"
   */
  public String tableToClassName(TableIdentifier tableIdentifier)
  {
    String tableName = tableIdentifier.getName();
    
    String className = super.tableToClassName(tableIdentifier);
    String qualifiedName = getPackageName(className);
    
    // default
    String result = className;
    
    // proprietà mappata
    String mappedProperty = (String) properties.get("table."+tableName);
    if (mappedProperty != null && mappedProperty.length()>0)
    {
      result = qualifiedName + "." + mappedProperty;
    }
    // proprietà non mappata, rimuovo il prefisso delle tabelle - se presente
    else if (tableName.startsWith(TABLE_PREFIX))
    {
      String cleanClassName = getClassName(className).substring(1);
      result = qualifiedName + "." + cleanClassName;  
    }
    
    return result;
  }
  
  public String getPackageName(String fullyQualifiedName)
  {
    int dotIndex = fullyQualifiedName.lastIndexOf('.');
    return fullyQualifiedName.substring(0, dotIndex);
  }

  public String getClassName(String fullyQualifiedName)
  {
    int dotIndex = fullyQualifiedName.lastIndexOf('.');
    return fullyQualifiedName.substring(dotIndex+1);
  }
  
  public static void main(String[] args)
  {
    CustomReverseEngineeringStrategy cres = new   CustomReverseEngineeringStrategy(null);
    System.out.println(cres.getPackageName("it.package.test.Class1"));
    System.out.println(cres.getClassName("it.package.test.Class1"));
  }
  
}
NOTA: questa classe tra l'altro cerca un file .properties nel quale siano definite le chiavi table.t_nome_tabella=NomeClasse per un ulteriore livello di personalizzazione.
NOTA2: il metodo main serve solo per effettuare un test

Hibernate Tools: Custom Reverse Engineering/1

Hibernate non sarebbe granché utile se non fosse accompagnato da strumenti che permettono di creare automaticamente le classi POJO, i DAO e i mapping. Cionondimeno il comportamento standard dei tool (v. JBoss Tools) potrebbe non essere quello desiderato.
La configurazione di base si può cambiare aggiustando il file reveng.xml, ma si può andare ben oltre. Ad esempio si potrebbe volere un codice diverso per i DAO (che JBoss Tools chiama "Home") che forniscono - tabella per tabella - gli strumenti di base per cercare, inserire, modificare e cancellare record.
A tal fine è necessario recuperare il template del file in questione dal JAR hibernate-tools che in genere si trova nella cartella del plugin di Eclipse. Una volta scompattata la cartella (conservando la struttura dei package) si possono modificare i file *.ftl desiderati e cancellare quelli non intessanti (il tool prenderà quelli standard dal jar). Bisogna anche far puntare il tool alla cartella dei nuovi template, nella configurazione di lancio.

lunedì 16 giugno 2008

Top Ten Errors Java Programmers Make

Interessante... Top Ten Errors Java Programmers Make.

Aggiungo il mio personalissimo tallone d'achille:

private void foo(MyClass smtg)
{
    smtg = new MyClass();
}

private MyClass bar()
{
    return new MyClass();
}

MyClass mc = null;

foo(mc);

assertNull(mc); // ANCORA NULL! foo() NON HA SIDE EFFECTS!

mc = bar();

assertNotNull(mc); // ORA INIZIALIZZATO

Ancora più interessante, a margine: Overriding vs. Hiding

venerdì 6 giugno 2008

Java native debugging

Segnalo un post di Kohsuke Kawaguchi nel suo blog in cui dà alcune dritte su come effettuare il debugging del codice nativo di Java. Oltre alle ovvie applicazioni (scovare cioè quel bug così profondo nello stack di strati software da sfuggire agli altri strumenti di analisi) Kawaguchi suggerisce di usare questa tecnica per il debug di JNI.

martedì 1 aprile 2008

Java to Assembly

Un interessante esperimento di Johsuke Kawaguchi, di Java.net: che codice assembly viene generato a partire da codice Java?

Deep dive into assembly code from Java (Kohsuke Kawaguchi @ Java.net)