• Blog


    JAVA 5 and Maven 2.2.1 on Snow Leopard OSX

    No Comments// Posted in Java, Uncategorized by admin on 05.02.11.

    Currently i am working on a project that requires the java 5 jdk and maven 2.2.1.
    I knew OSX came with Java and Maven preinstalled, but i was a bit baffled with the fact you cannot chose which jdk to compile to.
    Snow Leopard also seems to use maven 3 by default.

    After a fair amount of googling i came up with the following solution:

    Installing maven2

    cd /tmp/
    curl -o maven221.tar.gz http://www.apache.org/dyn/closer.cgi/maven/binaries/apache-maven-2.2.1-bin.tar.gz
    tar -xvzf maven221.tar.gz
    sudo mv maven221 /usr/share/maven221
    chmod -R 775 /usr/share/maven221
    cd /usr/share
    unlink maven
    ln -s maven221 maven
    

    installing java 5

    cd /tmp/
    curl -o java.1.5.0-leopard.tar.gz http://www.cs.washington.edu/homes/isdal/snow_leopard_workaround/java.1.5.0-leopard.tar.gz
    tar -xvzf java.1.5.0-leopard.tar.gz
    sudo mv 1.5.0 /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0-leopard
    cd /System/Library/Frameworks/JavaVM.framework/Versions/
    sudo rm 1.5.0
    sudo ln -s 1.5.0-leopard 1.5.0
    sudo rm 1.5
    sudo ln -s 1.5.0 1.5
    open "/Applications/Utilities/Java Preferences.app"
    

    Latest came from this link


    Apple Store Experience, and shipment via “Expeditors Shanghai”

    1 Comment// Posted in Uncategorized by admin on 03.19.11.

    I recently ordered a MacBookPro from the Belgian apple store.
    I customized my new MBP a bit, and i ordered some peripherals like a remote and a dvi-cable.
    As i did my modifications, i saw the shipment date shift from 1 day to 1 – 3 days.
    Effectively, after my payment was cleared, my MBP was assembled, and the order was shipped 2 days later.

    But here comes the good stuff:
    As i received word from apple, saying i can track my shipment via the app store, information there seems fairly static.
    I also notice 2 shipments, only one of them has a ‘track shipment’ button, and on the bottom left there’s a little ‘Merge In Tnst NL Til’ message.

    So what was going on?

    • Apparently apple ships goods from 2 different parts in china. The macs are being shipped from the factory, the peripherals from elsewhere. However, those shipments will arrive together at your doorstep in one package, hence the ‘merge in tnst’ thing.
      Which only means: wait in a depot in Holland until the two shipments have arrived, and dispatch them together.
    • The apple.com store offers more information about your shipments than the apple.be or apple.nl site.
    • This way I found that my MBP was being shipped via “Expeditors Shanghai”, and the peripeherals via Syncreon.
    • Both have a distinct number, but more information is lacked by apple.
      I only get ‘in transit to final destination – carrier details to be updated shortly’ and ‘In Transit to Customer – Shipment on Schedule’ for about a week.

    So were the hell was my new MBP and when would it arrive?

    • For the Expeditors Shanghai part of the delivery, i found  – After a fair amount of googling – the distinct number can be used to track down the shipment via the Expeditors Shangai website.
    • Until now, i have not yet found a way to track syncreon deliveries, so no way of tracking the peripherals.

    A few thoughts

    • If you buy a mac from the appstore, only buy the mac, and order your peripherals and software from a reseller! This will make your delivery MUCH faster, as the shipment can be sent to you directly. You will have no merge, and no different logistics partners.
    • For an expensive product like this, tracking should be made much more transparent by apple.
    • The app stores should contain the same tracking  information regardless of the country your in.

    As always, if you have any feedback, please reply.


    Google AdSense

    No Comments// Posted in Uncategorized by admin on 02.27.11.

    I have been fidling around with google adsense lately.
    I have to say this is very easy to integrate in your site.
    If you are using wordpress, i can higly reccomend the wordpress-rax-google-adsense-plugin


    MessageFormat and Quotes (in JSF Tags)

    1 Comment// Posted in JSF, Java, Web by admin on 01.20.10.

    java.text.MessageFormat has the odd behaviour of deleting single quotes when they are passed in via the pattern string.
    This is no bug, but in my opinion the documentation of this api ‘feature’ is not very clear.
    If you want to give it a try though you can find the api explications
    here.
    And if you want you can find a bugdescription of the problem here.

    But perhaps even better:
    I have written a little tescase to show you the behaviour.
    In the first test you will find the original MessageFormat behaviour.
    The last test will test my solution. But this is dicscussed further on.

    /**
     * This class will test the {@link MessageFormat} class,
     * and its parent {@link java.text.MessageFormat}.
     *
     * @author t51sagtdo Tim De Roock
     * @date 7-jan-2010
     * @version %PR%
     */
    public class MessageFormatTest extends TestCase {
    
    	private static final Map MAP = new HashMap();
    	private static final Map MAP2 = new HashMap();
    
    	static {
    		MAP.put("1", new String[] {"t is een", "'t is een", null});
    		MAP.put("2", new String[] {"t is een {0}", "'t is een {0}", "test"});
    		MAP.put("3", new String[] {"'t is een test", "''t is een {0}", "test"});
    		MAP.put("4", new String[] {"'t is een", "''t is een", null});
    		MAP.put("5", new String[] {"'t is een t'est", "''t is een {0}", "t'est"});
    		MAP.put("6", new String[] {"'t is een t''est", "''t is een {0}", "t''est"});
    
    		MAP2.put("1", new String[] {"'t is een", "'t is een", null});
    		MAP2.put("2", new String[] {"'t is een test", "'t is een {0}", "test"});
    		MAP2.put("3", new String[] {"'t is een test", "''t is een {0}", "test"});
    		MAP2.put("4", new String[] {"'t is een", "''t is een", null});
    		MAP2.put("5", new String[] {"'t is een t'est", "''t is een {0}", "t'est"});
    		MAP2.put("6", new String[] {"'t is een t''est", "''t is een {0}", "t''est"});
    	}
    
    	/**
    	 * This method will test the original MessageFormat Behaviour.
    	 */
    	public void testQuotesOnOriginalMessageFormat() {
    		Set> aSet = MAP.entrySet();
    		for (Entry entry : aSet) {
    			assertEquals(entry.getValue()[0], java.text.MessageFormat.format(entry.getValue()[1], entry.getValue()[2]));
    		}
    	}
    
    	/**
    	 * This method will test the {@link MessageFormat#stripPattern(String)} method.
    	 */
    	public void testStripPattern() {
    		assertEquals("aaa", MessageFormat.stripPattern("aaa"));
    		assertEquals("a''a", MessageFormat.stripPattern("a'a"));
    		assertEquals("a''a", MessageFormat.stripPattern("a''a"));
    		assertEquals("a''a", MessageFormat.stripPattern("a'''a"));
    	}
    
    	/**
    	 * This method will test the original MessageFormat Behaviour.
    	 */
    	public void testQuotesOnAdaptedMessageFormat() {
    		Set> aSet = MAP2.entrySet();
    		for (Entry entry : aSet) {
    			assertEquals(entry.getValue()[0], MessageFormat.format(entry.getValue()[1], entry.getValue()[2]));
    		}
    	}
    

    As you may notice, it does not matter if you pass in an argument or not. The quote is always replaced and/or omitted.
    If we want to show the quotes however, we need to properly escape it quote with another one.
    But this does pose some problems for the i18n team,
    as they do not know which messages will go through java.text.MessageFormat, and which do not.

    As a solution, I have written a delegate MessageFormat class which replaces one quote to two if one is present in the pattern.

    /**
     * This class will be used as Delegate for the java.text.MessageFormat Class.
     * This is because java.text.MessageFormat has the behaviour of deleting
     * single quotes '.
     *
     * This means every String going throuh MessageFormat needs to be checked for a quote,
     * and the quote needs to be doubled if found.
     *
     * @author Tim De Roock
     * @date 7-jan-2010
     * @version %PR%
     */
    public class MessageFormat extends java.text.MessageFormat {	
    
    	private static final long serialVersionUID = -7732948871517816579L;
    
    	/**
    	 * Default constructor takes a pattern.
    	 * @see java.text.MessageFormat
    	 *
    	 * @param pattern
    	 * 			the pattern
    	 */
    	public MessageFormat(String pattern) {
    		super(pattern);
    		applyPattern(stripPattern(pattern));
    	}
    
    	/**
    	 * Overloaded Constructor.
    	 * @see java.text.MessageFormat
    	 *
    	 * @param pattern
    	 * 			The Pattern
    	 * 			@see java.text.MessageFormat
    	 * @param locale
    	 * 			The locale
    	 * 			@see java.text.MessageFormat
    	 */
    	public MessageFormat(String pattern, Locale locale) {
    		super(pattern, locale);
    		applyPattern(stripPattern(pattern));
    	}
    
    	/**
    	 * Static 'Override'. (Redefine)
    	 *
    	 * @param pattern
    	 * 			The pattern
    	 * 			@see java.text.MessageFormat#format(String, Object...)
    	 * @param arguments
    	 * 			The arguments
    	 * 			@see java.text.MessageFormat#format(String, Object...)
    	 * @return
    	 * 			The string
    	 */
    	public static String format(String pattern, Object... arguments) {
    		return java.text.MessageFormat.format(stripPattern(pattern), arguments);
    	}
    
    	/**
    	 * This method will convert the pattern to add quotes if needed.
    	 *
    	 * @param pattern
    	 * 			The original pattern.
    	 * @return the adapted pattern.
    	 */
    	protected static String stripPattern(String pattern) {
    		return pattern.replaceAll("('(^['])*)+", "''");
    	}
    }

    MessageFormat in JSF

    Now to take the solution a bit further, on my current project we make use of MyFaces 1.5 and the tomahawk library.
    In here we make a lot of use of the the MessageFormat tag, which in turn uses… java.text.MessageFormat.

    Here is a solution to write a custom renderer for the Format renderer-type,
    this way you can use the custom MessageFormat class.

    In short these are the steps you need to take.

    1) Write a class that extends HtmlFormatRenderer
    2) Overwrite the encodeEnd so that the custom MessageFormat is used.
    3) Register the renderer in faces-config.xml

    The htmlformatrenderer:

    /**
     * Custom Renderer for HtmlFormat.
     * This custom renderer uses an adapted MessageFormatter.
     * The formatter will add a double quote to the string passed in.
     * This way a single quote will be shown.
     *
     * @author t51sagtdo Tim De Roock
     * @date 19-jan-2010
     * @version %PR%
     */
    public class HtmlFormatRenderer extends org.apache.myfaces.renderkit.html.HtmlFormatRenderer {
    
    	private static final Object[] EMPTY_ARGS = new Object[0];
    
    	/**
    	 * {@inheritDoc}
    	 */
    	public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
    		RendererUtils.checkParamValidity(facesContext, component, UIOutput.class);
    
    		String text = getOutputFormatText(facesContext, component);
    		boolean isEscape;
    		if (component instanceof HtmlOutputFormat) {
    			isEscape = ((HtmlOutputFormat) component).isEscape();
    		} else {
    			isEscape = RendererUtils.getBooleanAttribute(component, JSFAttr.ESCAPE_ATTR, true);
    		}
    		HtmlTextRendererBase.renderOutputText(facesContext, component, text, isEscape);
    	}
    
    	/**
    	 * {@inheritDoc}
    	 */
    	@SuppressWarnings("unchecked")
    	private String getOutputFormatText(FacesContext facesContext,
    			UIComponent htmlOutputFormat) {
    		String pattern = RendererUtils.getStringValue(facesContext, htmlOutputFormat);
    		Object[] args;
    		if (htmlOutputFormat.getChildCount() == 0) {
    			args = EMPTY_ARGS;
    		} else {
    			List argsList = new ArrayList();
    			for (Iterator it = htmlOutputFormat.getChildren().iterator(); it.hasNext();) {
    				UIComponent child = (UIComponent) it.next();
    				if (child instanceof UIParameter) {
    					argsList.add(((UIParameter) child).getValue());
    				}
    			}
    			args = argsList.toArray(new Object[argsList.size()]);
    		}
    
    		be.solidconsulting.util.MessageFormat format = new be.solidconsulting.util.MessageFormat(pattern, facesContext.getViewRoot().getLocale());
    		try {
    			return format.format(args);
    		} catch (Exception e) {
    			return "";
    		}
    	}
    }

    Here is the faces-config.xml registration of the renderer.
    If you need to regiser antoher renderer, you can find the component-family and renderer-type
    here.
    Please note that this is for JSF 1.1.

    Faces-config

    Faces-config

    If you should have any remarks on this, or you just want to thank me, please leave a reply ;-)


    Iphone Support

    No Comments// Posted in iphone by admin on 12.30.09.

    The website is now fully compatible with the Iphone. This is achieved via the excellent wptouch plugin.
    Let me know what we can improve!


    Ninite

    No Comments// Posted in Uncategorized by admin on 12.27.09.

    I just came across this superhandy tool called Ninite. Basically it let’s you choose all the programs you want to install on your windows box, and then provides you an installer for all the latest versions of those programs!
    Check it out on ninite.com


    Joomla 1.5.15 left to right print bug

    No Comments// Posted in Uncategorized by admin on 12.18.09.

    Joomla 1.5.15 text right to left rtl

    On a recent Joomla project, i noticed the text was aligned right to left when you want to print an article. This is due to a few missing brackets in the component.php file.
    The component.php file is located under site-root/templates/system/component.php.
    You need to change line 29.

    From this:

    if($this->direction == 'rtl' && !file_exists(JPATH_THEMES.DS.$template.DS.'css/template_rtl.css') ||
    !file_exists(JPATH_THEMES.DS.$template.DS.'css/template.css'))
    

    To This:

    if($this->direction == 'rtl' && (!file_exists(JPATH_THEMES.DS.$template.DS.'css/template_rtl.css') ||
    !file_exists(JPATH_THEMES.DS.$template.DS.'css/template.css')))
    


    JSF 1.1 Tomahawk SelectOneRadio And DataTable

    No Comments// Posted in Java by admin on 12.18.09.

    In JSF it is rather difficult to put a SelectOneRadio (a radioButton) in a dataTable.
    This actually does not work out of the box with the standard implementation. The problem and the solution will be explained here.

    The Problem

    The following JSF page fragment shows the usage of the h:selectOneRadio tag

    
      
        
          
            
          
        
        
          
        
      
    
    

    This syntax mandates that the f:selectItems tag (which is actually responsible for the individual radio items) must be nested inside the h:selectOneRadio tag. All the radio buttons behave as if they were residing under a radio button group. We cannot put this radio button inside a JSF dataTable tag and span the radio button group behavior across rows or across columns because h:selectOneRadio cannot contain the h:column element, which represents a column inside an h:dataTable.

    When each column is rendered, the name generated by the JSF containers differs for each cell. As a result, individual radio buttons receive different names and create separate radio groups (with only one radio) in each group.

    Generated Source:

    Jef
    Jos
    Prosper
    Charel
    Dirk

    The important point to note is, if we use h:selectOneRadio and f:selectItems or f:selectItem inside dataTable, the radio buttons render properly; that is, when the page renders, the page displays a table that contains the right radio buttons. But the problem is all the radio buttons inside each cell (inside each
    and tag) fall under different radio button groups, because each radio button’s name attribute is generated uniquely by the JSF container. So they can all be selected, but not unselected.

    The Solution

    I did however find a way to achieve our goals with the tomahawk component library.

    
    
      
    
    
    
    
    
      
        
          
        
        
      
    
    
    

    There are a couple of things that are important here.

    * First of all we have a outside the datatable component. This still takes an component, but if you look carefully, the value contains an other list than the valu
    of the dataTable! This means we always need to synchronize our dataList with the selectItemsList!

    * Second important thing to notice in the selectOneRadio component is the layout=”spread” attribute. This will make sure every generated radio has the same name!

    * Third, we have a component in our t:dataTable component which actually draws the checkboxes where we want it. In our case for every row in the datatable

    By implementing this way, we make sure a previous checkbox is unchecked whenever we check another one. And if we submit the form, the #{invoiceSwitchBean.selectedItem} will contain the value of the correct Sending. (Considering the two lists are always synchronized.)

    Now the synchronization can be achieved like this:

    /**
     * This Method will align two internal lists, that are used to represent the
     * data in our datatable.
     * The synchronization of these two lists is very important , as it is the
     * value of the selectOneRadio that is used to find our sending id. 
     *
     * The use of 2 different lists to represent our model is inherent to the
     * use of jsf , it cannot combine a datatable and a selectOneRadio.
     *
     * More information can be found here: 
     * http://wiki.apache.org/myfaces/Display_Radio_Buttons_In_Columns
     *
     *
    
    Note: This method is rather in-performant, as it constructs * the selectOneRadioList everytime from scratch...
    */ @SuppressWarnings("unchecked") private void alignSelectBoxesWithModel() { setSelectItemsList(new ArrayList()); for (Sending s : getData()) { getSelectItemsList().add(new SelectItem(String.valueOf(s.getId()), "")); } }

    The getData() method represents the sortableModel of the dataTable, internally this is an arraylist in our implementation.
    As you can see in the previous method we provide a way to construct a new selectItemslist, with the data we want in our checkbox.
    Now from where do you call this method?

    We implemented our custom sort method, which is called from the invoiceSwitchBean.getSortableModel() method. The last step we do in our sort method is call the alignSelectBoxesWithModel() method. This way we are sure our dataTable is sorted, and then our selectItemsList is constructed, so our checkboxes always stay “in sync” with the sortableModel. This can however be implemented without the sort method, calling the alignSelectBoxesWithModel() straight away from the getSortableModel() method.


    Time is money: Formatting Strings and Dates

    2 Comments// Posted in Java by admin on 12.17.09.

    Small things can have big impacts. We all know this saying.
    But this is not always obvious. On my current project, we are writing a rather complicated batch that has to go fast.
    It has a few dependencies on webservices, on the database, on file I/O and as always: it has some businesslogic in it.

    While this little project is coming to an end, we are investigating the speed. But as it turns out, the batch is slow and sluggish. This was however a bit expected, as we do not do premature optimization.
    The main bottlenecks were obvious: some database queries, and the webservice invocations, but we managed to improve those quite fast via caching.

    But something else showed up in our profiler. Something we did not expect to have such an impact on performance… the “new” String.format(); method!
    When you thing about it, it is quite logical. The format takes a string parameter, describing how you are going to format the incoming string. And of course this string needs to be parsed. Hence the time loss.

    Here’s a quick test I wrote to compare alternatives: …

    public class FormatterTest extends TestCase {
      private static final String NUMERIC_FORMAT = "%1$010d";
      private static final int MAX_SIZE = 500000;
    
      public void testCalculatedSpeedString() {
        String[] stringList = createStrings();
        long startTime = System.currentTimeMillis();
        for (String aString : stringList) {
          StringUtils.leftPad(aString, 10, '0');
        }
        long endTime = System.currentTimeMillis();
    
        System.out.println("Millis For Stringutils: " + (endTime - startTime));
      }
    
      public void testCalculatedSpeed() {
        String[] stringList = createStrings();
        long startTime = System.currentTimeMillis();
        for (String aString : stringList) {
          long zeros = 10 - aString.length();
          StringBuilder bldZeros = new StringBuilder();
          for (int j = 0; j < zeros; j++) {
            bldZeros.append('0');
          }
          bldZeros.append(aString);
        }
        long endTime = System.currentTimeMillis();
    
        System.out.println("Millis For calculated: " + (endTime - startTime));
      }
    
      public void testFormatterSpeed() {
        String[] stringList = createStrings();
        long startTime = System.currentTimeMillis();
        for (String aString : stringList) {
          Long aLong = Long.parseLong(aString);
          String.format(NUMERIC_FORMAT, aLong);
    
        }
        long endTime = System.currentTimeMillis();
    
        System.out.println("Millis For formatter: " + (endTime - startTime));
      }
    
      public void testDateFormatter() {
        Date[] dateList = createDates();
        long startTime = System.currentTimeMillis();
        for (Date date : dateList) {
          String.format("%1$tY%1$tm%1$td", date);
        }
        long endTime = System.currentTimeMillis();
    
        System.out.println("Millis For String.format(Date): " + (endTime - startTime));
      }
    
      public void testSimpleDateFormatter() {
        Date[] dateList = createDates();
        long startTime = System.currentTimeMillis();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        for (Date date : dateList) {
          formatter.format(date);
        }
        long endTime = System.currentTimeMillis();
    
        System.out.println("Millis For SimpleDateFormat: " + (endTime - startTime));
      }
    
      public void testJodaDateFormatter() {
        Date[] dateList = createDates();
        long startTime = System.currentTimeMillis();
        for (Date date : dateList) {
          DateTime jodaDate = new DateTime(date);
          jodaDate.toString("yyyyMMdd");
        }
        long endTime = System.currentTimeMillis();
    
        System.out.println("Millis For JodaTime: " + (endTime - startTime));
      }
    
      private String[] createStrings() {
        String[] stringList = new String[MAX_SIZE];
        for (int i = 0; i < MAX_SIZE; i++) {
          stringList[i] = String.valueOf(i);
        }
        return stringList;
      }
    
      private Date[] createDates() {
        Date[] dateList = new Date[MAX_SIZE];
        for (int i = 0; i < MAX_SIZE; i++) {
          dateList[i] = new Date(i*10000);
        }
        return dateList;
      }
    

    And these are the outputs:

    Millis For Stringutils: 149
    Millis For calculated: 86
    Millis For formatter: 2981
    Millis For String.format(Date): 8305
    Millis For SimpleDateFormat: 531
    Millis For JodaTime: 691

    As you can see if you need performance, do not use the String.format() method!
    If you need your SimpleDateFormat() creation inside a loop, use JodaTime! Jodatime uses caching for the pattern.

    If you have any comments, please do post them!