Saturday, January 31, 2009

2D acceleration blurs out pages - Adobe Reader

If you find pages in Adobe Reader fading out as shown below, then it means the 2D acceleration API is not functioning as expected.


You may want to turn it off to get rid of the above effect. Now goto the preferences page in the Reader and select Page Display section. Unselect the choice box shown below.

 

That should solve your problem.

Friday, January 30, 2009

Python under Moon light

After reading this post I thought of comparing the performance of python against the lightweight scripting language Lua. So to have a fair comparison I ported the MorseCode encoder/decoder wirtten in python into a Lua script with no change to the logic or the sequence.



--morse code table
codes = {
['!'] = "-.-.--", [' '] = "|", ['"'] = ".-..-.", ['$'] = "...-..-",
['\''] = ".----.", ['&'] = ".-...", [')'] = "-.--.-", ['('] = "-.--.",
['+'] = ".-.-.", ['-'] = "-....-", [','] = "--..--", ['/'] = "-..-.",
['.'] = ".-.-.-", ['1'] = ".----", ['0'] = "-----", ['3'] = "...--",
['2'] = "..---", ['5'] = ".....", ['4'] = "....-", ['7'] = "--...",
['6'] = "-....", ['9'] = "----.", ['8'] = "---..", [';'] = "-.-.-",
[':'] = "---...", ['='] = "-...-", ['?'] = "..--..", ['A'] = ".-",
['@'] = ".--.-.", ['C'] = "-.-.", ['B'] = "-...", ['E'] = ".",
['D'] = "-..", ['G'] = "--.", ['F'] = "..-.", ['I'] = "..",
['H'] = "....", ['K'] = "-.-", ['J'] = ".---", ['M'] = "--",
['L'] = ".-..", ['O'] = "---", ['N'] = "-.", ['Q'] = "--.-",
['P'] = ".--.", ['S'] = "...", ['R'] = ".-.", ['U'] = "..-",
['T'] = "-", ['W'] = ".--", ['V'] = "...-", ['Y'] = "-.--",
['X'] = "-..-", ['Z'] = "--..", ['_'] = "..--.-"
}


binary = {['.']="10",['-']="1110",[',']="000",['|']="0000000"}


function encode(value)
--encodes the value into morse code
value = string.upper(value)
value = string.gsub(value,'%*', 'X')
value = string.gsub(value,'%^', 'XX')
local morse_value=""
local length = string.len(value)
local i = 1
while i <= length do
local chr = string.sub(value,i,i)
if chr then
morse_value = morse_value .. codes[chr] .. ","
end
i = i + 1
end
return _get_binary(morse_value)
end

function _get_binary(value)
local binary_value = ""
local length = string.len(value)
local i = 1
while i <= length do
local chr = string.sub(value,i,i)
if chr then
binary_value = binary_value .. binary[chr]
end
i = i + 1
end
return binary_value
end

function decode(morse_code_value)
-- decodes the morse bytes
decoded_value = _decode_binary(morse_code_value)
ascii_value=""
for w in string.gfind(decoded_value, "[-.|]+") do
ascii_value = ascii_value .. _get_key(w)
end
return ascii_value
end

function _get_key(value)
--returns the key for the given value
for k, v in next, codes do
if v == value then
return k
end
end
return ''
end

function _decode_binary(binary)
dah_replaced = string.gsub(binary,'1110', '-')
dit_replaced = string.gsub(dah_replaced,'10', '.')
comma_replaced = string.gsub(dit_replaced,'000', ',')
zero_replaced = string.gsub(comma_replaced,'0', '|,')
return zero_replaced
end

function print_usage()
print("Usage : "..arg[0].." [d (decode) |e (encode)] [input string]")
end


if arg[1] == nil then
print_usage()
else
if arg[1] == 'd' then
print("Decoded value : "..decode(arg[2]))
elseif arg[1] == 'e' then
if arg[2] == nil then
print_usage()
else
print("Encoded value : "..encode(arg[2]))
end
else
print("Encoded value : "..encode(arg[1]))
end
end



