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 }