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

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

Complete rewriting of the api
The api now uses interfaces everywhere (for the dao, services and session manager). This allows the developer to use his own implementations if he wants.
Deletion of the singletons. There are now getters and setters. It allows to make dependency injection.
Use of sl4j in the api, instead of using log4j.

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