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

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

Adds support for method pwg.categories.delete
(allows to delete a category).

File size: 12.2 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 retourne : \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        if (el != null) {
354            return el.getFirstChild().getNodeValue();
355        }
356        // if not, empty string is safer then null
357        return "";
358    }
359
360    /**
361     * Sets the value of a document node
362     * @param element
363     * @param tagName
364     * @param value
365     */
366    public static void setStringValueDom(Element element, String tagName, String value) {
367        Element el = (Element) element.getElementsByTagName(tagName).item(0);
368        el.setNodeValue(value);
369    }
370
371    /**
372     * Write an xml document to a file
373     * @param doc document to write
374     * @param filename file where to write the document
375     */
376    public static void writeXmlFile(Document doc, String filename) {
377        try {
378            Source source = new DOMSource(doc);
379            File file = new File(filename);
380            Result result = new StreamResult(file);
381            Transformer xformer = TransformerFactory.newInstance().newTransformer();
382            xformer.transform(source, result);
383        } catch (TransformerConfigurationException e) {
384            LOG.error(getStackTrace(e));
385        } catch (TransformerException e) {
386            LOG.error(getStackTrace(e));
387        }
388    }
389}
Note: See TracBrowser for help on using the repository browser.