Today in France, we celebrate ""
Posts
04/07/10 : Android sorting
16/06/10 : Flex XML parsing
15/06/10 : Android settings
14/06/10 : Pax daemon
10/06/10 : Bundle CPU %
04/06/10 : Wicket CheckBox
03/06/10 : Thread monitor

By tag
Ajax
Android
AspectJ
Flex
Java
JMX
OSGi
Shell
Wickets

Here are some lights and tips on various Object Oriented Programming aspects that I would have dealt with during my software development and architecture activities..., for sharing.

"Beauty is an inexhaustible source of happyness for the one who discovers it" (Alexis Carrel)



Wednesday, 16 June 2010

Flex complex XML structure parsing

Question : in Flex, how to filter an items list embedded in a complex XML event ?

Answer :
- retrieve the exact XML path as per the corresponding embedded schema
- iterate over the received XMLList, providing this path filter


Details :

Step #1 : consider the following XML tree, containing a block of <objInst> nodes to be mapped into corresponding Java business instances :
<root>
<tag1>tag1_value</tag1>
<tag2>tag2_value</tag2>
<config>
<tag3>tag3_value</tag3>
<tag4>tag4_value</tag4>
<dir>
<objInst>
<tag1_obj>tag1_obj1_value</tag1_obj>
<tag2_obj>tag1_obj1_value</tag2_obj>
<tag3_obj>tag1_obj1_value</tag3_obj>
<objInst>
<objInst>
<tag1_obj>tag1_obj2_value</tag1_obj>
<tag2_obj>tag1_obj2_value</tag2_obj>
<tag3_obj>tag1_obj2_value</tag3_obj>
<objInst>
<objInst>
<tag1_obj>tag1_obj3_value</tag1_obj>
<tag2_obj>tag1_obj3_value</tag2_obj>
<tag3_obj>tag1_obj3_value</tag3_obj>
<objInst>
</dir>
</config>
<tag5>tag5_value</tag5>
</root>


Step #2 : upon receipt of the HTTPService ResultEvent (event below), here is the easiest/safest way to iterate over the received XMLList :
try
{
for each (var objInst:XML in new XML(event.result.config.dir).elements())
{
// accessing objInst tag1 value simply via : objInst.tag1_obj
// accessing objInst tag2 value simply via : objInst.tag2_obj
// accessing objInst tag2 value simply via : objInst.tag3_obj
// ...
}
}
catch (e:Error)
{
// In case the XML response is not properly formatted
}

Nota: the <root> XML node must be omitted in the above 'event.result.config.dir' notation, since 'event.result' already corresponds to the <root> node of the downloaded XML document.

Tuesday, 15 June 2010

Android application preferences

Question : how to access/set preferences of an Android application ?

Answer :
- think about the MENU_SETUP of the onOptionsItemSelected method (override)
- from there, start a specialized PreferenceActivity


Details :

Step #1 : MENU_SETUP press handling :

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case MENU_SETUP:
showPreferences();
break;

default:
break;
}

return true;
}

Step #2 : an Android intent allows to start a to-be-specialized PreferenceActivity, named here : Prefs

/**
* Dialog box display of the preferences setting window
*/
private void showPreferences()
{
Intent prefs = null; // Preferences activity display intent

prefs = new Intent(getApplicationContext(), Prefs.class);
startActivity(prefs);
}

Step #3 : specialized Prefs class body

public final class Prefs extends PreferenceActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
// Setting activity content
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.prefs);
}
}
The 'R.layout.prefs' being given by a './res/layout/Prefs.xml' resource file ; here is such a resource contents in case just 2 edit text components are needed :
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="Preferences">
<EditTextPreference
// ...
/>
<EditTextPreference
// ...
/>
</PreferenceScreen>


Step #4 : finally, add this entry into the AndroidManifest.xml :
<activity android:name=".Prefs" android:label="Configuration"/>

Monday, 14 June 2010

Automatic Pax daemon commands

