Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Tuesday, September 25, 2007

Coherence Contd. Listening the cluster

I am assuming my other blogs related to Coherence has been read. The nodes in a cluster are also called Members. Like Cache events, cluster also generates events when a Member joins, leaving or left. Say, if we need to clear some of the resources if a Member leaves or dynamically increase the pool size of a resource when additional members join in (I don't know, I am just making the requirements up!). Here is a sample code showing where and how to do it:


NamedCache nCache = CacheFactory.getCache ("Cache");
nCache.getCacheService ().addMemberListener (new MemberListener () {
final Member local = nCache.getCacheService ().getCluster ().getLocalMember ();
public void memberJoined (MemberEvent evt) {
// -- The Member which the event is associated to
Member eM = evt.getMember ();
// -- Do the fancy stuff
}

public void memberLeaving (MemberEvent evt) {
}

public void memberLeft (MemberEvent evt) {
}
});


And thats it again!

Monday, August 27, 2007

Coherence is suspiciously easy to use

Do you need fine grained control over your Cache? Do you need advanced cache management? Do you need cache partitions? Then Tangosol Coherence is for you. The cache objects must be Serializable or Externalizable. Because of the high performance, Oracle recommends to use ExternalizableLite instead. So here you go:


#The SClass to cache
public class SClass implements ExternalizableLite {
private String a;
public SClass () {
}
public void setA (String a) {
this.a = a;
}
public String getA () {
return a;
}
public String toString () {
return a;
}

public void readExternal (DataInput dataInput) throws IOException {
a = dataInput.readUTF ();
}

public void writeExternal (DataOutput dataOutput) throws IOException {
dataOutput.writeUTF (a);
}
}

# Now how to use it?
public class CacheClient {

private NamedCache nCache;

public CacheClient () {
nCache = CacheFactory.getCache ("Name");
}

public static void main (String[] args) {
CacheClient cacheClient = new CacheClient ();

// -- Put the Object in Cache
SClass sC = new SClass ();
sC.setA ("Srivastava");
cacheClient.putValue ("a", sC);

// -- Now retrieve it
System.out.println ("Entered: " + cacheClient.getValue ("a"));
}

private void putValue (String k, Object v) {
nCache.put (k, v);
}

private String getValue (String k) {
Object obj = nCache.get (k);
// -- Assuming the Object was added in the Cache and not expired
// -- More details on Object expiration later.
return obj.toString ();
}
}

Thats it! And you get a high performing Caching infrastructure.

Friday, June 22, 2007

What is a Pojo? Again?

Keep hearing this word? With numerous definitions already, here is one more: A Pojo is not just a javabean with getter/setter and isX() methods but can have other behaviors too, provided they only work on the attributes owned, associated or inherited by it. The definition extends to the anemic and rich domain modeling. Event handling in Toplink is an example of a rich domain model. The following is a Pojo even though DescriptorEvent and ClassDescriptor raises eyebrows but its fine as in ORM, the Domain object "is a" descriptor.


public class Domain {
protected String name;
public String getName () { return name; }
public void setName (String name) { this.name = name; }
// -- Richness for postBuild events..
public void addHandler (DescriptorEvent event) {
...
}
// -- More Richness for After Load...
public static void addOrder(ClassDescriptor desc) {
.....
}
}

Wednesday, May 30, 2007

Twitterize your SunBird (Calendar)

Aren't you tired of typing all the twitter updates? But still want to let your friends know what you are doing? So here you go... I have twitterized your SunBird. SunBird is Mozilla's open source calendar. My code reads the events from the SunBird database every half hour and updates the Twitter with the first upcoming event. So, if you have a meeting at 11PM and Lunch @ 12:30 then this application will update the twitter with Meeting@11PM. So all you have to do is to update your Calendar (SunBird) with the events and Twitter will be your flash screen. Save some typing Guys!

So what do you do?
I have uploaded the entire application at the download section of ezduck.com so go ahead and download it. Cut and paste the link if the href does not work: http://www.angelfire.com/co3/ashish7s/download/s2t.jar. I have provided the source under the open GPL license, so feel free to enhance it, make it fancier and redistribute it. Just think about me before you do so

How does it work?
SunBird uses the OpenSource SQLite format for its' data storage. So, if you are using any Calendar system which uses the same format, you can use this application against it. Sorry Outlook folks! Microsoft has to open a bit. The application uses the SQLite jdbc driver to connect to the SDB file and selects the future events from the CAL_EVENTS table. It brings the title of the first upcoming calendar event and then connects to the twitter.com to log you in and publishes the message.

How to run the application?
All you need is Java. The manifest file has already been updated to set the mainClass. Open a terminal/console/command prompt and run the following command:
java -Ddb=<location_of_sdb> -Dun=<twitter_login> -Dpw=<twitter_password> -jar s2t.jar
Where,


  • db is the fully qualified location of the SDB file. Usually, Mozilla SunBird saves the calendar in $HOME/.mozilla/sunbird/<id>.default/storage.sdb file on Unix and something similar to "/c:/Documents and Settings/<username>/Application Data/Mozilla/Sunbird/Profiles/<id.default>/storage.sdb" on Windows. Make sure the location of this file is correct. Guys this is your database!

  • un stands for your twitter.com user name. Usually its' your email address.

  • pw stands for your twitter.com password. This is legible text. As SunBird runs locally on your system and so is the terminal which you are running this application on, so its not too bad to type this in. If you are geek enough then go ahead and update the code to encode it.


Future Enhancements:
1. Behind a proxy server? its simple to modify but not done in this release. [Done]
2. A properties file to save the input parameters. [Why to complicate]
3. Targetted messaging from Calendar.
4. From Twitter to your Calendar.

Keep reading the comments on this blog for more options and happy Twittering and Calendaring friends!

Wednesday, May 09, 2007

Simple little things in programming (Part-II) - make configure

In my short span of programming life I have done quite a few "make configure (or ./configure)". Thanks to www.sunfreeware.com. The concept is simple. You get a package and you configure it for your environment. Then came ANT and we forgot about the power of 'configure'. Its not ANT's problem but we as developers don't bother to create any such targets. Ah.. may be I am generalizing my own habit. Anyway, we always have at least three platforms in any serious programming project. dev, test and prod. I have seen numerous teams building three deployment packages - one for dev, one for test and one for prod. Usually the problem is solved by putting the platform specific values in a properties or a config xml. The solution? You don't have to be a configuration management expert. If you are ANTing you can use the replace tag. The Ant replace tag allows certain tokens to be replaced at the deployment time. Remember make configure? Instead of multiple builds, use the Ant replace and ship the package to the deployment folks to run "ant configure" instead. I think make configure (or just configure) still sound sexier but who listens to me?


# A very simple build.xml
<target name="configure">
<replace dir="${dir}" value="{val}">
<include name="**/*.properties"/>
<replacetoken>@val@</replacetoken>
</replace>
</target>

Assuming you have @val@ in the platform specific files as tokens which you need to replace.
$ ant configure -Dval=p_value

... And the old days will be back.

Friday, April 20, 2007

Simple little things in programming - Part 1

No I am not a guru and have no jurisdiction to teach good programming skills and patterns. But its a good practice to keep the code clean and provide room for scalability. I have seen failed but very well written codes as well as very successful but piece of $%!^. Don't use badly written code as a tool for the job security. I think I should start some simple little things in Java programming which is not too much to do but adds to the quality. This sequence is in no effort to discuss complex pattern, or may be later. Your comments are most welcome.

# Use of Reflection to eliminate if-then-else:
==============================================
If-then-else is one of the very basic and one of the most powerful syntax provided by the programming languages. Its also a source of unmanageable, lengthy and cumbersome codes. Most of the patterns defined in GoF and beyond try to address the If-Then-Else world. Java Reflection on the other hand is one of the building blocks of most of the patterns. It provides a very strong set of APIs which can make your code very scalable and easy to maintain. Lets take an example:


# Sample(1):
ReturnType rT = null;
if (condition1) {
rT = callMethod1 (param1, param2);
} else if (condition2) {
rT = callMethod2 (param1, param3);
} else {
rT = callMethod3 (param3);
}


The callMethodX () takes different set of parameters but either returns the same Object or something which can be made more generic. In most cases, the params are owned by the same class. Even though these params have different scopes but together they form one logical set. The problem with the above code is it is not scalable. The invoker has a strong dependency on these call methods. New call methods can be added but they can not be used unless the section of invoker is updated. Lets take another sample:


# Sample(2):
import java.lang.reflect.Method;

public class ClassName {
..
public ReturnType invoker (param1, param2, param3) { // -- scope can change
Object [] inputs = {param1, param2, param3};
Class [] params = new Class [3];
parmas [0] = String.class;
params [1] = Boolean.class;
params [2] = String.class;
ClassName theClass = new ClassName ();
Class thisClass = theClass.getClass ();
// -- put some standardization to the namings
// -- derive the "call" + methodName from the condition.
Method method = thisClass.getMethod ("call" + methodName, params);
ReturnType rT = (ReturnType) method.invoke (theClass, inputs);

return rT;
}


The Sample(2) disconnects the need for the invoker () method to know anything about whats its invoking. Clean yeah? So the code has become a little rich by a simple standard driven method nomenclature. A full blown command pattern will take it to the new heights. Will talk about it later.