Rowell Belen

Musings of a Primal Brogrammer.

Meet AngularJS!

This simple example demonstrates how to react on a model change to trigger some further actions. The value greeting will change whenever there’s a change to the name model.

Demo

JavaScript (helloAngular.js) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
require([
  'angular',
  'requirejs-domready'
],
  function (angular, domReady) {
    domReady(function() {

      angular.module('helloAngular',[]);
      angular.module('helloAngular').controller('Ctrl', function($scope) {
        $scope.name = "";
        $scope.greeting = "Greetings!"

        $scope.$watch("name", function(newValue, oldValue) {
          if (newValue.length > 0) {
            $scope.greeting = "Greetings " + newValue + "!";
          }
          else{
            $scope.greeting = "Greetings!"
          }
        });
      });

      angular.bootstrap($('#hello-angular'), ['helloAngular']);
    });
  }
);
HTML (helloAngular.html) download
1
2
3
4
5
6
<div id='hello-angular'>
  <div ng-controller="Ctrl">
    <input type="text" ng-model="name" placeholder="Enter your name">
    <h2 ng-bind="greeting"></h2>
  </div>
</div>

Simple Mediator Design Pattern for AngularJS

Code snippet for creating a simple mediator for cleanly separating concerns within an AngularJS application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
angular
    .module('app', [])
    .controller('MainCtrl', function($scope, Order) {
      $scope.newOrder = function() { new Order(); }
    })
    .factory('$emit', function($rootScope) {
      return function() { $rootScope.$emit.apply($rootScope, arguments); }
    })
    .factory('Order', function($emit) {
      function Order() {
        this.email   = 'nobody@gmail.com';
        this.product = 'Macbook Pro';
        $emit('order:created', this);
      }
      return Order;
    })
    .factory('Email', function($window) {
      function Email(text) {
        $window.alert(text);
      }
      return Email;
    })
    .run(function($rootScope, Email) {
      $rootScope.$on('order:created', function(event, order) {
        new Email('Email sent to ' + order.email + ' for ' + order.product);
      });
    });

Another Custom Wicket Component - DateDropDownField

I needed a date drop down component (see below) for my current project. Unfortunately, I couldn’t find a built-in Wicket component that does the job. So why not write my own???

Date Drop Down

Java Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
public class DateDropDownField extends FormComponentPanel<Date>
{
  private static final long serialVersionUID = -839727513016106766L;

  private int month, day, year;
  private final DropDownChoice<Integer> monthField;
  private final DropDownChoice<Integer> dayField;
  private final DropDownChoice<Integer> yearField;

  public DateDropDownField(String id, IModel<Date> model)
  {
    super(id, model);

    // create month field
    monthField = new DropDownChoice<Integer>("month",
                   new PropertyModel<Integer>(this, "month"), // bind model
                   getMonths(),                               // list of choices
                   new MonthRenderer());                      // renderer
    monthField.setLabel(new Model<String>("month"));
    monthField.add(new RangeValidator<Integer>(0, 11));       // add a simple validator

    // create day field
    dayField = new DropDownChoice<Integer>("day",
                   new PropertyModel<Integer>(this, "day"), getDays());
    dayField.setLabel(new Model<String>("day"));

    // create year field
    yearField = new DropDownChoice<Integer>("year",
                   new PropertyModel<Integer>(this, "year"), getYears());
    yearField.setLabel(new Model<String>("year"));

    add(monthField);
    add(dayField);
    add(yearField);
  }

  @Override
  public void onBeforeRender()
  {
    // initialize model
    Date date = getModelObject();
    if(date == null)
    {
      date = new Date();
      setModelObject(date);
    }

    // synchronize main model and drop down components
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    month = cal.get(Calendar.MONTH);
    day = cal.get(Calendar.DAY_OF_MONTH);
    year = cal.get(Calendar.YEAR);

    super.onBeforeRender();
  }

  @Override
  public void convertInput()
  {
    try
    {
      // get values from individual components
      int month = monthField.getConvertedInput();
      int day = dayField.getConvertedInput();
      int year = yearField.getConvertedInput();

      // TODO check for valid date (example - 02/31/11 is invalid)

      // update the model from converted input
      Calendar calendar = Calendar.getInstance();
      calendar.set(Calendar.MONTH, month);
      calendar.set(Calendar.DAY_OF_MONTH, day);
      calendar.set(Calendar.YEAR, year);
      setConvertedInput(calendar.getTime());
    }
    catch(Exception e){
      setConvertedInput(null);
    }
  }

  // month choices
  private List<Integer> getMonths() {...}

  // day choices
  private List<Integer> getDays() {...}

  // year choices
  private List<Integer> getYears() {...}

  // render months as names instead of numbers
  private class MonthRenderer extends ChoiceRenderer<Integer>{
    private static final long serialVersionUID = -9037815586384085976L;
    @Override
    public String getDisplayValue(Integer object)
    {
      SimpleDateFormat format = new SimpleDateFormat("MMM");
      Calendar cal = Calendar.getInstance();
      cal.set(Calendar.MONTH, object);
      return format.format(cal.getTime());
    }
  }
}