The Lua script was much faster than the python one. May be i have not written the python script in an optimistic way, but logic remains the same.

Aanand Natarajan@AANAND /h/MorseEnDecode/src
$ time python MorseEnDecode.py aanand
encoding
Encoded : 10111000010111000011101000010111000011101000011101010000

real 0m0.140s
user 0m0.015s
sys 0m0.015s

Aanand Natarajan@AANAND /h/MorseEnDecode/src
$ time lua MorseEnDecode.lua aanand
Encoded value : 10111000010111000011101000010111000011101000011101010000

real 0m0.031s
user 0m0.015s
sys 0m0.015s


Look at the real time which is 0.140 seconds for the Python version and 0.31 seconds for the Lua version.
This doesn't mean Python is not fast. I like Python as a language, for its features and its highly performant comparing against many other scripting languages.

Monday, January 26, 2009

Morse code encoder/decoder

This is a Morse code encoder/decoder program written in python. Simply pass a string that contains Morse code supported characters and you'll see a binary format of the string, encoded as Morse code as specified @ http://en.wikipedia.org/wiki/Morse_code.

  1. short mark, dot or 'dit' (·) — 1
  2. longer mark, dash or 'dah' (–) — 111
  3. intra-character gap (between the dots and dashes within a character) — 0
  4. short gap (between letters) — 000
  5. medium gap (between words) — 0000000


#!/usr/bin/python
import sys
__author__="Aanand Natarajan"

#morse code dictionary
codes = {'1':".----",'2':"..---",'3':"...--",'4':"....-",'5':".....",'6':"-....",'7':"--...",'8':"---..",
'9':"----.",'0':"-----",'A':".-",'B':"-...",'C':"-.-.",'D':"-..",'E':".",'F':"..-.",'G':"--.",
'H':"....",'I':"..",'J':".---",'K':"-.-",'L':".-..",'M':"--",'N':"-.",'O':"---",'P':".--.",
'Q':"--.-",'R':".-.",'S':"...",'T':"-",'U':"..-",'V':"...-",'W':".--",'X':"-..-",'Y':"-.--",
'Z':"--..",
#punctuations
',':"--..--",'.':".-.-.-",'?':"..--..",';':"-.-.-",':':"---...",'/':"-..-.",
'-':"-....-","'":".----.",'(':"-.--.",')':"-.--.-",'!':"-.-.--",'&':".-...",
'=':"-...-",'+':".-.-.",'_':"..--.-",'"':".-..-.",'$':"...-..-",'@':".--.-.",
#space
' ':"|"}

binary = {'.':'10','-':'1110',',':'000','|':'0000000'}


def encode(value):
""" encodes the value into morse code """
morse_value=""
value.replace('*', 'X')
value.replace('^', 'XX')
for c in value:
try :
morse_value += codes[c.upper()]+','
except :
print "Unintended character " + c + " omitted"
return _get_binary(morse_value)

def decode(morse_code_value):
""" decodes the morse bytes """
decoded_value = _decode_binary(morse_code_value)
ascii_value=""
for v in decoded_value.split(","):
ascii_value += _get_key(v)
return ascii_value

def _get_binary(value):
binary_value = ""
for c in value:
binary_value += binary[c]
return binary_value

def _get_key(value):
""" returns the key for the given value """
for k,v in codes.items():
if v == value:
return k
return ''

def _decode_binary(binary):
dah_replaced = binary.replace('1110', '-')
dit_replaced = dah_replaced.replace('10', '.')
comma_replaced = dit_replaced.replace('000', ',')
zero_replaced = comma_replaced.replace('0', '|,')
return zero_replaced

def _do_decode(value):
print "Decoded : "+decode(value)

def _do_encode(value):
print "Encoded : "+encode(value)

