In this post we’ll look at some alternative solutions to the traditional loop. The great thing about the new functional features in Java 8, is that it allows us to say what we want to be done instead of saying how to do it. This is where loops fall short. Sure loops are flexible, but this flexibility doesn’t come without a price. A return, break or continue dramatically changes how the loop will act, forcing us not only to understand what the code is trying to achieve, but also understand how the loop works.

Let the coding begin!

This time we’re going to work with articles. An article has a title, an author and several tags.

 private class Article {  
   private final String title;  
   private final String author;  
   private final List<String> tags;  
   private Article(String title, String author, List<String> tags) {  
     this.title = title;  
     this.author = author;  
     this.tags = tags;  
   }  
   public String getTitle() {  
     return title;  
   }  
   public String getAuthor() {  
     return author;  
   }  
   public List<String> getTags() {  
     return tags;  
   }  
 }  

Each of the examples will contain a traditional loop solution, and a solution using the new features in Java 8.
In the first example we want to find the first article in the collection that has the tag “Java”.

Let’s look at a solution using a for-loop.
 public Article getFirstJavaArticle() {  
   for (Article article : articles) {  
     if (article.getTags().contains("Java")) {  
       return article;  
     }  
   }  
   return null;  
 }  

Now let’s solve the problem using operations from the stream API.
 public Optional<Article> getFirstJavaArticle() {   
   return articles.stream()  
     .filter(article -> article.getTags().contains("Java"))  
     .findFirst();  
   }  

Pretty cool right? We first use the filter operation to find all articles that have the Java tag, then used the findFirst() operation to get the first occurrence. Since streams are lazy and filter returns a stream, this approach only processes elements until it finds the first match.

Now, lets get all the elements that match instead of just the first.
First, the solution using a for-loop.
 public List<Article> getAllJavaArticles() {  
   List<Article> result = new ArrayList<>();  
   for (Article article : articles) {  
     if (article.getTags().contains("Java")) {  
       result.add(article);  
     }  
   }  
   return result;  
 }  

Solution using stream operations.
 public List<Article> getAllJavaArticles() {   
   return articles.stream()  
     .filter(article -> article.getTags().contains("Java"))  
     .collect(Collectors.toList());  
   }  

In this example we used the collect operation to perform a reduction on the result stream instead of declaring a collection ourselves and explicitly add the articles if they match.

So far so good. Time to create a few examples that really make the stream API shine! Let's group all the articles based on the author. As usual, we start with the solution using a loop.

 public Map<String, List<Article>> groupByAuthor() {  
   Map<String, List<Article>> result = new HashMap<>();  
   for (Article article : articles) {  
     if (result.containsKey(article.getAuthor())) {  
       result.get(article.getAuthor()).add(article);  
     } else {  
       ArrayList<Article> articles = new ArrayList<>();  
       articles.add(article);  
       result.put(article.getAuthor(), articles);  
     }  
   }  
   return result;  
 }  

Can we find a clean solution for this problem using the stream operation?

 public Map<String, List<Article>> groupByAuthor() {   
   return articles.stream()  
     .collect(Collectors.groupingBy(Article::getAuthor));  
 }    

Great! Using the groupingBy operation and a method reference to getAuthor we got some clean and readable code.

Now, let's find all the different tags used in the collection. We start with the loop example.

 public Set<String> getDistinctTags() {  
   Set<String> result = new HashSet<>();  
   for (Article article : articles) {  
     result.addAll(article.getTags());  
   }  
   return result;  
 }  

Ok, let's see how we can solve this with the stream operations.

 public Set<String> getDistinctTags() {   
   return articles.stream()  
     .flatMap(article -> article.getTags().stream())  
     .collect(Collectors.toSet());  
 }  

Nice! flatmap helpes us flatten the tag lists into one result stream, then we use collect to create a set to return.

Endless possibilities

That was 4 examples of how you can replace the loops with more readable code. Make sure to take a closer look at the stream API, because this post has barely scratched the surface.

Spring Data MongoDB 1.2.0 silently introduced new feature: support for basic auditing. In this post I will show what benefits does it bring, how to configure Spring for auditing and how to annotate your documents to make them auditable.
Auditing let you declaratively tell Spring to store:

Configuration

First of all add Maven dependencies to latest Spring Data MongoDB and Spring Data Commons. Additionally in order to use date-related audit annotations we need to add joda-time to class-path.

 <dependency>  
   <groupId>org.springframework.data</groupId>  
   <artifactId>spring-data-mongodb</artifactId>  
   <version>1.2.1.RELEASE</version>  
 </dependency>  
 <dependency>  
   <groupId>org.springframework.data</groupId>  
   <artifactId>spring-data-commons</artifactId>  
   <version>1.5.1.RELEASE</version>  
 </dependency>  
 <dependency>  
   <groupId>joda-time</groupId>  
   <artifactId>joda-time</artifactId>  
   <version>2.2</version>  
 </dependency>  

