Tuesday, May 29, 2018

Oracle Database Change Notification

Pros:
Instantaneous notification when the table changes

Cons:
When there is a network outage between server and client adapter, the notification will not work anymore, a new registration has to be made.

Friday, May 13, 2016

C programming using cmd.exe

Windows provides you command line tools when you install VisualStudio Community 2015 (VS2015). You can use VS2015 up to 30 days trial, and after that you'll get prompt asking you to get license, but you still can use the command line tools.

To compile a C program, VS2015 provides you a command line intepreter called cl. To use it, you need to setup the development environment. Luckily, VS2015 also provides a batch script to do this for you. The script is called VsDevCmd.bat and is located inside <VS2015 installation folder>\Common7\Tools.

The most basic usage of cl is:
cl your_first_program.c

If you wish to add extra libraries, you need to append the %INCLUDE% and %LIB% variables. To do this just use the SET command. For example, if you want to include Python.h, you do the following:
SET LIB=%LIB%%PYTHON_HOME%\libs;
SET INCLUDE=%INCLUDE%%PYTHON_HOME%\include;

Sunday, November 2, 2014

GWT 2.3: Display blank column for DatePickerCell

If your Column.getValue returns null, you wouldn't be able to popup DatePickerCell.datePicker since you pass null to its datePicker.setValue method.
Here's my solution:

DatePickerCell<Object, Date> cell = new DatePickerCell(datetimeFormatter) {
     @Override
     protected void onEnterKeyDown(Context context,
                                   Element parent,
                                   Date value,
                                   NativeEvent event,
                                   ValueUpdater<Date> valueUpdater) {
         if (value == null)
             value = new Date();
         super.onEnterKeyDown(context, parent, value, event, valueUpdater);
     }
};

Friday, July 4, 2014

Java: Comparing date with today's date

Usually in Java, if you want to compare there are three methods (that I know of); using DateFormat; using Calendar; and using milliseconds since epoch. The following is how I do date comparison for each methods (starting from the slowest based on my own tests) with d as the target date:

Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE, -5); // 5 days ago.
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date d = cal.getTime();

DateFormat

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Date today = sdf.parse(sdf.format(new Date));
boolean isBeforeToday = d.getTime() < today.getTime();
boolean isToday = d.getTime() == today.getTime();
boolean isAfterToday = d.getTime() > today.getTime();

Calendar

This is quite fast, so if you prefer readability, I suggest you choose this.
 
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
// I think you can also use Calendar.before() & Calendar.after()...
boolean isBeforeToday = d.getTime() < cal.getTime().getTime();
boolean isToday = d.getTime() == cal.getTime().getTime();
boolean isAfterToday = d.getTime() > cal.getTime().getTime();
 

Milliseconds

 I prefer this method, which I believe the fastest. But it's the least readable...

long now = new Date().getTime();
long delta = d.getTime() - now;
boolean isBeforeToday = delta <= -86400000; // 24*60*60*1000, milliseconds in a day
boolean isToday = delta <= 0 && delta > -86400000;
boolean isAfterToday = delta > 0;

NOTE: Don't use this if the time part of java.util.Date is non-zero. :)

Friday, December 20, 2013

Fedora 20: Touchscreen doesn't work after lid closed

Fedora 20 was released recently and finally I've got the balls to install it in my new touchscreen laptop (which is preinstalled with Windows 8). The installation step is rather easy, takes me only few steps and I was like "that's it? It's installed?"

It looks nice, but there're some issues with my touchscreen. It appears that touchscreen will not work after I close my laptop lid, or probably when the laptop is put to sleep. So my early assumption is that whatever thing that should be handling the input from the touchscreen is not restarted. I'm almost correct, but the actual reason is that the touchscreen device was not mapped to the output device (i.e. the screen).

To solve this, first you need to know the name of your output device using the following command:
$ xrandr
Screen 0: minimum 320 x 200, current 1366 x 768, maximum 8192 x 8192
LVDS1 connected primary 1366x768+0+0 (normal left inverted right x axis y axis) 344mm x 193mm
   1366x768       60.0*+
   1024x768       60.0 
   800x600        60.3     56.2 
   640x480        59.9 
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
DP1 disconnected (normal left inverted right x axis y axis)


in my case, LVDS1 is my laptop screen. Then you need to know your touchscreen ID using the following command:
$ xinput list
⎡ Virtual core pointer                        id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                  id=4    [slave  pointer  (2)]
⎜   ↳ Atmel Atmel maXTouch Digitizer              id=11    [slave  pointer  (2)]
⎜   ↳ ETPS/2 Elantech Touchpad                    id=14    [slave  pointer  (2)]
⎣ Virtual core keyboard                       id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard                 id=5    [slave  keyboard (3)]
    ↳ Power Button                                id=6    [slave  keyboard (3)]
    ↳ Video Bus                                   id=7    [slave  keyboard (3)]
    ↳ Video Bus                                   id=8    [slave  keyboard (3)]
    ↳ Sleep Button                                id=9    [slave  keyboard (3)]
    ↳ USB Camera                                  id=10    [slave  keyboard (3)]
    ↳ Asus WMI hotkeys                            id=12    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard                id=13    [slave  keyboard (3)]


from the output, my touchscreen would be Atmel maxTouch with id 11.

Now that you have both my output and input id, you can now map the input to the out using the following command:
$ xinput --map-to-output 11 LVDS1

Now test your touchscreen, it should've work after you execute the command.

Hope this helps. :)

Monday, August 5, 2013

Java RMI: Client timeout

Creating a timeout for Java RMI client is important  since LocateRegistry.getRegistry would make your application unresponsive when the Java RMI server is not available. To create a timeout at the client-side, I suggest you to use ExecutorService. The following codes is an example how to use it:

Suppose you have your localhost listening on port 1099 for RMI and your server serve an interface

public interface RMIService() {
  public String sayHello throws RemoteException;
}

Then at your client app, you do this

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Callable<Object>() {
 

  @Override
  public Object call() throws Exception {
    String host = "localhost";
    int port = 1099;
    RMIService service = (RMIService) LocateRegistry

      .getRegistry(host, port).lookup("RMIService");
    System.err.println(service.sayHello());
    return null;
  }


});
 

try {
  future.get(5, TimeUnit.SECONDS);

} catch (InterruptedException | TimeoutException |
    ExecutionException e) {
  System.err.println(e.getMessage());

}

The above code will try executing the remote method and will throw exception if  the lookup time exceeds 5 seconds.

Hope this helps. :)

Monday, February 18, 2013

Java EE: Persists entity beans with generated primary key (SQL Server)

In developing an enterprise application in Java EE, sometimes you would come across a database table with auto-generated primary key. If you're using NetBeans to generante entity beans from a database, you would get something like this:

@Entity
@Table(name = "your_table_name")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "YourTableName.findByTheId", ... )})
public class YourTableName implements Serializable {
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "the_id")
    private Integer theId;


    ...
}

But if you try to persists an instance of the entity bean, you would get an error and you would not be able to alter your database. This is because when you try to persist the instance you would do this

YourTableName yourTableName = new YourTableName();
yourTableName.setFooBarField("foobar"); //example field in table

em.persists(yourTableName);

You could not set the yourself, since it's suppose to be autogenerated by the database. So, in order to solve this, you have to edit the generated entity beans, by adding GeneratedValue annotation to the primary key variable, and also remove the NotNull annotation, like so:

@Id
@Basic(optional = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "the_id")
private Integer theId;

You have to remove @NotNull since, during persisting, you does not set the value for the primary key. Not removing this would throw an error (at least in my case).

Hope this would help. :)