if __name__ == "__main__":
if len(sys.argv) > 2:
if sys.argv[1] == 'd' :
print "decoding"
_do_decode(sys.argv[2])
else:
print "encoding"
_do_encode(sys.argv[2])
elif len(sys.argv) > 1:
print "encoding"
_do_encode(sys.argv[1])
else:
print "Usage : "+sys.argv[0]+" [d (decode) |e (encode)] [input string]"


Usage:
aanand@AanandDL:~$ ./MorseEnDecode.py "aanand aka tuxaanand"
encoding
Encoded : 101110000101110000111010000101110000111010000111010
1000000000000001011100001110101110000101110000000000000011100
0010101110000111010101110000101110000101110000111010000101110
00011101000011101010000
aanand@AanandDL:~$ ./MorseEnDecode.py d "1011100001011100001110
100001011100001110100001110101000000000000001011100001110101110
000101110000000000000011100001010111000011101010111000010111000
010111000011101000010111000011101000011101010000"
decoding
Decoded : AANAND AKA TUXAANAND
aanand@AanandDL:~$

Wednesday, December 24, 2008

Numerology in Erlang

After a long time, again with the same problem but using a different language. I have been watching the talks on Erlang - about its strength and stability. I thought why not give it a try.

This is the same numerology problem written in Erlang.


-module(numero).
-export([value/1,start/1]).

start(Args) -> value(lists:nth(1,Args)).

value(NAME) -> io:write(sum(0,lists:sum([val(A) || A <- NAME]))),io:nl(),halt().

sum(SUM,NUM) when NUM > 0 -> Q = NUM,
R = Q rem 10,
NEWQ = Q div 10,
sum(SUM + R,NEWQ);
sum(SUM,0) ->
if
SUM > 9 -> sum(0,SUM);
true -> SUM
end.


val(C) ->
if
(($A =:= C) or ($J =:= C) or ($I =:= C) or ($Y =:= C) or ($Q =:= C)) -> 1;
(($B =:= C) or ($K =:= C) or ($R =:= C)) -> 2;
(($S =:= C) or ($C =:= C) or ($L =:= C) or ($G =:= C)) -> 3;
(($T =:= C) or ($D =:= C) or ($M =:= C)) -> 4;
(($E =:= C) or ($N =:= C) or ($X =:= C) or ($H =:= C)) -> 5;
(($U =:= C) or ($V =:= C) or ($W =:= C)) -> 6;
(($O =:= C) or ($Z =:= C)) -> 7;
(($F =:= C) or ($P =:= C)) -> 8;
true -> 0
end.

Saturday, September 27, 2008

Netbeans setting jvmargs for SHIFT-F6

In Netbeans there is an option to run the current file. It works fine until we need the option to set a JVM argument.
I hit the same problem and was searching the build xml for target that runs the file and customize it. But accidentally found a property runmain.jvmargs in project.properties file and set the JVM args that i wanted and it worked.

--> {project}/nbproject/project.properties (runmain.jvmargs)

This also works for web projects.

Sunday, July 13, 2008

Numerology with Ruby

This is a simple Numerology calculator written in ruby. Just a pass time program while learning ruby.
This will give you the value of the given name and date (date of birth)
Usage:
./numerology.rb <your_name> <date> <month> <year>


#!/usr/bin/env ruby
class Numerology
@name
@date
@month
@year
$map = {'A' => 1, 'J' =>1, 'I' =>1, 'Y' => 1, 'Q' => 1,
'B' => 2, 'K' => 2, 'R' => 2,
'S' =>3, 'C' =>3, 'L' =>3, 'G' => 3,
'T' => 4, 'D' => 4, 'M' => 4,
'E' =>5, 'N' => 5, 'X' =>5, 'H' => 5,
'U' => 6, 'V' => 6, 'W'=>6,
'O' =>7, 'Z' => 7,
'F' =>8, 'P' => 8 ,
' ' => '' #for removing spaces
}

