/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.vertical.adminweb.handlers.xmlbuilders;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.fileupload.FileItem;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.enonic.esl.containers.ExtendedMap;
import com.enonic.esl.xml.XMLTool;
import com.enonic.vertical.adminweb.AdminHandlerBaseServlet;
import com.enonic.vertical.adminweb.VerticalAdminException;
import com.enonic.vertical.adminweb.VerticalAdminLogger;
import com.enonic.cms.core.content.binary.BinaryData;
import com.enonic.cms.core.content.image.ContentImageUtil;
import com.enonic.cms.core.content.image.ImageUtil;
import com.enonic.cms.core.security.user.User;
import com.enonic.cms.core.service.AdminService;
public class ContentEnhancedImageXMLBuilder
extends ContentBaseXMLBuilder
{
public String getTitleFormKey()
{
return "name";
}
public String getContentTitle( Element contentDataElem, int contentTypeKey )
{
return XMLTool.getElementText( XMLTool.getElement( contentDataElem, "name" ) );
}
public int[] getRelatedContentKeys( ExtendedMap formItems )
{
return AdminHandlerBaseServlet.getIntArrayFormItem( formItems, "relatedfile" );
}
public void buildContentTypeXML( User user, Document doc, Element contentdata, ExtendedMap formItems )
throws VerticalAdminException
{
// Name
XMLTool.createElement( doc, contentdata, "name", formItems.getString( "name" ) );
// Description
Element tempElement = XMLTool.createElement( doc, contentdata, "description" );
XMLTool.createCDATASection( doc, tempElement, formItems.getString( "description", "" ) );
// Photographer
tempElement = XMLTool.createElement( doc, contentdata, "photographer" );
tempElement.setAttribute( "name", formItems.getString( "photographername", "" ) );
tempElement.setAttribute( "email", formItems.getString( "photographeremail", "" ) );
// Copyright
XMLTool.createElement( doc, contentdata, "copyright", formItems.getString( "copyright", "" ) );
// keywords
XMLTool.createElement( doc, contentdata, "keywords", formItems.getString( "keywords", "" ) );
// sourceimage
//String sourceKey = (String) ;
if ( formItems.containsKey( "sourceimagekey" ) )
{
tempElement = XMLTool.createElement( doc, contentdata, "sourceimage" );
tempElement.setAttribute( "width", formItems.getString( "originalwidth" ) );
tempElement.setAttribute( "height", formItems.getString( "originalheight" ) );
tempElement = XMLTool.createElement( doc, tempElement, "binarydata" );
tempElement.setAttribute( "key", formItems.getString( "sourceimagekey" ) );
}
// Images
Element images = XMLTool.createElement( doc, contentdata, "images" );
images.setAttribute( "deprecated", "Use binaries instead" );
if ( "on".equals( formItems.getString( "chkorgimageborder", null ) ) )
{
images.setAttribute( "border", "yes" );
}
else
{
images.setAttribute( "border", "no" );
}
// Original image
Element image = XMLTool.createElement( doc, images, "image" );
image.setAttribute( "type", "original" );
String tmp = formItems.getString( "rotate", null );
if ( tmp != null )
{
image.setAttribute( "rotation", tmp );
}
// Check if image is set. This should be done in the client for better control.
if ( !formItems.containsKey( "originalwidth" ) )
{
throw new VerticalAdminException( "Image is not set. Please choose an image to upload." );
}
String width = formItems.getString( "originalwidth" );
String height = formItems.getString( "originalheight" );
XMLTool.createElement( doc, image, "width", width );
XMLTool.createElement( doc, image, "height", height );
tempElement = XMLTool.createElement( doc, image, "binarydata" );
tempElement.setAttribute( "key", formItems.getString( "originalbinarydatakey" ) );
// related file
if ( formItems.containsKey( "relatedfile" ) )
{
tempElement = XMLTool.createElement( doc, contentdata, "file" );
tempElement.setAttribute( "key", formItems.getString( "relatedfile" ) );
}
}
public void applyImageData( ExtendedMap formItems )
{
if ( "on".equals( formItems.getString( "chkorigimageborder", null ) ) )
{
// original width
int tmp = formItems.getInt( "originalwidth" );
formItems.put( "originalwidth", new Integer( tmp - 2 ) );
// original height
tmp = formItems.getInt( "originalheight" );
formItems.put( "originalheight", new Integer( tmp - 2 ) );
// custom width
tmp = formItems.getInt( "customwidth" );
formItems.put( "customwidth", new Integer( tmp - 2 ) );
// custom height
tmp = formItems.getInt( "customheight" );
formItems.put( "customheight", new Integer( tmp - 2 ) );
}
ArrayList<String[]> otherImages = new ArrayList<String[]>();
formItems.put( "otherimages", otherImages );
String[] keys = AdminHandlerBaseServlet.getArrayFormItem( formItems, "scaledimage" );
String[] widths = AdminHandlerBaseServlet.getArrayFormItem( formItems, "scaledimagewidth" );
String[] heights = AdminHandlerBaseServlet.getArrayFormItem( formItems, "scaledimageheight" );
int i = 0;
for (; i < keys.length; i++ )
{
otherImages.add( new String[]{keys[i], widths[i], heights[i]} );
}
}
public int[] getDeleteBinaries( ExtendedMap formItems )
throws VerticalAdminException
{
if ( formItems.getBoolean( "newimage", false ) )
{
int versionKey = formItems.getInt( "versionkey" );
return admin.getBinaryDataKeysByVersion( versionKey );
}
else
{
return null;
}
}
public BinaryData[] getBinaries( ExtendedMap formItems )
throws VerticalAdminException
{
ArrayList<BinaryData> binaryList = null;
if ( formItems.getBoolean( "newimage", false ) )
{
FileItem imageFile = formItems.getFileItem( "origimagefilename" );
BinaryData image = AdminHandlerBaseServlet.createBinaryData( imageFile, "source" );
try
{
// find file type
String type = null;
int idx = image.fileName.lastIndexOf( "." );
if ( idx != -1 )
{
type = image.fileName.substring( idx + 1 ).toLowerCase();
if ( "jpg".equals( type ) )
{
type = "jpeg";
}
}
// Check for unsupported image format
if ( !isSupportedFormat( type ) )
{
VerticalAdminLogger.errorAdmin("I/O error processing file \"" + image.fileName + "\": Unsupported Image Type", (Throwable)null );
}
// Rotate source image?
String rotate = formItems.getString( "rotate", "none" );
if ( !"none".equals( rotate ) )
{
image.data = rotateImage( rotate, image.data, ContentImageUtil.getEncodeType( type ) );
}
String filenameWithoutExtension = image.fileName.substring( 0, idx );
BufferedImage origImage;
try
{
origImage = ImageUtil.readImage( image.data );
}
catch ( final Exception e )
{
origImage = null;
}
// ImageIO.read may return null without any exception.
if ( origImage == null )
{
VerticalAdminLogger.errorAdmin(
"Unsupported Image Type. Supported formats: jpeg (rgb not cmyk), gif (without transparency), png (with or without transparency) and bmp" );
return null;
}
if ( !formItems.containsKey( "originalwidth" ) )
{
formItems.put( "originalwidth", origImage.getWidth() );
}
if ( !formItems.containsKey( "originalheight" ) )
{
formItems.put( "originalheight", origImage.getHeight() );
}
// scale all images
binaryList =
scaleAndAddImages( formItems, admin, origImage, ContentImageUtil.getEncodeType( type ), filenameWithoutExtension );
// add source image
binaryList.add( image );
formItems.put( "sourceimagekey", "%" + ( binaryList.size() - 1 ) );
}
catch ( IOException ioe )
{
VerticalAdminLogger.errorAdmin("I/O error processing file \"" + image.fileName + "\": %t", ioe );
}
}
else
{
applyImageData( formItems );
}
if ( binaryList == null )
{
return null;
}
else
{
return binaryList.toArray( new BinaryData[binaryList.size()] );
}
}
private boolean isSupportedFormat( String extension )
{
return "jpeg".equals( extension ) || "png".equals( extension ) || "gif".equals( extension ) || "bmp".equals( extension );
}
private byte[] rotateImage( String rotate, byte[] image, String encodeType )
throws IOException
{
BufferedImage bufferedImage = ImageUtil.readImage( image );
if ( "90left".equals( rotate ) )
{
bufferedImage = ImageUtil.rotateImage270( bufferedImage, ContentImageUtil.getBufferedImageType( encodeType ) );
}
else if ( "90right".equals( rotate ) )
{
bufferedImage = ImageUtil.rotateImage90( bufferedImage, ContentImageUtil.getBufferedImageType( encodeType ) );
}
else if ( "180".equals( rotate ) )
{
bufferedImage = ImageUtil.rotateImage180( bufferedImage, ContentImageUtil.getBufferedImageType( encodeType ) );
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageUtil.writeImage( bufferedImage, encodeType, baos, 1.0f );
return baos.toByteArray();
}
private ArrayList<BinaryData> scaleAndAddImages( ExtendedMap formItems, AdminService admin, BufferedImage origImage, String encodeType,
String originalFilenameWithoutExtension )
throws VerticalAdminException, IOException
{
ArrayList<BinaryData> binaryData = new ArrayList<BinaryData>();
formItems.put( "originalbinarydatakey", "%0" );
final List<BinaryData> newStyleScaledImages =
ContentImageUtil.createStandardSizeImages( origImage, encodeType, originalFilenameWithoutExtension );
binaryData.addAll( newStyleScaledImages );
return binaryData;
}
}