View Javadoc

1   /*
2    * The contents of this file are subject to the terms 
3    * of the Common Development and Distribution License 
4    * (the "License").  You may not use this file except 
5    * in compliance with the License.
6    * 
7    * You can obtain a copy of the license at 
8    * http://www.sun.com/cddl/cddl.html. 
9    * See the License for the specific language governing 
10   * permissions and limitations under the License.
11   * 
12   * When distributing Covered Code, include this CDDL 
13   * HEADER in each file and include the License file at 
14   * license.txt.  If applicable, add the following below 
15   * this CDDL HEADER, with the fields enclosed by brackets 
16   * "[]" replaced with your own identifying information: 
17   * Portions Copyright [yyyy] [name of copyright owner]
18   * 
19   * Portions Copyright 2004 eBay, Inc.
20   */
21  package com.ebay.carad.os.vitalsigns;
22  
23  import java.util.Collections;
24  import java.util.List;
25  
26  import org.apache.commons.lang.builder.ToStringBuilder;
27  import org.apache.log4j.Logger;
28  
29  import com.ebay.carad.os.vitalsigns.templates.ITemplatizable;
30  import com.ebay.carad.os.vitalsigns.util.ITimeConstants;
31  import com.ebay.carad.os.vitalsigns.util.MessageFormatUtil;
32  
33  /***
34   * Configuration object for the reports that are run by ReportAgent.
35   * 
36   * @author Jeremy Kraybill
37   * @author Jeremy Thomerson
38   * @version $Id$
39   */
40  public class DashboardReport extends AbstractListenerContainer implements Comparable, IDashboardReport, IDashboardReportContainer, ITemplatizable {
41  	
42  	private String title;
43  	private String subTitle;
44      private String mGroupName;
45      private int frequencyInMinutes;
46  	private int id = -1;
47  	private int sortOrder;
48  	private boolean moreIsBetter;
49      private IDataRetriever mDataRetriever = IDataRetriever.NO_OP_DATA_RETRIEVER;
50  	
51      private Float lastObservedValue = IDataRetriever.ZERO;
52      private Float previouslyObservedValue = IDataRetriever.ZERO;
53  	private long lastRunTimestamp = 0;
54  	private boolean mIncludeInSummary;
55  
56  	private static final Logger LOGGER = Logger.getLogger(DashboardReport.class);
57  	
58  	/***
59  	 * Basic constructor.
60  	 */
61  	public DashboardReport() {
62  		// do nothing
63  	}
64  	
65  	/***
66  	 * Copy constructor.
67  	 * 
68  	 * @param copyFrom report to use as a template
69  	 */
70  	public DashboardReport(DashboardReport copyFrom) {
71  		frequencyInMinutes = copyFrom.getFrequencyInMinutes();
72  		id = copyFrom.getID();
73  		moreIsBetter = copyFrom.getMoreIsBetter();
74  		sortOrder = copyFrom.getSortOrder();
75  		subTitle = copyFrom.getSubTitle();
76  		title = copyFrom.getTitle();
77  		try {
78              mDataRetriever = (IDataRetriever) copyFrom.mDataRetriever.clone();
79          } catch (CloneNotSupportedException cnse) {
80              throw new ReportingException("error cloning data retriever for template creation: " + cnse.getMessage(), cnse);
81          }
82  		mIncludeInSummary = copyFrom.mIncludeInSummary;
83  	}
84  
85  	public void run(IDashboardAgent agent, long inRunTime) {
86          // run daily reports at 2 AM (UTC - 5 for eastern, then -2 to key off 2am)
87  		// TODO FIXME : this is specialized for CARad - needs to be genericized 
88          //      -- preferably allow daily run time to be configured (injected)
89  	    long runTime = inRunTime - (7 * ITimeConstants.HOUR); 
90  	    long runMinute = runTime / ITimeConstants.MINUTE;
91  		if ((runMinute % getFrequencyInMinutes() == 0) || (runTime - lastRunTimestamp >= getFrequencyInMinutes() * ITimeConstants.MINUTE)) {
92  		    // it's either on the correct minute for us to run, 
93              //      or it's been longer than our frequency since we last ran; do it now.
94              Float data = mDataRetriever.getData(agent);
95              // preserve this and previous data
96              previouslyObservedValue = lastObservedValue;
97              lastObservedValue = data;
98  			lastRunTimestamp = runTime;
99  	        if (lastObservedValue != null) {
100 	            agent.getDefaultDataDAO().storeReportData(lastObservedValue.floatValue(), agent, this);
101 	        }
102 		}
103 		
104 		// The following line is not necessary because a well-behaved implementation of 
105 		//	IDashboardAgent will perform this function.
106 		// fireListenersReportRan(agent, this);
107     }
108 	
109     /***
110      * Templatizes the title / subtitle / ID based on the objects passed in.
111      * Note the behavior: we reset ID based on templatized title's hashcode, therefore,
112      * the ID must be unique among your report set.
113      * @see com.ebay.carad.os.vitalsigns.templates.ITemplatizable#templatize(java.lang.Object[])
114      */
115     public void templatize(Object[] substitutions) {
116     	setTitle(MessageFormatUtil.format(getTitle(), substitutions));
117     	setSubTitle(MessageFormatUtil.format(getSubTitle(), substitutions));
118 		setID(getTitle().hashCode());
119         if (mDataRetriever instanceof ITemplatizable) {
120             ((ITemplatizable) mDataRetriever).templatize(substitutions);
121         }
122 		LOGGER.info("templatize(): templatized into report \"" + getTitle() + "\" as ID " + getID());
123     }
124 
125 	public int getID() {
126 	    return id;
127 	}
128 
129 	public String getTitle() {
130 	    return title;
131 	}
132 	
133 	public String getSubTitle() {
134 	    return subTitle;
135 	}
136 	
137 	public boolean getMoreIsBetter() {
138 	    return moreIsBetter;
139 	}
140 	
141 	/***
142 	 * Sets the title of this report.
143 	 * 
144 	 * @param inTitle the title to set to
145 	 */
146 	public void setTitle(String inTitle) { 
147 	    title = inTitle;
148     }
149 	
150 	/***
151 	 * Sets the sub-title of this report.
152 	 * 
153 	 * @param title the sub-title to use
154 	 */
155 	public void setSubTitle(String title) {
156 	    subTitle = title;
157 	}	
158 	
159 	public int getFrequencyInMinutes() {
160 	    return frequencyInMinutes;
161 	}
162 	
163 	/***
164 	 * Sets the frequency in minutes for the generation of this report. Currently, only valid values are
165 	 * 15, 60 or 1440.
166 	 * TODO : is this comment still correct?  is there a restriction on how often it can run? I presume this is only valid if the reportagent is triggered less than given amount
167 	 * 
168 	 * @param freq the frequency in minutes
169 	 */
170 	public void setFrequencyInMinutes(int freq) {
171 	    frequencyInMinutes = freq;
172 	}
173 	
174 	/***
175 	 * Sets the ID of this report. If more than one report has the same ID, bad things will happen!
176 	 * 
177 	 * @param setId the ID to use
178 	 */
179 	public void setID(int setId) { 
180 		id = setId;
181 	}	
182 
183     /***
184 	 * Sets the display sort order of this report. Reports with the same sort order will be sorted
185 	 * in a non-guaranteed order.
186 	 * 
187 	 * @param setSortorder the order to use
188 	 */
189 	public void setSortOrder(int setSortorder) {
190 	    sortOrder = setSortorder;
191 	}
192 
193 	/***
194 	 * Sets whether this report represents a value that should be increasing over time.
195 	 * 
196 	 * @param flag if true, this report is "happy" when its value has increased
197 	 */
198 	public void setMoreIsBetter(boolean flag) { moreIsBetter = flag; }
199 	
200 	public int compareTo(Object obj) {
201 		IDashboardReportContainer rc = (IDashboardReportContainer) obj;
202 		return getSortOrder() - rc.getSortOrder();
203 	}
204 	
205 	public List getReports() {
206 		return Collections.singletonList(this);
207 	}
208 
209 	public int getSortOrder() {
210 		return sortOrder;
211 	}
212 
213     public void setDataRetriever(IDataRetriever dataRetriever) {
214         mDataRetriever = dataRetriever;
215     }
216 
217     public Float getThisRunData() {
218         return lastObservedValue;
219     }
220 
221     public Float getPreviousData() {
222         return previouslyObservedValue;
223     }
224 
225 	public boolean getIncludeInSummary() {
226 		return mIncludeInSummary;
227 	}
228 	public void setIncludeInSummary(boolean includeInSummary) {
229 		mIncludeInSummary = includeInSummary;
230 	}
231 
232 
233     /***
234      * @return Returns the groupName.
235      * @see IDashboardReportContainer#getGroupName()
236      */
237     public String getGroupName() {
238         return mGroupName;
239     }
240 
241     /***
242      * @param groupName The groupName to set.
243      * @see IDashboardReportContainer#getGroupName()
244      */
245     public void setGroupName(String groupName) {
246         mGroupName = groupName;
247     }
248 
249     public String toString() {
250         return new ToStringBuilder(this)
251             .append("id", id)
252             .append("title", title)
253             .append("sortOrder", sortOrder)
254             .toString();
255     }
256 }