def initialize(name,date,month,year)
if name.nil? or name.empty?
raise "Please provide a name"
end
@name = name.upcase
@date = date.to_i
@month = month.to_i
@year = year.to_i
if @date == 0 or @month == 0 or @year == 0
raise "Please provide a valid date"
end
end

def calculate
puts "Name : #{@name} \n"
puts "Date : #{@date}/#{@month}/#{@year} \n"
sum = 0

#old version
#~ Range.new(0,@name.length).each do|n|
#~ #puts "char at #{n} = #{@name[n]}"
#~ #print @name[n]
#~ case @name[n]
#~ when ?A , ?J , ?I , ?Y , ?Q then sum = sum + 1
#~ when ?B , ?K , ?R then sum = sum + 2
#~ when ?S , ?C, ?L, ?G then sum = sum +3
#~ when ?T, ?D, ?M then sum = sum +4
#~ when ?E, ?N, ?X, ?H then sum = sum + 5
#~ when ?U, ?V, ?W then sum = sum + 6
#~ when ?O, ?Z then sum = sum + 7
#~ when ?F, ?P then sum = sum +8
#~ end
#~ while sum > 9
#~ sum = sum_digits(sum)
#~ end
#~ end

#replace the chararcters with thier numberic equivalent
#map contains key value pairs - A : 1, B : 2....
#replace each char (key in map) in the string with the value from the map
$map.each do |k,v|
@name.gsub!(k, v.to_s)
end

#find the sum of digits until the sum is single digit
sum = @name.to_i
while sum > 9
sum = sum_digits(sum)
end

#calculate sum value for date of birth
dateSum = @date + @month + @year
while dateSum > 9
dateSum = sum_digits(dateSum)
end

print "Name value :#{sum}\n"
print "Date value :#{dateSum}\n"

end

private
#sum the digits of the given number
def sum_digits(num)
sum = 0
quotient = num
while quotient > 0
#puts "sum : #{sum}, reminder: #{reminder}, quotient: #{quotient}"
reminder = quotient % 10
quotient = quotient / 10
sum = sum + reminder
end
return sum
end
end


if __FILE__ == $0
begin
num = Numerology.new(ARGV[0],ARGV[1],ARGV[2],ARGV[3])
num.calculate
rescue => ex
puts "Error : #{ex.message}"
end
end

Friday, March 28, 2008

Komodo may be the choice now....

I have been looking for an open source feature rich IDE for dynamic languages such as Python, ruby and Javascript. Now that ActiveState has released an opensource version of its Komodo, that may be become a primary choice for dynamic languages.

http://www.activestate.com/Products/komodo_ide/komodo_edit.mhtml

No more pydev - a huge junk of java for editing python files.

Thanks a lot ActiveState....

Sunday, February 10, 2008

GWT - FlexTable with frozen header

DataGrids displaying a huge set of data with header for each column would be better usable with its header row frozen.
Plain HTML tables, with frozen header are very simple to create.

  1. Create THEAD and TBODY elements.
  2. For TBODY element's style set overflow: auto or scroll;
  3. Set fixed size for the TBODY element
In GWT, a table created using either using Grid or FlexTable, creates only TBODY element and no THEAD element.
So to render a table with frozen header, in GWT we'll have to extend either Grid or FlexTable with a THEAD element and a few getter and setter methods for accessing the THEAD columns.



package name.aanand.magix.client;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Widget;


