Raging Goblin

24 March 2015

OcNotes 1.1 released

Filed under: OcNotes — raginggoblin @ 21:20
Tags: , ,

I released OcNotes version 1.1. It has some minor improvements. The delete button shows a trash icon and the fonts are configurable.

For more information see: https://raginggoblin.wordpress.com/ocnotes
For downloads see: https://github.com/raginggoblin/ocnotes

9 March 2015

Oops

Filed under: Uncategorized — raginggoblin @ 10:44

Oops

21 February 2015

Infolog turned to OcNotes

Filed under: OcNotes — raginggoblin @ 20:02
Tags: , ,

Today I released OcNotes version 1.0. I moved from Egroupware to Owncloud and therefore had to rewrite my notes desktop client. I released it on Github today.

For more information see: https://raginggoblin.wordpress.com/ocnotes
For downloads see: https://github.com/raginggoblin/ocnotes

29 May 2014

KNMI Rain radar app for Android

Filed under: Android — raginggoblin @ 20:22
Tags:

On my telephone I wanted a very simple rain radar app. The Android appstore provide tons of weather apps, but I could not find a simple rain radar viewer without any bells or whistles at all. I do not care about all these nice features and especially hate the meaningless predictions of these apps. The combination of my eye and brain does a much better prediction than some simple pixel shifting algorithm. Besides this, it has the extra benefit of no advertisements cluttering my screen! Look here for details.

20 March 2014

Search Java SE API

Filed under: Java — raginggoblin @ 20:27
Tags: , ,

For many years Sun and Oracle have failed to add a searchfield to the Javadocs found on http://docs.oracle.com/javase/7/docs/api/. Most of the time I use the Zeal API browser to search the Javadocs. But sometimes it is easier to let Google do the searching for you. To add a ‘site-specific’ search engine to Firefox add the following xml to a file in your profile directory inside the directory searchengines or searchplugins:

<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
                       xmlns:moz="http://www.mozilla.org/2006/browser/search/">
  <ShortName>Java SE7 API</ShortName>
  <Description>Search Java Standard Edtition API with Google</Description>
  <InputEncoding>UTF-8</InputEncoding>
  <Image width="16" height="16" type="image/x-icon">data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAHBPoACxfnAEtN7wCHhv4AAAL9AENF8QD29f8AwML/AAQA8wCHhf8AAAH+ABkT6ADv7v8AJiDpAAYE+ADx7v8A0tb/AAEJ5gDv8f8AAAT3APnu/wAAAvsAT1PnAAYD+QAIBPcADgf4AAoE9wACBP0AAQjnAPb0/wAAA/gAAgX0AAoM5gAAAvoABQP/AAAA/gACAvoAAgD+ANHV/wADAP4A6PD/AIiH/wDs8P8AAAP3ACUf6AADAfsARkj0AGBk8gCcnv8AAAH6AAcF+QAAAPwABwbwAOfv/wBOUuYACQbwAFdU8ACGhv8AAAP8ABER5wCIhv8AAAL+AHx59wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALSclJSETEx4THhMkJSclLSMVEwQKCgoKCgoKCgQTFSMECgoVHzQ3Nzc3NB8VCgoEKzMZDRY5KQkDPDkWDRkzKyI7LyYPKig1NSgqDyYvOyIIOBIMMAIuBQUuAjAMEjgIIAcGPgsaDgAyFxgLPgYHIBEUHQEEGzozMT0bBAEdFBwRFB0BBBs6MzE9GwQBHRQcIAcGPgsaDgAyFxgLPgYHIAg4EgwwAi4FBS4CMAwSOAgiOy8QDyooNTUoKg8QLzsiKzMZLDY5KQkDPDk2LBkzKwQKChUfNDc3Nzc0HxUKCgQjFRMECgoKCgoKCgoEExUjLSclJSETEx4THhMkJSclLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= </Image>
  <Url type="text/html" method="GET" template="http://www.google.com/search">
    <Param name="q" value="{searchTerms}"/>
    <Param name="sitesearch" value="http://docs.oracle.com/javase/7/docs/api/"/>
  </Url>
  <moz:SearchForm>http://www.world-connect-commodities.ro:8775/Search/default.aspx</moz:SearchForm>
