Wednesday, December 8, 2010

Pipe to clipboard in bash on ubuntu

Say you wanted the output of a command like ls to be copied directly into the clipboard for pasting into your gui windows. Use xclip:
sudo apt-get install xclip
Then
ls | xclip -selection clipboard
will copy the output of ls into the clipboard.

I use an alias in my .bashrc for it:
alias c='xclip -selection clipboard'
So the command becomes:
ls | c

Quickly changing your .bashrc file

I use aliases all the time and am always adding more shortcuts for my terminal experience to the .bashrc file. So it's only natural that I made a convenient alias for doing exactly that.

Add this line to your .bashrc file:
alias vib='vi ~/.bashrc && source ~/.bashrc'

Then type source ~/.bashrc and the change will have been made.

So whenever you want to change your .bashrc file and have it come into effect for the current terminal:
vib
which will edit .bashrc and will run source on it automatically when you finish editing.

Sunday, October 10, 2010

Maven site and multi-module broken links on site:stage

Maven 2.2.1 default site plugin does a strange job of making parent to child links for a multimodule site report. When I have the parent reporting url set to a file:// url the links are broken after doing a site:stage. There is an easy workaround though. Make the reporting url a property in the parent pom.xml, say ${site.url} and from parent directory call

mvn clean site site:deploy -Dsite.url=file://`pwd`/target/deployed-site

This will deploy the site into target/deployed-site. Note that the url must be absolute, that's why I use `pwd` to insert the current directory (not for windoze of course). Put whatever url you like in site.url if the above does not suit.

Friday, April 16, 2010

IMDB Lookup from Nautilus in Ubuntu

This is how you implement a Lookup IMDB right click menu action for a movie file visible in Nautilus. It's really easy using Nautilus Actions!

First install nautilus-actions
sudo apt-get install nautilus-actions
Now create the script to launch the browser given a filename.
sudo wget -N -P /usr/bin http://moten-util.googlecode.com/svn/ubuntu/trunk/lookup-imdb/lookup-imdb sudo chmod 755 /usr/bin/lookup-imdb
Choose System - Preferences - Nautilus Actions Configuration - Add.
Set values in Action tab as below
Label: Lookup IMDB
Path: lookup-imdb
Parameters: %b
Logout and back in again and you should be ready to go.

Note: if you find that your default browser is not being opened by the x-www-browser command then select your default browser by
sudo update-alternatives --config x-www-browser
As of 5 May 2013 this works fine in Ubuntu 12.04 with Unity.

Friday, January 29, 2010

Guice 2.0: Mixing injected and non-injected parameters

Have been using Guice for a couple of years now after a friend at Google put me on to it. Guice 2.0 is great too, one thing it makes easier is mixing injector controlled parameters and non-injector controlled parameters into a constructor (I think constructor injection is way more solid than field/method injection when you can).

The feature is called AssistedInject, here is an example:

public class PersonLocator() {
@Inject
public PersonLocator(GeneralLocator locator, @Assisted String name) {
...
}
}

To instantiate PersonLocator using the injector you need to create a PersonLocatorFactory:

public interface PersonLocatorFactory {
PersonLocator create(String name);
}

Put a binding into the injector module:

bind(PersonLocatorFactory.class).toProvider(
FactoryProvider.newFactory(PersonLocatorFactory.class, PersonLocator.class));

Then to instantiate PersonLocator use an injected PersonLocatorFactory:

public PersonHunter {
@Inject
public PersonHunter(PersonLocatorFactory personLocatorFactory, String name){
PersonLocator personLocator = personLocatorFactory.create(name);
}
}

Thursday, September 24, 2009

Unmarshalling and validating xml without a namespace using JAXB

Unmarshalling and validating xml using jaxb where the xml does not have a namespace specified has driven me crazy for years now. I even did text insertion on the xml before unmarshalling as a workaround. Here's a good way of doing it that's great for xml without any namespace attributes (on the child elements too):

This code unmarshals the object into an org.jdom.Document object then recurses through the object setting namespaces. That object is then passed as a Source to the unmarshaller.

Note also that I did not have @XmlRootElement annotation on GCOM3DRequest so I asked the unmarshaller to unmarshal to that class explicitly.

Primary source for this was here.

package au.gov.amsa.er.nwm.scenario;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.Source;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.apache.log4j.Logger;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import org.jdom.transform.JDOMSource;
import org.xml.sax.SAXException;

import au.gov.amsa.nwm.gcom3drequest.GCOM3DRequest;
import au.gov.amsa.nwm.gcom3drequest.ObjectFactory;

