001/** 002 * '$Author: welker $' 003 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 004 * '$Revision: 24234 $' 005 * 006 * For Details: 007 * http://www.kepler-project.org 008 * 009 * Copyright (c) 2009-2010 The Regents of the 010 * University of California. All rights reserved. Permission is hereby granted, 011 * without written agreement and without license or royalty fees, to use, copy, 012 * modify, and distribute this software and its documentation for any purpose, 013 * provided that the above copyright notice and the following two paragraphs 014 * appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF 015 * CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, 016 * OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS 017 * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE 018 * POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY 019 * DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 021 * SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 * ENHANCEMENTS, OR MODIFICATIONS. 024 */ 025 026package org.kepler.workflowrunmanager; 027 028import java.util.regex.Matcher; 029import java.util.regex.Pattern; 030 031public class DurationQueryParse { 032 033 // TODO looks weird/ambiguous to allow e.g. 10:5:4 034 // TODO temporarily removing single-date-without-op searches since queries 035 // haven't been written yet. 036 private String singleDurationRegEx = "\\s*((\\d*):)??(([0-5]?[0-9]):)?([0-5]?[0-9])\\s*"; 037 // String oneDurationRegEx = "\\s*"+singleDurationRegEx; 038 // Pattern oneDurationPattern = Pattern.compile(oneDurationRegEx); 039 040 private String oneDurationWithOpRegEx = "\\s*([><])\\s*" 041 + singleDurationRegEx; 042 private Pattern oneDurationWithOpPattern = Pattern 043 .compile(oneDurationWithOpRegEx); 044 045 private static final String RANGE_SEPARATOR = " - "; 046 047 // pattern for duration range. dur1 - dur2 048 private String durationRangeRegEx = singleDurationRegEx + "\\s*-\\s*" 049 + singleDurationRegEx; 050 private Pattern durationRangePattern = Pattern.compile(durationRangeRegEx); 051 052 private boolean isValid = false; 053 private boolean isRange = false; 054 private String operator = null; 055 private int numDurations = 0; 056 057 private static final String SEPARATOR = ":"; 058 private String completeText = ""; 059 060 private static final String LESS_THAN = "<"; 061 private static final String GREATER_THAN = ">"; 062 063 // we could let users specify multiple ranges with a bit more work 064 // elsewhere... 065 private static int numAllowedDurations = 2; 066 private DurationParse[] parsedDurations = new DurationParse[numAllowedDurations]; 067 068 public DurationQueryParse(String durationQuery) { 069 070 for (int i = 0; i < numAllowedDurations; i++) { 071 parsedDurations[i] = new DurationParse(); 072 } 073 074 // Matcher oneDurationMatcher = 075 // oneDurationPattern.matcher(durationQuery); 076 Matcher oneDurationWithOpMatcher = oneDurationWithOpPattern 077 .matcher(durationQuery); 078 Matcher durationRangeMatcher = durationRangePattern 079 .matcher(durationQuery); 080 081 if (durationRangeMatcher.matches()) { 082 isRange = true; 083 isValid = true; 084 085 for (int i = 0, j = 2; i < numAllowedDurations; i++, j += 5) { 086 if (durationRangeMatcher.group(j) == null 087 || durationRangeMatcher.group(j).equals("")) { 088 parsedDurations[i].setHours(0); 089 } else { 090 parsedDurations[i].setHours(Integer 091 .parseInt(durationRangeMatcher.group(j))); 092 } 093 if (durationRangeMatcher.group(j + 2) == null 094 || durationRangeMatcher.group(j + 2).equals("")) { 095 parsedDurations[i].setMins(0); 096 } else { 097 parsedDurations[i].setMins(Integer 098 .parseInt(durationRangeMatcher.group(j + 2))); 099 } 100 if (durationRangeMatcher.group(j + 3) == null 101 || durationRangeMatcher.group(j + 3).equals("")) { 102 parsedDurations[i].setSecs(0); 103 } else { 104 parsedDurations[i].setSecs(Integer 105 .parseInt(durationRangeMatcher.group(j + 3))); 106 } 107 numDurations = i + 1; 108 109 if (i % 2 == 0) { 110 completeText += parsedDurations[i].getHours() + SEPARATOR 111 + parsedDurations[i].getMins() + SEPARATOR 112 + parsedDurations[i].getSecs() + RANGE_SEPARATOR; 113 } else { 114 completeText += parsedDurations[i].getHours() + SEPARATOR 115 + parsedDurations[i].getMins() + SEPARATOR 116 + parsedDurations[i].getSecs(); 117 // comma here if we allow >1 range 118 } 119 120 } 121 122 } else if (oneDurationWithOpMatcher.matches()) { 123 isRange = false; 124 operator = oneDurationWithOpMatcher.group(1); 125 numDurations = 1; 126 isValid = true; 127 128 if (oneDurationWithOpMatcher.group(3) == null 129 || oneDurationWithOpMatcher.group(3).equals("")) { 130 parsedDurations[0].setHours(0); 131 } else { 132 parsedDurations[0].setHours(Integer 133 .parseInt(oneDurationWithOpMatcher.group(3))); 134 } 135 if (oneDurationWithOpMatcher.group(5) == null 136 || oneDurationWithOpMatcher.group(5).equals("")) { 137 parsedDurations[0].setMins(0); 138 } else { 139 parsedDurations[0].setMins(Integer 140 .parseInt(oneDurationWithOpMatcher.group(5))); 141 } 142 if (oneDurationWithOpMatcher.group(6) == null 143 || oneDurationWithOpMatcher.group(6).equals("")) { 144 parsedDurations[0].setSecs(0); 145 } else { 146 parsedDurations[0].setSecs(Integer 147 .parseInt(oneDurationWithOpMatcher.group(6))); 148 } 149 150 completeText = getOperator() + " " + parsedDurations[0].getHours() 151 + SEPARATOR + parsedDurations[0].getMins() + SEPARATOR 152 + parsedDurations[0].getSecs(); 153 } 154 /* 155 * else if (oneDurationMatcher.matches()){ durationParse.put("isRange", 156 * false); durationParse.put("numDurations", 1); 157 * durationParse.put("valid", true); 158 * 159 * parsedDurations[0] = new HashMap<String, Integer>(); if 160 * (oneDurationMatcher.group(2) == null || 161 * oneDurationMatcher.group(2).equals("")){ 162 * parsedDurations[0].put("hours", 0); } else{ 163 * parsedDurations[0].put("hours", 164 * Integer.parseInt(oneDurationMatcher.group(2))); } if 165 * (oneDurationMatcher.group(4) == null || 166 * oneDurationMatcher.group(4).equals("")){ 167 * parsedDurations[0].put("minutes", 0); } else{ 168 * parsedDurations[0].put("minutes", 169 * Integer.parseInt(oneDurationMatcher.group(4))); } if 170 * (oneDurationMatcher.group(5) == null || 171 * oneDurationMatcher.group(5).equals("")){ 172 * parsedDurations[0].put("seconds", 0); } else{ 173 * parsedDurations[0].put("seconds", 174 * Integer.parseInt(oneDurationMatcher.group(5))); } } 175 */ 176 177 } 178 179 public String getCompleteText() { 180 return completeText; 181 } 182 183 public int getTotalSecondsForDuration(int durationIndex) { 184 return parsedDurations[durationIndex].getTotalSeconds(); 185 } 186 187 public boolean isValid() { 188 return isValid; 189 } 190 191 public boolean isRange() { 192 return isRange; 193 } 194 195 public String getOperator() { 196 return operator; 197 } 198 199 public int getNumItems() { 200 return numDurations; 201 } 202 203 public boolean passesFilter(int inputDuration) { 204 if (isValid()) { 205 if (isRange()) { 206 if ((getTotalSecondsForDuration(0) <= inputDuration) 207 && (getTotalSecondsForDuration(1) >= inputDuration)) { 208 return true; 209 } 210 } else { 211 if (getOperator().equals(GREATER_THAN)) { 212 if (inputDuration > getTotalSecondsForDuration(0)) { 213 return true; 214 } 215 } else if (getOperator().equals(LESS_THAN)) { 216 if (inputDuration < getTotalSecondsForDuration(0)) { 217 return true; 218 } 219 } 220 } 221 } 222 223 return false; 224 } 225 226 private static class DurationParse { 227 228 private static final int NUM_SECONDS_IN_HOUR = 3600; 229 private static final int NUM_SECONDS_IN_MINUTE = 60; 230 231 private Integer hours = 0; 232 private String hoursString = hours.toString(); 233 private Integer minutes = 0; 234 private String minutesString = minutes.toString(); 235 private Integer seconds = 0; 236 private String secondsString = seconds.toString(); 237 private Integer totalSeconds = 0; 238 239 public DurationParse() { 240 } 241 242 public String getHours() { 243 return hoursString; 244 } 245 246 public String getMins() { 247 return minutesString; 248 } 249 250 public String getSecs() { 251 return secondsString; 252 } 253 254 public void setHours(int h) { 255 hours = h; 256 hoursString = hours.toString(); 257 if (hours < 10) { 258 hoursString = "0" + hours; 259 } 260 setTotalSeconds(); 261 } 262 263 public void setMins(int mins) { 264 minutes = mins; 265 minutesString = minutes.toString(); 266 if (minutes < 10) { 267 minutesString = "0" + minutes; 268 } 269 setTotalSeconds(); 270 } 271 272 public void setSecs(int secs) { 273 seconds = secs; 274 secondsString = seconds.toString(); 275 if (seconds < 10) { 276 secondsString = "0" + seconds; 277 } 278 setTotalSeconds(); 279 } 280 281 public void setTotalSeconds() { 282 totalSeconds = (hours * NUM_SECONDS_IN_HOUR) 283 + (minutes * NUM_SECONDS_IN_MINUTE) + seconds; 284 } 285 286 public int getTotalSeconds() { 287 return totalSeconds; 288 } 289 } 290 291}