Toolbox

Various tools and technologies which are useful.

Guava

guava-libraries

The Guava project contains several of Google’s core libraries that we rely on in our Java-based projects: collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth. Each of these tools really do get used every day by Googlers, in production services.

Preconditions

In PLI you can find in a wrapper implementation. Use a precondition checking utilities.

1Preconditions.checkArgument(i >= 0, "Argument was %s but expected nonnegative", i);
2Preconditions.checkArgument(i < j, "Expected i < j, but %s > %s", i, j);

Throwables

For Exception propagation. Several of the Java API forces us to handle checked Exceptions even if we could do not do anything with that. Most of the times we just log, wrap into RuntimeException then throw again and let calling process to deal with it. Lots of repetitive steps.

It will shorten it.

1          public static String getProperty(Object bean, String name) {
2                try {
3                  return delege.getProperty(bean, name);
4                }
5                catch (InvocationTargetException e) {
6                  throw Throwables.propagate(e);
7                }
8          }

Immutable collections

Immutable collections are faster to use in multithreaded environment. Majority of the operations are just more clear using immutable (value) objects. Using immutable collections is more memory efficient than using mutable counterpart.

Plus lost of useful function to make life more easy when dealing with collections.

1                Map<?, ?> ret = ImmutableMap.of("status", "OK", "data", resp);

Imagine when you want to filter a collections - getting a subset based on certain conditions

 1                List<InterpreterDto> relevantInterpreters = Collections2.filter(interpreters, new Predicate<InterpreterDto>() {
 2                  public boolean apply(InterpreterDto input) {
 3                        for (InterpreterBoothDto b : input.getBooths()) {
 4                          if (langs.contains(b.getLanguage())) {
 5                                return true;
 6                          }
 7                        }
 8                        return false;
 9                  }
10                });

Of course you could reuse that Predicate. Imagine when you get a list of object and want to lookup based on some id of that object.

 1        Function<Unavailability, Long> interp_pers_uid_extractor = new Function<Unavailability, Long>() {
 2                @Override
 3                public Long apply(Unavailability input) {
 4                  return input.getPers_pers_uid();
 5                }
 6          }; 
 7        ...
 8        List<Unavailability> unavs = search(s)
 9        ListMultimap<Long, Unavailability> res = groupBy(unavs, interp_pers_uid_extractor)

Where the interp_pers_uid_extractor can be reused in multiple places. In this example the groupBy is synonym for Multimaps.index.

Using functional programing idioms can produce shorter and simpler programs.

Strings

Joiner

1        Joiner joiner = Joiner.on("; ").skipNulls();
2        return joiner.join("Harry", null, "Ron", "Hermione");

Splitter

Typical problem o splitting String. I java you could use Spring.split which can be difficult because you have to deal with regex; or StringTokenizer which is failing when want split by multiple characters.

But you can feel the difference:

1        List<String> tokens = copyOf(Splitter.on(CharMatcher.WHITESPACE).omitEmptyStrings().trimResults().split(prop));

EventBus

In a desktop application it can be very useful.

 1        // Class is typically registered by the container.
 2        class EventBusChangeRecorder {
 3          @Subscribe public void recordCustomerChange(ChangeEvent e) {
 4                recordChange(e.getChange());
 5          }
 6        }
 7        // somewhere during initialization
 8        eventBus.register(new EventBusChangeRecorder());
 9        // much later
10        public void changeCustomer() {
11          ChangeEvent event = getChangeEvent();
12          eventBus.post(event);
13        }

Generic hibernate Dao

hibernate-generic-dao

We had worked on a project where we hand-coded all of our DAOs. This produced four irksome difficulties: (1) Method names and implementations were not altogether consistent. (2) It was a pain to make additional columns sortable or filterable, and as a result, a lot of pages lacked good sorting and filtering. (3) Making additional DAOs was tedious and took a fair amount of time. (4) Writing tests for DAOs is tricky and tedious, so no one really did.

What we use:

Examples - Generic dao interface:

1        public interface ProjectDAO extends GenericDAO<Project, Long> {}
2        public class ProjectDAOImpl extends GenericDAOImpl<Project, Long> implements ProjectDAO {}