In order to enable auditing we need to add <mongo:auditing/> to Spring configuration. Currently there is no way to configure it through Java Config.

 <mongo:auditing />  
 <mongo:mongo id="mongo" />  
 <bean class="org.springframework.data.mongodb.core.MongoTemplate">  
   <constructor-arg name="mongo" ref="mongo" />  
   <constructor-arg name="databaseName" value="blog-tests" />  
 </bean>  

Usage

Configuration above provides us way for auditing that includes versioning and time stamps. Example document will look like:

 @Document  
 public class Item {  
   @Id  
   private String id;  
   ...  
   @Version  
   private Long version;  
   @CreatedDate  
   private DateTime createdAt;  
   @LastModifiedDate  
   private DateTime lastModified;  
   ...  
 }  

Now you can save document using MongoTemplate or your repository and all annotated fields are auto magically set.

As you have probably noticed I did not use here user related annotations @CreatedBy and @LastModifiedBy. In order to use them we need to tell Spring who is a current user.

First add user related fields to your audited class:

 @CreatedBy  
 private String createdBy;  
 @LastModifiedBy  
 private String lastModifiedBy;  

Then create your implementation of AuditorAware that will obtain current user (probably from session or Spring Security context – depends on your application):

 public class MyAppAuditor implements AuditorAware<String> {  
   @Override  
   public String getCurrentAuditor() {  
     // get your user name here  
     return "John Doe";  
   }  
 }  

Last thing is to tell Spring Data MongoDB about this auditor aware class by little modification in Mongo configuration:

 <mongo:auditing auditor-aware-ref="auditor" />  
 <bean id="auditor" class="pl.maciejwalkowiak.blog.MyAppAuditor"/>  
Today, I want to show you debugging method, more specifically one for measuring execution times: Say hello to console.time().

Measuring Execution Times the Classic Way

Here's a small JavaScript snippet which concatenates the first one million natural numbers:
 var i, output = "";    
 for (i = 1; i <= 1e6; i++)  
   output += i;  

If you're wondering what 1e6 means, it's just a short way to write ten to the sixth power, which equals one million. It means exactly the same as the number literal 1000000.

The script is very simple, yet takes a couple dozen milliseconds (about 150ms on my machine) to execute. How did I measure this time? I could've done something like this:
 var i, output = "";  
 // Remember when we started  
 var start = new Date().getTime();  
 for (i = 1; i <= 1e6; i++)  
   output += i;  
 // Remember when we finished  
 var end = new Date().getTime();  
 // Now calculate and output the difference    
 console.log(end - start);  

This approach is very straightforward. It also has the advantage that it runs pretty much everywhere. If you're using a modern browser though, there's a shorthand method for measuring durations and logging them to the console. Let's inspect console.time()now.

Measuring Execution Times Using console.time()
Making use of console.time(), the code from before can be rewritten as this:

 var i, output = "";  
 // Start timing now  
 console.time("concatenation");  
 for (i = 1; i <= 1e6; i++)  
   output += i;  
 // ... and stop.  
 console.timeEnd("concatenation");  

We've now managed to make the code more expressive and slightly shorter than before: The call to console.time() starts a timer with the name concatenation, which is later stopped by console.timeEnd(). The timer names passed to both function calls have to match in order for the measuring to work.
Note that console.time() and console.timeEnd() are only supported by modern browsers, starting with Chrome 2, Firefox 10, Safari 4, and Internet Explorer 11.

Displaying the Measured Duration in the Console

Chrome 31 has written the following output to the console:

Here is what Firefox 25 gives us (notice the concatenation: timer started information):

A Closing Word on High-Precision Timing

If you need to measure time precisely, neither Date.getTime() nor console.time()will get you far. Check out John Resig's blog post about the accuracy of JavaScript time to learn why.
There's a different API for that purpose, though: the Performance interface, which is implemented by most modern browsers. For more information, I recommend you go read Matthew Johnson's blog post JavaScript precision timing.
Spring MVC provides a great way to handle exceptions and errors. @ExceptionHandler annotation is core to this feature. For each Spring controller we can simply define a method that automatically gets called if a given exception occurs. For example:
import org.springframework.web.bind.annotation.ExceptionHandler;
//..
@ExceptionHandler(IOException.class)
public String exception(Exception e) {
         
    //..
    return "error";
}
Thus whenever an IOException is raised from any controller method will call the above method exception(). We mapped IOException.class to this method using @ExceptionHandler annotation.

