001    /*
002     * Dataset.java
003     *
004     * Created on June 29, 2006, 7:05 PM
005     *
006     * This file is part of the STAR Scheduler.
007     * Copyright (c) 2002-2006 STAR Collaboration - Brookhaven National Laboratory
008     *
009     * STAR Scheduler is free software; you can redistribute it and/or modify
010     * it under the terms of the GNU General Public License as published by
011     * the Free Software Foundation; either version 2 of the License, or
012     * (at your option) any later version.
013     *
014     * STAR Scheduler is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017     * GNU General Public License for more details.
018     *
019     * You should have received a copy of the GNU General Public License
020     * along with STAR Scheduler; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022     */
023    
024    package gov.bnl.star.offline.scheduler.dataset;
025    
026    import java.io.BufferedReader;
027    import java.io.FileNotFoundException;
028    import java.io.FileReader;
029    import java.util.ArrayList;
030    import java.util.Hashtable;
031    import java.util.List;
032    import org.apache.log4j.Logger;
033    import java.io.BufferedWriter;
034    import java.io.File;
035    import gov.bnl.star.offline.scheduler.dataset.Dataset;
036    import java.io.FileWriter;
037    import java.io.IOException;
038    import org.apache.log4j.Logger;
039    
040    /**
041     * This class represents the dataset. Through this class the .dataset file on hard-disk can be accessed and manipulate.   
042     * @author Levente B. Hajdu
043     */
044    public class Dataset {
045        
046        static public Logger log = Logger.getLogger(Dataset.class.getName());
047        
048        private String datasetName = null;
049        private String datasetFileBufferName = null; 
050        
051        /** Creates a new instance of Dataset */
052        public Dataset(String datasetName) { 
053            setDatasetName(datasetName); 
054            openBuffer();
055        }
056        
057        /** !!! This constructor should not be used, use Dataset(String datasetName)  !!! */
058        public Dataset() { }
059        
060        public void setDatasetName(String datasetName){
061            //Used to test if the dataset name is valid
062            if(datasetName == null) throw new RuntimeException("Error tryed to make dataset with null name"); 
063            if(datasetName.equals(""))throw new RuntimeException("Error tryed to make dataset with \"\" name"); 
064            if(! datasetName.matches(".*\\.dataset")) datasetName = datasetName + ".dataset"; // add ".dataset" to the back of the file if it is not already there
065            this.datasetName = datasetName; 
066            this.datasetFileBufferName = datasetName + ".tmp"; //The makes the temp name the same as the true dataset name but with a "~" at the end
067        } 
068        
069        public String getDatasetName(){ return this.datasetName; }
070        public String getDatasetFileBufferName(){return this.datasetFileBufferName;}
071        
072        
073        private int datasetSize = 0;
074        public void incrementSize(){datasetSize ++; }
075        public void decrementSize(){datasetSize --; }
076        public int getDatasetSize(){return datasetSize; }
077        public void setDatasetSize(int datasetSize){this.datasetSize = datasetSize;}
078        
079        
080    //////////////////////////////////////////// Dataset I/O functions ////////////////////////////////////////////
081        
082        
083          /**Ater a data set has been copyed from "bla.dataset" to "bla.data~" this function will delete "bla.dataset" and rename "bla.dataset~" to "bla.dataset".
084         * note: Fill in "bla" for the the name of the dataset 
085        */    
086        public void swap_buffer_dataset_with_dataset(){
087            log.debug("Rolling over dataset file buffer");
088            
089            ////////////////////delete the old file///////////////////////
090            deleteDataset();
091            
092            ////////////////////rename the new file///////////////////////
093            log.debug("renaming new dataset file file");
094            File oldfile = new File(this.getDatasetName()); 
095            boolean success = oldfile.delete();
096            File file = new File(this.getDatasetFileBufferName()); // File (or directory) with old name
097            // Rename file
098            success = file.renameTo(new File(this.getDatasetName()));
099            if (! success) {
100                // File was not successfully renamed
101                String error = "There was an error renaming the dataset.  Could not renaming file : \"" + ((this.getDatasetFileBufferName() != null)?this.getDatasetFileBufferName():" null " ) + "\" to \"" + ((this.getDatasetName() != null)?this.getDatasetName():" null " ) + "\"";
102                log.fatal(error);
103                throw new RuntimeException(error);   
104                
105            }
106            openBuffer();
107        }
108        
109        
110        public void deleteDataset(){
111            closeBuffer();
112                    
113            ////////////////////delete the old dataset file///////////////////////
114            log.debug("deleting the old file");
115            File oldfile = new File(this.getDatasetName());  
116            boolean success = oldfile.delete();
117            if (! success) { //If the file can not be deleted, SUMS must holt because the dataset can net be modifyed
118                String error = "Could not swap the dataset file, becuase the old file can not be deleted: " + "\ncould not delete file : \"" + ((this.getDatasetName() != null)?this.getDatasetName():" null " ) + " \"\n";
119                log.fatal(error);
120                throw new RuntimeException(error);   
121            }
122            
123        }
124        
125        
126        public void deleteBuffer(){
127            closeBuffer();
128                    
129            ////////////////////delete the old dataset file///////////////////////
130            log.debug("deleting the old file");
131            File oldfile = new File(this.getDatasetFileBufferName() );  
132            boolean success = oldfile.delete();
133            if (! success) { //If the file can not be deleted, SUMS must holt because the dataset can net be modifyed
134                String error = "Could not swap the dataset file, becuase the old file can not be deleted: " + "\ncould not delete file : \"" + ((this.getDatasetName() != null)?this.getDatasetName():" null " ) + " \"\n";
135                log.fatal(error);
136                throw new RuntimeException(error);   
137            }
138            
139        }
140        
141        
142    
143    ////////////////////////////////////////////file buffer io functions///////////////////////////////
144        private BufferedWriter datasetBuffer = null;
145        
146        
147         /** Close the file srteam to the buffer file */  
148         public void closeBuffer(){
149             
150             if(datasetBuffer == null){
151                 System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>> the datasetBuffer is null");
152                 return;
153             }
154             
155           log.debug("Closing dataset file buffer");
156            try {
157                datasetBuffer.flush();
158                datasetBuffer.close();
159                datasetBuffer = null;
160            } catch (IOException ex) {
161                ex.printStackTrace();
162                log.fatal("Could not close the dataset buffer file" + this.getDatasetFileBufferName());
163                throw new RuntimeException("Could not close the dataset buffer file" + this.getDatasetFileBufferName());   
164            }
165         } 
166        
167        
168        /**Open the file srteam to write to the buffer file*/
169        public void openBuffer(){
170            log.debug("Openning dataset file buffer");
171             try {
172                    datasetBuffer = new BufferedWriter(new FileWriter(this.getDatasetFileBufferName()));
173                } catch (IOException e) {
174                    e.printStackTrace();
175                    log.fatal("Could not write to the dataset buffer file" + this.getDatasetFileBufferName());
176                    throw new RuntimeException("Could not write to the dataset buffer file" + this.getDatasetFileBufferName());   
177                } 
178        }
179        
180        
181        /**Open file file stream if it is not already open. Print a line to the buffer file*/
182        public void writeToBuffer(String line){
183            if(datasetBuffer == null) openBuffer();
184            try {
185                datasetBuffer.write(line + '\n');
186                 datasetBuffer.flush();
187            } catch (IOException ex) {
188                ex.printStackTrace();
189                log.fatal("(error -1) Could not write to the dataset buffer file" + this.getDatasetFileBufferName());
190                throw new RuntimeException("(error -1) Could not write to the dataset buffer file" + this.getDatasetFileBufferName());    
191            }   
192        }
193        
194        
195        
196        
197        
198        //////////////////////////////////////// splits in datasets /////////////////////////////////
199        
200        
201        //note in order for this to be changed it will need to be set in the config file somewhere 
202        private String splitRegX = ":::::::::::::::::::::::::::::::::::::::::::::::::::::::";
203        /** gets the regX that matchs a split but notting else */
204        public String getSplitRegX(){return this.splitRegX;}
205        /** sets the regX that matchs a split but notting else */
206        public void setSplitRegX(String splitRegX){this.splitRegX = splitRegX;}
207        
208        //note in order for this to be changed it will need to be set in the config file somewhere 
209        private String splitString = ":::::::::::::::::::::::::::::::::::::::::::::::::::::::";
210        /** gets the split string */
211        public String getSplitString(){return this.splitString;}
212        /** sets the split string */
213        public void setSplitString(String splitString){this.splitString = splitString;}
214        
215        
216        //////////////////////////////////
217        
218        
219        private EntryParser entryParser;
220        public void setEntryParser(EntryParser entryParser){ this.entryParser = entryParser;}
221        public EntryParser getEntryParser(){return this.entryParser;} 
222        
223    
224        
225        
226        /**Returns the number of subsets in the list.*/
227        public int subsetIndexSize(){
228            
229            int size = 0;
230            try {
231                
232                BufferedReader currentDataset = new BufferedReader( new FileReader(this.getDatasetName() ));
233                String datsetEntry;
234                while ((datsetEntry = currentDataset.readLine()) != null) {
235                    if(datsetEntry.matches(this.splitRegX )) size ++;
236                }
237                
238                
239            } catch (FileNotFoundException ex) {
240                ex.printStackTrace();
241                throw new RuntimeException("The dataset file \"" + this.datasetName + "\" was lost and could not be openned");
242            } catch (IOException ex) {
243                ex.printStackTrace();
244                throw new RuntimeException("There was an error readdding from the dataset file to recover a subset.");
245            }
246            
247    
248            if(size == 0){
249                throw new RuntimeException("Error the dataset " + this.datasetName + " subsetIndexSize() function failed becuase the dataset has not been split. No splitting lines where found");
250            } 
251             
252            return (size - 1);
253        }
254        
255        
256        
257        /** Returns a list of entry strings that is a subset of the database at a given index */
258        List getSubset(int index){
259            String datsetEntry = null;
260            int indexNow = -1;
261            List entrySubset = new ArrayList();
262            
263            try {
264                
265                BufferedReader currentDataset = new BufferedReader( new FileReader(this.getDatasetName() ));
266                while ((datsetEntry = currentDataset.readLine()) != null) {
267                    
268                    if(datsetEntry.matches(this.splitRegX )){
269                        indexNow ++;
270                        if(indexNow ==  index){
271                            currentDataset.close();
272                            return entrySubset;
273                        }
274                    }
275                    else if(indexNow == (index - 1)) entrySubset.add(datsetEntry);
276                    
277                    
278                }
279                currentDataset.close();
280                return entrySubset;
281       
282            } catch (FileNotFoundException ex) {
283                ex.printStackTrace();
284                throw new RuntimeException("The dataset was lost and could not be openned");
285            } catch (IOException ex) {
286                ex.printStackTrace();
287                throw new RuntimeException("There was an error readdding from the dataset file to recover a subset.");
288            }
289            
290            
291            //throw new RuntimeException("The dataset hit EOF before the subset index =" + index + " could be hit.");
292        
293        }
294        
295        
296        
297     
298        
299          
300    }