/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2006-2011 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/
package org.opennms.netmgt.config;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.ValidationException;
import org.opennms.core.utils.ConfigFileConstants;
import org.opennms.core.xml.CastorUtils;
import org.opennms.netmgt.config.kscReports.Report;
import org.opennms.netmgt.config.kscReports.ReportsList;
import org.springframework.core.io.FileSystemResource;
import org.springframework.util.Assert;
/**
* <p>KSC_PerformanceReportFactory class.</p>
*
* @author ranger
* @version $Id: $
*/
public class KSC_PerformanceReportFactory {
/**
* The static singleton instance object.
* Null if init() hasn't been successfully called.
*/
private static KSC_PerformanceReportFactory s_instance = null;
/** File name of the KSC_PerformanceReport.xml */
private static File s_configFile = null;
/** An instance of the ReportsList configuration */
private ReportsList m_config;
/**
* The array of values that may be used in the timespan declaration of a
* graph
*/
public static final String[] TIMESPAN_OPTIONS = {
"1_hour",
"2_hour",
"4_hour",
"6_hour",
"8_hour",
"12_hour",
"1_day",
"2_day",
"7_day",
"1_month",
"3_month",
"6_month",
"1_year",
"Today",
"Yesterday",
"Yesterday 9am-5pm",
"Yesterday 5pm-10pm",
"This Week",
"Last Week",
"This Month",
"Last Month",
"This Quarter",
"Last Quarter",
"This Year",
"Last Year"
};
/**
* Map of all Reports by their ID, ordered based on their order in the config file.
*/
private Map<Integer, Report> m_reportList;
/**
* Empty Private Constructor. Cannot be instantiated outside itself.
*/
private KSC_PerformanceReportFactory() {
}
/**
* Init routine. Must be called before calling getInstance() to instantiate *
*
* @throws java.io.IOException if any.
* @throws java.io.FileNotFoundException if any.
* @throws org.exolab.castor.xml.MarshalException if any.
* @throws org.exolab.castor.xml.ValidationException if any.
*/
public static synchronized void init() throws IOException, FileNotFoundException, MarshalException, ValidationException {
if (isInitialized()) {
return;
}
KSC_PerformanceReportFactory newInstance = new KSC_PerformanceReportFactory();
newInstance.reload();
s_instance = newInstance;
}
/**
* Singleton static call to get the only instance that should exist for the
* KSC_PerformanceReportFactory
*
* @return the single KSC_PerformanceReportFactory instance
* @throws java.lang.IllegalStateException if any.
*/
public static synchronized KSC_PerformanceReportFactory getInstance() throws IllegalStateException {
assertInitialized();
return s_instance;
}
/**
* Parses the KSC_PerformanceReport.xml via the Castor classes.
*
* @throws java.io.IOException if any.
* @throws java.io.FileNotFoundException if any.
* @throws org.exolab.castor.xml.MarshalException if any.
* @throws org.exolab.castor.xml.ValidationException if any.
*/
public synchronized void reload() throws IOException, FileNotFoundException, MarshalException, ValidationException {
if (s_configFile == null) s_configFile = ConfigFileConstants.getFile(ConfigFileConstants.KSC_REPORT_FILE_NAME);
m_config = CastorUtils.unmarshal(ReportsList.class, new FileSystemResource(s_configFile));
setIdsOnAllReports();
m_reportList = createReportList();
}
public static void setConfigFile(final File configFile) {
s_configFile = configFile;
}
private void setIdsOnAllReports() {
int i = 0;
// Make sure that i is larger than the highest report ID
for (Report report : m_config.getReportCollection()) {
if (report.hasId() && report.getId() >= i) {
i = report.getId() + 1;
}
}
// Set IDs for any report lacking one.
for (Report report : m_config.getReportCollection()) {
if (!report.hasId()) {
report.setId(i);
i++;
}
}
}
/**
* Saves the KSC_PerformanceReport.xml data.
*
* @throws java.io.IOException if any.
* @throws java.io.FileNotFoundException if any.
* @throws org.exolab.castor.xml.MarshalException if any.
* @throws org.exolab.castor.xml.ValidationException if any.
*/
public synchronized void saveCurrent() throws IOException, FileNotFoundException, MarshalException, ValidationException {
assertInitialized();
sortByTitle();
CastorUtils.marshalViaString(m_config, s_configFile);
reload();
}
private static void assertInitialized() {
Assert.state(isInitialized(), "KSC_PerformanceReportFactory.init() has not been called");
}
private static boolean isInitialized() {
return s_instance != null;
}
/**
* Sorts the Reports List by their title.
*/
public void sortByTitle() {
Arrays.sort(m_config.getReport(), new Comparator<Report>() {
public int compare(Report o1, Report o2) {
return o1.getTitle().compareTo(o2.getTitle());
}
});
}
/**
* <p>getReportByIndex</p>
*
* @param index a int.
* @return a {@link org.opennms.netmgt.config.kscReports.Report} object.
*/
public Report getReportByIndex(int index) {
return m_reportList.get(index);
}
private Map<Integer, Report> createReportList() {
Map<Integer, Report> reports = new LinkedHashMap<Integer, Report>(m_config.getReportCount());
for (Report report : m_config.getReportCollection()) {
if (reports.containsKey(report.getId())) {
throw new IllegalArgumentException("Report id " + report.getId() + " is used by multiple reports in configuration file");
}
reports.put(report.getId(), report);
}
return reports;
}
/**
* <p>getReportList</p>
*
* @return a {@link java.util.Map} object.
*/
public Map<Integer, String> getReportList() {
LinkedHashMap<Integer, String> reports = new LinkedHashMap<Integer, String>(m_config.getReportCount());
List<Report> reportList = m_config.getReportCollection();
Collections.sort(reportList, new Comparator<Report>() {
public int compare(Report o1, Report o2) {
return o1.getTitle().compareTo(o2.getTitle());
}
});
for (Report report : reportList) {
reports.put(report.getId(), report.getTitle());
}
return Collections.unmodifiableMap(reports);
}
/**
* Deletes the indexed report and updates file configuration
*
* @param index a int.
* @throws java.lang.ArrayIndexOutOfBoundsException if any.
* @throws java.io.IOException if any.
* @throws java.io.FileNotFoundException if any.
* @throws org.exolab.castor.xml.MarshalException if any.
* @throws org.exolab.castor.xml.ValidationException if any.
*/
public void deleteReportAndSave(int index) throws ArrayIndexOutOfBoundsException, IOException, FileNotFoundException, MarshalException, ValidationException {
Report report = getReportByIndex(index);
if (report == null) {
throw new ArrayIndexOutOfBoundsException("Reports List index to be deleted is out of bounds: " + index);
}
m_config.removeReport(report);
saveCurrent();
}
public void addReport(Report report) {
m_config.addReport(report);
setIdsOnAllReports();
}
public void setReport(int index, Report report) {
int arrayIndex = getArrayIndex(index);
if (arrayIndex == -1) {
throw new IllegalArgumentException("Could not find report with ID of " + index);
}
// Make sure we preserve the existing ID, if it exists (which it should)
if (m_config.getReport(arrayIndex).hasId()) {
report.setId(m_config.getReport(arrayIndex).getId());
}
m_config.setReport(arrayIndex, report);
setIdsOnAllReports();
}
private int getArrayIndex(int index) {
int i = 0;
for (Report report : m_config.getReportCollection()) {
if (report.getId() == index) {
return i;
}
i++;
}
return -1;
}
/**
* This method requires begin time and end time to be set to the current
* time prior to call. The start and stop times are relative to this time.
* Init values as follows: begin_time = Calendar.getInstance(); end_time =
* Calendar.getInstance();
*
* @param interval a {@link java.lang.String} object.
* @param begin_time a {@link java.util.Calendar} object.
* @param end_time a {@link java.util.Calendar} object.
* @throws java.lang.IllegalArgumentException if any.
*/
public static synchronized void getBeginEndTime(String interval, Calendar begin_time, Calendar end_time) throws IllegalArgumentException {
if (interval.equals("1_hour")) {
begin_time.add(Calendar.HOUR, -1);
} else if (interval.equals("2_hour")) {
begin_time.add(Calendar.HOUR, -2);
} else if (interval.equals("4_hour")) {
begin_time.add(Calendar.HOUR, -4);
} else if (interval.equals("6_hour")) {
begin_time.add(Calendar.HOUR, -6);
} else if (interval.equals("8_hour")) {
begin_time.add(Calendar.HOUR, -8);
} else if (interval.equals("12_hour")) {
begin_time.add(Calendar.HOUR, -12);
} else if (interval.equals("1_day")) {
begin_time.add(Calendar.DATE, -1);
} else if (interval.equals("2_day")) {
begin_time.add(Calendar.DATE, -2);
} else if (interval.equals("7_day")) {
begin_time.add(Calendar.DATE, -7);
} else if (interval.equals("1_month")) {
begin_time.add(Calendar.DATE, -30);
} else if (interval.equals("3_month")) {
begin_time.add(Calendar.DATE, -90);
} else if (interval.equals("6_month")) {
begin_time.add(Calendar.DATE, -183);
} else if (interval.equals("1_year")) {
begin_time.add(Calendar.DATE, -365);
} else {
// From current time, lets zero out the small components
begin_time.set(Calendar.HOUR_OF_DAY, 0);
begin_time.set(Calendar.MINUTE, 0);
begin_time.set(Calendar.SECOND, 0);
end_time.set(Calendar.HOUR_OF_DAY, 0);
end_time.set(Calendar.MINUTE, 0);
end_time.set(Calendar.SECOND, 0);
if (interval.equals("Today")) {
end_time.add(Calendar.DATE, 1);
} else if (interval.equals("Yesterday")) {
begin_time.add(Calendar.DATE, -1);
} else if (interval.equals("Yesterday 9am-5pm")) {
begin_time.add(Calendar.DATE, -1);
begin_time.set(Calendar.HOUR_OF_DAY, 9);
end_time.add(Calendar.DATE, -1);
end_time.set(Calendar.HOUR_OF_DAY, 17);
} else if (interval.equals("Yesterday 5pm-10pm")) {
begin_time.add(Calendar.DATE, -1);
begin_time.set(Calendar.HOUR_OF_DAY, 17);
end_time.add(Calendar.DATE, -1);
end_time.set(Calendar.HOUR_OF_DAY, 22);
} else if (interval.equals("This Week") || interval.equals("Last Week")) {
begin_time.set(Calendar.DAY_OF_WEEK, 1);
end_time.set(Calendar.DAY_OF_WEEK, 7);
end_time.set(Calendar.HOUR_OF_DAY, 23);
end_time.set(Calendar.MINUTE, 59);
if (interval.equals("Last Week")) {
begin_time.add(Calendar.DATE, -7);
end_time.add(Calendar.DATE, -7);
}
} else if (interval.equals("This Month")) {
begin_time.set(Calendar.DATE, 1);
end_time.add(Calendar.MONTH, 1);
end_time.set(Calendar.DATE, 1);
} else if (interval.equals("Last Month")) {
begin_time.add(Calendar.MONTH, -1);
begin_time.set(Calendar.DATE, 1);
end_time.set(Calendar.DATE, 1);
} else if (interval.equals("This Quarter") || interval.equals("Last Quarter")) {
begin_time.set(Calendar.DATE, 1);
end_time.set(Calendar.DATE, 1);
switch (begin_time.get(Calendar.MONTH)) {
case 0:
case 1:
case 2:
begin_time.set(Calendar.MONTH, 0);
end_time.set(Calendar.MONTH, 3);
break;
case 3:
case 4:
case 5:
begin_time.set(Calendar.MONTH, 3);
end_time.set(Calendar.MONTH, 6);
break;
case 6:
case 7:
case 8:
begin_time.set(Calendar.MONTH, 6);
end_time.set(Calendar.MONTH, 9);
break;
case 9:
case 10:
case 11:
begin_time.set(Calendar.MONTH, 9);
end_time.set(Calendar.MONTH, 0);
end_time.add(Calendar.YEAR, 1);
break;
default:
throw new IllegalArgumentException("Invalid Calendar Month " + begin_time.get(Calendar.MONTH));
}
if (interval.equals("Last Quarter")) {
begin_time.add(Calendar.MONTH, -3);
end_time.add(Calendar.MONTH, -3);
}
} else if (interval.equals("This Year")) {
begin_time.set(Calendar.MONTH, 0);
begin_time.set(Calendar.DATE, 1);
end_time.set(Calendar.MONTH, 0);
end_time.set(Calendar.DATE, 1);
end_time.add(Calendar.YEAR, 1);
} else if (interval.equals("Last Year")) {
begin_time.set(Calendar.MONTH, 0);
begin_time.set(Calendar.DATE, 1);
begin_time.add(Calendar.YEAR, -1);
end_time.set(Calendar.MONTH, 0);
end_time.set(Calendar.DATE, 1);
} else {
throw new IllegalArgumentException("Unknown graph timespan: " + interval);
}
}
}
}