Question : how to launch/stop Pax at any Linux startup/shutdown ?

Answer :
- launch Pax as an extra Linux service
- a daemon being available since Pax v0.20 (refer to OPS4J site for introduction)


Details :

Step #1 : consider these shell variables :

#!/bin/bash
#
# Common definitions & Current working directory
# . .start_profile
# <begin> of such a profile
cd /home/osgi
export PORTWEB=8080
export DIRBASICBUNDLES=./bundles
PATH_RUNNER=./pax/
PATH_PROV=./provisionning_file.txt
PAXD_PASSWD=./paxd_passwd
PATH_PAX_BIN=./pax/bin
PATH_PAX_DIR=~osgi/.pax/runner
PATH_PAX_LOCK=$PATH_PAX_DIR/org.ops4j.pax.runner.daemon.lock
# <end>



Step #2 : here is an example of paxd service, to be added under /etc/init.d :

# Provisionning file
# ------------------
if [ ! -f $PATH_PROV ] ; then
echo "Creating provisionning file..."
list=`ls $DIRBASICBUNDLES/*.jar`
for bundle in $list; do echo "file:$bundle" >> $PATH_PROV; done
for opt in $JAVA_OPTS; do echo $opt >> $PATH_PROV; done
echo "-Dorg.osgi.service.http.port=$PORTWEB" >> $PATH_PROV
echo "=> done"
else
echo "Provisionning file retrieved !"
fi

# Depending on input option
# -------------------------
case "$1" in
start)
rm -f $PATH_PAX_LOCK
if [ -d $PATH_RUNNER ] ; then
echo "Launching PAX Runner Daemon... "
if [ ! -d $PATH_PAX_DIR ] ; then
su osgi -c "$PAXD_PASSWD $PATH_PAX_BIN/pax-rund.sh --startd --profiles=war,obr,log,config,felix.event,felix.ds --usePersistedState=true $PATH_PROV"
else
su osgi -c "$PATH_PAX_BIN/pax-rund.sh --startd --profiles=war,obr,log,config,felix.event,felix.ds --usePersistedState=true $PATH_PROV"
fi
fi
;;
stop)
echo "Stopping PAX Runner Daemon... "
su osgi -c "$PATH_PAX_BIN/pax-rund.sh --stop"
rm -f $PATH_PAX_LOCK
sleep 1
;;
restart)
;;
*)
echo "Usage: $N {startstoprestart}" >&2
exit 1
;;
esac
exit 0



Step #3 : Finally, run the update-rc.d command to automatically add any required links to this new service, as per your /etc/initab.

Thursday, 10 June 2010

OSGi bundle CPU usage

Question : how to compute the CPU used by an OSGi bundle ?

Answer :
- manage a Map table for the threads list owned by any given OSGi bundle
- rely on the JMX standard API


Details :

Step #1 : consider these attributes, based on JMX Beans :

private Map<Bundle, ArrayList<Thread>> threadMap =
new HashMap<Bundle, ArrayList<Thread>>();
private Map<Long, Long> threadTime =
new HashMap<Long, Long>();
private RuntimeMXBean runTimeBean =
ManagementFactory.getRuntimeMXBean();
private ThreadMXBean threadBean =
ManagementFactory.getThreadMXBean();
private int nbProcs =
ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
private long timerStart;
private long timerDelay;

Where 'timerStart' and 'timerDelay' should be updated as follows :

timerStart = runTimeBean.getUptime(); // init time
timerDelay = (runTimeBean.getUptime() - timerStart) * 1000000L; // window time

Step #2 : assuming that the 2 Map instances are being successfully maintained while any bundle is getting started/stopped on the OSGi framework, the percentage of CPU used by a given bundle can be computed as follows :