public class DataGrid extends FlexTable {

private Element head;
private Element headerTr;

public DataGrid() {
super();
head = DOM.createTHead();
headerTr = DOM.createTR();
DOM.insertChild(this.getElement(), head, 0);
DOM.insertChild(head, headerTr, 0);
Element tBody = getBodyElement();
DOM.setElementAttribute(tBody, "style", "overflow:auto;text-align: left;");
DOM.setElementAttribute(head, "style", "text-align: left;");

}

public void setHeight(String height) {
DOM.setElementAttribute(getBodyElement(), "height", height);
}

public void setHeader(int column,String text){
prepareHeader(column);
if (text != null) {
DOM.setInnerText(DOM.getChild(headerTr, column), text);
}
}

private void prepareHeader(int column) {
if (column < 0) {
throw new IndexOutOfBoundsException(
"Cannot create a column with a negative index: " + column);
}
int cellCount = DOM.getChildCount(headerTr);
int required = column + 1 - cellCount;
if (required > 0) {
addCells(head, 0, required);
}
}


public void setHeaderWidget(int column, Widget widget) {
prepareHeader(column);
if (widget != null) {
widget.removeFromParent();
// Physical attach.
DOM.appendChild(DOM.getChild(headerTr, column), widget.getElement());

adopt(widget);
}
}

private native void addCells(Element table, int row, int num)/*-{
var rowElem = table.rows[row];
for(var i = 0; i < num; i++){
var cell = $doc.createElement("td");
rowElem.appendChild(cell);
}
}-*/;

Monday, November 12, 2007

Buggy IE

IE fails to parse <script> content if its in XHTML shorthand format that is <script src="some.js" type="text/javascript" />.
But works fine in Firefox and other mozilla based browsers.

To fix this one has expand the tag as follows:

<script src="some.js" type="text/javascript">
</script>

I checked it with IE 6, may be in version 7 it could be working..

Blogged with Flock

Sunday, November 04, 2007

GWT and its package names

Recently I and my friend came across a silly bug that took nearly half a day for us to find a solution for it. The bug that i encountered is with the GWTCompiler.

We had some compilation problems when we started writing an Async interface for one of our services. The error log said that the Proxy class that was generated by GWT for deferred binding had some errors.
It pointed out at some line and read com.google was not resolved. But the snapshot of the file was pretty clean and had no errors.
At first i thought it was some classpath problem, but after fighting and struggling with it for about 2 hours or so my friend suddenly popped up with a doubt, eyeing at the Async interface's method which had a parameter named com.

That's it; it is not able to resolve packages, if there is any variable declared with same name as the package.

For example

//imports
public interface MyServiceAsync{
public void save(SomeType com, CallBack c);
}

This Async interface will produce errors while compiling. So make sure that you don't name the variables with any package names.

Friday, October 12, 2007

Class.forName("fully.qualified.ClassName").newInstance() in GWT

In Java, when we design something to work generically like loading a plugin Class or something like that, we use the classloader to load some arbitrary class and instantiate it using the Class.newInstance() (Assuming that our Class has a Zero argument constructor) or using the constructors through the Class's getConstructor method.

This feature cannot be used in GWT, as you may all know that the client code (JavaScript) is statically generated. There is no Classloader or no Class.newInstance() or no reflection at all in Javascript. So to provide very least feature of instantiating a Class by knowing its classname, here is a tip that you may like.

We may not require all the Class types to be available for dynamic instantiation. So we are gonna mark the required Class types as Instantiable (A marker interface).
Now, we need some factory class which has a method newInstance(String className), using which we can create an instance of specified classname.



1 package name.aanand.gwt.client;

2

3
/**

4 * Platform factory to create instance of any {@link Instantiable} type.

5 * @author aanandn

6 *

7 */

8 public interface Factory {

9 Instantiable getInstance(String className);

10 }




Now we are gonna create a Class called ReflectiveFactory which is defined as follows...


1 package name.aanand.gwt.client;

2

3

4 /**

5 * Factory class for instantiating any {@link Instantiable} type by providing

6 * the fully qualified Class name.

7 * @author aanandn

8 *

9 */

10 public class ReflectiveFactory implements FactoryWrapper{

11 }


The ReflectiveFactory implements an interface called FactoryWrapper which is again a marker interface to identify the factory classes for which Wrapper implementations or Proxies have to be generated. Now we are ready with our base interfaces. And here begins how its achieved...

First have a singleton class which instantiates our Factory like this:

factory = (Factory) GWT.create(ReflectiveFactory.class);

and return this factory whenever its asked for.

Now you may wonder, how will it work without any real code in the ReflectiveFactory. So here is the explaination of how its gonna work.

