http://www.vogella.de/blog/2009/07/15/find-unused-methods/
I really enjoyed this blog entry - it contains all of the code for creating an Eclipse plugin to determine method usage in a table view. Quite handy.
EnMobile DevBlog
Friday, September 4, 2009
Friday, August 7, 2009
Use Smooks to convert Java to XML
I spent a week or so surveying different methods to serialize Java objects into XML. I had some small success with java.beans.XMLEncoder, but it tends to break down with hibernate (workaround) and Enums (with Java 5, fixed in 6).
This solution uses two jars and a very small part of the Smooks api. Just include milyn-smooks-core-1.2.1.jar and milyn-commons-1.2.1.jar in your project and test drive this code:
The XML that gets produced is extremely clean and ready for XSLT data extraction.
Incidentally, the Smooks instance is thread safe and may be cached. The ExecutionContext is not thread safe, which is why it is created for every run.
This solution uses two jars and a very small part of the Smooks api. Just include milyn-smooks-core-1.2.1.jar and milyn-commons-1.2.1.jar in your project and test drive this code:
import java.io.StringWriter;
import java.util.Properties;
import javax.xml.transform.stream.StreamResult;
import org.milyn.GenericReaderConfigurator;
import org.milyn.Smooks;
import org.milyn.container.ExecutionContext;
import org.milyn.payload.JavaSource;
public class Serializer {
private static Smooks smooks;
static {
try {
smooks = new Smooks();
// This configuration uses a sax processor to create the serialize
// xml from the java object. It isn't strictly necessary, but it is
// not a bad idea.
Properties parameters = new Properties();
parameters.put("stream.filter.type", "SAX");
GenericReaderConfigurator readerConfigurator = new GenericReaderConfigurator();
readerConfigurator.setParameters(parameters);
smooks.setReaderConfig(readerConfigurator);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String serialize(Object obj) {
ExecutionContext executionContext = smooks.createExecutionContext();
StringWriter writer = new StringWriter();
smooks.filterSource(executionContext, new JavaSource(obj),
new StreamResult(writer));
return writer.toString();
}
}
The XML that gets produced is extremely clean and ready for XSLT data extraction.
Incidentally, the Smooks instance is thread safe and may be cached. The ExecutionContext is not thread safe, which is why it is created for every run.
Friday, July 31, 2009
UTF-8 encoding problems?
Use this code to find the location of a wayward non-UTF-8 character:
Use this class to automagically scrub out unwanted bad characters:
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
public class CheckEncoding {
public static void main(String[] args) {
FileInputStream fis;
try {
fis = new FileInputStream(new File(args[0]));
CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPORT);
decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
byte[] buff = new byte[1];
int i = 0;
while ((i = fis.read(buff)) > 0) {
System.out.print(decoder.decode(ByteBuffer.wrap(buff, 0, i))
.array());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Use this class to automagically scrub out unwanted bad characters:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
public class UTF8Scrubber extends InputStream {
CharsetDecoder decoder = null;
CharsetEncoder encoder = null;
private InputStream is;
public UTF8Scrubber(InputStream is) {
super();
this.is = is;
decoder = Charset.forName("UTF-8").newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPLACE);
decoder.replaceWith(" ");
decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
encoder = Charset.forName("UTF-8").newEncoder();
}
@Override
public int read() throws IOException {
byte[] b = new byte[1];
if(is.read(b) == 1)
return encoder.encode(decoder.decode(ByteBuffer.wrap(b))).array()[0];
return -1;
}
public static void main(String[] args) throws IOException {
byte[] buff = new byte[1024];
int i = 0;
InputStream is = new UTF8Scrubber(new FileInputStream(new File(args[0])));
while((i=is.read(buff))>0) {
System.out.print(new String(buff,0,i));
}
}
}
Thursday, July 30, 2009
JELDoclet and interface extraction
Today I was asked to help out another developer with some interface extraction work. This type of refactoring is normally tedious on a good day, but this task was especially difficult.
In this particular case, I was presented with 54 classes containing static methods implementing business logic. The developer in question was tasked with creating factories and company subsidiary specific implementations of these business methods, and felt that if I could pull all method signatures, parameter names, and documentation into a single mega-interface, he could easily split this up into smaller interfaces and construct his factories.
As you would expect, I quickly wrote a program based on reflection that almost entirely missed the point and came close to not having any of the information actually needed...
...in walks JELDoclet
JELDoclet is, well, a doclet that works with the javadoc tool to produce XML output rather than the HTML output we're all familiar with. Starting with an ant task:
(replace [] with your project setup)
I very quickly had a jel.xml file that included something like the following:
Now we're getting somewhere.
With the application of a simple xslt to the JELDoclet xml output, I have an interface definition. Try it out!
In this particular case, I was presented with 54 classes containing static methods implementing business logic. The developer in question was tasked with creating factories and company subsidiary specific implementations of these business methods, and felt that if I could pull all method signatures, parameter names, and documentation into a single mega-interface, he could easily split this up into smaller interfaces and construct his factories.
As you would expect, I quickly wrote a program based on reflection that almost entirely missed the point and came close to not having any of the information actually needed...
...in walks JELDoclet
JELDoclet is, well, a doclet that works with the javadoc tool to produce XML output rather than the HTML output we're all familiar with. Starting with an ant task:
<javadoc access="private" additionalparam="-J-Xmx1024m -d [output-dir]"
classpath="[classpath]"
packagenames="[list-of-packagenames]" sourcepath="[source-path]">
<doclet name="com.jeldoclet.JELDoclet" path="[path-to]\jeldoclet.jar"/>
</javadoc>
(replace [] with your project setup)
I very quickly had a jel.xml file that included something like the following:
<jelclass superclass="Object" visibility="public" superclassfulltype="java.lang.Object" fulltype="com.some.Clazz" type="Clazz" package="com.some">
<methods>
<method visibility="public" fulltype="java.util.List" returncomment="List of objects" type="List" name="getObjects" static="true">
<comment>
<description>Get the objects</description>
<attribute name="@param">
<description>refId ref ID</description>
</attribute>
<attribute name="@return">
<description>List of objects</description>
</attribute>
<attribute name="@throws">
<description>SomeException</description>
</attribute>
</comment>
<params>
<param fulltype="java.lang.Long" type="Long" comment="ref ID" name="refId"/>
</params>
<exceptions>
<exception fulltype="com.co.util.SomeException" type="SomeException" comment=""/>
</exceptions>
</method>
</methods>
</jelclass>
Now we're getting somewhere.
With the application of a simple xslt to the JELDoclet xml output, I have an interface definition. Try it out!
//com.some.Clazz
/**
* Get the objects
* @param refId ref ID
* @return List of objects
* @throws SomeException
*/
public java.util.List getObjects(java.lang.Long refId) throws com.co.util.SomeException;
Subscribe to:
Posts (Atom)