Coding

CXF, JAXRS, XML and CDATA

I was in a need to export some XML tags as CDATA in my CXF XML @WebService that generates some XML for our partner.

We had a field that contained an URL and in that we have ampersand characters. By default these get turned into “&” but our specific XML partner was not OK with that so we had to adjust to CDATA. That turned out to be rather complex as I was hoping for something simple like @CDATA annotation – but as always, life is full of suprises.

Anyway, the trick is rather simple to make it work – We need to define our own XML Stream Writer and overwrite the default write method from “writeCharacters” to “writeCData”.

We had a very specific tags in mind only so we specified those as static string array.

You can do this like this:

import java.util.Arrays;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;

/**
 * Simple CDATA XML Stream Writer that exports some items as CDATA
 */
public class CDataXMLStreamWriter extends DelegatingXMLStreamWriter {

	// All elements with these names will be turned into CDATA
	private static String[] CDATA_ELEMENTS = { "infoUrl", "description" };

	private String currentElementName;

	public CDataXMLStreamWriter(XMLStreamWriter del) {
		super(del);
	}

	@Override
	public void writeCharacters(String text) throws XMLStreamException {
		if (Arrays.asList(CDATA_ELEMENTS).contains(currentElementName)) {
			super.writeCData(text);
		} else {
			super.writeCharacters(text);
		}
	}

	public void writeStartElement(String prefix, String local, String uri) throws XMLStreamException {
		currentElementName = local;
		super.writeStartElement(prefix, local, uri);
	}
}

OK; So now we have this nice writer, but how do you use it? Well, we are running it all inside a CXF that’s running with Spring container so as it turns out, we need an “Interceptor” that would help us write stuff. You can make one easily like this.


import java.io.OutputStream;

import javax.xml.stream.XMLStreamWriter;

import org.apache.cxf.interceptor.AttachmentOutInterceptor;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.staxutils.StaxUtils;

public class CDataWriterInterceptor extends AbstractPhaseInterceptor {

	public CDataWriterInterceptor() {
		super(Phase.PRE_STREAM);
		addAfter(AttachmentOutInterceptor.class.getName());
	}

	@Override
	public void handleMessage(Message message) {
		// Required for CDATA to working
		message.put("disable.outputstream.optimization", Boolean.TRUE);
		XMLStreamWriter writer = StaxUtils.createXMLStreamWriter(message.getContent(OutputStream.class));
		message.setContent(XMLStreamWriter.class, new CDataXMLStreamWriter(writer));
	}
}

And now, how do you use this interceptor? In your applicationContext.xml or similar Spring context file, define the interceptor and use it!
Note that the LoggingFeature is not required but I’ve left it in here so that you could easily enable logging to see the incoming and outgoing messages better.


	<bean id="CDataWriterInterceptor" class="com.amivarius.cxf.util.CDataWriterInterceptor" />

	<jaxrs:server .... >

		<jaxrs:features>
			<bean class="org.apache.cxf.feature.LoggingFeature" />
		</jaxrs:features>

		<jaxrs:outInterceptors>
			<ref bean="CDataWriterInterceptor" />
		</jaxrs:outInterceptors>

	</jaxrs:server>

And that’s it folks!

The output will be <![CDATA[]]> nicely ūüôā

Java watermark image

Today I needed to add a watermark on my client images. I had a look around for available libraries. I didn’t find a good solutions that I could use straight out of the box in Java so I just created my own ImageUtil class and made my own Java watermark image method.

First things first – If we want to watermark an image then we have to decide on where should we anchor our watermark. For that I decided to use a simple ENUM called PlacementPosition:

public enum PlacementPosition {
	TOPLEFT, TOPCENTER, TOPRIGHT, MIDDLELEFT, MIDDLECENTER, MIDDLERIGHT, BOTTOMLEFT, BOTTOMCENTER, BOTTOMRIGHT
}

When you want to add a watermark then you probably need to resize it so you might want a good image resizer. That one I found and we can use an already existing one. I personally prefer to use Scalr named image library from https://github.com/thebuzzmedia/imgscalr because it’s very good, pretty damn fast and has controllable quality. Also it’s available on Maven repository.

