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)



Sunday, 4 July 2010

Android ListActivity sorting

Question : how to sort on a given Android ListActivity column ?

Answer :
- attach a setOnClickListener to its corresponding TextView instance
- think about the Comparator interface
- after comparison, call notifyDataSetChanged on your list view adapter


Details :

Step #1 : Layout definition :
<LinearLayout
android:layout_marginTop="10dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dip"
android:layout_marginLeft="10dip"
android:background="@drawable/background">
<TextView
android:id="@+id/cName"
android:textColor="@drawable/black"
android:layout_width="0dip"
android:layout_weight="46"
android:layout_height="25dip"
android:text="@string/bdle_name"
android:gravity="center"
/>
<TextView
...
/>
<TextView
...
/>
</LinearLayout>
<ListView
android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="verticalhorizontal"
android:layout_marginRight="15dip"
android:layout_marginLeft="15dip"
android:layout_marginTop="5dip"
/>

Step #2 : given the BundleInfo class that holds the different attributes/columns of the list to be displayed, attach the listener to the TextView column subject to sorting, here : cName

public final class RestClient extends ListActivity
{
/**
* Bundles list
*/
private ArrayList<BundleInfo> bundles = new ArrayList<BundleInfo>();

/**
* List view adapter
*/
private CustomAdapter adapter = null;

/**
* list sorting type
*/
private SortType sortType = SortType.NONE;

/**
* Sorting order (-1 if reversed)
*/
private int sign = 1;

/**
* Name column widget
*/
private TextView cName = null;

/**
* Enumerated type for column sorting
*/
private enum SortType
{NAME, // by 'Name'
// OTHER, // by 'Other' column
NONE}

/**
* List refresh handler
*/
private Runnable refresh = new Runnable()
{

@Override
public void run()
{
// refresh your list here
// ...

if (!bundles.isEmpty())
switch (sortType)
{
case NAME:
comp = new SortByName();
Collections.sort(bundles, comp);
break;

// other cases as needed

default:
break;
}
else sortType = SortType.NONE;
adapter.notifyDataSetChanged();
}
};

@Override
public void onCreate(Bundle savedInstanceState)
{
// Setting activity content
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Other initializations
// ...
adapter = new CustomAdapter(this, R.layout.main, R.id.name, bundles);
setListAdapter(adapter);

// Sorting
sortType = SortType.NONE;
cName = (TextView) findViewById(R.id.cName);
cName.setOnClickListener(new ImageButton.OnClickListener()
{
public void onClick(View v)
{
sign = ((sortType == SortType.NAME) ? sign * -1 : sign);
sortType = SortType.NAME;
if (!isRunning) runOnUiThread(refresh);
}
});
}

/**
* List view adapter
*/
private final class CustomAdapter extends ArrayAdapter<BundleInfo>
{
// List view adapter class body
// ...
}
}
The 'refresh' thread being responsible for refreshing the view whenever needed.


Step #3 : for each column you wish to apply a sorting, add such an inner class definition :
/**
* List comparator for sorting by 'name'
*/
private final class SortByName implements Comparator<BundleInfo>
{
public int compare(BundleInfo i1, BundleInfo i2)
{
return i1.getBundleName().compareTo(i2.getBundleName()) * sign;
}
}

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.