001    /*
002     * $RCSfile: StarCatalog.java,v $
003     *
004     * Created on August 19, 2002, 4:29 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    package gov.bnl.star.offline.scheduler.catalog;
024    
025    import java.io.BufferedReader;
026    import java.io.InputStreamReader;
027    import java.io.Reader;
028    
029    import java.util.*;
030    import java.util.logging.Level;
031    import org.apache.log4j.Logger;
032    
033    import gov.bnl.star.offline.scheduler.util.CSHCommandLineTask; //for testing 
034    
035    
036    /** @deprecated please see gov.bnl.star.offline.scheduler.dataset.* for replacements.
037     * 
038     * This class is able to execute file catalog queries on the STAR file catalog
039     * implementation.
040     *
041     * @author  Gabriele Carcassi
042     * @version $Revision: 1.20 $ $Date: 2006/11/21 00:41:31 $
043     */
044    public class StarCatalog extends FileCatalog {
045        static private Logger log = Logger.getLogger(StarCatalog.class.getName());
046    
047        private static List executeCommand(String commandLine, List attributeNames) {
048            
049            
050            log.info("Executing : " + commandLine);
051    
052            try {
053                
054                
055                //This code caused more problems then it has solved. The ,<,>,|| don"t work when it is used.
056                //This code replaces the code commented out below. The changes where needed because the code below does not allow the user to use " " in there code.  
057                //CSHCommandLineTask task = new CSHCommandLineTask(commandLine, true, 0);       
058                //task.execute(); //run the get_file_list.pl command 
059                //List result = parseOutput(task.getOutputReader(), attributeNames); //get the output back
060                
061               Process proc = Runtime.getRuntime().exec(commandLine);
062               List result = parseOutput(new InputStreamReader(proc.getInputStream()), attributeNames);
063               proc.waitFor();
064                
065                return result;
066            } catch (Exception e) {
067                throw new RuntimeException("Couldn't execute query: " + commandLine + "\n" + e.getMessage());
068            }
069        }
070    
071        
072        
073        
074        
075        /** Parses the output of a get_file_list.pl command.
076         * @param in the input reader with the command output
077         * @return a list of PhysicalFiles
078         */    
079        protected static List parseOutput(Reader in, List attributeNames) {
080            try {
081                List files = new ArrayList();
082                BufferedReader reader = new BufferedReader(in);
083                String line;
084    
085                while ((line = reader.readLine()) != null) {
086                    List tokens = parseOutputLine(line);
087                    PhysicalFile newFile = new PhysicalFile((String) tokens.get(0), (String) tokens.get(1),(String) tokens.get(2), (String) tokens.get(3), (String) tokens.get(4), null);
088                    for (int nAtt = 5; nAtt < tokens.size(); nAtt++) {
089                        int nName = nAtt - 5;
090                        String name = (String) attributeNames.get(nName);
091                        String token = (String) tokens.get(nAtt);
092                        // Hack to prevent garbage values: 0 for nEvents really means that
093                        // the value is not set
094                        if ("events".equals(name)) {
095                            if (!"0".equals(token)) {
096                                newFile.setAttribute(name, new Integer(token));
097                            }
098                        } else {
099                            newFile.setAttribute(name, new Integer(token));
100                        }
101                    }
102                    files.add(newFile);
103                }
104    
105                return files;
106            } catch (Exception e) {
107                log.error("Couldn't parse output of STAR catalog query", e);
108    
109                return new ArrayList();
110            }
111        }
112    
113        private static List parseOutputLine(String line) {
114            log.debug("Parsing : " + line);
115    
116            List tokens = new ArrayList();
117            StringTokenizer tokenizer = new StringTokenizer(line, ":");
118            int nToken = 0;
119            int parsedLength = 0;
120    
121            while (tokenizer.hasMoreTokens()) {
122                String token = tokenizer.nextToken();
123    
124                // If more spaces is detected, than a token was empty, and a position
125                // should be skipped.
126                if (nToken != 0) {
127                    int nWhiteSpaces = line.indexOf(token, parsedLength) -
128                        parsedLength;
129                    nToken += ((nWhiteSpaces / 2) - 1);
130                    parsedLength += nWhiteSpaces;
131                }
132    
133                // Saves the value of the token in the correct position
134                tokens.add(token);
135                parsedLength += token.length();
136                nToken++;
137            }
138    
139            return tokens;
140        }
141        private List executeQuery(String query, Integer start, Integer limit) {
142            if (CatalogManager.getAttrList() != null) {
143                return executeQuery(query, start, limit, CatalogManager.getAttrList());
144            } else {
145                return executeQuery(query, start, limit, new ArrayList());
146            }
147        }
148    
149        private List executeQuery(String query, Integer start, Integer limit, List attributeNames) {
150            // Always get the number of events
151            attributeNames.add("events");
152            
153            Iterator iter = attributeNames.iterator();
154            StringBuffer commaSeparated = new StringBuffer();
155            while (iter.hasNext()) {
156                String att = (String) iter.next();
157                commaSeparated.append(',').append(att);
158            }
159            
160            String commandLine =
161                "get_file_list.pl -keys fdid,storage,node,path,filename" + commaSeparated +" -cond " +
162                query + "";
163    
164            if (start != null) {
165                commandLine += (" -start " + start);
166            }
167    
168            if (limit != null) {
169                commandLine += (" -limit " + limit);
170            } else {
171                commandLine += (" -limit 0");
172            }
173    
174            List result = executeCommand(commandLine, attributeNames);
175            log.info("Number of files returned: " + result.size());
176    
177            return result;
178        }
179    
180        public Iterator executeQuery(String query) {
181            return executeQuery(query, null, null).iterator();
182        }
183    
184        public Iterator executeQuery(String query, int nExpectedResults) {
185            return new CatalogIterator(query, nExpectedResults);
186        }
187    
188        public Iterator executeQuery(String query, int start, int limit) {
189            return executeQuery(query, new Integer(start), new Integer(limit))
190                       .iterator();
191        }
192    
193        private class CatalogIterator implements Iterator {
194            private String query;
195            private List buffer;
196            private int nCurrentInBuffer;
197            private int nCurrentStart;
198            private int bufferSize;
199    
200            public CatalogIterator(String query, int bufferSize) {
201                this.query = query;
202                this.bufferSize = bufferSize;
203            }
204    
205            private void fetchData() {
206                buffer = executeQuery(query, new Integer(nCurrentStart),
207                        new Integer(bufferSize));
208                nCurrentInBuffer = 0;
209                nCurrentStart += bufferSize;
210            }
211    
212            public boolean hasNext() {
213                if (buffer == null) {
214                    fetchData();
215    
216                    boolean test = hasNext();
217    
218                    return test;
219                }
220    
221                if (buffer.size() == 0) {
222                    return false;
223                }
224    
225                if (nCurrentInBuffer < buffer.size()) {
226                    return true;
227                }
228    
229                fetchData();
230    
231                return hasNext();
232            }
233    
234            public Object next() {
235                if (hasNext()) {
236                    Object temp = buffer.get(nCurrentInBuffer);
237                    nCurrentInBuffer++;
238    
239                    return temp;
240                }
241    
242                throw new NoSuchElementException(
243                    "Catalog query has no more results.");
244            }
245    
246            public void remove() {
247                throw new UnsupportedOperationException(
248                    "Catalog query result don't support remove");
249            }
250        }
251    }