package de.juwimm.cms.content.panel.util; import static de.juwimm.cms.client.beans.Application.getBean; import static de.juwimm.cms.common.Constants.rb; import java.awt.Cursor; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.awt.MediaTracker; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.filechooser.FileFilter; import org.apache.log4j.Logger; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; import de.juwimm.cms.client.beans.Beans; import de.juwimm.cms.common.Constants; import de.juwimm.cms.content.frame.DlgSavePicture; import de.juwimm.cms.content.frame.helper.ImageFileView; import de.juwimm.cms.content.frame.helper.ImageFilter; import de.juwimm.cms.content.frame.helper.ImagePreview; import de.juwimm.cms.content.frame.helper.Utils; import de.juwimm.cms.gui.FrmProgressDialog; import de.juwimm.cms.util.Communication; import de.juwimm.cms.util.UIConstants; import de.juwimm.cms.vo.PictureSlimValue; public abstract class PictureUploadUtil { private JComponent parentComponent; private Integer unitId; private Integer viewComponentId; private String titleBarText; protected Communication comm = ((Communication) getBean(Beans.COMMUNICATION)); private static Logger log = Logger.getLogger(PictureUploadUtil.class); /** * Initialize the picture upload utility by passing a tile bar text and either * a unitId or a viewComponentId that will be the entity the picture is attached to. * If both are not null the utility will throw an exception. * <br><br> * The upload will be done in a separate thread. * * @param titleBarText * @param unitId * @param viewComponentId */ public PictureUploadUtil(JComponent parentComponent, final String titleBarText, final Integer unitId, final Integer viewComponentId) { this.parentComponent = parentComponent; if (unitId != null && viewComponentId != null) { throw new IllegalArgumentException("Only one of unitId and viewComponentId are supposed to be not null"); } this.unitId = unitId; this.viewComponentId = viewComponentId; this.titleBarText=titleBarText; } public void show(){ Thread t = new Thread(new Runnable() { public void run() { upload(titleBarText); } }); t.setPriority(Thread.NORM_PRIORITY); t.start(); } protected void upload(String prosa) { parentComponent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); int retInt = 0; JFileChooser fc = new JFileChooser(); int ff = fc.getChoosableFileFilters().length; FileFilter[] fft = fc.getChoosableFileFilters(); for (int i = 0; i < ff; i++) { fc.removeChoosableFileFilter(fft[i]); } fc.addChoosableFileFilter(new ImageFilter()); fc.setFileView(new ImageFileView()); fc.setAccessory(new ImagePreview(fc)); fc.setDialogTitle(prosa); fc.setMultiSelectionEnabled(true); fc.setCurrentDirectory(Constants.LAST_LOCAL_UPLOAD_DIR); int returnVal = fc.showDialog(parentComponent, rb.getString("panel.content.picture.addPicture")); if (returnVal == JFileChooser.APPROVE_OPTION) { File[] files = fc.getSelectedFiles(); uploadFiles(files, fc.getCurrentDirectory()); parentComponent.setCursor(Cursor.getDefaultCursor()); } else { parentComponent.setCursor(Cursor.getDefaultCursor()); } } /** * Upload the selected images * @param files * @param unit * @param localUploadDir */ public void uploadFiles(File[] files, File localUploadDir) { if (files != null) { for (int i = (files.length - 1); i >= 0; i--) { Constants.LAST_LOCAL_UPLOAD_DIR = localUploadDir; if (files[i].length() > 4000000) { parentComponent.setCursor(Cursor.getDefaultCursor()); JOptionPane.showMessageDialog(UIConstants.getMainFrame(), rb.getString("exception.FileTooBig") + ": " + files[i].getName(), rb.getString("dialog.title"), JOptionPane.ERROR_MESSAGE); continue; } FrmProgressDialog prog = new FrmProgressDialog(rb.getString("panel.content.picture.addPicture"), rb.getString("panel.content.upload.ParseFile"), 100); prog.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); try { byte[] bty = getBytesFromFile(files[i]); ImageIcon tmpIcon = new ImageIcon(bty); ImageIcon thumbnail = null; if (tmpIcon.getIconWidth() > 90 || tmpIcon.getIconHeight() > 90) { thumbnail = new ImageIcon(tmpIcon.getImage().getScaledInstance(90, -1, Image.SCALE_DEFAULT)); } else { thumbnail = tmpIcon; } ByteArrayOutputStream out = new ByteArrayOutputStream(); try { out = manipulateImage(thumbnail.getImage()); } catch (Exception e) { JOptionPane.showMessageDialog(UIConstants.getMainFrame(), rb.getString("panel.content.picture.onlyPictures"), rb.getString("dialog.title"), JOptionPane.INFORMATION_MESSAGE); return; } String fext = Utils.getExtension(files[i]); String mimetype = "image/jpeg"; if (fext.equals(Utils.JPEG) || fext.equals(Utils.JPG)) { mimetype = "image/jpeg"; } else if (fext.equals(Utils.GIF)) { mimetype = "image/gif"; } else if (fext.equals(Utils.TIF) || fext.equals(Utils.TIFF)) { mimetype = "image/tif"; } prog.setProgress(rb.getString("panel.content.upload.Uploading"), 50); int existingPicId = 0; try { existingPicId = findExistingPicture(files[i].getName()); } catch (Exception e) { log.error("Error during getting getPictureIdForUnitAndName"); } if (existingPicId == 0) { pictureSelectedAction(out.toByteArray(), bty, mimetype, files[i].getName()); } else { /**picture name already exists=>dialog message*/ PictureSlimValue picSlimVal = comm.getPicture(existingPicId); DlgSavePicture saveDialog = new DlgSavePicture(picSlimVal, bty, out.toByteArray()); saveDialog.addSaveActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { pictureExistsAction(e.getID()); } }); int frameHeight = 180; int frameWidth = 250; saveDialog.setSize(frameWidth, frameHeight); saveDialog.setLocationRelativeTo(UIConstants.getMainFrame()); saveDialog.setModal(true); saveDialog.setVisible(true); } } catch (Exception exe) { log.error("Error during the upload of the picture " + files[i].getName(), exe); } finally { prog.setProgress(rb.getString("panel.content.upload.Finished"), 100); prog.dispose(); } } } } public static byte[] getBytesFromFile(File file) throws IOException { InputStream is = new FileInputStream(file); long length = file.length(); if (length > Integer.MAX_VALUE) { throw new IOException("File too big"); } byte[] bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } if (offset < bytes.length) { throw new IOException("Could not completely read file " + file.getName()); } is.close(); return bytes; } public static ByteArrayOutputStream manipulateImage(Image image) { ByteArrayOutputStream imageStream = null; Frame frame = null; Graphics graphics = null; try { frame = new Frame(); MediaTracker mt = new MediaTracker(frame); // frame acts as an ImageObserver mt.addImage(image, 0); mt.waitForAll(); int w = image.getWidth(frame); int h = image.getHeight(frame); BufferedImage offscreen = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); graphics = offscreen.getGraphics(); graphics.drawImage(image, 0, 0, frame); imageStream = new ByteArrayOutputStream(); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(imageStream); encoder.encode(offscreen); } catch (InterruptedException e) { log.error("Interrupted the manipulation of the image", e); } catch (IOException e) { log.error("IO ERROR manipulating the image", e); } finally { if (graphics != null) { graphics.dispose(); } } return imageStream; } public abstract void pictureExistsAction(int i); public abstract void pictureSelectedAction(byte[] thumbnail, byte[] picture, String mimeType, String pictureName) throws Exception; public abstract int findExistingPicture(String fileName); public Integer getUnitId() { return unitId; } public void setUnitId(Integer unitId) { this.unitId = unitId; } public Integer getViewComponentId() { return viewComponentId; } public void setViewComponentId(Integer viewComponentId) { this.viewComponentId = viewComponentId; } }