One short coming of this annotation is that it only handles exception getting raised from the controller where it is defined. It will not handle exceptions getting raised from other controllers. However this is a way to overcome this problem. @ControllerAdvice annotation is at your service for that.

@ControllerAdvice annotation

This annotation is used to define @ExceptionHandler, @InitBinder, and @ModelAttribute methods that apply to all @RequestMapping methods. 
import org.springframework.web.bind.annotation.ControllerAdvice;
//..
@ControllerAdvice
public class ExceptionControllerAdvice {
    @ExceptionHandler(Exception.class)
    public String exception(Exception e) {
        return "error";
    }
}

Thus if we define our @ExceptionHandler annotation on method in @ControllerAdvice class, it will be applied to all the controllers.

One thing worth noting here is that Spring configuration must define mvc namespace in order to identify @ControllerAdvice annotation. Thus you must define following in your spring-servlet.xml file.

    <mvc:annotation-driven>
</mvc:annotation-driven>
If you have defined just the it wouldn’t work. The @ControllerAdvice will simply wont be loaded. So always remember to use in Spring configuration.

It's no secret that my favorite browser is Google Chrome. I like it because it's fast, reliable, it doesn't crash (very often), and it looks good. There's also something else which I find even more valuable. It's the fact that you can build an extension for it using only HTML, CSS, and JavaScript. I always support such products, products that are open to the community and Chrome happens to be one of these products. If you need something and it is not yet implemented, you are free to develop it yourself.
So at the end of this article you will find a working Chrome extension which uses most of the techniques explained below. 
The software which we use should help us, we should not have to fight with it. Developing extensions/plugins for your favorite editor or browser helps not only you, but also other programmers, who sooner or later will be in the same situation. If something is missing, you can build it yourself and with Chrome this is really easy. Modeling your environment around your needs is key to being highly productive.
Thankfully there is a way to test your extension without having to upload it to Chrome's web store. In your browser's address bar, just type in:
Make sure that you check Developer mode and click the Load unpacked extension... button. Then simply select the folder from your hard disk which contains the extension's files.