/**
* Get the percentage of CPU used by a bundle
*
* @param bundle
* The monitored bundle instance
* @return The percentage of CPU used
*/
private float getBundlePercentTime(Bundle bundle)
{
long cpuTime = 0L; // CPU used in nanoseconds
float cpuPercent = 0F; // percentage of CPU used

if ((cpuTime = getBundleCpuTime(bundle)) > 0)
{
cpuPercent = Math.min(0.99F, (float) cpuTime / (float) timerDelay);
}

return cpuPercent * 100.0F;
}


/**
* Get the overall CPU used by a bundle
*
* @param bundle
* The monitored bundle instance
* @return Its actual CPU usage in nanoseconds
*/
private long getBundleCpuTime(Bundle bundle)
{
long cpuTime = 0L; // CPU used in nanoseconds

if (threadMap.containsKey(bundle))
{
for (Thread thread : threadMap.get(bundle))
{
cpuTime += updateThreadCpuTime(thread.getId());
}
}
else
{
// Error handling
}

return cpuTime;
}


/**
* Refresh the CPU used by a thread, given its identifier
*
* @param threadID
* The monitored thread identifier
* @return Its actual CPU usage in nanoseconds
*/
private long updateThreadCpuTime(long threadID)
{
long diffCpu = 0L; // actual CPU difference in nanoseconds
long currentCpu = 0L; // actual CPU in nanoseconds
long previousCpu = 0L; // previous CPU in nanoseconds
Long previousCpuL = 0L; // previous CPU in nanoseconds

// Compute actual CPU usage
if ((previousCpuL = threadTime.get(threadID)) != null)
previousCpu = previousCpuL.longValue();
if ((currentCpu = threadBean.getThreadCpuTime(threadID)) >= 0)
diffCpu = currentCpu - previousCpu;

// Map table update
threadTime.put(threadID, currentCpu);

return diffCpu;
}

Thursday, 3 June 2010

Wicket AjaxCheckBox

Question : how to Ajax-ify a CheckBox in Wickets ?

Answer : need to specialize the AlaxCheckBox class.


Details :

Step #1 : consider these Wicket class attributes :

private static Boolean isAuto = false;
private static final String WICKET_CB = "autoCheck";
private IModel<Boolean> autoCheckModel = new Model<Boolean>(isAuto);
private AutoRefreshCheckBox autoCheck = new AutoRefreshCheckBox(WICKET_CB, autoCheckModel);

Step #2 : the customized AjaxCheckBox is added within the constructor of this same Wicket class :

add(autoCheck);

Step #3 : specialized AjaxCheckBox class body

private class AutoRefreshCheckBox extends AjaxCheckBox
{
public AutoRefreshCheckBox(final String id, IModel<Boolean> model)
{
super(id, model);
}

/**
* Says whether or not the "AutoRefresh" mode is enabled
*/
public Boolean isChecked()
{
final String value = getValue();
if (value != null)
{
try
{
return Strings.isTrue(value);
}
catch (StringValueConversionException e)
{
return false;
}
}

return false;
}

@Override
protected synchronized void onUpdate(AjaxRequestTarget target)
{
long period = 0L;

isAuto = isChecked();
autoCheckModel.setObject(isAuto);
target.addComponent(refreshBtn);
if (isAuto)
{
period = Long.valueOf(periodField.getValue()) * TO_MS;
// might be completed (e.g.: overall page refresh)
}
else
{
// might be completed (e.g.: period = PERIOD_MONITOR_OFF;)
}

// might be completed (e.g.: other components update)
}
}

Thread start/stop monitoring

Question : how to monitor a Java thread getting started or stopped ?

Answer : think about the run() method of the Runnable interface.


Details :

Step #1 : consider this AspectJ pointcut definition :

pointcut threadRun() : execution (* Runnable.run());

Step #2 : you can now rely on these 2 respective AspectJ advices :

before () : threadRun() && !cflowbelow(threadRun())
{
System.out("Starting Thread ID : " + Thread.currentThread().getId());
}

after () : threadRun()
{
System.out("Stopping Thread ID : " + Thread.currentThread().getId());
}

The '!cflowbelow' filter controling any reentrant situation.
Previous Post