Java tutorial
/* * This file is part of the PdfTrick project. * Copyright: (C) 2014 * Author: Gian Luca Mori * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * For more information, please contact Gian Luca Mori at this * address: giansluca@gmail.com */ package org.gmdev.pdftrick.engine; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Properties; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPasswordField; import javax.swing.SwingUtilities; import javax.swing.border.Border; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.apache.log4j.Logger; import org.gmdev.pdftrick.factory.PdfTrickFactory; import org.gmdev.pdftrick.utils.Consts; import org.gmdev.pdftrick.utils.PdfTrickMessages; import com.itextpdf.text.exceptions.BadPasswordException; import com.itextpdf.text.pdf.PdfName; import com.itextpdf.text.pdf.PdfObject; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStream; /** * @author Gian Luca Mori */ public class CheckFiles { private static final Logger logger = Logger.getLogger(CheckFiles.class); private static final PdfTrickFactory factory = PdfTrickFactory.getFactory(); private boolean checkEncryption = false; private HashMap<String, String> namePwd; private boolean userProtection = false; private boolean ownerProtection = false; /** * Constructor */ public CheckFiles() { this.namePwd = factory.getNamePwd(); } /** * Check files selected (pdf integrity, images inside, protection ... ecc.). * @param filesVett * @param messages * @return TRUE if all the checks are passed. */ public boolean check() { final Properties messages = factory.getMessages(); final ArrayList<File> filesVett = factory.getFilesVett(); boolean check = false; boolean checkPdf = false; boolean checkNumImg = false; checkPdf = checkPdf(filesVett, messages); if (checkPdf) { try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { checkEncryption = checkEncryption(filesVett, messages); } }); } catch (InterruptedException e) { logger.error("Exception", e); } catch (InvocationTargetException e) { logger.error("Exception", e); } if (checkEncryption) { checkNumImg = checkNumberImages(filesVett, messages); if (checkNumImg) { check = true; } } } return check; } /** * Check if pdf files selected are valid and are actually pdf files and maximus size 256 MB. * @param filesVett * @param messages * @return TRUE if the pdf file is OK. */ private boolean checkPdf(ArrayList<File> filesVett, Properties messages) { boolean check = true; long sizeResultFile = 0; Iterator<File> ite = filesVett.iterator(); while (ite.hasNext()) { File item = ite.next(); sizeResultFile += item.length(); String nameFile = item.getName(); String fileString = this.readFile(item); // check if the file uploaded is actually a pdf file if (!fileString.substring(0, 4).equalsIgnoreCase("%PDF")) { check = false; PdfTrickMessages.append("WARNING", MessageFormat.format(messages.getProperty("dmsg_04"), nameFile)); } } long sizeResultFileKB = sizeResultFile / 1024; long sizeResultFileMB = sizeResultFileKB / 1024; if (sizeResultFileMB > 256) { check = false; PdfTrickMessages.append("WARNING", messages.getProperty("tmsg_20")); } return check; } /** * Read a pdf file and return first line as String representation (for checkPdf method). * @param file * @param area * @return The first line of the PDF file as a String. */ private String readFile(File file) { String line = null; try { FileReader in = new FileReader(file); BufferedReader brd = new BufferedReader(in); line = brd.readLine(); in.close(); } catch (IOException e) { logger.error("Exception", e); PdfTrickMessages.append("ERROR", Consts.SENDLOG_MSG); } return line; } /** * Check the number of images contained in the file's selection, if == 0 return false. * @param filesVett * @param messages * @return TRUE if the there is at least one image in the PDF files selection. */ private boolean checkNumberImages(ArrayList<File> filesVett, Properties messages) { boolean checkNumImg = false; Iterator<File> ite = filesVett.iterator(); while (ite.hasNext()) { File item = ite.next(); PdfReader reader = null; try { if (namePwd.containsKey(item.getName())) { reader = new PdfReader(item.getPath(), namePwd.get(item.getName()).getBytes()); } else { reader = new PdfReader(item.getPath()); } for (int i = 0; i < reader.getXrefSize(); i++) { PdfObject pdfobj = reader.getPdfObject(i); if (pdfobj == null || !pdfobj.isStream()) { continue; } PdfStream stream = (PdfStream) pdfobj; PdfObject pdfsubtype = stream.get(PdfName.SUBTYPE); if (pdfsubtype != null && pdfsubtype.toString().equals(PdfName.IMAGE.toString())) { checkNumImg = true; break; } } if (checkNumImg) { break; } } catch (IOException e) { logger.error("Exception", e); PdfTrickMessages.append("ERROR", Consts.SENDLOG_MSG); } } if (!checkNumImg) { PdfTrickMessages.append("WARNING", messages.getProperty("tmsg_21")); } return checkNumImg; } /** * Check and manage pdf with protection. * @param filesVett * @param messages * @return TRUE if everiting if OK with PDF files protection (correct password if the PDF require it). */ private boolean checkEncryption(ArrayList<File> filesVett, Properties messages) { boolean check = true; Iterator<File> ite = filesVett.iterator(); while (ite.hasNext()) { userProtection = false; ownerProtection = false; final File item = ite.next(); hasProtection(item); if (userProtection || ownerProtection) { int i = 1; String _ck = askAndChekPwd(item, messages, i); if (_ck.equalsIgnoreCase("no")) { while (_ck.equalsIgnoreCase("no") && i < 3) { i++; _ck = askAndChekPwd(item, messages, i); check = false; } } if (_ck.equalsIgnoreCase("abort")) { PdfTrickMessages.append("WARNING", messages.getProperty("tmsg_22")); check = false; } if (_ck.equalsIgnoreCase("ok")) { check = true; } } if (!check) break; } return check; } /** * method that check is single pdf has a User password protected, set userProtection = true if BadPasswordException; * @param File */ private void hasProtection(File file) { PdfReader reader = null; try { reader = new PdfReader(file.getPath()); if (reader != null) { if (reader.isEncrypted()) { ownerProtection = true; } reader.close(); } } catch (BadPasswordException e) { userProtection = true; } catch (IOException e) { logger.error("Exception", e); PdfTrickMessages.append("ERROR", Consts.SENDLOG_MSG); } } /** * Show dialog to get the User password and check it. * @param file * @param messages * @param n * @return The string answer of the password check (abort, no, ok). */ private String askAndChekPwd(File file, Properties messages, int n) { ImageIcon imageIcon = new ImageIcon(getClass().getResource(Consts.MAIN_ICO)); final JDialog userPwdDialog = new JDialog((JDialog) null, true); userPwdDialog.setTitle(Consts.PWDDIALOG); userPwdDialog.setIconImage(imageIcon.getImage()); userPwdDialog.setSize(620, 80); userPwdDialog.setResizable(false); userPwdDialog.setLocationRelativeTo(null); userPwdDialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); userPwdDialog.setLayout(null); final JPasswordField userPwdField = new JPasswordField(); userPwdField.setBounds(25, 25, 500, 20); userPwdField.setEchoChar('*'); final JLabel userPwdLabel = new JLabel(); userPwdLabel.setBounds(30, 5, 500, 18); userPwdLabel.setText(MessageFormat.format(messages.getProperty("dmsg_06"), file.getName())); final JButton okButton = new JButton("OK"); okButton.setBounds(530, 25, 70, 20); okButton.setOpaque(true); final OkCloseAction ok = new OkCloseAction(messages, file, n); final Thread t = new Thread(ok); okButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { userPwdDialog.setVisible(false); userPwdDialog.dispose(); ok.pwd = String.valueOf(userPwdField.getPassword()); t.start(); } }); userPwdField.getDocument().addDocumentListener(new DocumentListener() { @Override public void removeUpdate(DocumentEvent e) { go(); } @Override public void insertUpdate(DocumentEvent e) { go(); } @Override public void changedUpdate(DocumentEvent e) { go(); } public void go() { Border borderOrange = BorderFactory.createLineBorder(Color.ORANGE); if (userPwdField.getPassword().length > 0) { okButton.setBorder(borderOrange); } else { okButton.setBorder(new JButton().getBorder()); } } }); userPwdDialog.getRootPane().setDefaultButton(okButton); userPwdDialog.add(userPwdField); userPwdDialog.add(userPwdLabel); userPwdDialog.add(okButton); userPwdDialog.setVisible(true); if (t.isAlive()) { try { t.join(); } catch (InterruptedException e) { logger.error("Exception", e); } } return ok.check; } /** * @author Gian Luca Mori */ public class OkCloseAction implements Runnable { private volatile String check = "abort"; private volatile String pwd; private Properties messages; private File file; private int n; /** * Constructor * @param messages * @param file * @param n */ public OkCloseAction(Properties messages, File file, int n) { this.messages = messages; this.file = file; this.n = n; } /** * Thread called by listener for Ok / Close button on password box */ @Override public void run() { PdfReader reader = null; try { if (userProtection || ownerProtection) { reader = new PdfReader(file.getPath(), pwd.getBytes()); if (reader != null) { if (reader.isEncrypted()) { if (reader.isOpenedWithFullPermissions()) { check = "ok"; namePwd.put(file.getName(), pwd); } else { check = "no"; PdfTrickMessages.appendLater("WARNING", MessageFormat.format(messages.getProperty("dmsg_08"), n, file.getName())); } } reader.close(); } } } catch (BadPasswordException e) { check = "no"; PdfTrickMessages.appendLater("WARNING", MessageFormat.format(messages.getProperty("dmsg_07"), n, file.getName())); } catch (IOException e) { logger.error("Exception", e); PdfTrickMessages.appendLater("ERROR", Consts.SENDLOG_MSG); } } } }