From aca1ae6aa9bfa0c8fdd1b49034ea244743764b90 Mon Sep 17 00:00:00 2001 From: Massimiliano Assante Date: Mon, 20 Jan 2014 18:35:57 +0000 Subject: [PATCH] image preview for PDF done git-svn-id: https://svn.research-infrastructures.eu/d4science/gcube/trunk/portlets/user/share-updates@90273 82a268e6-3cf1-43bd-a215-b396298e98cf --- .settings/org.eclipse.wst.common.component | 2 +- pom.xml | 7 +- .../client/view/LinkPreviewer.java | 17 +++- .../client/view/LinkPreviewer.ui.xml | 1 + ...{LinkPlaceholder.java => Placeholder.java} | 2 +- .../client/view/SaveInWorkspaceBox.java | 38 +++++++++ .../client/view/SaveInWorkspaceBox.ui.xml | 9 +++ .../client/view/ShareUpdateForm.java | 10 +-- .../client/view/ShareUpdateForm.ui.xml | 2 +- .../server/ShareUpdateServiceImpl.java | 79 ++++++++++++++++++- 10 files changed, 151 insertions(+), 16 deletions(-) rename src/main/java/org/gcube/portlets/user/shareupdates/client/view/{LinkPlaceholder.java => Placeholder.java} (73%) create mode 100644 src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.java create mode 100644 src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.ui.xml diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index 8dc8e36..dde9c8f 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -4,7 +4,7 @@ - + uses diff --git a/pom.xml b/pom.xml index 78f0d95..e5d1a1b 100644 --- a/pom.xml +++ b/pom.xml @@ -99,9 +99,14 @@ org.gcube.portlets.widgets fileupload-progress-bar - [0.1.0-SNAPSHOT, 1.0.0-SNAPSHOT) + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) compile + + org.swinglabs + pdf-renderer + 1.0.5 + commons-fileupload commons-fileupload diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.java index e6a88cd..130ed61 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.java @@ -24,9 +24,12 @@ public class LinkPreviewer extends Composite { private LinkPreview toShow; - @UiField HTML closeImage; - @UiField ImageSwitcher switcher; - + private SaveInWorkspaceBox saveCopy; + + @UiField + HTML closeImage; + @UiField + ImageSwitcher switcher; @UiField HTML titleArea; @UiField @@ -37,8 +40,10 @@ public class LinkPreviewer extends Composite { CheckBox hideCheckBox; @UiField CheckBox hideImageCheckBox; + @UiField + Placeholder uploadInWS; - public LinkPreviewer(ShareUpdateForm parent, LinkPreview toShow) { + public LinkPreviewer(ShareUpdateForm parent, LinkPreview toShow, boolean isFilePreview) { initWidget(uiBinder.createAndBindUi(this)); closeImage.setStyleName("su-closeImage"); closeImage.setTitle("Cancel"); @@ -51,6 +56,10 @@ public class LinkPreviewer extends Composite { String desc = toShow.getDescription(); descText.setHTML((desc.length() > 256) ? desc.substring(0, 256)+"..." : desc); switcher.setImages(toShow.getImageUrls()); + if (isFilePreview) { + saveCopy = new SaveInWorkspaceBox(); + uploadInWS.add(saveCopy); + } } diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.ui.xml b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.ui.xml index 719cc47..b9f47a6 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.ui.xml +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPreviewer.ui.xml @@ -32,5 +32,6 @@ + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPlaceholder.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/Placeholder.java similarity index 73% rename from src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPlaceholder.java rename to src/main/java/org/gcube/portlets/user/shareupdates/client/view/Placeholder.java index 48aa0e8..0e3a2c3 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/LinkPlaceholder.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/Placeholder.java @@ -6,6 +6,6 @@ import com.google.gwt.user.client.ui.SimplePanel; * @author massi * */ -public class LinkPlaceholder extends SimplePanel { +public class Placeholder extends SimplePanel { } diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.java new file mode 100644 index 0000000..7c32fbc --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.java @@ -0,0 +1,38 @@ +package org.gcube.portlets.user.shareupdates.client.view; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.CheckBox; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HasText; +import com.google.gwt.user.client.ui.Widget; + +public class SaveInWorkspaceBox extends Composite { + + private static SaveInWorkspaceBoxUiBinder uiBinder = GWT + .create(SaveInWorkspaceBoxUiBinder.class); + + interface SaveInWorkspaceBoxUiBinder extends + UiBinder { + } + + public SaveInWorkspaceBox() { + initWidget(uiBinder.createAndBindUi(this)); + } + + @UiField + CheckBox saveCheckBox; + + public SaveInWorkspaceBox(String firstName) { + initWidget(uiBinder.createAndBindUi(this)); + } + + + +} diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.ui.xml b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.ui.xml new file mode 100644 index 0000000..66b2e13 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/SaveInWorkspaceBox.ui.xml @@ -0,0 +1,9 @@ + + + +
+ Also save a copy in my Workspace +
+
+
\ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.java b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.java index bad4a1f..5cbdb14 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.java @@ -82,7 +82,7 @@ public class ShareUpdateForm extends Composite { @UiField HTMLPanel mainPanel; @UiField - LinkPlaceholder preview; + Placeholder preview; @UiField Button submitButton; @@ -336,7 +336,7 @@ public class ShareUpdateForm extends Composite { public void onSuccess(LinkPreview result) { preview.clear(); if (result != null) - addPreview(result); + addPreview(result, false); } }); break; @@ -366,7 +366,7 @@ public class ShareUpdateForm extends Composite { preview.clear(); uploadProgress.setVisible(false); if (result != null) - addPreview(result); + addPreview(result, true); } }); } @@ -393,9 +393,9 @@ public class ShareUpdateForm extends Composite { * add the link preview in the view * @param result */ - private void addPreview(LinkPreview result) { + private void addPreview(LinkPreview result, boolean isFilePreview) { uploadProgress.setVisible(false); - myLinkPreviewer = new LinkPreviewer(this, result); + myLinkPreviewer = new LinkPreviewer(this, result, isFilePreview); preview.add(myLinkPreviewer); } /** diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.ui.xml b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.ui.xml index ddd0b37..a6ee339 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.ui.xml +++ b/src/main/java/org/gcube/portlets/user/shareupdates/client/view/ShareUpdateForm.ui.xml @@ -25,7 +25,7 @@ - + diff --git a/src/main/java/org/gcube/portlets/user/shareupdates/server/ShareUpdateServiceImpl.java b/src/main/java/org/gcube/portlets/user/shareupdates/server/ShareUpdateServiceImpl.java index c728b55..79dbf4f 100644 --- a/src/main/java/org/gcube/portlets/user/shareupdates/server/ShareUpdateServiceImpl.java +++ b/src/main/java/org/gcube/portlets/user/shareupdates/server/ShareUpdateServiceImpl.java @@ -1,17 +1,28 @@ package org.gcube.portlets.user.shareupdates.server; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.UUID; +import javax.imageio.ImageIO; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; @@ -22,6 +33,7 @@ import org.gcube.application.framework.core.session.ASLSession; import org.gcube.application.framework.core.session.SessionManager; import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager; import org.gcube.applicationsupportlayer.social.NotificationsManager; +import org.gcube.applicationsupportlayer.social.ftp.FTPManager; import org.gcube.common.homelibrary.home.HomeLibrary; import org.gcube.common.homelibrary.home.exceptions.HomeNotFoundException; import org.gcube.common.homelibrary.home.exceptions.InternalErrorException; @@ -37,6 +49,7 @@ import org.gcube.portal.databook.server.DatabookStore; import org.gcube.portal.databook.shared.ClientFeed; import org.gcube.portal.databook.shared.Feed; import org.gcube.portal.databook.shared.FeedType; +import org.gcube.portal.databook.shared.ImageType; import org.gcube.portal.databook.shared.PrivacyLevel; import org.gcube.portal.databook.shared.UserInfo; import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; @@ -69,6 +82,9 @@ import com.liferay.portal.service.OrganizationLocalServiceUtil; import com.liferay.portal.service.UserLocalServiceUtil; import com.liferay.portal.theme.ThemeDisplay; import com.sun.net.ssl.HttpsURLConnection; +import com.sun.pdfview.PDFFile; +import com.sun.pdfview.PDFPage; +import com.sun.pdfview.PDFParseException; /** * The server side implementation of the RPC service. @@ -79,6 +95,10 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar * */ private static final String ADMIN_ROLE = "Administrator"; + /** + * + */ + private static final String PDF_DEFAULT_IMAGE = "default_pdf.png"; /** * */ @@ -87,6 +107,8 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar * The store interface */ private DatabookStore store; + + private FTPManager ftpStore; /** * used for debugging in eclipse */ @@ -96,6 +118,7 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar */ public void init() { store = new DBCassandraAstyanaxImpl(); + ftpStore = FTPManager.getManager(); } public void destroy() { @@ -314,17 +337,67 @@ public class ShareUpdateServiceImpl extends RemoteServiceServlet implements Shar */ @Override public LinkPreview checkUploadedFile(String fileName, String fileabsolutePathOnServer) { + String imageUrl = null; try { - Thread.sleep(2000); - } catch (InterruptedException e) { + imageUrl = getPdfPreviewImage(fileabsolutePathOnServer); + } catch (Exception e) { e.printStackTrace(); } ArrayList imagesUrl = new ArrayList(); - imagesUrl.add("http://www.ask-cato.com/wp-content/uploads/2012/02/PDF5.gif"); + imagesUrl.add(imageUrl); return new LinkPreview(fileName, "the Desc", "http://www.lalala.com", "d4science.org", imagesUrl); } + private String getPdfPreviewImage(String path2Pdf) throws Exception { + File pdfFile = new File(path2Pdf); + RandomAccessFile raf = new RandomAccessFile(pdfFile, "r"); + FileChannel channel = raf.getChannel(); + ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); + PDFFile pdf = null; + try { + pdf = new PDFFile(buf); + } catch (PDFParseException ex) { + raf.close(); + _log.error("PDF Parse exception, returning default pdf image"); + return ftpStore.getBaseURL()+PDF_DEFAULT_IMAGE; + } + PDFPage page = pdf.getPage(0); + + int width = (int) page.getBBox().getWidth(); + int height = (int) page.getBBox().getHeight(); + + int scaledWidth = width/8; + int scaledHeight = height/8; + + // create the image + Rectangle rect = new Rectangle(0, 0, width, height); + + BufferedImage bufferedImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB); + + Image image = page.getImage(scaledWidth, scaledHeight, // width & height + rect, // clip rect + null, // null for the ImageObserver + true, // fill background with white + true // block until drawing is done + ); + Graphics2D bufImageGraphics = bufferedImage.createGraphics(); + bufImageGraphics.drawImage(image, 0, 0, scaledWidth, scaledHeight, null); + + //images are very small in this case we can use in-memory streams + ByteArrayOutputStream out = new ByteArrayOutputStream(); + boolean result = ImageIO.write(bufferedImage, "JPG", out); + raf.close(); + + if (result) { + String httpLink = ftpStore.uploadImageOnFTPServer(new ByteArrayInputStream(out.toByteArray()), ImageType.JPG); + _log.debug("PDF thumbnail available at: " + httpLink); + return httpLink; + } + else + throw new IOException("Could not process pdf file"); + } + /** * return the id as key and the names as value of the vre a user is subscribed to * @param username