Something useful for when you have to juggle command line parameters in Java.
mercoledì 26 giugno 2013
mercoledì 8 agosto 2012
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]
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
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
martedì 1 aprile 2008
Java to Assembly
Deep dive into assembly code from Java (Kohsuke Kawaguchi @ Java.net)