14 November 2013

Streaming takes over internet

The Sandvine report on the first half of 2013 reports 40% of the fixed access downstream traffic entertainment streaming. YouTube accounts for half of this traffic.

In the US, entertainment already takes up 70% of fixed downstream traffic. Here, half of the entertainment downstream traffic is NetFlix, while YouTube accounts for another 25% of entertainment traffic.


12 November 2013

StartWebLogic: \xxx was unexpected at this time

Just installed weblogic 12c with an initial domain on windows.
When running startweblogic in the domain i get an error
\xxx was unexpected at this time 

WebLogic seems to stumble over some stuff in my CLASSPATH. Mine 
has jars for the Belgium identity Card in it (others had a problem with QuickTime: QTJava.zip).

Easiest solution is the cleean my classpath, but then other applications will have problems.

After the SETLOCAL line in the startWebLogic.cmd and stopWeblogic.cmd in my domain, I added a line
set CLASSPATH=

Now it starts fine. Updating all these scripts is not the ideal solution however.

6 November 2013

Java 7 NIO.2 file handling (updated)

Java 7 contains a newer set of IO API's. This is an extension of the NIO (New Input/Output) API introduced in Java 1.4. The extenson is is called NIO.2 and specified in JSR 203. NIO.2 contains
  • a new API for handling filesystems and files
  • an API for asynchronous  I/O on both sockets and files
  • additional features on sockets ( binding, multicast datagrams...)

java.nio.file

In this article we will discuss the file handling API. All the classes for this functionality are in the new java.nio.file package.

The Path class

This is the new class  representing a file location (replacing corresponding methodsd in java.io.File).
The Paths (plural!) class contains static utility methods that return a Path object:
import java.nio.file.Path;
import java.nio.file.Paths; 


