EMMA Coverage Report (generated Tue May 01 18:46:53 CEST 2007)
[all classes][dk.deepthought.sidious.greenhouse]

COVERAGE SUMMARY FOR SOURCE FILE [ClimaticState.java]

nameclass, %method, %block, %line, %
ClimaticState.java100% (2/2)100% (16/16)65%  (460/709)80%  (106,9/133)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ClimaticState100% (1/1)100% (14/14)64%  (451/700)80%  (104,9/131)
impact (Collection): State 100% (1/1)37%  (15/41)71%  (5/7)
total (ArrayList, ClimaticState): ClimaticState 100% (1/1)40%  (46/116)76%  (13/17)
toClimaticStateList (Collection): ArrayList 100% (1/1)42%  (36/85)60%  (9/15)
getSensors (): Collection 100% (1/1)52%  (14/27)67%  (4/6)
average (Collection): ClimaticState 100% (1/1)66%  (76/116)82%  (14/17)
sum (ClimaticState): ClimaticState 100% (1/1)67%  (72/108)85%  (17/20)
equals (Object): boolean 100% (1/1)76%  (28/37)69%  (9/13)
hashCode (): int 100% (1/1)89%  (17/19)97%  (3,9/4)
partiallyEquals (State): boolean 100% (1/1)93%  (27/29)88%  (7/8)
sameStateSpace (State): boolean 100% (1/1)96%  (49/51)91%  (10/11)
<static initializer> 100% (1/1)100% (8/8)100% (2/2)
ClimaticState (Collection): void 100% (1/1)100% (9/9)100% (3/3)
incrementTime (): ClimaticState 100% (1/1)100% (38/38)100% (7/7)
toString (): String 100% (1/1)100% (16/16)100% (1/1)
     
class ClimaticState$1100% (1/1)100% (2/2)100% (9/9)100% (2/2)
ClimaticState$1 (): void 100% (1/1)100% (3/3)100% (1/1)
compare (SensorInput, SensorInput): int 100% (1/1)100% (6/6)100% (1/1)

