Archive

Archive for September, 2009

Simple Java File Logging

September 30th, 2009 No comments

Not much to say about this one, a small one off independent class to simplify the process of logging stuff to file. Something like this is often handy when writing backgrounded daemon processes.

FileLogger class

package Utils;

import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileLogger{
	
	private File logFile;
	
	private long logEntryNo = 0;
	
	private static FileLogger instance = null;
	
	public static final String DEFAULT_LOG_FILEPATH = "bin/Log/Daemon.log";
	
	public FileLogger(String logFilePath){
		logFile = new File(logFilePath);
		try{
			logFile.createNewFile();
		} 
		catch (IOException e) {
			e.printStackTrace();
		}
		calcNumLines();
		instance = this;
	}
	
	public FileLogger(File logFile){
		this.logFile = logFile;
		calcNumLines();
		instance = this;
	}
	
	public static FileLogger getInstance(){
		return instance;
	}

	/**
	 * Adds and entry in the log file but also echos the log to standard out
	 * 
	 * @param data
	 * @param printToStdOut
	 */
	
	public void add(String data,boolean printToStdOut){
		if (printToStdOut){
			System.out.print("\n" + data + "\n");
		}
		add(data);
	}
	
	/**
	 * Add a log file entry
	 * 
	 * @param data
	 */
	
	public synchronized void add(String data){
		DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
		Date date = new Date();
		String dateTime = dateFormat.format(date);
		
		try{
			if (logFile.createNewFile()){
				FileWriter fileWriter = new FileWriter(logFile);
				BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
				bufferedWriter.write("[" + dateTime +  "]#" + ++logEntryNo + ": " + data);
				bufferedWriter.newLine();
				bufferedWriter.close();
			}
			else{
				FileWriter fileWriter = new FileWriter(logFile,true);
				BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
				bufferedWriter.write("[" + dateTime +  "]#" + ++logEntryNo + ": " + data);
				bufferedWriter.newLine();
				bufferedWriter.close();
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void calcNumEntries(){
		try {
			FileReader fileReader = new FileReader(logFile);
			BufferedReader bufferedFileReader = new BufferedReader(fileReader);
			
			try{
				String line;
				while((line = bufferedFileReader.readLine()) != null){
					Pattern p = Pattern.compile("^\\[\\d+\\.\\d+\\.\\d+\\s+\\d+:\\d+:\\d+]#\\d+");
					Matcher m = p.matcher(line);
					
					if (m.find()){
						logEntryNo++;
					}
				}
				bufferedFileReader.close();
			} 
			catch (IOException e){
				e.printStackTrace();
			}
		} 
		catch (FileNotFoundException e){
			// The log file hasn't been created yet so gracefully ignore that fact
		}
	}
	
}

Usage:

FileLogger myFileLogger = new FileLogger(FileLogger.DEFAULT_LOG_FILEPATH);
myFileLogger.add("my log entry");

WordPress: Custom Post Order

September 25th, 2009 No comments

I recently had a requirement for custom ordering on WordPress categories and thought that I would share how I did it.

All that is needed is this piece of code which essentially modifies the SQL statement being generated. Note that the argument assigned to orderby is the column name, hence it is case sensitive (I found out that ID breaks the naming conversion on the post table);

<?php 
   if (is_category(array($myCatId))){
      query_posts($query_string . "&orderby=ID&order=DESC");
   } 
?>

Code needs to be placed before this line

<?php if (have_posts()) : while (have_posts()) : the_post(); update_post_caches($posts); ?>
Categories: Code, General, PHP, Wordpress Tags: ,

Auto Object Population via Reflection

September 24th, 2009 1 comment

Using reflection in the right place can some what simplify certain tasks, in this case the population of Custom classes (data objects). I have supplied below an example of a Class being auto-populated using ResultSet data from a JDBC request (of course it could really be any type of 2D data object).

If a public class variable is declared in the implementation of IModelObject (in this case the implementation is the RemoteConfig class) if the variable name is matched against a column name in the JDBC ResultSet then the value is assigned to the class variable. The great thing is if the variable is not defined in the class then it will quite simply never be populated…obviously as it doesn’t exist :)

In the example below only; String, int and boolean types are supported.

Basic interface class to keep thing reasonably generic

package Model.Objects;

import java.sql.ResultSet;

public interface IModelObject{
	
	public void populate(ResultSet rs);
	
	public String objToString();
	
	public void setDebug(boolean debug);
	
	public boolean getDebug();

}

Implementation of IModelObject which is the Class (data access object) to be auto-populated, (variables; var1, var2, var3, var4 will attempt to be auto-populated)

package Model.Objects;

import java.lang.reflect.*;
import java.sql.ResultSet;
import java.sql.SQLException;

@SuppressWarnings("unused")
public class RemoteConfig implements IModelObject{
	
	// Public variables ONLY are auto-populated using reflection

	public String var1;
	
	public int var2;
	
	public String var3;
	
	public boolean var4;
	
	private ResultSet resultSet;
	
	private static final String REFLECTION_TYPE_INT = "int";
	
	private static final String REFLECTION_TYPE_INTEGER = "Integer";
	
	private static final String REFLECTION_TYPE_STRING = "String";
	
	private static final String REFLECTION_TYPE_BOOLEAN = "boolean";
	
	private boolean debug = false;
	
	public RemoteConfig(){
		// Default constructor
	}
	
	public RemoteConfig(ResultSet rs){
		this.resultSet = rs;
		populate(rs);
	}
	
	public RemoteConfig(ResultSet rs,boolean debug){
		this.resultSet = rs;
		this.setDebug(debug);
		populate(rs);
	}
	
	public void populate(ResultSet rs){
		// NOTE: getFields only returns public variables (which is what we want)
		// if you need all declared variables the use getDeclaredFields
		for(int i=0;i< this.getClass().getFields().length;i++){
			try {
				String varName = this.getClass().getDeclaredFields()[i].getName();
				Field field = this.getClass().getDeclaredField(varName);
				
				try{
					populateClassVarByName(field);
				} 
				catch (IllegalArgumentException e) {
					e.printStackTrace();
				} 
			} 
			catch (SecurityException e) {
				e.printStackTrace();
			}
			catch (NoSuchFieldException e) {
				e.printStackTrace();
			}
		}
		if (debug){
			System.out.print(objToString());
		}
	}
	
	private void populateClassVarByName(Field field){
		try{
			if (field.getType().getSimpleName().equals(REFLECTION_TYPE_INT) || 
				field.getType().getSimpleName().equals(REFLECTION_TYPE_INTEGER)){
			
				try {
					field.set(this,resultSet.getInt(field.getName()));
				} 
				catch (IllegalArgumentException e){
					e.printStackTrace();
				} 
				catch (IllegalAccessException e){
					e.printStackTrace();
				}
			}
			else if (field.getType().getSimpleName().equals(REFLECTION_TYPE_STRING)){
				try{
					field.set(this,resultSet.getString(field.getName()));
				}
				catch (IllegalArgumentException e){
					e.printStackTrace();
				}
				catch (IllegalAccessException e){
					e.printStackTrace();
				}
			}
			else if (field.getType().getSimpleName().equals(REFLECTION_TYPE_BOOLEAN)){
				try{
					if (resultSet.getString(field.getName()).equals("1")){
						field.set(this,true);
					}
					else if (resultSet.getString(field.getName()).equals("0")){
						field.set(this,false);
					}
					else{
						field.set(this,resultSet.getBoolean(field.getName()));
					}
				}
				catch (IllegalArgumentException e){
					e.printStackTrace();
				}
				catch (IllegalAccessException e){
					e.printStackTrace();
				}
			}
			
		} 
		catch (SQLException e){
			System.out.print("\n" + e.toString() + "\n");
		}
	}
	
	public String objToString(){
		String toStringResult = "\n---------" + this.getClass().getName() + "---------\n";
		
		for(int i=0;i< this.getClass().getDeclaredFields().length;i++){
			String varName = this.getClass().getDeclaredFields()[i].getName();
			try{
				Field field = this.getClass().getDeclaredField(varName);
				try {
					toStringResult += varName + ":" + field.get(this) + " (" + field.getType().getSimpleName() + ")\n";
				}
				catch (IllegalArgumentException e) {
					e.printStackTrace();
				} 
				catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			} 
			catch (SecurityException e) {
				e.printStackTrace();
			} 
			catch (NoSuchFieldException e) {
				e.printStackTrace();
			}
		}
		toStringResult += "---------\n";
		
		return toStringResult;
	}
	
	public void setDebug(boolean debug){
		this.debug = debug;
	}
	
	public boolean getDebug(){
		return debug;
	}
}

Basic usage


/**
 * Get you your ResultSet via JDBC and pass it in
 */

RemoteConfig remoteConfig = new RemoteConfig(myResultSet,debug);

New: Google Fast Flip

September 15th, 2009 No comments

Looks like GoogleLabs are working on something new FastFlip, which appears to be a “flippy” news reader. It essentially screen shots important news from various sites, catalogs them and displays them with a “flippy” browse view. In conjunction with the browse view you can drill down and view a screen shot of the websites main page and if need be click and follow through to the actual site.

Google FastFlipGoogle FastFlip

fastflip.googlelabs.com

Categories: General, Google Tags: ,

Java Reflection Examples

September 14th, 2009 No comments

Just to clear the air we are not talking about some funky new graphics render we are talking about programmatic reflection access of variables and methods :)

1. All of the variables public or private in a class can be accessed via reflection, it is assumed for this example that the code is in a class with class variables, hence the usage of “this” (but it doesn’t have to be it could be an instance object). Although we are only echoing the variable name and value to the screen we could be assigning them using the setter functions in the Field class. Really practical usage of this functionality is automatic population of Model classes from the Data Access layer, for example when using SOAP.

for(int i=0;i< this.getClass().getDeclaredFields().length;i++){
	try {
		String varName = this.getClass().getDeclaredFields()[i].getName();
		Field field = this.getClass().getDeclaredField(varName);
		field.setAccessible(true);
				
		try {
			System.out.print("Variablename: " + varName + "\n");
			System.out.print("Value: " + field.get(this).toString() + "\n");
		} 
		catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	} 
	catch (SecurityException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	catch (NoSuchFieldException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

2. This is an example of invoking a method via reflection, again this code assumes you are in a class. Also that class should contain a method called “test” with one String and an argument.

Class<?> params[] = {String.class};
		
try {
	Method method = this.getClass().getDeclaredMethod("test",params);
	try {
		method.invoke(this,"argument!!!!!");
	} 
	catch (IllegalArgumentException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
	catch (IllegalAccessException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
	catch (InvocationTargetException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
} 
catch (SecurityException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
} 
catch (NoSuchMethodException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

Test function to be called via reflection.

public void test(String str){
	System.out.print("Method test invoked via reflection with arg: " + str);
}
Categories: Code, General, Java Tags: ,