Example - search: Search search = new Search(Project.class);

 1        //filtering
 2        search.addFilterEqual("name", "hibernate-generic-dao");
 3        search.addFilterLessThan("completionDate", new Date());
 4        search.addFilterOr(
 5                Filter.equal("name", "Jack"),
 6                Filter.and(
 7                        Filter.equal("name", "Jill"),
 8                        Filter.like("location", "%Chicago%"),
 9                        Filter.greaterThan("age", 5)
10                )
11        );
12        search.addFilterIn("name", "Jack", "Jill", "Bob");
13        //paging
14        search.setMaxResults(15); //a.k.a. results per page
15        search.setPage(3);

And if any of the features are suitable to your need you still have access to hibernate session.

iText and table builder

iText

Within the team we have an electronic book (ask Otto) which contains lots of really good examples of using iText. (iText in Action)

iText is a really low level API for building PDF. Low level and, that is the why, flexible.

But to make it effective you have to build your high level API to use that. For example when creating complex layouts you have to use tables and cells in the PDF document. For building up you could use TableBuilder

Example use of TableBuilder:

 1                TableBuilder table = new TableBuilder();
 2                //@formatter:off
 3           table
 4                 .attr("totalWidth", 1842F)
 5                 .attr("headerRows", 1)
 6                 .newRow()
 7                   .newHeaderCell().text(i18n.get("pdf.table.name"),"header")
 8                                                   .attr("colspan", Integer.valueOf(2))
 9                                                   .attr("verticalAlignment", ALIGN_BOTTOM)
10                                                   .attr("backgroundColor", "header")
11                                                   ;
12           List<Date> valueDates = data.getValueDates();
13           for(Date valueDate: valueDates){
14                 table
15                   .newHeaderCell().text(dayNameOfWeek(valueDate).toUpperCase(),"header").text("\n")
16                                                   .text(formatIfNotNull(valueDate, DATE_FORMAT),"header")
17                                                   .attr("horizontalAlignment", ALIGN_CENTER)
18                                                   .attr("backgroundColor", "header")
19                                                   ;
20           }
21           table.endRow();
22           //@formatter:on

After building up an abstract table you could apply a visitor which will interpret this abstract table to specific implementation. For example: this table can be rendered in both HTML and PDF.

 1        public class ITextTableVisitor extends ReflectiveVisitor {
 2          private static final Map<String, Font> fonts = Map();
 3          static {
 4                fonts.put("default", new Font(Font.HELVETICA, 8, Font.NORMAL, Color.BLACK));
 5                fonts.put("error", new Font(Font.HELVETICA, 8, Font.NORMAL, Color.RED));
 6                fonts.put("header", new Font(Font.HELVETICA, 8, Font.NORMAL, Color.YELLOW));
 7                fonts.put("title", new Font(Font.HELVETICA, 16, Font.NORMAL, Color.BLACK));
 8                fonts.put("title-emph", new Font(Font.HELVETICA, 16, Font.BOLD, Color.BLACK));
 9          }
10          private static final Map<String, Color> colors = Map();
11          static {
12                colors.put("header", new Color(0, 0, 128));
13                colors.put("plain", Color.WHITE);
14          }
15
16          static Color getColor(String color) {
17                return colors.get(color);
18          }
19
20          static Font getFont(String fontDesc) {
21                Font res = fonts.get(fontDesc);
22                if (null == res) {
23                  res = fonts.get("default");
24                }
25                return res;
26          }
27
28          private Image getImage(String image) throws Exception {
29                if ("eu_logo".equals(image)) {
30                  return Image.getInstance(this.getClass().getResource("/img/eu_flag.jpg"));
31                }
32                return null;
33          }
34
35          private PdfPTable table;
36
37          public void visitTTable(TTable t) throws DocumentException {
38                table = new PdfPTable(t.getMaxColOfRows());
39                table.setWidthPercentage(100);
40                if (null != t.getWidthPercentage()) {
41                  table.setWidthPercentage(t.getWidthPercentage());
42                }
43                ...
44                for (TRow r : t.getRows()) {
45                  r.accept(this);
46                }
47          }
48
49          public void visitTCell(TCell c) throws Exception {
50                PdfPCell cell = new PdfPCell();
51                cell.setHorizontalAlignment(Element.ALIGN_LEFT);
52                cell.setBackgroundColor(Color.LIGHT_GRAY);
53                cell.setBorderColor(Color.GRAY);
54                cell.setPadding(2);
55                if (null != c.getHorizontalAlignment()) {
56                  cell.setHorizontalAlignment(c.getHorizontalAlignment());
57                }
58                if (null != c.getVerticalAlignment()) {
59                  cell.setVerticalAlignment(c.getVerticalAlignment());
60                }
61                cell.setColspan(c.getColspan());
62                ...
63
64                for (TTable t : c.getTables()) {
65                  ITextTableVisitor innerVisitor = new ITextTableVisitor();
66                  t.accept(innerVisitor);
67                  PdfPTable innerTable = innerVisitor.getTable();
68                  cell.addElement(innerTable);
69                }
70                table.addCell(cell);
71          }
72
73          public void visitTRow(TRow r) {
74                for (TCell c : r.getCells()) {
75                  c.accept(this);
76                }
77          }
78
79          public PdfPTable getTable() {
80                return table;
81          }
82
83          public void setTable(PdfPTable table) {
84                this.table = table;
85          }
86        }