1package dk.deepthought.sidious.greenhouse;
2 
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Collections;
6import java.util.Comparator;
7import java.util.List;
8 
9import net.jcip.annotations.Immutable;
10 
11import org.apache.commons.logging.Log;
12import org.apache.commons.logging.LogFactory;
13 
14import dk.deepthought.sidious.supportsystem.State;
15import dk.deepthought.sidious.supportsystem.SystemSettings;
16 
17/**
18 * This class represents a climatic state of the environment. It is a collection
19 * of environmental sensor inputs.
20 * 
21 * @author Deepthought
22 * 
23 */
24@Immutable
25public class ClimaticState implements State {
26        /**
27         * Logger for this class.
28         */
29        private static final Log logger = LogFactory.getLog(ClimaticState.class);
30 
31        /**
32         * The list of sensors.
33         */
34        private final List<SensorInput> sensors;
35 
36        /**
37         * This comparator orders sensors by their <code>SuperLinkID</code>.
38         */
39        static final Comparator<SensorInput> SENSOR_ORDER = new Comparator<SensorInput>() {
40                public int compare(SensorInput o1, SensorInput o2) {
41                        return o1.getID().compareTo(o2.getID());
42                }
43        };
44 
45        /**
46         * Creates a <code>ClimaticState</code> object containing the specified
47         * sensor inputs.
48         * 
49         * @param sensors
50         *            a collection of sensor inputs related this climatic state
51         */
52        public ClimaticState(Collection<SensorInput> sensors) {
53                this.sensors = new ArrayList<SensorInput>(sensors);
54        }
55 
56        /*
57         * (non-Javadoc)
58         * 
59         * @see dk.deepthought.sidious.supportsystem.State#impact(java.util.Collection)
60         */
61        public State impact(Collection<State> states) {
62                if (logger.isDebugEnabled()) {
63                        logger.debug("impact(Collection<State> states=" + states
64                                        + ") - start");
65                }
66        
67                // Current implementation calculates the average.
68                ClimaticState returnState = average(toClimaticStateList(states));
69                returnState = returnState.incrementTime();
70                if (logger.isDebugEnabled()) {
71                        logger.debug("impact(Collection<State> states=" + states
72                                        + ") - end - return value=" + returnState);
73                }
74                return returnState;
75        }
76 
77        /**
78         * Calculates and returns the average <code>State</code>, based on the
79         * input <code>states</code>.
80         * <p>
81         * The method returns <code>null</code>, when presented with
82         * <code>null</code> or an empty collection.
83         * 
84         * @param states
85         *            states to base calculation on
86         * @return the average state
87         */
88        static ClimaticState average(Collection<ClimaticState> states) {
89                if (logger.isDebugEnabled()) {
90                        logger.debug("average(Collection<ClimaticState> states=" + states
91                                        + ") - start");
92                }
93 
94                if ((states == null) || states.isEmpty()) {
95                        if (logger.isDebugEnabled()) {
96                                logger.debug("average(Collection<ClimaticState> states="
97                                                + states + ") - end - return value=" + null);
98                        }
99                        throw new IllegalArgumentException("States list cannot be: " + states);
100                }
101                int size = states.size();
102                ClimaticState average = null;
103                ClimaticState cs = total(new ArrayList<ClimaticState>(states), average);
104                ArrayList<SensorInput> sensors = new ArrayList<SensorInput>(cs
105                                .getSensors());
106                for (int i = 0, s = sensors.size(); i < s; i++) {
107                        SensorInput sensor = sensors.remove(i);
108                        sensors.add(i, sensor.newInstanceWithNewValue(sensor.getValue()
109                                        / size));
110                }
111                ClimaticState returnClimaticState = new ClimaticState(sensors);
112                if (logger.isDebugEnabled()) {
113                        logger.debug("average(Collection<ClimaticState> states=" + states
114                                        + ") - end - return value=" + returnClimaticState);
115                }
116                return returnClimaticState;
117        }
118 
119        /**
120         * This method converts the input <code>State</code> objects to a list of
121         * <code>ClimaticState</code> objects.
122         * 
123         * @param states
124         *            input states to be concerted
125         * @return the input states as climatic states
126         */
127        static ArrayList<ClimaticState> toClimaticStateList(Collection<State> states) {
128                if (logger.isDebugEnabled()) {
129                        logger.debug("toClimaticStateList(Collection<State> states="
130                                        + states + ") - start");
131                }
132 
133                if ((states == null) || states.isEmpty()) {
134                        ArrayList<ClimaticState> returnArrayList = new ArrayList<ClimaticState>();
135                        if (logger.isDebugEnabled()) {
136                                logger.debug("toClimaticStateList(Collection<State> states="
137                                                + states + ") - end - return value=" + returnArrayList);
138                        }
139                        return returnArrayList;
140                }
141                ArrayList<ClimaticState> returnStates = new ArrayList<ClimaticState>();
142                for (State state : states) {
143                        if (state instanceof ClimaticState) {
144                                returnStates.add((ClimaticState) state);
145                        }
146                }
147 
148                if (logger.isDebugEnabled()) {
149                        logger.debug("toClimaticStateList(Collection<State> states="
150                                        + states + ") - end - return value=" + returnStates);
151                }
152                return returnStates;
153        }
154 
155        /**
156         * This method calculates the total sum of all related sensor inputs in the
157         * <code>states</code>. The sum is calculated recursively.
158         * <p>
159         * The method returns <code>null</code>, when presented with
160         * <code>null</code> or an empty collection.
161         * 
162         * @param states
163         *            the list of climatic states to be summed
164         * @param total
165         *            the parameter in which the sum will be calculated; is needed
166         *            for recursive purposes
167         * @return a <code>ClimaticState</code> representing the total sum of the
168         *         related sensor inputs
169         */
170        static ClimaticState total(ArrayList<ClimaticState> states,
171                        ClimaticState total) {
172                if (logger.isDebugEnabled()) {
173                        logger.debug("total(ArrayList<ClimaticState> states=" + states
174                                        + ", ClimaticState total=" + total + ") - start");
175                }
176 
177                if ((states == null) || states.isEmpty()) {
178                        if (logger.isDebugEnabled()) {
179                                logger.debug("total(ArrayList<ClimaticState> states=" + states
180                                                + ", ClimaticState total=" + total
181                                                + ") - end - return value=" + null);
182                        }
183                        return null;
184                }
185                ArrayList<ClimaticState> listOfCS = new ArrayList<ClimaticState>(states);
186                ClimaticState currentCS = listOfCS.remove(0);
187                if (listOfCS.isEmpty()) {
188                        total = currentCS.sum(total);
189 
190                        if (logger.isDebugEnabled()) {
191                                logger.debug("total(ArrayList<ClimaticState> states=" + states
192                                                + ", ClimaticState total=" + total
193                                                + ") - end - return value=" + total);
194                        }
195                        return total;
196                } else {
197                        ClimaticState returnClimaticState = total(listOfCS, currentCS).sum(
198                                        total);
199                        if (logger.isDebugEnabled()) {
200                                logger.debug("total(ArrayList<ClimaticState> states=" + states
201                                                + ", ClimaticState total=" + total
202                                                + ") - end - return value=" + returnClimaticState);
203                        }
204                        return returnClimaticState;
205                }
206        }
207 
208        /**
209         * This method calculates the sum of this <code>ClimaticState</code> and
210         * <code>other</code>.
211         * <p>
212         * The method returns a deep-copy of <code>this</code>, when presented
213         * with <code>null</code>.
214         * 
215         * @param other
216         *            the other climatic state
217         */
218        ClimaticState sum(ClimaticState other) {
219                if (logger.isDebugEnabled()) {
220                        logger.debug("sum(ClimaticState other=" + other + ") - start");
221                }
222        
223                if (other == null) {
224                        ClimaticState returnClimaticState = new ClimaticState(getSensors());
225                        if (logger.isDebugEnabled()) {
226                                logger.debug("sum(ClimaticState other=null)"
227                                                + " - end - return value=" + returnClimaticState);
228                        }
229                        return returnClimaticState;
230                }
231                Collection<SensorInput> sensorList = new ArrayList<SensorInput>();
232                for (SensorInput sensor : sensors) {
233                        double total = sensor.getValue();
234                        for (SensorInput input : other.getSensors()) {
235                                if (sensor.equalsOnSuperLinkID(input)) {
236                                        total += input.getValue();
237                                }
238                        }
239                        sensorList.add(sensor.newInstanceWithNewValue(total));
240                }
241                ClimaticState returnClimaticState = new ClimaticState(sensorList);
242                if (logger.isDebugEnabled()) {
243                        logger.debug("sum(ClimaticState other=" + other
244                                        + ") - end - return value=" + returnClimaticState);
245                }
246                return returnClimaticState;
247        }
248 
249        /*
250         * (non-Javadoc)
251         * 
252         * @see dk.deepthought.sidious.supportsystem.State#sameStateSpace(dk.deepthought.sidious.supportsystem.State)
253         */
254        public boolean sameStateSpace(State other) {
255                if (other instanceof ClimaticState) {
256                        ArrayList<SensorInput> otherSensors = new ArrayList<SensorInput>(
257                                        ((ClimaticState) other).getSensors());
258                        if (otherSensors.size() != sensors.size()) {
259                                return false;
260                        }
261                        Collections.sort(sensors, SENSOR_ORDER);
262                        Collections.sort(otherSensors, SENSOR_ORDER);
263                        for (int i = 0; i < sensors.size(); i++) {
264                                if (!sensors.get(i).equalsOnSuperLinkID(otherSensors.get(i))) {
265                                        return false;
266                                }
267                        }
268                        return true;
269                }
270                return false;
271        }
272 
273        /* (non-Javadoc)
274         * @see dk.deepthought.sidious.supportsystem.State#partiallyEquals(dk.deepthought.sidious.supportsystem.State)
275         */
276        public boolean partiallyEquals(State state) {
277                if (state instanceof ClimaticState) {
278                        ClimaticState climaticState = (ClimaticState) state;
279                        for (SensorInput sensor : climaticState.getSensors()) {
280                                if (!sensors.contains(sensor)) {
281                                        return false;
282                                }
283                        }
284                        return true;
285                }
286                return false;
287        }
288 
289        /**
290         * Gets a <code>Collection</code> of <code>SensorInput</code>
291         * 
292         * @return the sensors related to this climatic state
293         */
294        public Collection<SensorInput> getSensors() {
295                if (logger.isDebugEnabled()) {
296                        logger.debug("getSensors() - start");
297                }
298        
299                Collection<SensorInput> returnCollection = new ArrayList<SensorInput>(
300                                sensors);
301                if (logger.isDebugEnabled()) {
302                        logger.debug("getSensors() - end - return value="
303                                        + returnCollection);
304                }
305                return returnCollection;
306        }
307 
308        /**
309         * Increments the time of this.
310         * @return the time incremented version of this.
311         */
312        private ClimaticState incrementTime() {
313                ArrayList<SensorInput> newSensors = new ArrayList<SensorInput>();
314                for (SensorInput sensor : sensors) {
315                        if (SystemSettings.getTimeID().equals(sensor.getID())) {
316                                sensor = sensor.newInstanceWithNewValue(sensor.getValue()
317                                                + SystemSettings.getTimestep());
318                        }
319                        newSensors.add(sensor);
320                }
321                return new ClimaticState(newSensors);
322        }
323 
324        /*
325         * (non-Javadoc)
326         * 
327         * @see java.lang.Object#equals(java.lang.Object)
328         */
329        @Override
330        public boolean equals(Object obj) {
331                if (this == obj) {
332                        return true;
333                }
334                if (obj == null) {
335                        return false;
336                }
337                if (getClass() != obj.getClass()) {
338                        return false;
339                }
340                final ClimaticState other = (ClimaticState) obj;
341                if (sensors == null) {
342                        if (other.sensors != null) {
343                                return false;
344                        }
345                } else if (!sensors.equals(other.sensors)) {
346                        return false;
347                }
348                return true;
349        }
350 
351        /*
352         * (non-Javadoc)
353         * 
354         * @see java.lang.Object#hashCode()
355         */
356        @Override
357        public int hashCode() {
358                final int PRIME = 31;
359                int result = 1;
360                result = PRIME * result + ((sensors == null) ? 0 : sensors.hashCode());
361                return result;
362        }
363 
364        /*
365         * (non-Javadoc)
366         * 
367         * @see java.lang.Object#toString()
368         */
369        @Override
370        public String toString() {
371                return getClass().getSimpleName() + "[sensors=" + sensors + "]";
372        }
373 
374}

[all classes][dk.deepthought.sidious.greenhouse]
EMMA 2.0.5312 (C) Vladimir Roubtsov