package eu.jucy.op; import helpers.GH; import helpers.PrefConverter; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import logger.LoggerFactory; import org.apache.log4j.Level; import org.apache.log4j.Logger; import uc.IUser; import uc.files.filelist.FileListFile; public class CounterFactory { private static final Logger logger = LoggerFactory.make(Level.DEBUG); /** * name and id for counterFactory */ private String name = ""; /** * comment.. can be used in raw.. * for reference */ private String comment = ""; /** * if the counter should be evaluated * and cleared after each file. * */ private boolean perFile = false; /** * the priority that the counter has for execution */ private int priority = 100; private final List<CounterAction> actions = new ArrayList<CounterAction>(); public static List<WorkingCounter> getWorkingCounter(List<CounterFactory> factories,IUser usr) { List<WorkingCounter> c = new ArrayList<WorkingCounter>(); for (CounterFactory f: factories) { c.add(f.getWorkingCounter(usr)); } for (WorkingCounter first: c) { for (WorkingCounter second: c) { if (first != second) { first.addWorkingCounter(second); } } } Collections.sort(c); return c; } public String[] toStringAR() { return new String[] { name, ""+perFile, ""+priority, comment, getActions() }; } public static CounterFactory fromStrinngAR(String[] ar) { CounterFactory cf = new CounterFactory(); cf.name = ar[0]; cf.perFile = Boolean.parseBoolean(ar[1]); cf.priority = Integer.parseInt(ar[2]); cf.comment = ar[3]; cf.loadActions(ar[4]); return cf; } private String getActions() { List<String> ac = new ArrayList<String>(); for (CounterAction ca: actions) { ac.add(PrefConverter.asString(ca.toStringAR(0))); } return PrefConverter.asString(ac.toArray(new String[]{})); } private void loadActions(String s) { for (String sOfAction: PrefConverter.asArray(s)) { actions.add(new CounterAction(PrefConverter.asArray(sOfAction),0)); } } public boolean add(CounterAction o) { return actions.add(o); } public boolean remove(Object o) { return actions.remove(o); } public List<CounterAction> getAllActions() { return Collections.unmodifiableList(actions); } /** * the name of the CounterFactory * */ public String toString() { return name; } /** * makes this counter ready for the next user * @param next */ private WorkingCounter getWorkingCounter(IUser next) { return new WorkingCounter(next); } class WorkingCounter implements Comparable<WorkingCounter> { private Set<FileListFile> files = new HashSet<FileListFile>(); private FileListFile last = null; private final Map<String,WorkingCounter> otherCounters = new HashMap<String,WorkingCounter>(); private int count; private IUser usr; private WorkingCounter(IUser current) { this.usr = current; } private void addWorkingCounter(WorkingCounter counter) { otherCounters.put(counter.getName(), counter); } public String getName() { return CounterFactory.this.name; } public int getPriority() { return CounterFactory.this.priority; } public String getComment() { return CounterFactory.this.comment; } public boolean isPerFile() { return CounterFactory.this.perFile; } /** * adds multiple files to a counter * * @param s + the files to be added * @param count - how much the counter should be incremented.. * does not work perFile ! */ public void addFiles(Collection<FileListFile> s, int count) { if (!s.isEmpty() && !perFile) { files.addAll(s); this.count += count; } else if (perFile && files.size() == 1) { addFile((FileListFile)s.toArray()[0],count); } } /** * adds a file found to the counter * * @param f - the file found * @param count how the counter should be changed * @return true if checking should be broken.. */ public void addFile(FileListFile f,int count) { logger.debug("Add File: "+f.getPath()+" of User "+f.getParent().getUser().getNick()+ " "+count); files.add(f); last = f; this.count += count; } /** * if the current file has been finished.. * this will be called to clear per File Counters.. * * @return true if checking should be stopped */ public boolean fileFinished() { boolean breakAfter = false; if (perFile && last != null) { breakAfter = evaluate(); files.clear(); count = 0; last = null; } return breakAfter; } public boolean evaluate() { if (!isPerFile() || last != null) { for (CounterAction action : actions) { boolean breakAfter = action.evaluate(this); if (breakAfter) return true; } } return false; } /** * order by highest priority first.. */ public int compareTo(WorkingCounter o) { return -Integer.valueOf(this.getPriority()).compareTo(o.getPriority()); } } public static class CounterAction extends OPAction { //TODO a schedule re check in x minutes .. private static final int fields = 5; public CounterAction(){} public CounterAction(String[] arr,int extrafields) { super(arr,extrafields+fields); minCount = Integer.parseInt(arr[extrafields]); noLowerBound = Boolean.parseBoolean(arr[extrafields+1]); maxCount = Integer.parseInt(arr[extrafields+2]); noUpperBound = Boolean.parseBoolean(arr[extrafields+3]); breakAfterExecution = Boolean.parseBoolean(arr[extrafields+4]); } /** * interval of counts so the action gets executed * both inclusive */ private int minCount = 1, maxCount = 0; private boolean noLowerBound = false, noUpperBound = true; /** * raw to send */ // private String raw = ""; /** * open the FileList into the view of the user */ // private boolean openFileList; /** * increment some other counter by name */ // private String incrementCounter = ""; /** * how much the counter should be incremented.. */ // private int incrementByWhat; /** * if true stops more actions from being executed... * after being run */ private boolean breakAfterExecution = true; public String[] toStringAR(int extrafields) { String[] arr = super.toStringAR(fields+extrafields); arr[extrafields] = ""+minCount; arr[extrafields+1 ] = ""+noLowerBound; arr[extrafields+2] = ""+maxCount; arr[extrafields+3 ] = ""+noUpperBound; arr[extrafields+4] = ""+breakAfterExecution; return arr; /*return new String[] { ""+minCount, ""+maxCount, raw, ""+openFileList, incrementCounter, ""+ incrementByWhat, ""+ breakAfterExecution }; */ } /*public static CounterAction fromStringAR(String[] ar) { CounterAction ca = new CounterAction(); ca.minCount = Integer.parseInt(ar[0]); ca.maxCount = Integer.parseInt(ar[1]); ca.raw = ar[2]; ca.openFileList = Boolean.parseBoolean(ar[3]); ca.incrementCounter = ar[4]; ca.incrementByWhat = Integer.parseInt(ar[5]); ca.breakAfterExecution = Boolean.parseBoolean(ar[6]); return ca; } */ private boolean evaluate(WorkingCounter w) { if ((minCount <= w.count || noLowerBound ) && (w.count <= maxCount || noUpperBound) && !w.files.isEmpty()) { FileListFile random = (FileListFile)w.files.toArray()[GH.nextInt(w.files.size())]; execute(w.usr,random, w.files, w.count, w.getComment(), w.otherCounters); /* logger.info("Counter "+w.getName()+" Action evaluation: "+random.getName()+ " "+w.count+" number of files: "+w.files.size()); //OK .. we do sth.. if (openFileList) { OpenFilelistAction.openFileList(w.usr); } if (!GH.isNullOrEmpty(raw)) { IHub hub = w.usr.getHub(); if (hub != null) { hub.sendRaw(raw, new OpADLSendContext(hub,random,w.files,w.count,w.getComment())); } } if (incrementByWhat != 0 && !GH.isNullOrEmpty(incrementCounter)) { WorkingCounter other = w.otherCounters.get(incrementCounter); if (other != null) { other.addFiles(w.files, incrementByWhat); } } */ return breakAfterExecution; } return false; } public int getMinCount() { return minCount; } public void setMinCount(int minCount) { this.minCount = minCount; } public int getMaxCount() { return maxCount; } public void setMaxCount(int maxCount) { this.maxCount = maxCount; } public String getRaw() { return raw; } public void setRaw(String raw) { this.raw = raw; } public boolean isOpenFileList() { return openFileList; } public void setOpenFileList(boolean openFileList) { this.openFileList = openFileList; } public String getIncrementCounter() { return incrementCounter; } public void setIncrementCounter(String incrementCounter) { this.incrementCounter = incrementCounter; } public int getIncrementByWhat() { return incrementByWhat; } public void setIncrementByWhat(int incrementByWhat) { this.incrementByWhat = incrementByWhat; } public boolean isBreakAfterExecution() { return breakAfterExecution; } public void setBreakAfterExecution(boolean breakAfterExecution) { this.breakAfterExecution = breakAfterExecution; } public boolean isNoLowerBound() { return noLowerBound; } public void setNoLowerBound(boolean noLowerBound) { this.noLowerBound = noLowerBound; } public boolean isNoUpperBound() { return noUpperBound; } public void setNoUpperBound(boolean noUpperBound) { this.noUpperBound = noUpperBound; } } public int getPriority() { return priority; } public void setPriority(int priority) { this.priority = priority; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isPerFile() { return perFile; } public void setPerFile(boolean perFile) { this.perFile = perFile; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; } }