// p1: relative Path to a file
Path p1 = Paths.get(“subdir/in.txt"); 
// p2: Absolute path to c:\java\local\jan\Hello.java
// Paths.get() can take a variable number of arguments
// each extra argument indicates an extra directly level
Path p2 = Paths.get("c:\\java\\local”,”rijkswatch”,”Hello.java"); 
In the above example, remark that when using backslashes as a directory separator (Microsoft style), they need to be doubled to escape their special meaning in java String.

FileSystem support

These methods will give you information on the different filesystems on the machine, their mount points, type, size, free space...

The picture shows the output of the code in DOS.

// once more the plural class (FileSystems) contains static utility methods
// that produce objects of the singular (FileSystem) class
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths; 

FileSystem fs = FileSystems.getDefault(); 
for (Path rootPath : fs.getRootDirectories()) { 
  try { 
    FileStore store = Files.getFileStore(rootPath);
    System.out.println(rootPath + ": " + store.type()); 
  } catch (IOException e) { 
    System.out.println(rootPath + ": " + 
      "<error getting store details>"); 
  } 
} 


java.nio.file.Files methods

 

Static utilities in the Files class operate on Path (directory of file) objects.

searching in a directory

for (Path file : Files.newDirectoryStream(Path base, String pattern)){
   …
}
The pattern can contain wildcards like:

* any string
** any string, going down in directories
? any single character
[a,0-9] a or a number
[!a-z] NOT a lower case character
{one,two} String one or two

To recurse into subdirectories use Files.walkFileTree.

Some more static Files methods

public static long size(Path path) // Returns size of the file
public static boolean isReadable(Path path)
public static boolean isSymbolicLink(Path path) // path a soft link? 
  // LinkOption below specifies how symbolic links should be handled 
public static Path createLink(Path link,Path existing) // create hard link
public static Object getAttribute(Path path,String attribute,LinkOption... options)  
  // attribute "unix:nlink" gives # hard links in unix attribute space<
public static boolean exists(Path path, LinkOption... options)
public static boolean isDirectory(Path path, LinkOption... options)
public static Path move(Path source, Path target, CopyOption... options)
public static List<String> readAllLines(Path path, Charset cs) 

Switching between the new nio Path and the old io File

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

Path p1 = Paths.get(“subdir/in.txt");
File f1 = p1.getFile();
Path p2 = f2.getPath();

4 November 2013

JPA : choose your enum ordinals (Updated)

Ordinal enums are brittle with JPA.
If you change the order of the enum constants,
the ordinal number that is saved to the database changes.

You can solve that by assigning your own code in the enum (10,20,30 in the example).
In the entity, make the enum transient.
Before saving the entity put your code in an int attribute, which will be stored in the database.
After loading convert the int back to the enum.

 Update: In JPA 2.1 you can also do this with @Converter


public enum Status{
  OPEN(10), CLOSED(20), CANCELLED(30);
  private int code;  
  
  private Status(int code) {  
    this.code = code;  
  }  
       
  public int getCode() {  
    return code;  
  }
     
  public static  Status getStatus(int code){
    for (Status stat : Status.values()) {
      if (stat.getCode()==code) return stat;
    }
    return null; // not found: invalid code
  }
}
       
@Entity
public class Auction{
  private int status;
  @Transient private Status statEnum;

  public int getStatus(){
    return status;
  }

   public void setStatus(int status){
    this.status = status;
  }

  @PostLoad private void int2enum(){
    statenum = Status.getStatus(status);
  }

  @PrePersist private void enum2int(){
    status = statEnum.getCode();
  }
  //...
}


NB: kudos to Guy for moving conversion to callbacks.

A JUnit 4 Test class

package infotool;

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class InfoModelTest {

    private InfoModel instance;

    @Before
    public void setUp() {
        instance = new InfoModel();
    }

    /**
     * Test of getMessage method, of class InfoModel.
     */
    @Test
    public void testGetMessage() {
        assertEquals("welcome to mvc", instance.getMessage());
    }

    /**
     * Test of getWeather method, of class InfoModel.
     */
    @Test
    public void testGetWeather() {
        assertEquals("Sunny", instance.getWeather());
    }

    /**
     * Test of setMessage method, of class InfoModel.
     */
    @Test
    public void testSetMessage() {
        String wthString = "JUnit @Rules";
        instance.setMessage(wthString);
        assertEquals(wthString, instance.getMessage());
    }

    /**
     * Test of setWeather method, of class InfoModel.
     */
    @Test
    public void testSetWeather() {
        String wthString = "It's going to rain";
        instance.setWeather(wthString);
        assertEquals(wthString, instance.getWeather());
    }

    /**
     * Test of addModelChangeListener method, of class InfoModel.
     */
    @Test
    public void testAddModelChangeListener() {
        InfoModel instance = new InfoModel();
        InfoView view = new InfoViewTestSupport(instance);
        instance.addModelChangeListener(view);
        instance.setMessage("From testAddModelChangeListener");
        assertTrue(((InfoViewTestSupport) view).getNotification());
    }
}

1 November 2013

Java programming: extra labs

 Lesson 3

Extra Practice 3-2, Task 3

Step e. Add a method addEmployees that adds multiple employees

Lesson 4

  Extra Practice 3-2: Equals method

  1.  Add an equals method to the employee class
    1. Use employee id to test equality
      1. Make  sure that it takes into account null values and references to other classes being passed in
      2. You can use ALT+INSERT in NetBeans to insert a sample equals method
    2. Test and correct until the code succeeds
  2. Modify the equality test to use the social security number
    1. Test and correct until the code runs correctly

Lesson 5

  Extra Practice: Deck

  1. Start from the Deck lab from Java Funcamentals
  2. Replace the CardNames and CardValues arrays with enums Suit and Face
  3. Replace the decksize (52) with a number calculated from the available enums 
    1. hint: using the values() method on your enum, returns an array of all values
  4. Test and correct the code until the program runs correctly
  5. Extend the Suit enums with the corresponding unicode characters
    SPADES('\u2660'),CLUBS('\u2663'),DIAMONDS('\u2666'),HEARTS('\u2665');
  6. Extend the Face enum with numbers/names
     ACE("Ace"), TWO("2"), THREE("3"), FOUR("4"), FIVE("5"), SIX("6"),SEVEN("7"), EIGHT("8"), NINE("9"), TEN("10"), JACK("Jack"), QUEEN("Queen"), KING("King");
  7. Modify the code to display the cards using the new data
  8. Test and correct the code until the program runs correctly

Lesson 7

  Extra Practice: Couple

  1. Write a generic class Couple<S,T> that stores two values each with its own generic type
  2. Write a constructor without parameters and a constructor with two parameters
  3. Write getters and setters for each of the members
  4. Write a test, creating a Couple <Integer,String> 
    1. Try to call getters and setters respecting the given types
    2. Try to call getters and setters that do not respect the given types

Extra practice: EmployeeDAOMapImpl

  1. Write an EmployeeDAOMapImpl for practice 6-2 using a Map as internal storage. Start from a copy of the EmployeeDAOMemoryImpl 
  2. Have the factory return the  EmployeeDAOMapImpl
  3. Test and correct until the program runs well

Lesson JUnit

practice DAO

  1. Add a reset() method to the EmployeeDAO from practice 6-2 that clears the employee storage
  2. Create  a JUnit 4 testcase for the EmployeeDAO
    1. Right click on the class and select tools > create Tests
      1. The testcase is created in a dedicated test directory
      2. in which package does the testcase reside?
  3. Complete the generated testcase
    1. In the @BeforeClass method create the DAO object and store it in a static attribute
    2. In the @Before method, initialise the employee table with 3 records
      1. Hint: to make a Date object use Calendar cal = Calendar.getInstance();  
        // you can reuse the same cal object for multiple dates // set the date to januari 6th 2013
        cal.set(2013, 0, 6);
        Date d = cal.getTime();
    3. Write tests for all operations
      1. You may add a setter method to Employee for testing the update operation
  4. Right click the project and select Test (or press ALT+F6)
    1. Test until all tests succeed

Lesson 8

 Extra practice: CSV changer

Write a unit test that replaces all blanks in a file by colons. Multiple blanks should be replaced by only one colon.


30 October 2013

Flemish libraries to lend e-books

In april 2014 Flemish libraries will start a pilot project to extend their offer with e-books. The initial pilot will run for a year and the catalog wil contain 300 titles.
You will be able to read them for free in the library.  For reading anywhere readers will be charged using the 345-model: maximum 3 ebooks fro maximum 4 weeks will cost €5.
The e-books will be readable using an app for Android and Apple. They will not be readable using an e-reader device, like Amazon Kindle, unless it can run Android apps. This limitation was needed to enforce the 345 lending model.
Here's a presentation for libraries that want to participate in the pilot project. Below is an infograph on ebooks ales evolution from 2011 => 2012, taken from the presentation:



25 September 2013

Java fundamentals: extra labs

Lesson 6

Extra practice: Extend Customer Info

  1. Modify lab 6.1 to ask the user to enter the attributes of the customer
  2. Use java.util.Scanner to read the attributes
    1. Take care: after reading an int, you also need to read the return (newline) to advance to the next line of input

Lesson 7

Practice 7.1:

Modify the exercise to:
  1.     Use a java.util.Scanner to read the time of the day from the user input.
  2.     Allow the user to use the format hh:mm:

Extra practice: Seasons

  1.  Create a class Meteo with a method
  2.     public String getSeason(String month) 
  3.  Implement the method and let it return the meteorological season for the month 
    1. (e.g. for december to february return winter)
  4. Create a class MeteoTest
  5. Write a main method that
    1. Creates a Meteo object
    2. Asks the user for the name of a month
    3. Uses the Meteo object to get the corresponding season
    4. Prints out the season
  6. Run the test program and correct errors until it succeeds
  7. Modify the program to make it work no matter which case the user uses when entering the month.
  8. Run the test program and correct errors until it succeeds

Lesson 8

Extra practice: Deck

  1. Create a class Deck  
  2. Initialise a cardNames array with the value of all cards (ace, two, three..., jack, queen, king)
  3. Initilise a cardSuites array with the suites of all cards (hearts, spades, clubs, diamonds)
  4. Create a method called printSize, which
    1. prints the number of cardValues
    2. prints the number of cardSuites
    3. prints the number of cards
  5.  Create a class DeckTest
  6. Write a main method that
    1. Creates a Deck object
    2. Calls printSize on it
    3. Run the test program and correct errors until it succeeds
  7. Write a method drawCard, which prints the name of a random card (e.g. jack of spades)
    1. Hint: use Math.random()
  8. Draw two cards from the main method
  9. Run the test program and correct errors until it succeeds

Lesson 9

Extra practice: Dice

  1.  Create a class DiceStat with a method
  2.     public void printStat () 
  3. The method should roll 2 dice 10.000 times (Hint: use Math.random()
  4. Print the number of times each number was rolled
  5.  Create a class DiceTest
  6. Write a main method that
    1. Creates a DiceStat object
    2. Calls printStat
  7. Run the test program and correct errors until it succeeds
  8. For each result, express as a percentage, how often it is thrown
  9.  Run the test program and correct errors until it succeeds

Extra practice: Factorials

A factorial (n!) is the product of all numbers less than or equal to n. Example:

3!= 3*2*1

Create an application, called factor that will print the factorial of the number given as an argument to the application:

$ java FactorTest 3
3! = 6

Lesson10

Extra practice: Quiz

  1.  Create a class Quiz with keywords and definitions.You can find the keywords and definitions here.
  2. Create a method with signature
  3.     public boolean askQuestion()
    1. The method asks the user to give the keyword that corresponds to a randomly chosen definition
    2. The method compares the answer with the  keyword
    3. The method informs the user about the correctness of the result.
    4. If the answer was wrong, it shows the correct keyword
    5. The method returns if the respons is correct
  4. Create a class QuizTest
  5. Write a main method that
    1. Creates a Quiz object
    2. Calls askQuestion
  6. Run the test program and correct errors until it succeeds
  7. Add a method with this signature
  8.       public int askQuestions(int number) 
    1. The method asks multiple questions
    2. The method returns the number of correct answers
  9. Call the method from the main class
  10. Run the test program and correct errors until it succeeds
  11. Add a method with this signature
    1.  public boolean certify (int numberOfQuestions, int passPercentage)
    2. The method prints out your score percentage.
    3. The method prints out whether you passed the certification or not.
    4. The method returns a boolean with the pass result.
  12. Call the certify method from the main class
  13. Run the test program and correct errors until it succeeds

Extra practice: Hypothenuse

The hypotenuse is the longest side in a right angled triangle. Pythagore's theorem states that the length of the hyothenuse (h) relates to the two other sides (x and y)  as:

Write a program, using that calculates the hypothenus, using java's Math class:

$ java HypothenuseTest 2 3
Hypothenuse = 3.6

Lesson 11

Extra practice: Unique object ID's

  1.  Modify the Rectangle class to assign a unique ID to each object that is created.
    1. Start the ID's at 1 and increment for each new object
    2. Print the rectangle ID in the creation message from the constructor
  2.  Run the test program and correct errors until it succeeds

Extra practice: Deck

  1.  Add a Card class to the Deck project
    1. Add a suit and value attribute and methods to retrieve them
    2. Add a Constructor 
    3. Add a method that returns the card name (e.g. queen of hearts) with signature
         public String toString(); 
  2. Add a constructor to the Deck class that generates a Deck of 52 cards.
  3. Modify the drawCard method to return a Card
  4. After calling drawCard, print out the card name from the main method.

Extra practice: Dice constructor

  1. Add a constructor to the DiceStat class that accepts the number of dies, the number of sides each dice has and the number of throws.
  2. Make the Deck class generic to work with these variables.
  3. Run the test program and correct errors until it succeeds

Lesson 12

Extra practice: Rectangle class hierarchy

  1. Make a class Square, that is a subclass of the Rectangle class. 
    1. Add a Constructor that takes the side as an aargument
  2. Draw a square from the RetcangleTest main method
  3. Run the test program and correct errors until it succeeds
  4. Make rectangle a subclass of Shape. Make a class Shape with an abstract draw method.
    1. In Rectangle you can also use Refactor => extract interface
  5. Make a Triangle class that extends Shape (In the interface, you can press ALT+ENTER to generate a class that implements the interface)
    1. This class is a right angled triangle, with equal width and height. Example:
    2. *
      **
      ***
      ****
    3. Implement the necessary methods
  6. Draw a triangle from the RetcangleTest main method
  7. Run the test program and correct errors until it succeeds
  8.  Make a Canvas class, with a method with signature
  9. public void draw (List shapes)
    1. In the draw method  loop over the list
    2. Assign the objects from the list to a Shape variable
    3. Draw each Shape
  10. In the main method of TestRectangle, create a Canvas
  11. Add a number of rectangles, Squares and triangles to an Arraylist.
  12. Call the draw method on the canvas, and pass the arraylist to it.
  13. Run the test program and correct errors until it succeeds
  14. Make a Parallellogram class that extends Shape (you can make a copy of the Rectangle class and name it Parallellogram to start)
    1. This class draws a parallellogram with a slope that indents one character:
    2. ****
       ****
        ****
    3.  Implement the necessary methods
  15. In the main method of TestRectangle, add some paralellograms to the ArrayList
  16. Run the test program and correct errors until it succeeds

22 September 2013

Firefox on windows 64 bit : use the 32 bit plugins

When installing the java plugin on windows 64 bit (I have windows 7), which Java plugin do I need?
64 bit seems the logical choice.
Here's what Oracle, steward of Java says at this time:

Java for 64-bit browsers
Users should download 64-bit Java software, if they are running 64-bit browsers.
Allright, now do I have a 64 bit firefox, the page tells me how to check

Verify if you are using 32-bit or 64-bit browser


Firefox
To determine whether you are running on a 64-bit version of Firefox, use either of these methods.
  • Check the About Firefox panel
  • Type in the browser address about:support
If you are running 64-bit Firefox, it may be indicated as 64-bit (e.g., Win64); otherwise it is a 32-bit version of Firefox.  
 What can I find on this page?


 User Agent     Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0

There's a number 64 in there, but take care: this indicates that windows is 64 bit. To really know more about your firefox you need to follow the about:buildconfig link. oracle should recommend to type that one directly. Look at the target entry:

target i686-pc-mingw32

This is a 32 bit build after all. As a matter of fact, Firefox does currrently not provides a production quality 64 bit build for Windows. On Windows, Firefox currently is a 32 bit application, hence you always take the 32 bit plugins.

2 September 2013

Excel 2010 Advanced Filtering



The official excel (advanced) filtering doc is a step by step guide for some common cases, but does not explain well how it actually works.
The common case is not what i commonly need, so I lose time and patience looking this up.
So I'd better keep a good excel advanced filtering resource around in case I ever need this again.

Remark: every time you change your filter (or sorting) criteria, you have to point the advanced filter to the filtering criteria again. The only way to avoid this is to add a macro to your spreadsheet.

Adidias NEO window dressing

My colleague Eytan pointed me to this Video on Adidas window shopping.
Adidas mounted a giant touch screen in front of the shopping window,
on which you can by goods using a tablet interface.
Looks great!


11 July 2013

Tax on web bugs

In Belgium you can enter your tax form on the web.
Take care to save regurarly: the program is buggy and you can get disconnected unexpectedly (under heavy load, after a timeout...), losing all data you entered.
Not that it seems to matter much for the government: I have not found any way to pass a bug report to development. Well.... there is a phone number.  you can call if you have problems. More a helpdesk than a way to report bugs, but tried that just out of curiosity. After the classical phone menu trail you get into a waiting queue. I was number nine in the queue, so I gave up there.

Country menu bug

  1. The country menu is not sorted alfabetically, but by region. Hence entry completion does not work properly. I wanted to enter Verenigd Koninkrijk (United Kingdom). Entering V takes you to Vaticaanstad, entering VE takes you to Venezuela, but no UK. I'm using firefox 22 here.
  2. If you type a backspace in this field once or twice to correct, you loose your connection and all data you entered.

8 July 2013

Outlook: keep email addresses when forwarding

Outlook 2010 tends to show user names, not email addresses when you look at mails. I guess they want to make mails more user friendly, by automatically converting user names to and from email addresses. You can always retrieve the real email address in the original mail, although it's a bit annoying to do: to see the entire mail header

  1. open the mail in separate window
  2. click the File Tab
  3. click on the Properties button in the central window pane

When you forward the mail, the receiver can do this on the mail you sent, but not on the original, included mail. Outlook strips out header information for the To: and Cc: fields in the included mail, this time mainly out of privacy concerns. When I forward a mail to a project group, I often want to forward the email addresses on the original mail as well. To do this select Forward as attachment. This will include the original mail with all header info and send it to your recipient.

29 June 2013

100th tour de france doodle





If you read the bike wheels backward, you get 100.


15 June 2013

The registry refers to a nonexistent java runtime installation

Installing the EID viewer software for Belgian electronic identity card and got this error:

The registry refers to a nonexistent java runtime installation
Google showed some minecraft gamers having the same problem, so here's how I solved it on Windows 7.
Open the registry editor (regedit.exe).
Go to Computer\HKEY_LOOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment
For each version under this path, verify if the paths for the JavaHome and RuntimeLib variables are correct.
  • RuntimeLib should refer to an existent jvm.dll file, 
  • JavaHome should be the start of this path with the "\bin\client\jvm.dll" part removed. 
For each version of Java you have, you need to do this twice (once for the particular build you have (example 1.7.0_04) and once for the base version (example 1.7). Mine (but take care, I installed to a custom location) are:
  • JavaHome C:\java\jre
  • RuntimeLib C:\java\jre\7\bin\jvm.dll
I got the error because I moved the software to another directory after installation.

13 June 2013

Android Studio Early Access Preview

@ Google I/O there was an announcement for an Android development environment for IntelliJ IDEA.

Hybris 5.0.1 released

New Accelerator feature highlights:

  • Subscriptions (Telecommunications/Digital Accelerator):
    • Define complex subscription offerings with combinations of one-time, recurring, and per-usage charges
    • Manage multiple price periods
    • Personalize pricing based on customer profile
    • Manage subscription promotions by defining free trial or reduced price periods
    • Integrate with the organization’s billing system
    • Manage billing cycles (e.g., frequency, cycle type, cycle day)
    • Define metered and non-metered entitlements and associate them with subscription products
  • Order processing and delivery information Integrated with Store front (My account), Customer Service WebApp, email notification...
  • Progressing uncollected Buy-Online-Pickup-In-Store orders
    • Customers are reminded to pick up their orders if they forget
    • If customers never show then the order is cancelled and a ticket is generated for the Customer Service representative to contact the customer and refund.

11 June 2013

Hybris v5 new features (updated)

In march Hybris made an announcement of a new release. For a major version release the announcement was very low profile. It does not even say that it is a release at all, it just mentions some new features. Maybe they will make a more official announcement yet, who knows.
The release is much more about internals being updated than about radically new features, although there are some. Here's the stuff that caught ^my eye:

  • Architecture
    • New cockpit framework (a cockpit is a small web application directed at a specific task)
      • made up of widgets: multichannel screens that may user multiple datasources
      • Application Orchestrator: a graphical workflow tool to link widgets
    • Accelerators now have Addons: extensions without modifying the accelerator codebase. They may contain frontend functions
    • Mobile SDK
      • HTML5
      • sample apps with  GPS, camera, QR-code scanning, NFC...
    • Clustering without multicast
    • Better caching (EhCache default)
    • Default lazy loading
    • Media storage plugins + Cloud media support
    • Graphical workflow preview
  • Order Management Services (OMS) cockpit
    • single inventory view (multi shop, multi shop)
    • sourcing and allocation
    • pick/pack/dispatch
    • expected for V5.1
      • return management
      • back orders
  • Commerce Infrastructure Services (CIS): 
    • framework with pluggable payment, taxes, address verification, shipping, fraud detection, geolocation...
    • third party plugins for various services
  • InStore module: module providing services in brick and mortar stores
    • QR code, barcode, NFC identification
    • show rich product info
    • access to stock and order management

DZone Cloud Provider Overview

DZone has published an abolutely free (though you have to register) overview of cloud providers, with

  • A definition of different cloud types
  • A presentation of vendors for each type
  • A feature by feature comparison of vendors for each category
  • User survey on cloud intention
The guide does not contain a real evaluation of each product, but still is a great overview of the cloudscape.

7 June 2013

SAP acquires hybris (updated)

German enterprise software builder SAP announced that it is acquiring the Hybris e-commerce platform.
From a product perspective this makes sense: e-commerce software always needs to be integrated with enterprise ERP/CRM backend systems. With the growth of e-commerce SAP needs this to offer an overall solution to its customers and its own WCEM (Web Channel Experience Management) was too limited and too much linked to the SAP backends. Of course we can expect SAP technology creeping into Hybris in the future, like strong integration with the SAP backends and SAP's im-memory HANA database.
Care should be taken that these integrations do not reduce fexibility. Software moloch SAP does not exactly fit Hybris' catch phrase agile e-commerce. Let's hope agility prevails

6 June 2013

online retail trends (updated)

A recent report by the UK Center for Retail Research shows the expected rate of online retail increase. Increasing by 50% by 2018, almost one out of three non-food products will be bought online.

Retailer networks will need only 70 stores to cover the UK, compared to 250 in the mid 2000s.
Even the consumers that buy in brick go online to select the product they want to buy.

Here's what people are buying online (in Belgium). If you combine hotel and travel than holidays is the most important online sector.



In other countries the online retail market share is lower:

In Belgium, according to a study by retail organisation Comeos, the online retail market share is 3%. This is the level the Benelux market was at in 2008. If Belgium follows the global Benelux trend the market should double over the next four years.
Half of Belgian respondents prefers to buy in a Belgian webshop. 70% would like the goods to be delivered at home.


28 May 2013

Excel negative time differences

When you calculate the difference between two time cells in Microsoft Excel (2010 is what I'm using) displays ##### as a result if the difference is negative, because Excel can not display a negative time.

  • One solution is to convert this to a number, which can be shown as a negative value. Internally Excel has the time stored as a number of days, so convert this to the unit you want to display. e.g. to show the difference between time b1 and a1 as a number of minutes
= (b1-a1)*60*24
    • Doing so, you loose Excel time formatting
  • Sometimes the second time (b1) is always later, but because it can be after midnight its value  can be smaller. In thiscase, simply test if time b1 is smaller than a1, and add 1 day if this is so:
=IF(b1>=a1;b1-a1;b1-a1+1)

1 May 2013

1st Web Site

Here's the original CERN website (11/1992).

28 March 2013

JAX-RS 2.0 preview (updated)

Here's an overview of the most important new features in JAX-RS 2.0 (JSR339).
The JSR is currently in public review, so this is subject to change.

  • Asynchronous REST web services
  • REST web services are based on servlets. So the new asynchronous REST support looks a lot like the new asynchronous servlet support.
    The response to an asynchronous web service can be delegated to another thread.
     The webservice needs to pass the asynchronous response, to allow it to send a response.

    @Path ("/rest2/async")
    public class NoWaiter{
      @Asynchronous
      @GET 
      public String delegate(@Suspended AsyncResponse ctx) {
        // put context on a queue
        // for job to be picked up by a thread
        bloq.add(ctx);
        // exit immediatly
      }
    }
    
    class Handler implements Runnable{
      public void run(){
        AsyncResponse ctx bloq.take();
        // return response
        ctx.resume("response");
      }
    } 
  • Client API
  • Similar to Jersey 1 client API (some names change)
    Client client = ClientFactory.newClient();
    String result = client.target(“http://reasonsto.be”)
      .request("text/plain")
      .get(String.class); 
    
    Chaining async() in the call, the client becomes asynchronous:
    Future<String> result = client.target(“http://reasonsto.be”)
      .request("text/plain")
      .async()
      .get(String.class);
    You can also pass a listener to the asynchronous client:
    Future<String> result = client.target(“http://reasonsto.be”)
      .request("text/plain")
      .async()
      .get(new Hark()); 
    
    class Hark implements InvocationCallback<String>
    {
    public void completed(String result) {…}
    public void failed(InvocationException err) {…}
    }
  • Filters and Entity Interceptors
    • Similar to Jersey 1 filters 
    • @Provider annotated 
    • set order using @Priority
    • Filters wrap around an entire HTTP request. Mostly deal with HTTP headers, URI, method...
      • interface ContainerResponsFilter (javax.ws.rs.container)
        • void filter(ContainerResponseContext ctx) throws IOException
      • interface ContainerRequestFilter
        • void filter(ContainerRequestContext ctx) throws IOException 
        • Can have an additional @PreMatching annotation to run before JAX-RS resource method is selected (default is after resource method selection)
      • Throwing an exception will veto further processing of the message
      • javax.ws.rs.client contains similar clientside filters. Just replace Container with Client in the above interfaces. 
        • not annotated, but ClientBuilder, Client, and WebTarget all implement the Configurable interface. You can add your filter using its register(yourFilter) method.
    • Entity Interceptors wrap around the HTTP body <=> java Object marshalling/unmarshalling (e.g. for supporting compression encoding)
      •  interface WriterInterceptor
        • void aroundWriteTo(WriterInterceptorContext ctx) throws IOException, WebApplicationException
      • interface ReaderInterceptor
        • Object aroundReadFrom(ReaderInterceptorContext ctx) throws IOException, WebApplicationException
      • The aroundXXX  method naming indicate that these work like servlet filters:
        1. do some stuff
        2. ctx.proceed(): delegate to the next interceptor in the chain (of there is one)
        3. do some more stuff
    • Binding
      • Global
        •  @Provider
      • Local 
        • Using DynamicFeature
        • Using @NameBinding
          • Indicate that the usage of this resourcemethod is to be logged, using our own annotation:
          • @LogMe
            @GET
            @Produces("text/html")
            public String getXml(){ 
              return "<html>...</html>"
            }
            
          • Define the annotation
          • @NameBinding
            public @interface Logme{}
            
          • Implement the annotation
          • @LogMe
            public class LoggerLoggingFilter 
              implements ContainerRequestFilter, ContainerResponseFilter {
            // your logging code 
            }
            
        • Dynamic
          1. The filter is bound using one of the above methods, but there is an extra check to see if the filter should be applied
          2. The filter must implement the DynamicBinding interface
          3. The filter is applied only if the isBound() method returns true 
    • JSR303 validation
    • @Produces allows server to specify a mime type preference, using the qs attribute
    • Form class can be used as a resource method argument to capture a map of query parameters (shorthand for UriInfo.getQueryParameters()).

13 March 2013

Netbeans 7.3 comes with JPQL runner

A welcome addition to the new Netbeans release, issued last month:


6 March 2013

Carroussel considered harmful

Image sliders are popular on web sites these days.
They make your site more dynamic and save real estate.
However, they do not work as a call for action.
users are frustrated by them (you take away the message they are reading) and ignore them like the ignore add banners.
Here are some arguments and research.

28 February 2013

Sales conditions: see website.

Typically legal sales conditions are printed on offers and invoices (what happens if the invoice is payed to late, which courts are competent in case of disputes...).
A judgment by the commercial court of Oudenaarde (december 26th, 2011) has decided that a reference to the conditions on the website is sufficient to be legally valid in Belgium.
I wonder if the judge that issued this ruling is sufficiently acquainted with IT.
After all the supplier can change the conditions on the websiteany time, without notification and without leaving a dependable historical change track.
There is no independant party that can verify today what the conditions on the website were at the time the reference was communicated.

27 February 2013

Thoughtworks eliminates sales comissions

Here's an article by Martin Fowler on flat sales salaries at Toughtworks (his employer).

Also notice the informal layout (somewhere between slides and text)
and the navigation arrows in the top bar.

24 February 2013

iTunes 11: import individual songs

In iTunes 11 you only have a button to import an entire CD. If you just want a few songs, you have to uncheck all others, one by one.  There is no obvious option to uncheck all songs and then pick the ones you want.
Trick: CTRL+click a checkbox and all songs will be unselected/selected.

20 February 2013

Firefox 19 javascript PDF viewer

Firefox doesn't use an adobe plugin anymore to show PDF. It handles them entirely in javascript, using the same pdf.js library as Chrome.
Bleeding fast and responsive.
Still young though, you might get incompatibility messages. So I'm just waiting a little before dumping the adobe plugin (with its pesky McAffee bundle) entirely.


5 February 2013

Java 8



My colleague, Romain, went to ski at La Plagne (France)

18 January 2013

Candy Crush

Forgot to get off my train yesterday playing Candy Crush on Android.

10 January 2013

IT Users have to explictly agree on conditions

Applications that present "I agree" boxes that are already checked will not have any legal value in the latest draft report of the European Union General Data Protection Regulation act.
Users have to take an explicit action to express their agreement.
Looks like a good idea to me.
Another important element in the act is The right to be forgotten. This allows users to remove content they put online earlier.

More elements in the draft...