package org.hudson.trayapp.model; import java.io.IOException; import java.io.Writer; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.hudson.trayapp.actions.Action; import org.hudson.trayapp.actions.FileExecutor; import org.hudson.trayapp.util.XMLHelper; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Preferences { private int updateFrequency = 5; private boolean showHealthIcon = false; private boolean showAnimatedBuilds = true; private boolean showPopupNotifications = true; private class State { Integer colourFrom; Integer colourTo; Integer build; public State(final Integer colourFrom, final Integer colourTo, final Integer build) { if (colourFrom == null || colourTo == null || build == null) { throw new NullPointerException("Actions can not be created with Null arguments"); } this.colourFrom = colourFrom; this.colourTo = colourTo; this.build = build; } private State() {} public Integer getColourFrom() { return colourFrom; } public Integer getColourTo() { return colourTo; } public Integer getBuild() { return build; } public boolean equals(Object o) { if (o instanceof State) { State s = (State) o; return ( s.colourFrom == colourFrom && s.colourTo == colourTo && s.build == build); } return false; } public int hashCode() { return colourFrom.intValue() * 10000 + colourTo.intValue() * 100 + build.intValue(); } public void writeXML(Writer w) throws IOException{ w.write("<state>"); w.write("<from>"); w.write(Job.getColour(colourFrom)); w.write("</from>"); w.write("<to>"); w.write(Job.getColour(colourTo)); w.write("</to>"); w.write("<changed>"); w.write(build.equals(Job.BUILD_CHANGED) ? "Y": "N"); w.write("</changed>"); Action action = (Action) Preferences.this.actions.get(this); action.writeXML(w); w.write("</state>"); } public Action process(NodeList nodes) { Action actionReturn = null; for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); String name = node.getNodeName(); String value = XMLHelper.getTextContent(node); if (name.equals("state")) { process(node.getChildNodes()); } else if (name.equals("from")) { colourFrom = Job.convertColour(value); } else if (name.equals("to")) { colourTo = Job.convertColour(value); } else if (name.equals("changed")) { if (value.equals("Y")) build = Job.BUILD_CHANGED; else build = Job.BUILD_UNCHANGED; } else if (name.equals("fileToExecute")) { actionReturn = new FileExecutor(); actionReturn.process(node.getChildNodes()); } } return actionReturn; } } private HashMap actions = new HashMap(); public void setAction(final Integer colourFrom, final Integer colourTo, final Integer buildChanged, final String actionString) { FileExecutor action = new FileExecutor(); action.setFileToExecute(actionString); actions.put(new State(colourFrom, colourTo, buildChanged), action); } public Action getAction(final Integer colourFrom, final Integer colourTo, final Integer buildChanged) { return (Action) actions.get(new State(colourFrom, colourTo, buildChanged)); } public Object clone() { Preferences preferences = new Preferences(); preferences.actions.putAll(actions); return preferences; } public boolean equals(Object o) { if (o instanceof Preferences) { Preferences preferences = (Preferences) o; Iterator iterator = actions.entrySet().iterator(); boolean bool = true; while (bool && iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); Action action = (Action) preferences.actions.get(entry.getKey()); bool = entry.getValue().equals(action); } /* * We can say that the two preferences are identical if after checking through every * action in this preferences object, we have managed to match it to an action in the other * preferences object, and that the two list of actions are the same size */ return bool && actions.size() == preferences.actions.size(); } return false; } public int hashCode() { return actions.hashCode(); } public void setUpdateFrequency(int frequency) { updateFrequency = frequency; } public int getUpdateFrequency() { return updateFrequency; } public void writeXML(Writer w) throws IOException { w.write("<preferences>"); w.write("<updateFrequency>"); w.write(Integer.toString(updateFrequency)); w.write("</updateFrequency>"); w.write("<trayshowhealth>"); w.write(showHealthIcon ? "Y": "N"); w.write("</trayshowhealth>"); w.write("<trayshowanimation>"); w.write(showAnimatedBuilds ? "Y": "N"); w.write("</trayshowanimation>"); w.write("<trayshowpopup>"); w.write(showPopupNotifications ? "Y": "N"); w.write("</trayshowpopup>"); Iterator iterEntries = actions.entrySet().iterator(); while (iterEntries.hasNext()) { ((State) ((Map.Entry) iterEntries.next()).getKey()).writeXML(w); } w.write("</preferences>"); } public void process(NodeList nodes) { for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); String name = node.getNodeName(); String value = XMLHelper.getTextContent(node); if (name.equals("preferences")) { process(node.getChildNodes()); } else if (name.equals("updateFrequency")) { updateFrequency = Integer.parseInt(value); } else if (name.equals("trayshowhealth")) { showHealthIcon = value.equals("Y"); } else if (name.equals("trayshowanimation")) { showAnimatedBuilds = value.equals("Y"); } else if (name.equals("trayshowpopup")) { showPopupNotifications = value.equals("Y"); } else if (name.equals("state")) { State state = new State(); Action action = state.process(node.getChildNodes()); actions.put(state, action); } } } public boolean isShowHealthIcon() { return showHealthIcon; } public void setShowHealthIcon(boolean showHealthIcon) { this.showHealthIcon = showHealthIcon; } public boolean isShowAnimatedBuilds() { return showAnimatedBuilds; } public void setShowAnimatedBuilds(boolean showAnimatedBuilds) { this.showAnimatedBuilds = showAnimatedBuilds; } public boolean isShowPopupNotifications() { return showPopupNotifications; } public void setShowPopupNotifications(boolean showPopupNotifications) { this.showPopupNotifications = showPopupNotifications; } }