extensionspanel
Here's a diagram of the architecture for a Chrome extension:
architecture
And now let's take a closer look at each element within the architecture.
The entry point of your extension is the manifest.json file. It should contain a valid JSON object. For example:
1
2
3
4
5
6
7
8
9
{
    "name": "BrowserActionExtension",
    "version": "0.0.1",
    "manifest_version": 2,
    "browser_action": {
        "default_title": "That's the tool tip",
        "default_popup": "popup.html"
    }
}
The required properties are nameversion, and manifest_version. The versioncan be anywhere from one to four, dot-separated integers. It's something which is used by Google's autoupdate system. That's how it knows when to update your extension. The value of the manifest_version should be the integer 2.
The manifest could contain other properties depending on what kind of extension you need, but I'll describe only those which I find to be more interesting.
Every extension has an invisible background page which is run by the browser. There are two types - persistent background pages and event pages. The first one is active, all of the time. The second is active only when it is needed. Google encourages developers to use event pages, because this saves memory and improves the overall performance of the browser. However, it's good to know that this is also where you should put your main logic and initialization. Normally the background page/script plays the role of a bridge between the other parts of the extension.
Here is how you should describe it in the manifest:
1
2
3
4
"background": {
    "scripts": ["background.js"],
    "persistent": false/true
}
As you may have guessed, if the persistent property is false then you are using event pages. Otherwise, you are working with a persistent background page.
If you need access to the current page's DOM, then you have to use a content script. The code is run within the context of the current web page, which means that it will be executed with every refresh. To add such a script, use the following syntax.
1
2
3
4
5
6
"content_scripts": [
    {
        "matches": ["http://*/*", "https://*/*"],
        "js": ["content.js"]
    }
]
Keep in mind that the value of matches determines for which pages your script will be used. Read more about matches patterns here.
There are several ways to build the UI of your extension. Here are the four most popular.
Most developers use the browser_action property to build their plugins. Once you set it, an icon representing your extension will be placed on the right side of the address bar. Users can then click the icon and open a pop-up which is actually HTML content controlled by you.
browseraction
The manifest files should contain the following data:
1
2
3
4
5
6
7
8
"browser_action": {
    "default_icon": {
        "19": "icons/19x19.png",
        "38": "icons/38x38.png"
    },
    "default_title": "That's the tool tip",
    "default_popup": "popup.html"
}
The default_title is a little tool tip which is shown when the user mouses over your icon. default_popup is actually the HTML file which is loaded inside the pop-up. There is also a badge which you can place over your icon. You can do that inside of your background script. For example:
1
chrome.browserAction.setBadgeText({text: "yeah"});
This was the code which I used to produce the image above.
The page_action property is similar to the browser action, but the icon is shown inside the address bar:
pageaction
The interesting thing here is that your icon is hidden initially, so you should decide when to show it. For example, in the image above, the RSS icon will be shown only if the current page contains a link to the RSS feed. If you need to see your icon all the time, it is good to use browser_action directly.
To add the page action, type the following code inside your manifest:
1
2
3
4
5
6
7
8
"page_action": {
    "default_icon": {
        "19": "images/icon19.png",
        "38": "images/icon38.png"
    },
    "default_title": "Google Mail",
    "default_popup": "popup.html"
}
Unlike the browser action's icon, the page action's icon doesn't have badges.
I use DeveloperTools a lot and it's nice that Chrome offers a method for adding new tabs to these tools. The first thing you should do is add an HTML page which will be loaded when the panel is opened:
1
"devtools_page": "devtools.html"
There's no need to put any HTML inside the page, except for linking in a JavaScript file, which will create the tab:
1
<script src="devtools.js"></script>;
And then include the following code inside the devtools.js file:
1
2
3
4
5
6
7
8
chrome.devtools.panels.create(
    "TheNameOfYourExtension",
    "img/icon16.png",
    "index.html",
    function() {
    }
);
Now the above code will add a new tab with a name of TheNameOfYourExtension and once you click on it the browser will load index.html inside the DeveloperTools.
The omnibox is the keyword which is shown inside Chrome's address bar. For example, if you add the following property into your manifest:
1
"omnibox": { "keyword" : "yeah" }
And then add the code below, inside your background script:
1
2
3
4
5
6
7
8
9
chrome.omnibox.onInputChanged.addListener(function(text, suggest) {
    suggest([
      {content: text + " one", description: "the first one"},
      {content: text + " number two", description: "the second entry"}
    ]);
});
chrome.omnibox.onInputEntered.addListener(function(text) {
    alert('You just typed "' + text + '"');
});
You should be able to type yeah inside the address bar. Then you should see something like this:
omnibox
Pressing tab will produce the following screen:
omnibox2
Of course using the chrome.omnibox API, you could catch the user's input and react to that input.
There are bunch of different things which you can do in your extension. For example, you can get access to the user's bookmarks or history. You can move, create tabs or even resize the main window. I strongly recommend to check out the documentation to get a better idea of how to accomplish these tasks.
What you should know is that not all APIs are available in every part of your extension. For example, your content script can't access chrome.devtools.panels or the script in your DeveloperTools tab can't read the page's DOM. So, if you're wondering why something is not working, this could be why.
As I mentioned above, you don't always have access to the API that you want to use. If that's the case, then you should use message passing. There are two types of messaging - one-time requests and long-lived connections.
This type of communication happens only once. I.e. you send a message and wait for an answer. For example, you could place the following code in your background script:
1
2
3
4
5
6
7
8
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
    switch(request.type) {
        case "dom-loaded":
            alert(request.data.myProperty);
        break;
    }
    return true;
});
Then use the code from below in your content script:
1
2
3
4
5
6
7
8
window.addEventListener("load", function() {
    chrome.extension.sendMessage({
        type: "dom-loaded",
        data: {
            myProperty: "value"
        }
    });
}, true);
And this is how you can get information about the current page's DOM and use it inside your background script, which normally doesn't have access to this data.
Use this type of messaging if you need a persistent communication channel. Inside your content script place the following code:
1
2
3
4
5
var port = chrome.runtime.connect({name: "my-channel"});
port.postMessage({myProperty: "value"});
port.onMessage.addListener(function(msg) {
    // do some stuff here
});
And then in the background script, use this:
1
2
3
4
5
6
7
chrome.runtime.onConnect.addListener(function(port) {
    if(port.name == "my-channel"){
        port.onMessage.addListener(function(msg) {
            // do some stuff here
        });
    }
});
Overriding pages is a nice way to customize your browser. You're also able to substitute some of the default pages in Chrome. For example you can create your own history page. To do that, add in the following code snippet:
1
2
3
"chrome_url_overrides" : {
    "<page to override>;": "custom.html"
}
The possible values of <page to override> are bookmarkshistory, and newtab. It's kinda cool to have a fresh new tab page.

Conclusion

In my opinion, Chrome is one of the best browsers available. The developers at Google make creating extensions relatively easy by giving us the power to create them in HTML, CSS, and JavaScript.
Yes, there are some tricky parts, but generally we're able to produce valuable plugins. For the topics I did not cover, please refer to the documentation for more detailed information.
Previous Post Older Posts Home