HTML Code:

1
2
3
4
5
6
7
8
9
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
  <body>
    <wicket:panel>
      <select wicket:id="month"></select>
      <select wicket:id="day"></select>
      <select wicket:id="year"></select>
    </wicket:panel>
  </body>
</html>

Again, Wicket saved the day. Here’s another reusable and self-contained component. To use this anywhere in your code, you simply need to add this new component to a form, panel, etc. No need to duplicate code or html markup!

Java Code:

1
add(new DateDropDownField("date", new Model<Date>(new Date())));

Extending Wicket’s AjaxFallbackDefaultDataTable

I was looking for a Wicket datatable component with sorting, paging and ajax support. Fortunately, I found this component.The only problem is, I want to be able to apply a different background style when selecting each row (hover) and execute some action when the entire row is clicked. These features are not supported out-of-the-box.


Wicket table


Luckily, Wicket makes it very easy to extend components. All I had to do was hook into the method that creates each row object and add the new behavior. Here’s the code…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class CustomAjaxFallbackDefaultDataTable<T> extends AjaxFallbackDefaultDataTable<T>
{
   // Constructor
   public CustomAjaxFallbackDefaultDataTable(String id,
                                             List<IColumn<T>> columns,
                                             ISortableDataProvider<T> dataProvider,
                                             int rowsPerPage)
   {
      super(id, columns, dataProvider, rowsPerPage);
   }

   @Override
   protected Item<T> newRowItem(String id, int index, final IModel<T> model)
   {
      // let super class create row item as usual
      final Item<T> item = super.newRowItem(id, index, model);

      // add style on mouse over
      item.add(new SimpleAttributeModifier("onmouseover",
                                           "this.style.backgroundColor='#80b6ed';"));

      // remove style on mouse out                                    
      item.add(new SimpleAttributeModifier("onmouseout",
                                           "this.style.backgroundColor='';"));

      // execute when row is clicked
      item.add(new AjaxEventBehavior("onclick"){
         protected void onEvent(AjaxRequestTarget target){
            executeOnClick(target, item.getModel());
         }
      });

      return item;
   }

   public void executeOnClick(final AjaxRequestTarget target, final IModel<T> rowItem)
   {
      String message = rowItem.getObject() + " was clicked";

      // execute server side code
      System.out.println(message);

      // execute client side code
      target.appendJavascript("alert('" + message + "');");
   }
}

Now the table looks something like this…

New Table


As you can see, I was able to extend a component with minimal effort. In addition, this component is reusable. The user can simply override the executeOnClick method if a different action is required when the row is clicked. Try that with JSF =)


Drupal / Java Integration

Drupal is one of the best open source content management systems currently available. One of Drupal’s strengths is its module development architecture. It allows developers to extend Drupal’s core features in a non-invasive and elegant manner. My only problem with Drupal is that it is written in …. PHP.


I am not a PHP expert, but I am an experienced Java Developer. I have written and deployed many Java enterprise applications in production. I am very familiar with a number of Java frameworks and technologies such as Spring, Struts, JSF, Wicket, JPA, JMS, Web Services, etc. I am also proficient on several Java development/testing tools. However, I do not know of any Java open source projects that can provide all of Drupal’s features out-of-the-box.


Luckily, I found a way to integrate Drupal/PHP and Java using the Quercus PHP engine. Because Quercus can run PHP scripts and expose Java methods in PHP, I was able to write Drupal modules by calling Java methods inside PHP functions. I can write most of the business logic in Java and only use PHP to write the Drupal “hooks”!.


I was also able to integrate other Java frameworks such as Spring, Vaadin and Wicket. I used SiteMesh to decorate the Wicket/Vaadin pages using the same Drupal theme.


Check out my POC web application here!

POC


Vaadin Demo - SuperImmediateTextField

Here’s another example of how easy it is to write Vaadin applications. I used an add-on component called SuperImmediateTextField. This component triggers an event each time the user enters a character in the text field.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Window mainWindow = new Window("Demo Application");
setMainWindow(mainWindow);

final LocationService service = new LocationService();
final Label cityAndStateLabel = new Label();
final SuperImmediateTextField zipcode = new SuperImmediateTextField();
zipcode.setInputPrompt("Enter zipcode");
zipcode.addListener(new KeyPressListener(){
  private static final long serialVersionUID = 2328719780185993498L;

  @Override
  public void keyPressed(KeyPressEvent event) {

    String cityAndState = null;
    String zip = (String)zipcode.getValue();
    if(StringUtils.isNotBlank(zip) && zip.length() == 5){
            cityAndState = service.getCityAndState(zip);
    }

    if(StringUtils.isBlank(cityAndState)){
            cityAndState = "Unknown";
    }

    cityAndStateLabel.setValue(cityAndState);
  }
});

