Thursday, December 13, 2007

Serializable connection?

JDBC DataSource is the evolution of classic JDBC DriverManager. It is an entity that doles out database connections.
1) automatically pool and reuse database connection
2) DataSource objects can be stored in JNDI tree. i.e., it is serializable. How can we serialize a connection? The secret is that it does RMI-based proxy for JDBC connections. The actual connections are in the server JVM, but RMI connection (stub object) is sent to external clients, which do their JDBC calls, which ferry to the connection and ferry back results.
*** The RMI stub object is network aware reference to remote object and it is serializable.

Thursday, December 6, 2007

Spring AOP & Robotic Spiders

- Definition
# Advice
It contains the logic of your aspect. Also because Spring's jointPoint model is built around method interception. There are four types of advice types in Spring: Around, Before, After, Throws.

# PointCut
It defines where advices is woven into classes. It determines if a particular method on a particular class mataches a particular criterion. There are static and dynamic pointcut. Spring provides two static pointcuts: StaticMethodMatcherPointcut and RegexpMethodPointcut.

It seems a good practice to use annotation to identify the pointcuts and achieve a good balance between xml config and annotation, e.g.,
  public boolean matches(Method method, Class targetClass) {
     boolean isAnnotationPresent = method.isAnnotationPresent(Auditable.class);

# Advisor
It combine advice and pointcuts into one object. Most of Spring pointcuts have a corresponding pointcutAdvisor such as StaticMethodMatcherPointcutAdvisor.

public interface PointcutAdvisor {
  Pointcut getPointcut();
  Advice getAdvice();

- The ProxyFactoryBean class is a central class for explicitly creating proxied
objects within a BeanFactory. As demonstrated, you can give it an interface to
implement, a target object to proxy, and advice to weave in, and it will create a
brand-new proxied object. (dynamically create proxy class)

<bean id="kwikEMart" class="org.springframework.aop.framework.ProxyFactoryBean" >
   <property name="proxyInterfaces">
   <property name="interceptorNames">
   <property name="target"><ref bean="kwikEMartTarget"/>

The interceptorNames is the bean names of the advice to be applied to the target. It can be names of interceptors, advisors, or any other advice type.

The proxied objects will be created when it loads all of the beans from the BeanFactory on runtime. (aspect weaving could happen on compile time or class load time too which requires special compiler and classloader).
*** It is interesting to know that webwork (Struts2) interceptor uses different mechanism though they shares the same AOP concepts. It doesn't create proxy objects (classes) or modify byte code. It applies command pattern to decouple the caller and called action, ActionInvocation keeps a stack of interceptor, and it calls intercept() one by one until it reach the execute() of action instance. After result is return, the interceptors is invoked in reverse order. The magic exists in actionInvocation.invoke() which is a recursive call.

- Auto Proxy
For large application, it become cumbersome to explicitly create each proxy object using the ProxyFactoryBean. BeanNameAutoProxyCreator create proxies for beans that match a set of names. The more powerful autoproxy creator is the DefaultAdvisorAutoProxyCreator. The magic of it lies within its implementation of BeanPostProcessor interface. After you bean's definition have been read in by the ApplicationContext, the DefaultAdvisorAutoProxyCreator scours the context for any advisors. It then applied these advisors to any beans that match the advisor's pointcut. - It is like robotic spiders where unleashed to find Tom Cruise in Minority Report.

<bean id="performanceThreasholdInterceptor" ...>...</bean>
<bean id="advisor" class="...RegexpMethodPointcutAdvisor">
  <property name="advice">
    <bean class="performanceThresholdInterceptor"/>
  <property name="pattern">
<bean id="autoProxyCreator" class=".....DefaultAdvisorAutoProxyCreator"/>

Tuesday, December 4, 2007

CSS table layout

div.row {
clear: both;
padding-top: 5px;

div.row span.label {
float: left;
width: 100px;
text-align: right;

div.row span.formw {
float: right;
width: 235px;
text-align: left;

Span is inline element, and text-align can only be used inside a block element to align its content. So why can we use it here? The secret is that with 'float' defined, span is escalated to block level element, as you implicitly added a "display: block" to it.

Java File IO

“Bridge/Filter” classes: InputStreamReader (<-FileReader) converts an InputStream to a Reader and OutputStreamWriter (<-FileWriter) converts an OutputStream to a Writer.

- Two basic file format: binary vs ASCII
For example, integer 268
In binary representation, recall that in Java, integers are stored in 2's complement using 4 bytes of storage. Thus, 268 has the internal representation: 00000000 00000000 00000001 00001100
In ASCII representation, which would mean saving the ASCII code for the digits "2", "6", and "8". The code is

"2" = 50(10) = 00110010(2)
"6" = 54(10) = 00110110(2)
"8" = 56(10) = 00111000(2)

Thus, 268 would be written to the file as
00110010 00110110 00111000

The advantages of ACII Format
* ASCII text can be understood by any text editor.
* The file can be edited by hand if you wish to change information.
The disadvantages of ASCII Format
* Storing in ASCII requires first converting the number to ASCII
* In the above example, the ASCII version took less space (3 bytes vs 4 bytes). However, more typically, ASCII takes up more space and so your file will be bigger. For example, the number 10245 uses 5 bytes in ASCII rather than 4 in binary.
* ASCII only allows for 256 characters.

- Writing to an ASCII file using PrintWriter

File myFile = new File("DataFiles\\stuff.dat");

// Create an Output Stream
FileOutputStream outStream = new FileOutputStream(myFile);

// Filter bytes to ASCII
PrintWriter out = new PrintWriter(outStream);

// Here we actually write to file
out.println("Hello, this is a test.");

// Reading from an ASCII file using BufferedReader
File myFile = new File("DataFiles\\stuff.dat");
// Create a Character Input Stream
// Note: FileReader inherits from InputStreamReader, which is a bridge from byte
// streams to character streams
FileReader inStream = new FileReader(myFile)

// Filter the Input Stream - buffers characters for efficiency
BufferedReader in = new BufferedReader(inStream);

String first = in.readLine();
String second = in.readLine();
if (second == null) System.out.println("End of file reached.");

Thinking in Java / IO
File Input and Output