1/**
2 * Copyright (c) 2004-2011 QOS.ch
3 * All rights reserved.
4 *
5 * Permission is hereby granted, free  of charge, to any person obtaining
6 * a  copy  of this  software  and  associated  documentation files  (the
7 * "Software"), to  deal in  the Software without  restriction, including
8 * without limitation  the rights to  use, copy, modify,  merge, publish,
9 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
10 * permit persons to whom the Software  is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The  above  copyright  notice  and  this permission  notice  shall  be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
17 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
18 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25package org.slf4j.migrator;
26
27import java.io.BufferedReader;
28import java.io.ByteArrayInputStream;
29import java.io.ByteArrayOutputStream;
30import java.io.File;
31import java.io.FileInputStream;
32import java.io.FileOutputStream;
33import java.io.IOException;
34import java.io.InputStreamReader;
35import java.io.OutputStream;
36import java.io.Reader;
37
38import org.slf4j.migrator.internal.ProgressListener;
39import org.slf4j.migrator.line.LineConverter;
40import org.slf4j.migrator.line.RuleSet;
41
42public class InplaceFileConverter {
43
44    final static int BUFFER_LEN = 8 * 1024;
45    final LineConverter lineConverter;
46    final String lineTerminator;
47    final ProgressListener pl;
48
49    InplaceFileConverter(RuleSet ruleSet, ProgressListener pl) {
50        this.lineConverter = new LineConverter(ruleSet);
51        lineTerminator = System.getProperty("line.separator");
52        this.pl = pl;
53    }
54
55    private byte[] readIntoByteArray(File file) throws IOException {
56        FileInputStream fis = new FileInputStream(file);
57        ByteArrayOutputStream baos = new ByteArrayOutputStream();
58        int n = 0;
59        byte[] buffer = new byte[BUFFER_LEN];
60        while ((n = fis.read(buffer)) != -1) {
61            // System.out.println("ba="+new String(buffer, "UTF-8"));
62            baos.write(buffer, 0, n);
63        }
64        fis.close();
65        return baos.toByteArray();
66    }
67
68    void convert(File file) throws IOException {
69        byte[] originalBytes = readIntoByteArray(file);
70        byte[] convertedBytes = convertIntoTempByteArray(originalBytes);
71        if (lineConverter.atLeastOneMatchOccured()) {
72            // System.out.println("Converting ["+file+"]");
73            writeConvertedBytesIntoFile(file, convertedBytes);
74            pl.onInplaceConversion(file);
75        } else {
76            // System.out.println("Not touching ["+file+"]");
77        }
78    }
79
80    private void writeConvertedBytesIntoFile(File file, byte[] convertedBytes) throws IOException {
81        FileOutputStream fos = new FileOutputStream(file);
82        fos.write(convertedBytes);
83        fos.flush();
84        fos.close();
85    }
86
87    private byte[] convertIntoTempByteArray(byte[] input) throws IOException {
88        ByteArrayInputStream bais = new ByteArrayInputStream(input);
89        Reader reader = new InputStreamReader(bais);
90        BufferedReader breader = new BufferedReader(reader);
91        ByteArrayOutputStream baos = new ByteArrayOutputStream();
92        while (true) {
93            String line = breader.readLine();
94            if (line != null) {
95                String[] replacement = lineConverter.getReplacement(line);
96                writeReplacement(baos, replacement);
97            } else {
98                break;
99            }
100        }
101        return baos.toByteArray();
102    }
103
104    private void writeReplacement(OutputStream os, String[] replacement) throws IOException {
105        for (int i = 0; i < replacement.length; i++) {
106            os.write(replacement[i].getBytes());
107            os.write(lineTerminator.getBytes());
108        }
109    }
110}
111