  1. We are going to extend the GWT compiler to generate a wrapper or proxy for each of the Classes which implement FactoryWrapper.
  2. The generator should create a new class with name Wrapper, which implements Factory.
  3. In the case of ReflectiveFactory, first we are going to get all the Instantiable types.
  4. And finally generate the method newInstance(String className), conditionally returning one of the Reflectables based on the specified className.
To extend GWTCompiler we need to add an entry in our module XML as follows:


1 <module>
2
3 -- Inherit the core Web Toolkit stuff. -->
4 <inherits name='com.google.gwt.user.User'/>
5
6 -- Specify the app entry point class. -->
7 <entry-point class='name.aanand.gwt.client.MainEntryPoint'/>
8
9
<generate-with class="name.aanand.gwt.generator.FactoryGenerator" >
10
<when-type-assignable class="name.aanand.gwt.client.FactoryWrapper" />
11
</generate-with>
12
13
</module>
14



The FactoryGenerator class should extend the abstract class Generator and implement its method
public String generate(TreeLogger logger, GeneratorContext context, String typeName)

Simple implemenation of FactoryGenerator is given below:



1 package name.aanand.gwt.generator;

2

3 import java.io.PrintWriter;

4

5 import com.google.gwt.core.ext.Generator;

6 import com.google.gwt.core.ext.GeneratorContext;

7 import com.google.gwt.core.ext.TreeLogger;

8 import com.google.gwt.core.ext.UnableToCompleteException;

9 import com.google.gwt.core.ext.typeinfo.JClassType;

10 import com.google.gwt.core.ext.typeinfo.NotFoundException;

11 import com.google.gwt.core.ext.typeinfo.TypeOracle;

12 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;

13 import com.google.gwt.user.rebind.SourceWriter;

14

15 public class FactoryGenerator extends Generator {

16

17 public String generate(TreeLogger logger, GeneratorContext context,

18 String typeName) throws UnableToCompleteException {

19 logger.log(TreeLogger.INFO, "Generating source for " + typeName, null);

20 TypeOracle typeOracle = context.getTypeOracle();

21

22 JClassType clazz = typeOracle.findType(typeName);

23 if (clazz == null) {

24 logger.log(TreeLogger.ERROR, "Unable to find metadata for type '"

25 + typeName + "'", null);

26 throw new UnableToCompleteException();

27 }

28

29 try {

30 logger.log(TreeLogger.INFO, "Generating source for "

31 + clazz.getQualifiedSourceName(), null);

32

33 JClassType reflectableType = typeOracle

34 .getType("name.aanand.gwt.client.Instantiable");

35 SourceWriter sourceWriter = getSourceWriter(clazz, context, logger);

36 if (sourceWriter != null) {

37 sourceWriter.println("public "

38 + reflectableType.getQualifiedSourceName()

39 + " newInstance(String className) {");

40 JClassType[] types = typeOracle.getTypes();

41 int count = 0;

42 for (int i = 0; i < types.length; i++) {

43 if (types[i].isInterface() == null

44 && types[i].isAssignableTo(reflectableType)) {

45 if (count == 0) {

46 sourceWriter.println(" if(\""

47 + types[i].getQualifiedSourceName()

48 + "\".equals(className)) {"

49 + " return new "

50 + types[i].getQualifiedSourceName() + "();"

51 + "}");

52 } else {

53 sourceWriter.println(" else if(\""

54 + types[i].getQualifiedSourceName()

55 + "\".equals(className)) {"

56 + " return new "

57 + types[i].getQualifiedSourceName() + "();"

58 + "}");

59 }

60 count++;

61 }

62 }

63 sourceWriter.println("return null;");

64 sourceWriter.println("}");

65 sourceWriter.commit(logger);

66 logger.log(TreeLogger.INFO, "Done Generating source for "

67 + clazz.getName(), null);

68 return clazz.getQualifiedSourceName() + "Wrapper";

69 }

70 } catch (NotFoundException e) {

71 e.printStackTrace();

72 }

73 return null;

74

75 }

76

77 public SourceWriter getSourceWriter(JClassType classType,

78 GeneratorContext context, TreeLogger logger) {

79

80 String packageName = classType.getPackage().getName();

81 String simpleName = classType.getSimpleSourceName() + "Wrapper";

82 ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(

83 packageName, simpleName);

84 composer.addImplementedInterface("name.aanand.gwt.client.Factory");

85 PrintWriter printWriter = context.tryCreate(logger, packageName,

86 simpleName);

87 if (printWriter == null) {

88 return null;

89 } else {

90 SourceWriter sw = composer.createSourceWriter(context, printWriter);

91 return sw;

92 }

93 }

94

95 }

96




Now compile your code with GWTCompiler and start using as shown below:

Factory factory = (Factory) GWT.create(ReflectiveFactory.class);
factory.newInstance("fully.qualified.Classname");

Thats all folks!

Monday, October 08, 2007

Simple Key Mappings for VIM

These are very simple key-mappings for VIM 7.0 and above, to play with tabs (or tab pages).


