source: extensions/jiwigo-ws-api/src/main/java/fr/mael/jiwigo/transverse/util/Tools.java @ 10759

Last change on this file since 10759 was 10759, checked in by mlg, 13 years ago

Fixes problems with accents.

File size: 14.1 KB
Line 
1package fr.mael.jiwigo.transverse.util;
2
3import java.io.BufferedReader;
4import java.io.ByteArrayInputStream;
5import java.io.ByteArrayOutputStream;
6import java.io.File;
7import java.io.FileInputStream;
8import java.io.FileOutputStream;
9import java.io.IOException;
10import java.io.InputStream;
11import java.io.InputStreamReader;
12import java.io.PrintWriter;
13import java.io.Reader;
14import java.io.StringReader;
15import java.io.StringWriter;
16import java.io.Writer;
17import java.net.URL;
18import java.net.URLClassLoader;
19import java.security.MessageDigest;
20import java.security.NoSuchAlgorithmException;
21import java.util.ArrayList;
22
23import javax.xml.parsers.DocumentBuilder;
24import javax.xml.parsers.DocumentBuilderFactory;
25import javax.xml.parsers.ParserConfigurationException;
26import javax.xml.transform.Result;
27import javax.xml.transform.Source;
28import javax.xml.transform.Transformer;
29import javax.xml.transform.TransformerConfigurationException;
30import javax.xml.transform.TransformerException;
31import javax.xml.transform.TransformerFactory;
32import javax.xml.transform.dom.DOMSource;
33import javax.xml.transform.stream.StreamResult;
34
35import org.apache.sanselan.Sanselan;
36import org.apache.sanselan.common.IImageMetadata;
37import org.apache.sanselan.formats.jpeg.JpegImageMetadata;
38import org.apache.sanselan.formats.jpeg.JpegPhotoshopMetadata;
39import org.apache.sanselan.formats.jpeg.exifRewrite.ExifRewriter;
40import org.apache.sanselan.formats.jpeg.iptc.JpegIptcRewriter;
41import org.apache.sanselan.formats.jpeg.iptc.PhotoshopApp13Data;
42import org.apache.sanselan.formats.tiff.write.TiffOutputSet;
43import org.slf4j.Logger;
44import org.slf4j.LoggerFactory;
45import org.w3c.dom.Document;
46import org.w3c.dom.Element;
47import org.w3c.dom.Node;
48import org.xml.sax.InputSource;
49import org.xml.sax.SAXException;
50
51import fr.mael.jiwigo.service.impl.CategoryServiceImpl;
52import fr.mael.jiwigo.transverse.exception.FileAlreadyExistsException;
53
54/*
55 *  jiwigo-ws-api Piwigo webservice access Api
56 *  Copyright (c) 2010-2011 Mael mael@le-guevel.com
57 *                All Rights Reserved
58 *
59 *  This library is free software. It comes without any warranty, to
60 *  the extent permitted by applicable law. You can redistribute it
61 *  and/or modify it under the terms of the Do What The Fuck You Want
62 *  To Public License, Version 2, as published by Sam Hocevar. See
63 *  http://sam.zoy.org/wtfpl/COPYING for more details.
64 */
65/**
66
67 * @author mael
68 *
69 */
70public class Tools {
71    /**
72     * Logger
73     */
74    private static final Logger LOG = LoggerFactory.getLogger(CategoryServiceImpl.class);
75
76    //    /**
77    //     * Transformation of an inpustream into string.<br/>
78    //     * useful to read the result of the webservice
79    //     * @param input the stream
80    //     * @return the string
81    //     * @throws IOException
82    //     */
83    //    public static String readInputStreamAsString(InputStream input) throws IOException {
84    //  StringWriter writer = new StringWriter();
85    //  InputStreamReader streamReader = new InputStreamReader(input);
86    //  BufferedReader buffer = new BufferedReader(streamReader);
87    //  String line = "";
88    //  while (null != (line = buffer.readLine())) {
89    //      writer.write(line);
90    //  }
91    //  return writer.toString();
92    //    }
93
94    /**
95     * Transformation of an inpustream into string.<br/>
96     * useful to read the result of the webservice
97     * @param input the stream
98     * @return the string
99     * @throws IOException
100     */
101    public static String readInputStreamAsString(InputStream is) throws IOException {
102        if (is != null) {
103            Writer writer = new StringWriter();
104
105            char[] buffer = new char[1024];
106            try {
107                Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
108                int n;
109                while ((n = reader.read(buffer)) != -1) {
110                    writer.write(buffer, 0, n);
111                }
112            } finally {
113                is.close();
114            }
115            return writer.toString();
116        } else {
117            return "";
118        }
119    }
120
121    /**
122     * String to document
123     * @param string the string
124     * @return the corresponding document
125     * @throws JDOMException
126     * @throws IOException
127     */
128    public static Document stringToDocument(String xmlSource) throws SAXException, ParserConfigurationException,
129            IOException {
130        LOG.debug(xmlSource);
131        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
132        DocumentBuilder builder = factory.newDocumentBuilder();
133        return builder.parse(new InputSource(new StringReader(xmlSource)));
134    }
135
136    /**
137     * Inputstream to document
138     * @param input the inputStream
139     * @return the document
140     * @throws IOException
141     * @throws ParserConfigurationException
142     * @throws SAXException
143     * @throws JDOMException
144     * @throws IOException
145     */
146    public static Document readInputStreamAsDocument(InputStream input) throws SAXException,
147            ParserConfigurationException, IOException {
148        return stringToDocument(readInputStreamAsString(input));
149    }
150
151    /**
152     * Document to string
153     * @param doc the document to transform
154     * @return the string
155     */
156    public static String documentToString(Node node) {
157        try {
158            Source source = new DOMSource(node);
159            StringWriter stringWriter = new StringWriter();
160            Result result = new StreamResult(stringWriter);
161            TransformerFactory factory = TransformerFactory.newInstance();
162            Transformer transformer = factory.newTransformer();
163            transformer.transform(source, result);
164            return stringWriter.getBuffer().toString();
165        } catch (TransformerConfigurationException e) {
166            e.printStackTrace();
167        } catch (TransformerException e) {
168            e.printStackTrace();
169        }
170        return null;
171    }
172
173    /**
174     * Function that gets the url of a file
175     * Useful to get the images that are in the jar
176     * @param fileName the path of the file
177     * @return the url of the file
178     */
179    public static URL getURL(String fileName) {
180        URLClassLoader urlLoader = (URLClassLoader) Tools.class.getClassLoader();
181        URL fileLocation = urlLoader.findResource(fileName);
182        return fileLocation;
183    }
184
185    /**
186     * gets the md5 sum of a file
187     * @param filename the path of the file
188     * @return the checksum
189     * @throws IOException
190     * @throws NoSuchAlgorithmException
191     * @throws Exception
192     */
193    public static String getMD5Checksum(String filename) throws NoSuchAlgorithmException, IOException {
194        byte[] b = createChecksum(filename);
195        String result = "";
196        for (int i = 0; i < b.length; i++) {
197            result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
198        }
199        return result;
200    }
201
202    /**
203     * Creation of the checksum of a file
204     * @param filename the path of the file
205     * @return the checksum as array byte
206     * @throws NoSuchAlgorithmException
207     * @throws IOException
208     * @throws Exception
209     */
210    private static byte[] createChecksum(String filename) throws NoSuchAlgorithmException, IOException {
211        InputStream fis = new FileInputStream(filename);
212
213        byte[] buffer = new byte[1024];
214        MessageDigest complete = MessageDigest.getInstance("MD5");
215        int numRead;
216        do {
217            numRead = fis.read(buffer);
218            if (numRead > 0) {
219                complete.update(buffer, 0, numRead);
220            }
221        } while (numRead != -1);
222        fis.close();
223        return complete.digest();
224    }
225
226    /**
227     * File to array bytes
228     * @param file the file
229     * @return the array bytes
230     * @throws IOException
231     */
232    public static byte[] getBytesFromFile(File file) throws IOException {
233        InputStream is = new FileInputStream(file);
234        long length = file.length();
235
236        byte[] bytes = new byte[(int) length];
237        int offset = 0;
238        int numRead = 0;
239        while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
240            offset += numRead;
241        }
242
243        if (offset < bytes.length) {
244            throw new IOException("Could not completely read file " + file.getName());
245        }
246        is.close();
247        return bytes;
248    }
249
250    /**
251     * Function that checks if the webservice response is ok
252     * @param doc the document from the webservice
253     * @return true if ok
254     */
255    public static boolean checkOk(Document doc) throws FileAlreadyExistsException {
256        if (doc.getDocumentElement().getAttribute("stat").equals("ok")) {
257            return true;
258        } else {
259            LOG.error("Resultat : " + doc.getDocumentElement().getAttribute("stat") + "\nDocument retourne : \n"
260                    + Tools.documentToString(doc));
261            if (((Element) doc.getDocumentElement().getElementsByTagName("err").item(0)).getAttribute("msg").equals(
262                    "file already exists")) {
263                throw new FileAlreadyExistsException("The file already exists on the server");
264            }
265            return false;
266        }
267
268    }
269
270    /**
271     * Exception to string
272     * @param aThrowable exception
273     * @return l'exception en string
274     */
275    public static String getStackTrace(Throwable aThrowable) {
276        final Writer result = new StringWriter();
277        final PrintWriter printWriter = new PrintWriter(result);
278        aThrowable.printStackTrace(printWriter);
279        return result.toString();
280    }
281
282    /**
283     * Function that splits a file
284     * @param fichier the file to split
285     * @param size the size of the resulting chunks
286     * @return the list of files
287     * @throws IOException
288     */
289    //feature:0001827
290    public static ArrayList<File> splitFile(File fichier, int size) throws IOException {
291        FileInputStream fis = new FileInputStream(fichier);
292        byte buffer[] = new byte[size];
293        ArrayList<File> listFichiers = new ArrayList<File>();
294        int count = 0;
295        while (true) {
296            int i = fis.read(buffer, 0, size);
297            if (i == -1)
298                break;
299            File file = new File(System.getProperty("java.io.tmpdir") + "/tempcut" + count);
300            listFichiers.add(file);
301            FileOutputStream fos = new FileOutputStream(file);
302            fos.write(buffer, 0, i);
303            fos.flush();
304            fos.close();
305
306            ++count;
307        }
308        return listFichiers;
309    }
310
311    /**
312     * Function used to put the exif and iptc metadata from one image to another
313     * @param enriched original image where the metadata comes from
314     * @param naked image where to put metadata
315     * @return enriched image
316     * @throws Exception
317     */
318    public static byte[] enrich(byte[] enriched, byte[] naked) throws Exception {
319
320        // read IPTC metadata from the original enriched image
321        IImageMetadata metadata = Sanselan.getMetadata(enriched);
322        JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
323        JpegPhotoshopMetadata photoshopMetadata = jpegMetadata.getPhotoshop();
324        if (photoshopMetadata == null) {
325            return naked;
326        }
327
328        PhotoshopApp13Data data = photoshopMetadata.photoshopApp13Data;
329
330        // read the EXIF metadata from the parsed JPEG metadata
331        TiffOutputSet outputSet = jpegMetadata.getExif().getOutputSet();
332
333        // enrich the naked byte[] with EXIF metadata
334        ExifRewriter writer = new ExifRewriter();
335        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
336        writer.updateExifMetadataLossless(naked, outputStream, outputSet);
337
338        // enrich the partially clothed byte[] with IPTC metadata
339        InputStream src = new ByteArrayInputStream(outputStream.toByteArray());
340        ByteArrayOutputStream dest = new ByteArrayOutputStream();
341        new JpegIptcRewriter().writeIPTC(src, dest, data);
342
343        // return the fully clothed image as a byte[]
344        return dest.toByteArray();
345    }
346
347    /**
348     * Bytes to file
349     * @param fichier the file path
350     * @param bytes the array bytes
351     * @throws IOException
352     */
353    public static void byteToFile(String fichier, byte[] bytes) throws IOException {
354        FileOutputStream fos = new FileOutputStream(fichier);
355        fos.write(bytes);
356        fos.flush();
357        fos.close();
358
359    }
360
361    public static Document readFileAsDocument(String filePath) {
362        Document doc = null;
363        try {
364            DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
365            DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
366            doc = docBuilder.parse(filePath);
367        } catch (Exception e) {
368            LOG.error("Error converting file to Document : " + getStackTrace(e));
369        }
370        return doc;
371    }
372
373    /**
374     * Gets the value of a document node
375     * @param element
376     * @param tagName
377     * @return
378     */
379    public static String getStringValueDom(Element element, String tagName) {
380        Element el = (Element) element.getElementsByTagName(tagName).item(0);
381        if (el != null) {
382            return el.getFirstChild().getNodeValue();
383        }
384        // if not, empty string is safer then null
385        return "";
386    }
387
388    /**
389     * Sets the value of a document node
390     * @param element
391     * @param tagName
392     * @param value
393     */
394    public static void setStringValueDom(Element element, String tagName, String value) {
395        Element el = (Element) element.getElementsByTagName(tagName).item(0);
396        el.setTextContent(value);
397    }
398
399    /**
400     * Write an xml document to a file
401     * @param doc document to write
402     * @param filename file where to write the document
403     */
404    public static void writeXmlFile(Document doc, String filename) {
405        try {
406            Source source = new DOMSource(doc);
407            File file = new File(filename);
408            Result result = new StreamResult(file);
409            Transformer xformer = TransformerFactory.newInstance().newTransformer();
410            xformer.transform(source, result);
411        } catch (TransformerConfigurationException e) {
412            LOG.error(getStackTrace(e));
413        } catch (TransformerException e) {
414            LOG.error(getStackTrace(e));
415        }
416    }
417    //
418    //    /**
419    //     * Function used to get the md5 sum of a file
420    //     * @param fileToTest the file
421    //     * @return the md5 sum
422    //     * @throws NoSuchAlgorithmException
423    //     * @throws FileNotFoundException
424    //     * @throws JiwigoException
425    //     */
426    //    public static String getMD5Sum(File file) throws NoSuchAlgorithmException, JiwigoException, FileNotFoundException {
427    //  MessageDigest digest = MessageDigest.getInstance("MD5");
428    //  InputStream is = new FileInputStream(file);
429    //  byte[] buffer = new byte[8192];
430    //  int read = 0;
431    //  try {
432    //      while ((read = is.read(buffer)) > 0) {
433    //          digest.update(buffer, 0, read);
434    //      }
435    //      byte[] md5sum = digest.digest();
436    //      BigInteger bigInt = new BigInteger(1, md5sum);
437    //      String output = bigInt.toString(16);
438    //      return output;
439    //  } catch (IOException e) {
440    //      throw new JiwigoException("Unable to process file for MD5", e);
441    //  } finally {
442    //      try {
443    //          is.close();
444    //      } catch (IOException e) {
445    //          throw new JiwigoException("Unable to close input stream for MD5 calculation", e);
446    //      }
447    //  }
448    //    }
449
450}
Note: See TracBrowser for help on using the repository browser.