jGrowl

jGrowl

Useful visual utility for displaying message.

How jGrowl looks like

Usage example:

 1        // Sample 1
 2        $.jGrowl("Hello world!");
 3        // Sample 2
 4        $.jGrowl("Stick this!", { sticky: true });
 5        // Sample 3
 6        $.jGrowl("A message with a header", { header: 'Important' });
 7        // Sample 4
 8        $.jGrowl("A message that will live a little longer.", { life: 10000 });
 9        // Sample 5
10        $.jGrowl("A message with a beforeOpen callback and a different opening animation.", {
11                beforeClose: function(e,m) {
12                        alert('About to close this notification!');
13                },
14                animateOpen: {
15                        height: 'show'
16                }
17        });

Bootstrap

Bootstrap

Sleek, intuitive, and powerful front-end framework for faster and easier web development.

Bootstrap is a CSS and JavaScript framework to make initial website development easy and as a result having a consistent look and feel.

By applying Bootstrap we can have good looking website without any effort and lots of really useful visual effect which can spice up the look of certain components.

You must review Base CSS, Components and JavaScript sections.

Underscore.js

Underscore.js

Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects.

Really useful utility library for JavaScript.

Learn and apply utilities to make you JavaScript code shorter and simpler.

1    var interp = _.find(_self.interpreters, function(interp) {
2      return assignment_line_uid == interp.assignment_line_uid;
3    });
4        ...
5    _self.interpreters = _.reject(_self.interpreters, function(interp) {
6      return assignment_line_uid == interp.assignment_line_uid;
7    });

Templates

Templating when you take a spring the put values into certain places to produce a final string result.

By default you could implement with string concatenation. But after just a few variables to concatenate into string it become a really painful experience to read that source code.

Most of the time we want to generate some HTML fragment.

Teamplating in Java

Commons StrSubstitutor

Commons lang

1    String template = "  public ${baseClass} build(){\n" +
2        "    ${baseClass} inst = new ${baseClass}();\n" +
3        "${assignments}\n    return inst;\n" +
4        "  }\n";
5    StrSubstitutor.replace(template, 
6                        ImmutableMap.of("baseClass", baseClass, 
7                                                        "assignments", buildBuilderAssignments()));

JATL

JATL

 1    final Html html = new Html(that) {
 2      {
 3        Map<DateRange, List<LanguageCoverageInfo>> li = dto.getLang_coverage_info();
 4        for (DateRange range : li.keySet()) {
 5          div().id(dto.getSess_uid() + "-" + cssId(range));
 6          span().classAttr("label").text(timeInfo(range)).end();
 7          new LanguageCoverageFormatter(li.get(range)).format(this);
 8          end();
 9        }
10        endAll();
11        done();
12      }
13    };

Templating in JavaScript

Simple templating

See.

Underscore.js has utility called template.

Jaml

jaml

 1        Jaml.register('simple', function() {
 2          div(
 3                h1("Some title"),
 4                p("Some exciting paragraph text"),
 5                br(),
 6
 7                ul(
 8                  li("First item"),
 9                  li("Second item"),
10                  li("Third item")
11                )
12          );
13        });
14        ...
15        Jaml.render('simple');

Spring SpEL

Cases:

You might write several of the following code in you life:

 1    if (getPersonnelNumber() != null) {
 2      persNumberId = getPersonnelNumber().getPersNumberId();
 3    }
 4    if (getBooth() != null) {
 5      boothId = getBooth().getBoothId();
 6    }
 7    if (getProfDomicile() != null) {
 8      profDomId = getProfDomicile().getAddrId();
 9    }

Common attribute is that you intend to access a nested attribute but for not throwing NullPointerException you have to check the presence of intermediate object.

