package com.rectang.xsm.widget;
import com.rectang.xsm.XSM;
import com.rectang.xsm.io.PublishedFile;
import com.rectang.xsm.io.XSMDocument;
import com.rectang.io.TarFile;
import com.rectang.io.GZipFile;
import com.rectang.io.ZipFile;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;
import org.jdom.Element;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.markup.html.form.upload.FileUpload;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.AttributeModifier;
public class Image
extends File
implements Serializable
{
protected static HashSet hash, compHash;
{
hash = new HashSet();
hash.add( "jpeg" );
hash.add( "jpg" );
hash.add( "gif" );
hash.add( "png" );
/* FIXME add all images java + web supports */
compHash = new HashSet();
compHash.add( "gz" );
compHash.add( "tar.gz" );
compHash.add( "zip" );
}
public Image( java.lang.String name )
{
super( name );
}
protected java.lang.String getViewURL( Element node )
{
return getPath( node.getValue() );
}
public void view( Element node, StringBuffer s )
{
if ( node.getValue() == null || node.getValue().equals( "" ) )
{
s.append( "(no image)\n" );
}
else
{
s.append( "<img src=\"" + getSite().getRootUrl() );
s.append( getViewURL( node ) + "\" />\n" );
}
}
public void publish( Element node, StringBuffer s )
{
if ( node.getValue() == null || node.getValue().equals( "" ) )
{
s.append( "(no image)\n" );
}
else
{
s.append( "<img src=\"" + getSite().getPrefixUrl() );
s.append( getPath( node.getValue() ) + "\" />\n" );
}
}
public WebMarkupContainer edit( java.lang.String wicketId, Element node, java.lang.String path )
{
return new ImagePanel( wicketId, node, this );
}
public void destroy( Element node )
{
java.lang.String imageName = node.getText();
if ( imageName == null || imageName.equals( "" ) )
{
return;
}
PublishedFile file = (getSite().getPublishedDoc( getPath(
imageName ) ));
if ( file.exists() )
{
file.delete();
}
}
protected boolean addImagesRecurse( java.io.File file, Element node,
boolean addNode )
throws XSMDocument.GenerationException
{
if ( file.isDirectory() )
{
java.io.File[] children = file.listFiles();
for ( int i = 0; i < children.length; i++ )
{
if ( addImagesRecurse( children[i], node, addNode ) )
{
// only start adding nodes if we have hit a valid image upload
addNode = true;
}
}
file.delete();
return false;
}
java.lang.String fileName = (new java.io.File( File.fixSeparators( file.getName() ) )).getName();
// ignore non-image files and nasty OSX metadata
if ( !hash.contains( getFileExt( fileName ) ) || fileName.startsWith( "._" ) )
{
file.delete();
return false;
}
Element value = node;
if ( addNode )
{
/* FIXME - we need to hook into the node creation somehow!!! */
java.lang.String type = ((Element) node.getDocument().getRootElement().getChild( "data" ).getChildren().get( 0 )).getName();
if ( type.equals( "gallery" ) || type.equals( "book" ) ||
type.equals( "html" ) || type.equals( "php" ) )
{
Element newNode = new Element( "image" );
value = new Element( "path" );
newNode.addContent( value );
newNode.addContent( new Element( "caption" ) );
newNode.addContent( new Element( "comments" ) );
node.getParentElement().getParentElement().addContent( 0, newNode );
}
else
{
/* FIXME - make the next_index stuff work again */
value = new Element( "image" );
node.getParentElement().addContent( 0, value );
}
}
PublishedFile newFile = getSite().getPublishedDoc( getPath( fileName ) );
value.setText( fileName );
processFile( fileName, file, newFile );
file.delete();
return true;
}
protected void clearOldFiles( Element node )
{
java.lang.String oldName = node.getText();
if ( oldName != null && !oldName.equals( "" ) )
{
PublishedFile oldFile = getSite().getPublishedDoc(
getPath( oldName ) );
if ( oldFile.exists() )
{
oldFile.delete();
}
node.setText( "" );
}
}
protected void processFile( java.lang.String fileName,
java.io.File in, PublishedFile pub )
throws XSMDocument.GenerationException
{
pub.uploadFile( in );
}
public java.lang.String getPath( java.lang.String name )
{
return getPath( this, name );
}
public static java.lang.String getPath( com.rectang.xsm.doc.DocElement elem,
java.lang.String name )
{
return elem.getPublishedPath() + java.io.File.separatorChar + "_images"
+ java.io.File.separatorChar + name;
}
class ImagePanel
extends Panel
{
FileUploadField upload;
public ImagePanel( java.lang.String id, final Element node, final Image type )
{
super( id );
add( new Label( "label", name ) );
add( new WebMarkupContainer( "current" ).add( new AttributeModifier( "src",
new Model( getSite().getRootUrl() +
type.getViewURL( node ) ) ) ).setVisible( !node.getText().equals( "" ) ) );
add( upload = new FileUploadField( "value", new Model()
{
public void setObject( Serializable object )
{
FileUpload file = upload.getFileUpload();
java.lang.String ext = getFileExt( file.getClientFileName() ).toLowerCase();
if ( hash.contains( ext ) )
{
java.lang.String fileName = sanitiseName( file.getClientFileName() );
PublishedFile newFile = getSite().getPublishedDoc(
type.getPath( fileName ) );
java.lang.String oldName = node.getText();
if ( newFile.exists() && !oldName.equals( fileName ) )
{
error( "File " + fileName
+ " already exists, please rename your file and try uploading again" );
return;
}
/* remove the old images if they exist */
clearOldFiles( node );
node.setText( fileName );
java.io.File tmpFile = XSM.getTempFile();
try
{
file.writeTo( tmpFile );
processFile( fileName, tmpFile, newFile );
}
catch ( Exception e )
{
error( "Unable to write file " + newFile.getFileName() );
e.printStackTrace();
}
}
else if ( compHash.contains( ext ) )
{
java.io.File temp = XSM.getTempFile();
temp.mkdirs();
com.rectang.io.File zip = null;
TarFile tar = null;
try
{
if ( ext.equals( "gz" ) )
{
zip = new GZipFile( temp, "upload.gz" );
file.writeTo( zip );
java.io.File maybeTar = ((GZipFile) zip).expand();
zip.delete();
if ( file.getClientFileName().toLowerCase().endsWith( ".tar.gz" ) )
{
tar = new TarFile( maybeTar );
tar.expand();
tar.delete();
}
}
else if ( ext.equals( "zip" ) )
{
zip = new ZipFile( temp, "upload.zip" );
file.writeTo( zip );
((ZipFile) zip).expand();
zip.delete();
}
addImagesRecurse( temp, node, false );
}
catch ( IOException e )
{
error( "Error unpacking compressed file: " + e.getMessage() );
}
catch ( XSMDocument.GenerationException e )
{
error( "Unable to write images from zip file " );
}
finally
{
if ( tar != null && tar.exists() )
{
tar.delete();
}
if ( zip != null && zip.exists() )
{
zip.delete();
}
if ( temp.exists() )
{
temp.delete();
}
}
}
else
{
error( "Image type " + type + " is not supported" );
}
}
} ) );
StringBuffer note = new StringBuffer( "(image types " );
Iterator types = hash.iterator();
while ( types.hasNext() )
{
java.lang.String next = (java.lang.String) types.next();
note.append( next );
if ( types.hasNext() )
{
note.append( ", " );
}
}
note.append( " only) or you can upload a set of images in a compressed file (" );
types = compHash.iterator();
while ( types.hasNext() )
{
java.lang.String next = (java.lang.String) types.next();
note.append( next );
if ( types.hasNext() )
{
note.append( ", " );
}
}
note.append( ")" );
add( new Label( "note", note.toString() ) );
}
}
}