package simulator.workload.reader.archive; import java.io.IOException; import java.io.RandomAccessFile; import java.util.HashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import simulator.workload.exceptons.NoSuchCommentException; import simulator.workload.reader.archive.gwf.GWFParser; import simulator.workload.reader.archive.swf.SWFParser; /** * * @author Marcin Krystek * */ public abstract class AbstractWAParser extends RandomAccessFile implements WAParser { private Log log = LogFactory.getLog(AbstractWAParser.class); private static final long serialVersionUID = 1L; private String fileName; protected String COMMENT = ";"; protected String FIELD_SEPARATOR = "\\s"; //white spaces protected HashMap comments; protected HashMap idMapping; // key - swf job id, value - value[0] xml job id, value[1] xml task id protected HashMap reverseIdMapping; // key - xmlJobId_xmlTaskId, value - swf job id protected HashMap jobIndex; protected String fields[]; protected int fieldsNo; protected boolean headerLoaded; protected boolean buildIndex; public AbstractWAParser(String fileName) throws IOException, NullPointerException{ super(fileName, "r"); this.fileName = fileName; this.comments = new HashMap(); this.idMapping = new HashMap(); this.reverseIdMapping = new HashMap(); this.jobIndex = new HashMap(); this.headerLoaded = false; this.buildIndex = true; this.fieldsNo = 18; } /** * Reads one task description and returns all fields in table. * Skips comments lines, so you can mix task description with comments. */ public String[] readTask() throws IOException { String line = null; fields = null; while((line = readLine()) != null){ line = line.trim(); if(line.length() == 0 || line.startsWith(COMMENT)){ continue; } else{ fields = line.split(FIELD_SEPARATOR+"+"); if(fields == null || fields.length != fieldsNo) throw new IOException("Some data fields are missing."); else break; } } return fields; } public String[] readTask(String jobID, String taskId) throws IOException{ String key = jobID+"_"+taskId; String swfJobId; if(reverseIdMapping.containsKey(key)){ swfJobId = reverseIdMapping.get(key); } else { swfJobId = jobID; } return readTask(swfJobId); } public String getCommentValue(String label) throws NoSuchCommentException { if(!comments.containsKey(label)) throw new NoSuchCommentException("No comment value for "+label); return comments.get(label); } public String getDataField(int field) throws NoSuchFieldException { if(field >= fields.length) throw new NoSuchFieldException("No such field."); return fields[field]; } /** * Reads all comments that have appropriate format and place them in HashMap. * Builds job index - decision depends on value of buildIndex variable. */ public HashMap loadHeader() throws IOException { String line = null; String label = null; String value = null; int idx = -1; // default speed for processing unit in millions of instructions. comments.put(WAFields.COMMENT_PUSPEED, "1"); long position = 0; while((position = super.getFilePointer()) != -1 && (line = readLine()) != null){ line = line.trim(); if(!line.startsWith(COMMENT)){ if(buildIndex){ buildIdx(line, position); } continue; } idx = line.indexOf(":"); if(idx == -1) continue; label = line.substring(1, idx); label = label.trim(); if(idx + 1 > line.length()) throw new IOException("No value for comment: "+label); value = line.substring(idx + 1, line.length()); value = value.trim(); if(label.equals(WAFields.COMMENT_NOTE) && comments.containsKey(label)){ value = comments.get(label)+"; "+value; } else if(label.equals(WAFields.COMMENT_IDMAPPING)){ loadIDMapping(); continue; } comments.put(label, value); } reset(); headerLoaded = true; return comments; } protected void loadIDMapping() throws IOException{ String line = null; while((line = readLine()) != null){ line = line.trim(); if(!line.startsWith(COMMENT)) continue; line = line.substring(1).trim(); // to cut beginning ';' if(line.startsWith(WAFields.COMMENT_IDMAPPING+": end")) break; String idsInLine[] = line.split(","); String third = null; String ids[] = null; for(int i = 0; i < idsInLine.length; i++){ third = idsInLine[i]; ids = third.split(":"); if(ids.length < 3){ if(ids.length != 1) if(log.isWarnEnabled()) log.warn(third + " is not complete. Use swfJobId:xmlJobId:xmlTaskId"); continue; } String key = ids[0].trim(); String value[] = new String[2]; value[0] = ids[1].trim(); // job id value[1] = ids[2].trim(); // task id idMapping.put(key, value); reverseIdMapping.put(value[0]+"_"+value[1], key); } } } /** * Sets comment sign. Default is ';'. */ public String setCommentSign(String comment) { String oldComment = this.COMMENT; this.COMMENT = comment; return oldComment; } /** * Sets data fields separator. Default is tab (\t). */ public String setFieldSeparator(String fieldSeparator) { String oldSeparator = this.FIELD_SEPARATOR; this.FIELD_SEPARATOR = fieldSeparator; return oldSeparator; } /** * Decide if task position index should be build. It is very useful * and significantly speedup * @return previous value */ public boolean buildIndex(boolean build){ boolean old = this.buildIndex; this.buildIndex = build; return old; } public void close() throws IOException { super.close(); this.comments.clear(); this.comments = null; this.idMapping.clear(); this.idMapping = null; this.reverseIdMapping.clear(); this.reverseIdMapping = null; this.jobIndex.clear(); this.jobIndex = null; } /** * Puts file pointer to the beginning of file. */ public void reset() throws IOException { super.seek(0); } public boolean isHeaderLoaded() { return headerLoaded; } public HashMap getIDMapping(){ return this.idMapping; } public String[] getIDMapping(String waID) { if(idMapping.containsKey(waID)){ return this.idMapping.get(waID); } else { // if mapping for job is not provided, then we assume that xmlJobId, xmlTaskId, swfJobId are equal. String tab[] = {waID, waID}; return tab; } } public String getFileName(){ return this.fileName; } protected abstract void buildIdx(String line, long position); public static WAParser getInstance(String fileName){ String name = fileName.trim().toLowerCase(); try { if(name.endsWith("swf")){ return new SWFParser(fileName); } else if(name.endsWith("gwf")){ return new GWFParser(fileName); } } catch(Exception e){ e.printStackTrace(); } return null; } }