001    /////////////////////////////////////////////////
002    // This file is part of Sears project.
003    // Subtitle Editor And Re-Synch
004    // A tool to easily modify and resynch movies subtitles.
005    /////////////////////////////////////////////////
006    //This program is free software; 
007    //you can redistribute it and/or modify it under the terms 
008    //of the GNU General Public License 
009    //as published by the Free Software Foundation; 
010    //either version 2 of the License, or (at your option) any later version.
011    /////////////////////////////////////////////////
012    //Sears project is available under sourceforge
013    // at adress: http://sourceforge.net/projects/sears/
014    //Copyright (C) 2005 Booba Skaya
015    //Mail: booba.skaya@gmail.com
016    ////////////////////////////////////////////////
017    package sears.file;
018    
019    import java.io.BufferedReader;
020    import java.io.BufferedWriter;
021    import java.io.File;
022    import java.io.FileInputStream;
023    import java.io.FileOutputStream;
024    import java.io.IOException;
025    import java.io.InputStreamReader;
026    import java.io.OutputStreamWriter;
027    import java.util.ArrayList;
028    import java.util.Iterator;
029    import java.util.StringTokenizer;
030    import sears.tools.SearsProperties;
031    import sears.tools.Trace;
032    
033    /**
034     * Class SrtFile.
035     * <br><b>Summary:</b><br>
036     * This class represent a srt subtitle file.
037     * Specialize the SubtitleFile for srt type subtitles.
038     */
039    public class SrtFile extends SubtitleFile {
040    
041        /**
042         * Constructor SrtFile.
043         * <br><b>Summary:</b><br>
044         * Constructor of the class.
045         * Beware not to use this file directly, because it does contains no ST.
046         * You will have to fill the list of ST, and save the File first.
047         */
048    
049        public SrtFile(){
050            super();
051        }
052        
053        /**
054         * Constructor SrtFile.
055         * <br><b>Summary:</b><br>
056         * Constructor of the class.
057         * @param file            The <b>(File)</b> to open.
058         * @param subtitleList        The <b>(ArrayList)</b> List of subtitles.
059         */
060        public SrtFile(File file, ArrayList<Subtitle> subtitleList) {
061            super(file, subtitleList);
062        }
063    
064        /**
065         * Constructor SrtFile.
066         * <br><b>Summary:</b><br>
067         * Constructor of the class.
068         * @param file                The <b>(String)</b> path to file to open.
069         * @param subtitleList        The <b>(ArrayList)</b> List of subtitles.
070         */
071        public SrtFile(String file, ArrayList<Subtitle> subtitleList) {
072            super(file, subtitleList);
073        }
074    
075        /* (non-Javadoc)
076         * @see sears.file.SubtitleFile#parse()
077         */
078        protected void parse() {
079            {
080                try {
081                    //Using charset ISO8859_1, for linux sytem to read correctly windows accents.
082                    BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "ISO8859_1"));
083                    String str;
084                    while ((str = in.readLine()) != null) {
085                        if (str.trim().length() != 0) {
086                            StringTokenizer stk = new StringTokenizer(str);
087                            if (stk.countTokens() == 1) {
088                                Trace.trace("Find a new subtitle.", Trace.ALGO_PRIORITY);
089                                int numberFound = Integer.parseInt(stk.nextToken());
090                                Trace.trace("Number: " + numberFound, Trace.ALGO_PRIORITY);
091                                str = in.readLine();
092                                stk = new StringTokenizer(str, "-> ");
093                                int startDate = stringToTime(stk.nextToken());
094                                int endDate = stringToTime(stk.nextToken());
095                                String subtitle = "";
096                                //First is to read till we found a subtitle, to avoid error in files with an empty line
097                                //after the time definition.
098                                str = in.readLine();
099                                while(str != null && str.equals("")){
100                                    str = in.readLine();
101                                }
102                                //here we have found a subtitle, or reached end of file.
103                                if (str != null && !str.equals("")) {
104                                    //add the first subtitle line
105                                    subtitle += (String) str + END_OF_LINE;
106                                    //and read the rest of the subtitle.
107                                                                    for (str = in.readLine(); str != null && !str.equals(""); str = in.readLine()) {
108                                                                            subtitle += (String) str + END_OF_LINE;
109                                                                    }
110                                                                    Trace.trace("Subtitle :"+END_OF_LINE + subtitle, Trace.ALGO_PRIORITY);
111                                                                    Subtitle newSubtitle = new Subtitle(numberFound, startDate, endDate, subtitle);
112                                                                    subtitleList.add(newSubtitle);
113                                                            }
114                            }
115                        }
116                    }
117                    in.close();
118                } catch (IOException e) {
119                    Trace.trace("Parsing Error occured !", Trace.ERROR_PRIORITY);
120                    Trace.trace(e.getMessage(), Trace.ERROR_PRIORITY);
121                }
122            }
123        }
124    
125    
126    
127        /* (non-Javadoc)
128         * @see sears.file.SubtitleFile#writeToFile(java.io.File)
129         */
130        public void writeToFile(File fileToWrite) {
131            {
132                //First is to know which end of line to use.
133                //by default use the linux one.
134                String endOfLine = System.getProperty("line.separator");
135                if(!SearsProperties.getProperty(SearsProperties.DOS_LINE_SEPARATOR, "0").equals("0")){
136                    //If need to use a DOS end of line, use it.
137                    endOfLine = "\r\n";
138                }
139                try {
140                    //Using charset ISO8859_1, for linux sytem to write correctly windows accents.
141                    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileToWrite), "ISO8859_1"));
142                    Iterator subtitles = subtitleList.iterator();
143                    while (subtitles.hasNext()) {
144                        Subtitle subtitle = (Subtitle) subtitles.next();
145                        out.write(subtitle.getNumber() + endOfLine);
146                        out.write(timeToString(subtitle.getStartDate()) + " --> " + timeToString(subtitle.getEndDate()) + endOfLine);
147                        out.write(subtitle.getSubtitle().replaceAll(END_OF_LINE, endOfLine));
148                        //Check wether subtitle has an end of line.
149                        if(!subtitle.getSubtitle().endsWith(END_OF_LINE)){
150                            //If it doesn't have one, put one.
151                            out.write(endOfLine);
152                        }
153                        out.write(endOfLine);
154                    }
155                    out.close();
156                    //indicate file is good.
157                    fileChanged = false;
158                } catch (IOException e) {
159                    Trace.trace("Error while writing SRT file !", Trace.ERROR_PRIORITY);
160                    Trace.trace(e.getMessage(), Trace.ERROR_PRIORITY);
161                }
162            }
163        }
164    
165        /* (non-Javadoc)
166         * @see sears.file.SubtitleFile#writeToFile(java.io.File)
167         */
168        public void writeToTemporaryFile() {
169                    try {
170                            // Create the temporary subtitle file
171                            if (temporaryFile == null) {
172                                    temporaryFile = java.io.File.createTempFile("SRTSubtitle", null);
173                                    temporaryFile.deleteOnExit();
174                            }
175                            // Store to the temporary file
176                            boolean oldFileChangedStatus = fileChanged;
177                            writeToFile(temporaryFile);
178                            // Restore the old file changed value
179                            fileChanged = oldFileChangedStatus;
180                    } catch (IOException e) {
181                            Trace.trace("Error while writing temporary SRT file !",
182                                            Trace.ERROR_PRIORITY);
183                            Trace.trace(e.getMessage(), Trace.ERROR_PRIORITY);
184                    }
185            }
186    
187        /* (non-Javadoc)
188         * @see sears.file.SubtitleFile#getNewInstance()
189         */
190        protected SubtitleFile getNewInstance() {
191            return new SrtFile();
192        }
193    }