</OpenSearchDescription>

For your convenience, you can download the file from here as well. After restarting Firefox you get a nice Javadoc search engine:
Site specific search

30 November 2013

Infolog version 4.0 released

Filed under: Android,Egroupware,Java — raginggoblin @ 22:01
Tags: , ,

Infolog version 4.0 is released! The communication between the client and the server now uses a Rest webservice. This enabled me to write an Android client as wel. When upgrading, please note that data is now stored in json format. Before upgrading, make sure all your notes are on the server. See Infolog page for details about the program.

17 July 2013

Spring Roo 10: Update images

Filed under: Java,Spring Roo — raginggoblin @ 20:23
Tags: ,

In my previous blog about uploading images I left it to the reader to come up with a solution for updating an image once a LogItem is created. However, I recently noticed that I was not able to update this image as easy as I thought, due to the fact that the HiddenHttpMethodFilter provided by Spring is not capable of handling multipart forms. This will have the effect that when you click on an update button, you will end up creating a new one as the POST request will end up in this function. This is easy to remedy, but as it took me a while, I will put you in the right direction. We will continue where we left off the last time.

Step 9: Update update.jspx to send a MultipartFile

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields" xmlns:form="urn:jsptagdir:/WEB-INF/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <jsp:output omit-xml-declaration="yes"/>
    <form:update id="fu_raging_goblin_roo_domain_LogItem" modelAttribute="logItem" multipart="true" path="/logitems/update" versionField="Version" z="user-managed">
        <field:input field="message" id="c_raging_goblin_roo_domain_LogItem_message" z="apnKidZldiFISmA4Q9pumki/o6Q="/>
        <field:datetime dateTimePattern="${logItem_creationdate_date_format}" field="creationDate" id="c_raging_goblin_roo_domain_LogItem_creationDate" z="p5GCO6w9q76CIDoEn17xbZPqlT0="/>
		<img height="256px" src="${logItem.id}/image"/>
        <field:input field="image" id="c_raging_goblin_roo_domain_LogItem_image" type="file" z="user-managed" required="false"/>
        <field:input field="contentType" id="c_raging_goblin_roo_domain_LogItem_contentType" z="user-managed" render="false"/>
        <field:input field="path" id="c_raging_goblin_roo_domain_LogItem_path" render="false" z="user-managed"/>
    </form:update>
</div>

Note several things. First, I changed the multipart to true, just like the create.jspx page. This will result in the error I described. Therefore I changed the path item so that it points to another path. Secondly, I set the input for the image to ‘not required’ as you might want to choose not to change the image. For the rest, changes are similar to create.jspx.

Step 10: Add an update method to the controller
The update method should be moved from the LogItemController_Roo_Controller aspect to the controller, which by now should be a very familiar trick. Change it to:

@RequestMapping(value = "/update", method = RequestMethod.POST, produces = "text/html")
	public String update(@Valid LogItem logItem, BindingResult bindingResult,
			Model uiModel, HttpServletRequest httpServletRequest) {
		if (bindingResult.hasErrors()) {
			populateEditForm(uiModel, logItem);
			return "logitems/update";
		}
		uiModel.asMap().clear();

		CommonsMultipartFile image = logItem.getImage();
		if (image != null && image.getSize() != 0) {
			File file = new File(image.getOriginalFilename());
			try {
				image.transferTo(file);
				logItem.setContentType(image.getContentType());
				logItem.setPath(file.getAbsolutePath());
			} catch (Exception e) {
				e.printStackTrace();
				return "logitems/update";
			}
		} else {
			LogItem logItemFromDb = LogItem.findLogItem(logItem.getId());
			logItem.setContentType(logItemFromDb.getContentType());
			logItem.setPath(logItemFromDb.getPath());
		}

		logItem.merge();
		return "redirect:/logitems/"
				+ encodeUrlPathSegment(logItem.getId().toString(),
						httpServletRequest);
	}

As you see, I put the method on the path /update, which corresponds with the value in update.jspx. The rest is pretty standard in my humble opinion.

16 May 2013

Spring Roo 9: Uploading images 2 (store images on filesystem)

Filed under: Java,Spring Roo — raginggoblin @ 20:39
Tags: ,