HorizontalLayout layout = new HorizontalLayout();
layout.addComponent(zipcode);
layout.addComponent(cityAndStateLabel);

mainWindow.addComponent(layout);

EasyMock Objects Injection using Spring and Annotations

Declaring EasyMock objects as spring beans is easy…

1
2
3
<bean id="mailProcessor"  class="org.easymock.classextension.EasyMock" factory-method="createMock">
  <constructor-arg value="com.myservice.MailProcessor" />
</bean>

However, if the bean you want to test is dynamically proxied, you will get a ClassCastException. To work around this, you can create a custom annotation and bean post processor. This will allow you to annotate fields with @MockObject and Spring will provide the mock object using dependency injection…

Custom Annotation

1
2
3
4
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
public @interface MockObject {}

Custom Spring Bean Post Processor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Component
public class MockObjectBeanPostProcessor implements BeanPostProcessor
{
  private Log logger = LogFactory.getLog(this.getClass());

  /* (non-Javadoc)
   * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
   */
  public Object postProcessBeforeInitialization(Object bean, String beanName)
    throws BeansException
  {
    // get all the fields
    Field[] fields = bean.getClass().getDeclaredFields();
    for(Field field : fields)
    {
      // check if field is annotated by Environment Property
      if(field.isAnnotationPresent(MockObject.class))
      {
        try
        {
          field.setAccessible(true);
          field.set(bean, EasyMock.createMock(field.getType()));
        } catch (Exception e) {
          logger.warn(e);
        }
      }
    }
    return bean;
  }


  /* (non-Javadoc)
   * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
   */
  public Object postProcessAfterInitialization(Object bean, String beanName)
    throws BeansException
  {
    // do nothing, return original bean
    return bean;
  }
}

Sample JUnit Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/spring-test.xml"})
public class MailProcessorTest
{
  @MockObject private MailProcessor mailProcessor;

  @Test
  public void test()
  {
    // setup test behavior

    EasyMock.replay(mailProcessor);
  }
}

Declarative Caching using Spring

Java Class

1
2
3
4
5
6
7
8
9
10
package services.interfaces;

import org.springmodules.cache.annotations.Cacheable;
import services.model.Location;

public interface LocationService {

  @Cacheable(modelId="getLocationCacheModel")
  public Location getLocation(String zipcode);
}

ehcache.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<ehcache>
  <defaultCache
    maxElementsInMemory="500"
    eternal="true"
    overflowToDisk="false"
    memoryStoreEvictionPolicy="LFU" />

<cache name="getLocationCache"
    maxElementsInMemory="50"
    eternal="true"
    overflowToDisk="false"
    memoryStoreEvictionPolicy="LFU" />
</ehcache>

Spring Configuration File

Add the following namespace definition: http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd

1
2
3
4
5
<ehcache:config configLocation="classpath:ehcache.xml" />
<ehcache:annotations>
  <ehcache:caching id="getLocationCacheModel"
          cacheName="getLocationCache" />
</ehcache:annotations>

Unlocking a password-protected PDF using the iText library

iText is an excellent Java-PDF library that allows Java developers to easily generate and manipulate PDFs. Here is a simple code example that unlocks a password-protected PDF…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import com.lowagie.text.pdf.PdfEncryptor;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;

public class UnlockPDF
{
   public static void main(String[] args) throws Exception
   {
      String lockedFile = "locked.pdf"           // Locked pdf filename
      String password = "p@ssw0rd";              // Locked pdf password
      String unlockedFile = "unlocked.pdf";      // Filename of the new unlocked pdf

      PdfReader reader = new PdfReader(lockedFile, password.getBytes());

      System.out.println("Unlocking...");

      PdfEncryptor.encrypt(reader, new FileOutputStream("unlocked.pdf"), null,
         null, PdfWriter.AllowAssembly | PdfWriter.AllowCopy
         | PdfWriter.AllowDegradedPrinting | PdfWriter.AllowFillIn
         | PdfWriter.AllowModifyAnnotations | PdfWriter.AllowModifyContents
         | PdfWriter.AllowPrinting | PdfWriter.AllowScreenReaders, false);

      System.out.println("PDF Unlocked!");
   }
}

Exposing a Spring POJO as a Web Service using XFire

In your web.xml, add the following configuration:

1
2
3
4
5
6
7
8
9
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    classpath:org/codehaus/xfire/spring/xfire.xml
  </param-value>
</context-param>
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Then, add the following to your Spring context file..

1
2
3
4
5
6
<bean class="org.codehaus.xfire.spring.remoting.XFireExporter">
  <property name="serviceFactory" ref="xfire.serviceFactory" />
  <property name="xfire" ref="xfire" />
  <property name="serviceBean" ref="serviceImpl" />
  <property name="serviceClass" value="com.samples.interface.Service" />
</bean>