public class RequestMarshaller {

private static Logger log = Logger.getLogger(RequestMarshaller.class);
private JAXBContext jc;
private Schema schema;

public RequestMarshaller() {
try {
jc = JAXBContext.newInstance(ObjectFactory.class.getPackage()
.getName());
} catch (JAXBException e) {
throw new RuntimeException(e);
}

loadSchema();

}

private void loadSchema() {
SchemaFactory sf = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
schema = sf.newSchema(getClass().getResource(
"request/gcom3dRequest.xsd"));
} catch (SAXException e) {
throw new RuntimeException(e);
}
}

private Unmarshaller createUnmarshaller() {
Unmarshaller u;
try {
u = jc.createUnmarshaller();
// validate against the schema
u.setSchema(schema);
return u;
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}

private static Namespace DEFAULT_NS = Namespace
.getNamespace("http://www.amsa.gov.au/nwm/gcom3dRequest");

public GCOM3DRequest unmarshal(InputStream is) throws JAXBException {

try {
SAXBuilder sb = new SAXBuilder(false);
org.jdom.Document doc = sb.build(is);
setNamespace(doc.getRootElement(), DEFAULT_NS, true);

Source src = new JDOMSource(doc);
Unmarshaller u = createUnmarshaller();
u.setSchema(schema);
JAXBElement element = u.unmarshal(src,
GCOM3DRequest.class);
GCOM3DRequest gcom3d = element.getValue();
return gcom3d;
} catch (IOException e) {
throw new RuntimeException(e);
} catch (JDOMException e) {
throw new RuntimeException(e);
}
}

private static void setNamespace(Element elem, Namespace ns, boolean recurse) {
elem.setNamespace(ns);
if (recurse) {
for (Object o : elem.getChildren()) {
setNamespace((Element) o, ns, recurse);
}
}
}

public Marshaller createMarshaller() {
Marshaller m;
try {
m = jc.createMarshaller();
m.setSchema(schema);
return m;
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}

}

Monday, November 3, 2008

Create a WFS 1.1 service in java

I wanted to create an OGC Web Feature Service (version 1.1) from scratch in java. When I tried to use jdk6 xjc with the OpenGIS schemas I had lots of errors so I had to create a bindings file to resolve them. It all works fine now, here are the results of my labours:

Ant fragment:

<exec executable="${xjc}"
failonerror="true"
outputproperty="xjc.output"
errorproperty="xjc.error"
logerror="true">
<arg value="-extension">
<arg value="-verbose">
<arg value="-httpproxy">
<arg value="proxy:8080">
<arg value="-b">
<arg value="${opengis}/wfs/1.1.0/wfs-bindings.xml">
<arg value="-d">
<arg value="${generated}">
<arg value="${opengis}/wfs/1.1.0/wfs.xsd">
<arg value="${opengis}/cts/craft-feature.xsd">
<arg value="${opengis}/ows/1.0.0/owsExceptionReport.xsd">
</exec>


wfs-bindings.xml:

<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<bindings schemaLocation="wfs.xsd" node="/xs:schema">
<globalBindings
underscoreBinding="asCharInWord"
/>
<schemaBindings>
<package name="net.opengis.schema.wfs"/>
</schemaBindings>
</bindings>
<bindings schemaLocation="../../gml/3.1.1/base/gml.xsd" node="/xs:schema">
<schemaBindings>
<package name="net.opengis.schema.gml"/>
</schemaBindings>
<bindings schemaLocation="../../gml/3.1.1/base/defaultStyle.xsd" node="/xs:schema/xs:element[@name='topologyStyle']">
<class name="topologyStyleLowerCase"/>
</bindings>
<bindings schemaLocation="../../gml/3.1.1/base/defaultStyle.xsd" node="/xs:schema/xs:element[@name='geometryStyle']">
<class name="geometryStyleLowerCase"/>
</bindings>
<bindings schemaLocation="../../gml/3.1.1/base/defaultStyle.xsd" node="/xs:schema/xs:element[@name='graphStyle']">
<class name="graphStyleLowerCase"/>
</bindings>
<bindings schemaLocation="../../gml/3.1.1/base/defaultStyle.xsd" node="/xs:schema/xs:element[@name='featureStyle']">
<class name="featureStyleLowerCase"/>
</bindings>
<bindings schemaLocation="../../gml/3.1.1/base/defaultStyle.xsd" node="/xs:schema/xs:element[@name='labelStyle']">
<class name="labelStyleLowerCase"/>
</bindings>
</bindings>
<bindings schemaLocation="../../filter/1.1.0/filter.xsd" node="/xs:schema">
<schemaBindings >
<package name="net.opengis.schema.filter" />
</schemaBindings>
</bindings>
<bindings schemaLocation="../../ows/1.0.0/owsAll.xsd" node="/xs:schema">
<schemaBindings>
<package name="net.opengis.schema.ows"/>
</schemaBindings>
</bindings>
</bindings>