 5 set nu!

 6 set wrap!

 7 color desert

 8 set guioptions+=b

 9 :map <C-N> <M>:tabnew<CR>

10 :map <S-TAB> <M>:tabnext<CR>

11 :map <C-F4> <M>:tabclose!<CR>

12 :map <C-O> <M>:browse tabnew<CR>


All are command mode shortcuts.

CTRL-N  -  creates a new tab page.
CTRL-O  -  Opens a file in a new tab page.
CTRL-F4 - Closes current tab page

SHIFT-TAB - rotates through the tab pages.

Happy Vimming!

Sunday, September 02, 2007

FIndex

This a product of my last two or three weekends. It actually began as a duplicate file finder and has grown upto a source code search tool powered by Ctags the famaous code indexing utility.

The duplicate finder works based on file hashes using the Tiger Hash algorithm (BouncyCastle's impl).

The Code search is simply a UI to search Ctags tag files in each of your configured code repositories.




More at http://aanand.name/findex


Wednesday, July 25, 2007

Embedded tomcat without deployment descriptor(web.xml)

I just had to write some code for running a single servlet for testing and wrote this java program which uses Embedded tomcat.
The following code doesn't use web.xml to configure the context. Context configuration is done programmatically using the StandardContext class in catalina.jar. I have added a servlet and mapped it to the URL "/example".


System.setProperty("catalina.home", "./");
Embedded embedded = new Embedded();
Engine engine = null;
Host host = null;
// Create an embedded server
embedded = new Embedded();

// print all log statments to standard error
embedded.setDebug(0);
embedded.setLogger(new SystemOutLogger());

// Create an engine
engine = embedded.createEngine();
engine.setDefaultHost("localhost");

// Create a default virtual host
host = embedded.createHost("localhost", "./");
engine.addChild(host);


StandardContext context = (StandardContext) embedded.createContext("/ContextPath","/test");
context.setWorkDir("./test");
context.setConfigured(true);
Wrapper servlet = context.createWrapper();
servlet.setServletClass(ExampleServlet.class.getName());
servlet.setName("example");
context.addChild(servlet);
context.addServletMapping("/example", "example");

host.addChild(context);
host.setAutoDeploy(true);

// Install the assembled container hierarchy
embedded.addEngine(engine);

// Assemble and install a default HTTP connector
Connector connector = embedded.createConnector("127.0.0.1", 8080,
false);
embedded.addConnector(connector);
// Start the embedded server
embedded.start()


This may help while writing unit tests for servlets which cannot be tested with cactus or httpUnit.

Happy coding...

Sunday, May 27, 2007

Cream 0.39 beta2 looks good


After a long time I visited cream to check for updates. And i found a new version in beta stage. Its looks good and it has now got more items in settings menu. And more over you have a singe session mode, which turns VIM into a singleton application.
And the features of VIM 7.1 make it much more beautiful.


The application looks to be much faster, but it lags while processing huge documents. Particularly while editing large XML docs. But otherwise its cool as it was before and with new awesome features.
Long live VIM and Cream....

Tuesday, March 13, 2007

ClassLoader and the order of classpath entries

JBossAOP provides runtime aspectization feature. For this it has a classloader instrumentor which modifies the java.lang.ClassLoader which will intercept the call and invoke the interceptor chain.

Based on their docs
java -Xbootclasspath/p:<aop boot classpath as described> \
-Djboss.aop.path=<path to jboss-aop.xml> \
-classpath <path to your classes> com.blah.MyMainClass
The above command is used to execute a java class with the instrumented classloader. When i used this command, i had the bootclasspath as
(through eclipse) JRE Classpath;{generated ClassLoader};{JBossAOP jars};
It dint work as expected, that is the interceptors weren't invoked.

Then i remembered of ClassLoaders and the way it loads the classes. That is it searches the given paths, one by one and loads the class. Then i changed the order of the entries as {generated ClassLoader};{JBossAOP jars};JRE Classpath;. Now everything worked fine and the result was as expected.

The important point to remember is that, if you have duplicate classes like the one used above, java.lang.ClassLoader, the order of the desired class (instrumented ClassLoader) in the classpath should be at the top so that it will be loaded before other duplicate gets loaded.

Lesson learnt: order of the classpath entries is very important

Sunday, February 11, 2007

textEditorsInTheWorld++

I have been search, playing with and reviewing a number of text editors and now i have planned to roll out my own editor called MyMate soon.

This will be a project where i will learn advance C++ and I'm gonna enjoy using JUCE. The project is an inspiration from the wonderful editor TextMate.

This is an initial screen of MyMate(just started to work on it)


I'm not a very good C++ programmer, so i would like someone to guide me and help me in this project.
Anybody interested to help me, just add comment and we'll start a project with a repository in SourceForge.

Saturday, January 27, 2007

My dark colour scheme for VIM.

This is my dark colour scheme for VIM, which is based on rdark colour scheme. I have done some colour changes to

  1. highlight current line,
  2. type,
  3. special words
  4. and keywords.

Download colour scheme

Happy Vimming!

Sunday, January 14, 2007

Slippery Snippets for VIM. HOT!

Slippery Snippets brings the HOT HOT feature of TextMate to VIM. Define you snippet in snippets file and use the snippets with a single <TAB> key. And it also allows you to navigate to the fill up areas in the snippet using the same <TAB> key.

Just download the VIMBALL file and load it in VIM. Then use the sourcing command to extract it.

:so %

The content will be extracted to appropriate locations in the VIM's directory. Now, open a C++ source file and type "do"; then hit the
<TAB> key.

{ Note: Snippet files can be found at "vim/vimfiles/after/ftplugin". Refer the snippets files for creating your own snippets.}



Enjoy the Snippets!

Saturday, January 13, 2007

CrimsonEditor's opensourced and EmeraldEditor born

CrimsonEditor is a very clean, simple and lightweight editor for windows. And for a very long time there was no development. But now a team has come up with an idea to build cross platform editor using wxWindows and they call it EmeraldEditor.

I don't think i would be as light as Crimson, because WxWidgets is a huge and heavy library and makes the application a bit bloated.

Lets wait and check it out.