Lets simplify:

1    Long persNumberId = AppBean.get(this, "personnelNumber?.persNumberId", Long.class);
2    Long boothId = AppBean.get(this, "booth?.boothId", Long.class);
3    Long profDomId = AppBean.get(this, "profDomicile?.addrId", Long.class);

The construct if ?. is called Safe Navigation operator whihc become popular with Groovy. We could use the same concept in Java with Spring:

1  public static <T> T get(Object o, String property, Class<T> desiredReturnType) {
2    Expression exp = parser.parseExpression(property);
3    EvaluationContext context = new StandardEvaluationContext(o);
4    return exp.getValue(context, desiredReturnType);
5  }

Of course Spring expressions are much more powerfull than using for this purposes. Van be used for validation or in complex formatting in JSP.

Logging

slf4j

Use slf4j only. And in the bacground you could still use log4j configs as before.

Do you need asingle reason why using slf4j?

Before:

1if(log.isDebugEnabled()){
2        log.debug("Some text "+something+" and other to log);
3}
4

After:

1log.debug("Some text {} and other to log", something);

Trick to optimize

Although slf4j is really effective and optimized not to call toString unnecceseraly. It is still not enough. Sometimes the loggable object generation is as consuming as calling toString.

Try the following trick:

 1// The important part
 2log.debug("{}",new Object(){
 3        public String toString(){
 4                return Iterables.transform(col, BeanFieldValueExtractor.byField("interesting"))
 5        }
 6}); 
 7
 8...
 9//This is not so relevant just helps understanding the previous block
10public class BeanFieldValueExtractor<T> implements Function<Object, T> {
11  private final String attr;
12  //... constructor omited
13  public T apply(Object input) {
14    return (T) ReflectionUtil.getField(input, attr);
15  }
16  public static <T> BeanFieldValueExtractor<T> byField(String attr) {
17    return new BeanFieldValueExtractor<T>(attr);
18  }
19} 

So we are replacing an expensive operation by a cheap object creation.

JodaTime

Joda Time

Joda-Time provides a quality replacement for the Java date and time classes.

Once you have to use java.util.Date intensively you will understand how painfull it can be.

Just remove the pain by using Joda Time.

  • Easy to Use. Calendar makes accessing ‘normal’ dates difficult, due to the lack of simple methods. Joda-Time has straightforward field accessors such as getYear() or getDayOfWeek().
  • Easy to Extend. The JDK supports multiple calendar systems via subclasses of Calendar. This is clunky, and in practice it is very difficult to write another calendar system. Joda-Time supports multiple calendar systems via a pluggable system based on the Chronology class.
  • Comprehensive Feature Set. The library is intended to provide all the functionality that is required for date-time calculations. It already provides out-of-the-box features, such as support for oddball date formats, which are difficult to replicate with the JDK.
  • Up-to-date Time Zone calculations. The time zone implementation is based on the public tz database, which is updated several times a year. New Joda-Time releases incorporate all changes made to this database. Should the changes be needed earlier, manually updating the zone data is easy.
  • Calendar support. The library currently provides 8 calendar systems. More will be added in the future.
  • Easy interoperability. The library internally uses a millisecond instant which is identical to the JDK and similar to other common time representations. This makes interoperability easy, and Joda-Time comes with out-of-the-box JDK interoperability.
  • Better Performance Characteristics. Calendar has strange performance characteristics as it recalculates fields at unexpected moments. Joda-Time does only the minimal calculation for the field that is being accessed.

Simple and expressive.

Should I exmplain the following code?

1  public static boolean betweenOpenEnd(Date d, Date from, Date to) {
2    AppPreconditions.checkNotNull(d, from, to);
3    return new Interval(new DateTime(from), new DateTime(to)).contains(new DateTime(d));
4  }

It is possible to use in hibernate mapping:

1@Column
2@Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
3private DateTime fromDate;

Autocomplete Javascript solutions

Intelligent dropdown:

Maps with default values or on the fly init values

Jakarta commons way: Lazy Map

1 Factory<Date> factory = new Factory<Date>() {
2     public Date create() {
3         return new Date();
4     }
5 }
6 Map<String, Date> lazy = LazyMap.lazyMap(new HashMap<String, Date>(), factory);
7 Date date = lazy.get("NOW");

Technology stack
Jul 05, 2013
comments powered by Disqus

Links

Cool

RSS