So now the actual code of watermarking an image:


	/**
	 * Generate a watermarked image.
	 * 
	 * @param originalImage
	 * @param watermarkImage
	 * @param position
	 * @param watermarkSizeMaxPercentage
	 * @return image with watermark
	 * @throws IOException
	 */
	public static BufferedImage watermark(BufferedImage originalImage,
			BufferedImage watermarkImage, PlacementPosition position,
			double watermarkSizeMaxPercentage) throws IOException {

		int imageWidth = originalImage.getWidth();
		int imageHeight = originalImage.getHeight();

		int watermarkWidth = getWatermarkWidth(originalImage, watermarkImage,
				watermarkSizeMaxPercentage);
		int watermarkHeight = getWatermarkHeight(originalImage, watermarkImage,
				watermarkSizeMaxPercentage);

		// We create a new image because we want to keep the originalImage
		// object intact and not modify it.
		BufferedImage bufferedImage = new BufferedImage(imageWidth,
				imageHeight, BufferedImage.TYPE_INT_RGB);
		Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
		g2d.drawImage(originalImage, 0, 0, null);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
		        RenderingHints.VALUE_ANTIALIAS_ON);

		int x = 0;
		int y = 0;
		if (position != null) {
			switch (position) {
			case TOPLEFT:
				x = 0;
				y = 0;
				break;
			case TOPCENTER:
				x = (imageWidth / 2) - (watermarkWidth / 2);
				y = 0;
				break;
			case TOPRIGHT:
				x = imageWidth - watermarkWidth;
				y = 0;
				break;

			case MIDDLELEFT:
				x = 0;
				y = (imageHeight / 2) - (watermarkHeight / 2);
				break;
			case MIDDLECENTER:
				x = (imageWidth / 2) - (watermarkWidth / 2);
				y = (imageHeight / 2) - (watermarkHeight / 2);
				break;
			case MIDDLERIGHT:
				x = imageWidth - watermarkWidth;
				y = (imageHeight / 2) - (watermarkHeight / 2);
				break;

			case BOTTOMLEFT:
				x = 0;
				y = imageHeight - watermarkHeight;
				break;
			case BOTTOMCENTER:
				x = (imageWidth / 2) - (watermarkWidth / 2);
				y = imageHeight - watermarkHeight;
				break;
			case BOTTOMRIGHT:
				x = imageWidth - watermarkWidth;
				y = imageHeight - watermarkHeight;
				break;

			default:
				break;
			}
		}

		g2d.drawImage(Scalr.resize(watermarkImage, Method.ULTRA_QUALITY,
				watermarkWidth, watermarkHeight), x, y, null);

		return bufferedImage;

	}

watermark-full-width

That method uses some specific methods to calculate the watermark size. I wanted the user to be able to upload their own watermarks but that caused a problem where I didn’t want to hard-code the size of the watermark. So we ended up using a solution where we have defined a maximum percentage of size that the watermark can be relative to the original image.

For that we use these methods:



	/**
	 * 
	 * @param originalImage
	 * @param watermarkImage
	 * @param maxPercentage
	 * @return
	 */
	private static Pair<Double, Double> calculateWatermarkDimensions(
			BufferedImage originalImage, BufferedImage watermarkImage,
			double maxPercentage) {

		double imageWidth = originalImage.getWidth();
		double imageHeight = originalImage.getHeight();

		double maxWatermarkWidth = imageWidth / 100.0 * maxPercentage;
		double maxWatermarkHeight = imageHeight / 100.0 * maxPercentage;

		double watermarkWidth = watermarkImage.getWidth();
		double watermarkHeight = watermarkImage.getHeight();

		if (watermarkWidth > maxWatermarkWidth) {
			double aspectRatio = watermarkWidth / watermarkHeight;
			watermarkWidth = maxWatermarkWidth;
			watermarkHeight = watermarkWidth / aspectRatio;
		}

		if (watermarkHeight > maxWatermarkHeight) {
			double aspectRatio = watermarkWidth / watermarkHeight;
			watermarkHeight = maxWatermarkHeight;
			watermarkWidth = watermarkHeight / aspectRatio;
		}

		return Pair.of(watermarkWidth, watermarkHeight);
	}

	/**
	 * 
	 * @param originalImage
	 * @param watermarkImage
	 * @param maxPercentage
	 * @return
	 */
	public static int getWatermarkWidth(BufferedImage originalImage,
			BufferedImage watermarkImage, double maxPercentage) {

		return calculateWatermarkDimensions(originalImage, watermarkImage,
				maxPercentage).getLeft().intValue();

	}

	/**
	 * 
	 * @param originalImage
	 * @param watermarkImage
	 * @param maxPercentage
	 * @return
	 */
	public static int getWatermarkHeight(BufferedImage originalImage,
			BufferedImage watermarkImage, double maxPercentage) {

		return calculateWatermarkDimensions(originalImage, watermarkImage,
				maxPercentage).getRight().intValue();

	}

And now we have our scaled logo, this time it’s aligned to middle-left:
Java watermark image

If you have a question or having trouble getting it to work then feel free to write me a comment and I’ll do my best to help you out. If you would like to read more about general Java related subjects then also make sure to comment on that and if you liked what you read then make sure to subscribe – It’s FREE!

Swift programming language

Apple introduced a new Swift programming language for operating systems iOS and OS X at WWDC 2014. We’ll try to do our best to learn it fast and write something nice about it.

Apple has also released a nice book for learning the language that you can download for free into iBooks.
https://itunes.apple.com/us/book/the-swift-programming-language/id881256329?mt=11

If you don’t have access to iBooks at the moment, you can get the Swift programming language PDF book from here:¬†http://techietake.com/wp-content/uploads/2014/06/the-swift-rogramming-language.pdf

The most interesting parts of the Swift programming language seem to be it’s ability for multiple return types and Xcode¬†quick playground feature that allows you to quickly test your code and code much faster as you can understand the behavior of your code faster.¬†Swift¬†language integrates with a Xcode¬†Playgrounds¬†that¬†s is a¬†testing ground that renders developer code in realtime. Developers can jump in and out of their application¬†whilst typing.

Here’s a screenshot of Xcode Playgrounds in action:

Xcode playgrounds screenshot

 

According to Apple the Swift programming language has been over 3 years in the making and is friendly to new programmers. It is the first industrial-quality systems programming language that is as expressive and enjoyable as a scripting language. By all means it seems that Swift will be the ultra fast programming language of the future and all new code should be written in it. Only time will tell if we are right.