1 // Copyright (C) 2000 - 2009 Philip Aston 2 // All rights reserved. 3 // 4 // This file is part of The Grinder software distribution. Refer to 5 // the file LICENSE which is part of The Grinder distribution for 6 // licensing details. The Grinder distribution is available on the 7 // Internet at http://grinder.sourceforge.net/ 8 // 9 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 10 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 11 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 12 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 13 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 14 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 15 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 16 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 17 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 18 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 19 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 20 // OF THE POSSIBILITY OF SUCH DAMAGE. 21 22 package net.grinder.statistics; 23 24 import java.util.Comparator; 25 import java.util.HashSet; 26 import java.util.Set; 27 import java.util.SortedSet; 28 import java.util.TreeSet; 29 30 31 /** 32 * An ordered collection of {@link ExpressionView}s. 33 * 34 * @author Philip Aston 35 * @see net.grinder.script.Statistics#registerDataLogExpression 36 * @see net.grinder.script.Statistics#registerSummaryExpression 37 */ 38 public final class StatisticsView { 39 40 /** 41 * We define a <code>Comparator</code> for {@link ExpressionView}s 42 * rather than having the <code>ExpressionView</code> implement 43 * <code>Comparable</code> because our sort order is inconsistent with equals. 44 */ 45 private static final Comparator<ExpressionView> s_expressionViewComparator = 46 new CreationOrderComparator(); 47 48 /** 49 * We use this set to ensure that new views are unique. We can't 50 * do this with a SortedSet because our sort order is inconsistent 51 * with equals. 52 */ 53 private final Set<ExpressionView> m_unique = new HashSet<ExpressionView>(); 54 55 private final SortedSet<ExpressionView> m_columns; 56 57 /** 58 * Creates a new <code>StatisticsView</code> instance. 59 */ 60 public StatisticsView() { 61 m_columns = new TreeSet<ExpressionView>(s_expressionViewComparator); 62 } 63 64 /** 65 * Add all the {@link ExpressionView}s in <code>other</code> to 66 * this <code>StatisticsView</code>. 67 * 68 * @param other Another <code>StatisticsView</code>. 69 */ 70 public synchronized void add(StatisticsView other) { 71 for (ExpressionView expressionView : other.m_columns) { 72 add(expressionView); 73 } 74 } 75 76 /** 77 * Add the specified {@link ExpressionView} to this 78 * <code>StatisticsView</code>. 79 * 80 * @param statistic An {@link ExpressionView}. 81 */ 82 public synchronized void add(ExpressionView statistic) { 83 if (!m_unique.contains(statistic)) { 84 m_unique.add(statistic); 85 m_columns.add(statistic); 86 } 87 } 88 89 /** 90 * Return our {@link ExpressionView}s as an array. 91 * 92 * @return The {@link ExpressionView}s. 93 */ 94 public synchronized ExpressionView[] getExpressionViews() { 95 return m_columns.toArray(new ExpressionView[m_columns.size()]); 96 } 97 98 /** 99 * Package scope for unit tests. 100 */ 101 static final class CreationOrderComparator 102 implements Comparator<ExpressionView> { 103 104 public int compare(ExpressionView viewA, ExpressionView viewB) { 105 106 if (viewA.getCreationOrder() < viewB.getCreationOrder()) { 107 return -1; 108 } 109 else if (viewA.getCreationOrder() > viewB.getCreationOrder()) { 110 return 1; 111 } 112 else { 113 // Should assert ? Same creation order => same instance. 114 return 0; 115 } 116 } 117 } 118 }