1 37 package org.webharvest.runtime.processors; 38 39 import org.webharvest.definition.BaseElementDef; 40 import org.webharvest.definition.LoopDef; 41 import org.webharvest.runtime.Scraper; 42 import org.webharvest.runtime.ScraperContext; 43 import org.webharvest.runtime.scripting.ScriptEngine; 44 import org.webharvest.runtime.templaters.BaseTemplater; 45 import org.webharvest.runtime.variables.*; 46 import org.webharvest.utils.CommonUtil; 47 import org.webharvest.utils.Constants; 48 49 import java.util.*; 50 import java.util.regex.Matcher ; 51 import java.util.regex.Pattern ; 52 53 56 public class LoopProcessor extends BaseProcessor { 57 58 private LoopDef loopDef; 59 60 public LoopProcessor(LoopDef loopDef) { 61 super(loopDef); 62 this.loopDef = loopDef; 63 } 64 65 public IVariable execute(Scraper scraper, ScraperContext context) { 66 ScriptEngine scriptEngine = scraper.getScriptEngine(); 67 String item = BaseTemplater.execute( loopDef.getItem(), scriptEngine); 68 String index = BaseTemplater.execute( loopDef.getIndex(), scriptEngine); 69 String maxLoopsString = BaseTemplater.execute( loopDef.getMaxloops(), scriptEngine); 70 String filter = BaseTemplater.execute( loopDef.getFilter(), scriptEngine); 71 72 double maxLoops = Constants.DEFAULT_MAX_LOOPS; 73 if (maxLoopsString != null && !"".equals(maxLoopsString.trim())) { 74 maxLoops = Double.parseDouble(maxLoopsString); 75 } 76 77 BaseElementDef loopValueDef = loopDef.getLoopValueDef(); 78 IVariable loopValue = getBodyListContent(loopValueDef, scraper, context); 79 debug(loopValueDef, scraper, loopValue); 80 81 List resultList = new ArrayList(); 82 83 List list = loopValue != null ? loopValue.toList() : null; 84 if (list != null) { 85 IVariable itemBeforeLoop = (IVariable) context.get(item); 86 IVariable indexBeforeLoop = (IVariable) context.get(index); 87 88 List filteredList = filter != null ? createFilteredList(list, filter) : list; 89 Iterator it = filteredList.iterator(); 90 91 for (int i = 1; it.hasNext() && i <= maxLoops; i++) { 92 IVariable currElement = (IVariable) it.next(); 93 94 if ( item != null && !"".equals(item) ) { 96 context.put(item, currElement); 97 } 98 99 if ( index != null && !"".equals(index) ) { 101 context.put( index, new NodeVariable(String.valueOf(i)) ); 102 } 103 104 BaseElementDef bodyDef = loopDef.getLoopBodyDef(); 106 IVariable loopResult = bodyDef != null ? getBodyListContent(bodyDef, scraper, context) : new EmptyVariable(); 107 debug(bodyDef, scraper, loopResult); 108 resultList.addAll( loopResult.toList() ); 109 } 110 111 if (item != null && itemBeforeLoop != null) { 113 context.put(item, itemBeforeLoop); 114 } 115 116 if (index != null && indexBeforeLoop != null) { 118 context.put(index, indexBeforeLoop); 119 } 120 } 121 122 return new ListVariable(resultList); 123 } 124 125 131 private List createFilteredList(List list, String filterStr) { 132 List result = new ArrayList(); 133 Set stringSet = new HashSet(); 134 135 Filter filter = new Filter(filterStr, list.size()); 136 137 Iterator it = list.iterator(); 138 int index = 1; 139 while (it.hasNext()) { 140 IVariable curr = (IVariable) it.next(); 141 142 if (filter.isInFilter(index)) { 143 if (filter.isUnique) { 144 String currStr = curr.toString(); 145 if (!stringSet.contains(curr.toString())) { 146 result.add(curr); 147 stringSet.add(currStr); 148 } 149 } else { 150 result.add(curr); 151 } 152 } 153 154 index++; 155 } 156 157 return result; 158 } 159 160 164 private static class IntRange extends CommonUtil.IntPair { 165 166 static boolean isValid(String s) { 168 Pattern pattern = Pattern.compile("(\\d*)(-?)(\\d*?)"); 169 Matcher matcher = pattern.matcher(s); 170 return matcher.matches(); 171 } 172 173 private IntRange(int x, int y) { 174 super(x, y); 175 } 176 177 public IntRange(String s, int size) { 178 defineFromString(s, '-', size); 179 } 180 181 public boolean isInRange(int index) { 182 return index >= x && index <= y; 183 } 184 185 } 186 187 191 private static class IntSublist extends CommonUtil.IntPair { 192 193 static boolean isValid(String s) { 195 Pattern pattern = Pattern.compile("(\\d*)(:?)(\\d*?)"); 196 Matcher matcher = pattern.matcher(s); 197 return matcher.matches(); 198 } 199 200 private IntSublist(int x, int y) { 201 super(x, y); 202 } 203 204 public IntSublist(String s, int size) { 205 defineFromString(s, ':', size); 206 } 207 208 209 public boolean isInSublist(int index) { 210 return (index - x) % y == 0; 211 } 212 213 } 214 215 227 private static class Filter { 228 229 private boolean isUnique = false; 230 private List filterList; 231 232 private Filter(String filterStr, int size) { 233 StringTokenizer tokenizer = new StringTokenizer(filterStr, ","); 234 filterList = new ArrayList(); 235 236 while (tokenizer.hasMoreTokens()) { 237 String token = tokenizer.nextToken().trim(); 238 239 if ("unique".equals(token)) { 240 isUnique = true; 241 } else if ("odd".equals(token)) { 242 filterList.add(new IntSublist(1, 2)); 243 } else if ("even".equals(token)) { 244 filterList.add( new IntSublist(2, 2)); 245 } else if (IntRange.isValid(token)) { 246 filterList.add(new IntRange(token, size)); 247 } else if (IntSublist.isValid(token)) { 248 filterList.add(new IntSublist(token, size)); 249 } 250 } 251 } 252 253 256 private boolean isInFilter(int num) { 257 int listSize = filterList.size(); 258 259 if (listSize == 0) { 260 return true; 261 } 262 263 for (int i = 0; i < listSize; i++) { 264 CommonUtil.IntPair curr = (CommonUtil.IntPair) filterList.get(i); 265 if ( curr instanceof IntRange && ((IntRange)curr).isInRange(num) ) { 266 return true; 267 } else if ( curr instanceof IntSublist && ((IntSublist)curr).isInSublist(num) ) { 268 return true; 269 } 270 } 271 272 return false; 273 } 274 275 } 276 277 } | Popular Tags |