From the previous blog it is pretty easy to guess how to do this, but here is the recipe as promised to upload images and store them on the file system. As the images are not stored in the database you can use MySQL for this as well.

Step 1: Add maven dependencies
Same as previous.

Step 2: Add properties to the ‘LogItem’

private String contentType;
private String path;
@Transient
private CommonsMultipartFile image;

Note here that the image is added as a CommonsMultipartFile, exactly as it is received by Spring, but it is marked @Transient which will prevent it from entering the database. Besides this a path is added to enable us to retrieve the image later.

Step 3: Update create.jspx to send a MultipartFile
Like in step 3 of the previous post, the form to create a LogItem is adjusted to our needs:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields" xmlns:form="urn:jsptagdir:/WEB-INF/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:spring="http://www.springframework.org/tags" version="2.0">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <jsp:output omit-xml-declaration="yes"/>
    <form:create id="fc_raging_goblin_roo_domain_LogItem" modelAttribute="logItem" multipart="true" path="/logitems" render="${empty dependencies}" z="user-managed">
        <field:input field="message" id="c_raging_goblin_roo_domain_LogItem_message" z="apnKidZldiFISmA4Q9pumki/o6Q="/>
        <field:datetime dateTimePattern="${logItem_creationdate_date_format}" field="creationDate" id="c_raging_goblin_roo_domain_LogItem_creationDate" z="p5GCO6w9q76CIDoEn17xbZPqlT0="/>
        <field:input field="image" id="c_raging_goblin_roo_domain_LogItem_image" type="file" z="user-managed"/>
        <field:input field="contentType" id="c_raging_goblin_roo_domain_LogItem_contentType" render="false" z="user-managed"/>
        <field:input field="path" id="c_raging_goblin_roo_domain_LogItem_path" z="P0zJQZkpJ19wRptpdaKLWSTr/BU=" render="false"/>
    </form:create>
    <form:dependency dependencies="${dependencies}" id="d_raging_goblin_roo_domain_LogItem" render="${not empty dependencies}" z="Qbb30wyy/eoxYyR+b/J66Ec1Lxw="/>
</div>

Edit 17-07-2013: See next post how to handle updates to an image.

Step 4: Update input.tagx to handle type=”file”
If you have not done so yet, adjust it as described in step 4 earlier.

Step 5: Add a method to the controller to send the actual image
Images are now loaded from the filesystem, to be precise from the path field:

