Skip to content
accelerando

Tag Archives: Code Snippets

On my way to Java 8

12-Feb-14

This is a post where i want to collect some new expressions i’m learning on my way to Java 8. Hopefully i’ll keep updating it…

Use an IntStream to generate an Array with constant default values

// The "() -> 23" is a lambda that matches the functional interface of a Supplier 
// The the stream itself is infinite, but the array can certainly be not, so we must limit it
IntStream.generate(() -> 23).limit(42).toArray()

Use a similar construct to fill a list with constant values:

// The IntStream has a collect method that uses a supplier to instantiate a new target, 
// an accumulator to add to the new target and combiner to merge two targets to perform 
// a reduction of the given elements
IntStream.generate(() -> 23).limit(42).collect(ArrayList::new, ArrayList::add, ArrayList::addAll)

Use a range to zip elements of an indexable collection together:

List<Foobar> foobars = new ArrayList<>();
List<Double> differences = IntStream.range(1, foobars.size()) // create exclusive range
	.mapToObj(i -> { // map this to your result of pairwise combining elements
	    final Foobar left = foobars.get(i - 1);
	    return foobars.get(i).getAmount() - left.getAmount();
	}).collect(Collectors.toList()); // collect it in a list

Last update: 2014/02/12

Get the uptime of your Java VM

08-Feb-12

You don’t need JConsole or similar for just displaying the approximate uptime of your application respectively your Java Virtual Machine:

import java.lang.management.ManagementFactory;
 
public class Demo {
	public static void main(String... args) {
		final long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
		System.out.println(String.format("Up for %dms", uptime));
	}
}

If you use Joda-Time (and you should if you have anything to do with date/datetime processing), you can format it nicely like so:

import java.lang.management.ManagementFactory;
import java.text.MessageFormat;
 
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
 
public class Demo {
	public static void main(String... args) {
		final Period vmUptime = new Period(ManagementFactory.getRuntimeMXBean().getUptime()).normalizedStandard(PeriodType.yearDayTime());
		final PeriodFormatter pf = new PeriodFormatterBuilder()
				.printZeroAlways()
				.appendDays().appendLiteral(MessageFormat.format("{0,choice,0# days, |1# day, |2# days, }", vmUptime.getDays()))
				.minimumPrintedDigits(2)
				.appendHours().appendLiteral(":").appendMinutes()
				.toFormatter();
		System.out.println(String.format("Up for %s", pf.print(vmUptime)));
	}
}

You also have a nice example of the often unknown MessageFormat.

Creating a better PathMatcher for Spring 3

09-Mar-11

Spring 3 has excellent support for mapping URLs to @Controller methods through the @RequestMapping annotation. This works quite well and i especially like the fact having the mapping right next to the method and not in some other config file like routes.rb.

My goal was to have urls like http://foobar.com/resource, http://foobar.com/resource.html, http://foobar.com/resource.zip etc. This is no problem at all thanks to the ContentNegotiatingViewResolver.

The solution has only one draw back: The format is not known to the controller. Yes, this shouldn’t be a controller concern in most cases but what if you have a format that you don’t want to be available to all users? Maybe an nice zip download of your resources? Handling authentication in a view? I don’t think so.

So my first attempt looked like this

@RequestMapping("/resource.{format}")
public String resource(
		final @PathVariable String format,
		final HttpServletRequest request,
		final Model model
)

That didn’t work because it wouldn’t work for the default text/html resource http://foobar.com/resource so i added

@RequestMapping("/resource")
public String resource(
		final Model model
) {
  this.resource('html', model);
}

That worked for http://foobar.com/resource but not for http://foobar.com/resource.zip… “format” was always html. Hmmm…

After much googling and reading StackOverflow.com i found the “useDefaultSuffixPattern” option on org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping. If set to true (which is the default) the mapping “/resource/” will also map to “/resource/” and “/resource.*”. Although both useful i tried disabling it through my spring-cfg.xml like

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    	<property name="order" value="0" />
    	<property name="useDefaultSuffixPattern" value="false" />
</bean>

Enter the next problem: First, i didn’t work either. Second, all urls where mapped twice. Without the default suffix pattern and with. I spend 2 hours trying to locate the place where the spring config was loaded twice. In the end it was that one line that caused me trouble:

  <mvc:annotation-driven/>

That tag enables a lot of stuff in Spring 3, like the @Controller programming model and many other goodies. What it also does is establishing an AnnotationHandlerMapping that cannot be overwritten. So the next thing i did was browsing through the Spring sources to see what it does and redid with Spring beans in my config file (code follows later).

With that implemented, my urls still didn’t work, for all cases the URL without .{format} was called.

As i was already deep down in the Spring sources i had a look at the default path parser and matcher called AntPathMatcher. There is nothing wrong with the parsing code but the “getPatternComparator” method that “Given a full path, returns a Comparator suitable for sorting patterns in order of explicitness.” had some flaws, at least for my use case.

It sorts the patterns by explicitness and that explicitness is (among others) defined by how many placeholders for path variables are present. So my “/resource” is more explicit that “/resource.{format}”. With that in mind, i extend the path matcher like so:

This PathMatcher delegates most of his methods to the default AntPathMatcher but overwrites the getPatternComparator. If you have a look at the sources you’ll see that it is also partly copied. In the last else branch you’ll see that i sort both patterns by length, strip the default suffix (.*) and check wether the longer pattern starts with the other one. If it does i check wether the difference is just a .{format} (hardcoded). If that’s true, than the pattern with the format suffix is more explicit. Otherwise, i’ll use the default algorithm.

To get this to work, you cannot use the mvc:annotation-driven tag as the PathMatcher is a property of the AnnotationMappingHandler which in turn cannot be overwritten. So to get the same functionality like in Spring 3.0.5 with my PathMatcher use

As you can see i left the useDefaultSuffixPattern option enabled as it works very well with my PathMatcher and i didn’t want to care about mapping “/resource”, “/resource/” etc…

I really hope that the gists will save someone some time. I cannot imagine that i’m the only one having this kind of requirement. The solution is really simple but the way to it was not that easy.

Oracle “sleep” procedure: DBMS_LOCK.SLEEP

07-Sep-10

There’s a nice little “sleep” procedure in Oracle: A procedure that stops the execution of the current thread for n seconds.

Strangely, this method can be called in SQL*Plus like so:

EXEC dbms_lock.sleep(10);

but not in another stored procedure or function like so

CREATE OR REPLACE PROCEDURE FOOBAR AS
BEGIN
  DBMS_LOCK.SLEEP(1);
END;
/

To use “sleep” in your procedures or functions, login as administrator to your database (or ask you admin to to so) and create the following objects:

CREATE OR REPLACE PROCEDURE sleep(seconds NUMBER) AS
BEGIN
  DBMS_LOCK.SLEEP(seconds);
END;
/
 
CREATE OR REPLACE public synonym sleep FOR sleep;
 
GRANT EXECUTE ON sleep TO public;

and in your procedure just use “sleep”.

How to get UIDefaults in Java

06-Sep-10

If you’re loocking for Javas UIDefaults, use the UIManager class. This snippet gives you all installed UIDefaults:

UIDefaults defaults = UIManager.getDefaults();		 
for(Enumeration e = defaults.keys(); e.hasMoreElements(); ){
    String key = e.nextElement().toString();
    System.out.println(key + " = " + defaults.get(key));	         
}

Close
E-mail It