@RequestMapping(value = "/{id}/image", method = RequestMethod.GET)
public String showImage(@PathVariable("id") Long id,
		HttpServletResponse response, Model model) {
	LogItem logItem = LogItem.findLogItem(id);
	if (logItem != null && logItem.getPath() != null) {
		try {
			OutputStream out = response.getOutputStream();
			response.setContentType(logItem.getContentType());
			Files.copy(FileSystems.getDefault().getPath(logItem.getPath()),
					out);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	return null;
}

Step 6: Change create and update methods of LogItemController to save image to the filesystem
The create and update methods now should store the image on the filesystem. With the new file-io of Java 7 this has never been easier.

@RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(@Valid LogItem logItem, BindingResult bindingResult,
		Model uiModel, HttpServletRequest httpServletRequest) {
	if (bindingResult.hasErrors()) {
		populateEditForm(uiModel, logItem);
		return "logitems/create";
	}
	uiModel.asMap().clear();

	CommonsMultipartFile image = logItem.getImage();
	if (image != null) {
		File file = new File(image.getOriginalFilename());
		try {
			image.transferTo(file);
			logItem.setContentType(image.getContentType());
			logItem.setPath(file.getAbsolutePath());
		} catch (Exception e) {
			e.printStackTrace();
			return "logitems/create";
		}
	}
	logItem.persist();
	return "redirect:/logitems/"
			+ encodeUrlPathSegment(logItem.getId().toString(),
					httpServletRequest);
}

Note that the images will end up in the same directory where your webapp is running. This is something you probably wouldn’t do on a production system.

Step 7: Give webserver write access to the filesystem
Take care that the directory where you want to save the images is write-enabled for the webserver. Ok, I admit this is not really a decent step, but I just wanted to keep the numbering the same as in the previous post and this is the best I could come up with ;).

Step 8: Update show.jspx to display the image
The artificial step 7 allows me now to just redirect you to the previous step 8.

5 May 2013

Spring Roo 8: Uploading images 1 (store images as blob in database)

Here is some hard gained knowledge. How to provide the possibility to upload (and view) images to a Spring Roo website. It took me quite a while to understand how to do this and I will describe 2 ways of doing it. In this post I will show a method with storing the image as a byte-array in the database, in the next one I will describe how to store the images on disk. Each method has it’s own benefits so take your pick. The reference is our logbook application introduced in previous posts. For some reason I never have been able to get this working with MySQL, it will generate a tinyblob field which is not capable of storing my images, and using @Lob on the field causes a java.lang.AbstractMethodError: org.apache.commons.dbcp.DelegatingPreparedStatement.setBinaryStream(ILjava/io/InputStream;J). I don’t know how to solve this, so we switch to PostgreSQL. This might be a better choice anyway as I am not a particular fan of dinosaurs like Larry Ellison or Steve Ballmer. Now take care that PostgreSQL is a completely different beast than MySQL. Try to setup your database properly with the proper owner and access rights on the server and the database itself before you continue. I will not tell you how to do that as there is plenty of stuff about this on the internet and I don’t want to deprive you of a fine ‘cursing and banging your head against a wall’ adventure.

Edit 17-05-2013: See comments below, update commons-dbcp to version 1.4 and you will do fine with MySQL as well.

To start with the most simple method, here are the steps needed to store the images as blobs in the database:

Step 1: Add maven dependencies
To handle uploads Spring relies on 2 dependencies: commons-fileupload.jar and commons-io.jar. The first one is already in the pom, so only the latter should be added:

<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.4</version>
</dependency>

If you use the STS, right click on your project and update the maven dependencies.

Step 2: Add properties to the ‘LogItem’

private byte[] image;
private String contentType;

Take care that the Roo shell is running, you will notice that Roo updates the views and the ApplicationConversionFactoryBean as needed.

Step 3: Update create.jspx to send a MultipartFile
The view for creating a LogItem (~/src/main/webapp/WEB-INF/views/logitems/create.jspx) should be manually adjusted to provide an upload field:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields" xmlns:form="urn:jsptagdir:/WEB-INF/tags/form" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:spring="http://www.springframework.org/tags" version="2.0">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <jsp:output omit-xml-declaration="yes"/>
    <form:create id="fc_raging_goblin_roo_domain_LogItem" modelAttribute="logItem" multipart="true" path="/logitems" render="${empty dependencies}" z="user-managed">
        <field:input field="message" id="c_raging_goblin_roo_domain_LogItem_message" z="apnKidZldiFISmA4Q9pumki/o6Q="/>
        <field:datetime dateTimePattern="${logItem_creationdate_date_format}" field="creationDate" id="c_raging_goblin_roo_domain_LogItem_creationDate" z="p5GCO6w9q76CIDoEn17xbZPqlT0="/>
        <field:select field="logUser" id="c_raging_goblin_roo_domain_LogItem_logUser" itemValue="id" items="${logusers}" path="/logusers" z="RJfGPnxQnmkMqPwvKANgyfbJA6g="/>
        <field:input field="image" id="c_raging_goblin_roo_domain_LogItem_image" type="file" z="user-managed"/>
        <field:input field="contentType" id="c_raging_goblin_roo_domain_LogItem_contentType" z="user-managed" render="false"/>
    </form:create>
    <form:dependency dependencies="${dependencies}" id="d_raging_goblin_roo_domain_LogItem" render="${not empty dependencies}" z="Qbb30wyy/eoxYyR+b/J66Ec1Lxw="/>
</div>

Note several changes here: multipart=”true” on the form tag, type=”file” on the field tag for the image and render=”false” on the contentType tag. Spring Roo will adjust the z values to user-managed for us, but you can do this yourself as well. Change the update.jspx in the same way. I also removed the image and contentType from list.jspx by setting render=”false” on those columns.
Edit 17-05-2013: See later post on how to update an image.

Step 4: Update input.tagx to handle type=”file”
In the previous step we added type=”file” to the input fields of the images, but this field actually does nothing with this parameter, so add

<c:when test="${type eq 'file'}">
   <form:input type="file" id="_${sec_field}_id" path="${sec_field}" disabled="${disabled}" />
</c:when>

to this tag (~/src/main/webapp/WEB-INF/tags/form/fields/input.tagx) just above the line ‘<c:when test=”${type eq ‘password’}”>’.

Step 5: Add a method to the controller to send the actual image
In order to send the actual image to the browser we need to add an extra REST mapping to the LogItemController. Add the following method:

@RequestMapping(value = "/{id}/image", method = RequestMethod.GET)
	public String showImage(@PathVariable("id") Long id, HttpServletResponse response, Model model) {
		LogItem logItem = LogItem.findLogItem(id);
		if (logItem != null) {
			byte[] image = logItem.getImage();
			if (image != null) {
				try {
					response.setContentType(logItem.getContentType());
					OutputStream out = response.getOutputStream();
					IOUtils.copy(new ByteArrayInputStream(image), out);
					out.flush();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

This will take care of sending the image when you browse to an url like http://localhost:8080/logbook/logitems/1/image. Note that I just added /image to the standard url mapping of a LogItem.

Step 6: Change create and update methods of LogItemController to set contentType
Copy the create method from the aspect to the java file and wait to let Roo update the aspect. Than add a parameter and store the contentType:

    @RequestMapping(method = RequestMethod.POST, produces = "text/html")
    public String create(@Valid LogItem logItem, BindingResult bindingResult, Model uiModel, 
    		@RequestParam("image") MultipartFile multipartFile,
    		HttpServletRequest httpServletRequest) {
        if (bindingResult.hasErrors()) {
            populateEditForm(uiModel, logItem);
            return "logitems/create";
        }
        uiModel.asMap().clear();
        logItem.setContentType(multipartFile.getContentType());
        logItem.persist();
        return "redirect:/logitems/" + encodeUrlPathSegment(logItem.getId().toString(), httpServletRequest);
    }

You will have to edit the update method in a similar fashion.

Step 7: Add a PropertyEditor to the LogItemController
At this moment Spring will send a CommonMultipartFile to the controller, but the type of the image is a byte-array. Spring will fail with a IllegalArgumentException (Failed to convert property value of type org.springframework.web.multipart.commons.CommonsMultipartFile to required type byte[] for property image). Spring however comes very conveniently with a PropertyEditor to handle this conversion. Register this in the LogItemController:

	@InitBinder
	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws ServletException {
		binder.registerCustomEditor(byte[].class,
				new ByteArrayMultipartFileEditor());
	}

Step 8: Update show.jspx to display the image
To display an image add a standard HTML img tag to show.jspx:

<img src="${logitem.id}/image" height="256px"/>

Screenshot

Good luck!

References

  1. http://viralpatel.net/blogs/spring-roo-save-read-blob-object-spring-roo-tutorial/
  2. http://gadgets.coolman.ca/multipart-file-upload-spring-roo/
  3. http://whyjava.wordpress.com/tag/spring-roo/

2 May 2013

Spring Roo 7: JSTL

Filed under: Java,Spring Roo — raginggoblin @ 08:02
Tags: , ,

Yesterday I tried to edit a Spring Roo generated view and used one of those handy constructs of the jstl (JavaServer Pages Standard Tag Library), the foreach loop:

<c:forEach items="${vmpadresses}" var="address">
   <input type="text" value="${address}" />
</c:forEach>

When I ran the page it threw a org.apache.jasper.JasperException to me with the message: The prefix “c” for element “c:forEach” is not bound. I thought what, no jstl?! But of course I was wrong, it is just not registered in the generated views. Look for the tag with all the other tag directives. In my case this was the div tag. Ad

xmlns:c="http://java.sun.com/jsp/jstl/core"

to this tag so that it reads something like this:

<div xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:field="urn:jsptagdir:/WEB-INF/tags/form/fields" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:page="urn:jsptagdir:/WEB-INF/tags/form" version="2.0">

The dependency for the jstl is already in the pom, so this is all you have to do and all is fine again.

Next Page »

The Rubric Theme. Blog at WordPress.com.