/*******************************************************************************
* ALMA - Atacama Large Millimeter Array
* Copyright (c) ESO - European Southern Observatory, 2011
* (in the framework of the ALMA collaboration).
* All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*******************************************************************************/
package alma.acs.monitoring.DAO;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import alma.acs.monitoring.MonitorPointTimeSeries;
import alma.acs.monitoring.MonitorPointValue;
/**
* Creates a CLOB string intended for Oracle TMCDB storage from MonitorPointTimeSeries.
* TODO: Move this to the Oracle DAO and keep the ACS blobber layer free of CLOBs.
*
* @author hsommer
*/
public class Clobber
{
private final Logger logger;
/**
* @param logger
*/
public Clobber(Logger logger) {
this.logger = logger;
}
/**
* @param mpTs
* @return The CLOB, or null if the monitor point is of a floating number type and contains NaN
*/
public String generateClob(MonitorPointTimeSeries mpTs) {
List<MonitorPointValue> timeSeriesData = mpTs.getDataList();
StringBuilder clobBld = new StringBuilder();
for (int i = 0; i < timeSeriesData.size(); i++) {
MonitorPointValue mpVal = timeSeriesData.get(i);
List<Object> mpValData = mpVal.getData();
if (!mpValData.isEmpty()) {
// print the time
if (i > 0) {
clobBld.append('|');
}
clobBld.append(mpVal.getTime()).append('|');
// We check only the first object;
// other objects in mpValData are expected to be of the same type and same NaN status
Object sampleObj = mpValData.get(0);
// This if-else structure will allow us to use type-specific DecimalFormat etc masks
if (sampleObj instanceof Integer) {
appendValueString(mpValData, clobBld);
}
else if (sampleObj instanceof Long) {
appendValueString(mpValData, clobBld);
}
else if (sampleObj instanceof Float) {
// Skip NaN values (COMP-5564)
if (((Float)sampleObj).isNaN()) {
return null;
}
appendValueString(mpValData, clobBld);
}
else if (sampleObj instanceof Double) {
// Skip NaN values (COMP-5564)
if (((Double)sampleObj).isNaN() ) {
return null;
}
appendValueString(mpValData, clobBld);
}
else if (sampleObj instanceof Boolean) {
// according to http://jira.alma.cl/browse/COMP-8496, we want to store
// "1" for true and "0" for false. Thus cannot use Boolean.toString().
List<Object> boolStrings = new ArrayList<Object>(mpValData.size());
for (int j = 0; j < mpValData.size(); j++) {
boolStrings.add((((Boolean)mpValData.get(j)).booleanValue() ? "1" : "0"));
}
appendValueString(boolStrings, clobBld);
}
else if (sampleObj instanceof String) {
appendValueString(mpValData, clobBld);
}
else {
logger.info("Unexpected data type " + sampleObj.getClass().getName() + " found, coming from Corba type " + mpTs.getCorbaTypeId());
clobBld.append("?");
}
}
}
// TODO: Must we keep this trailing newline char from the legacy implementation?
clobBld.append('\n');
return clobBld.toString();
}
/**
* Appends the single value or space-separated list of values given in mpValData.
*
* TODO: Pass formatting info if needed.
* @param mpValData
* @param clobBld
*/
private void appendValueString(List<Object> mpValData, StringBuilder clobBld) {
for (int j = 0; j < mpValData.size(); j++) {
Object valueObj = mpValData.get(j);
clobBld.append(valueObj.toString());
if (j < mpValData.size() - 1) {
clobBld.append(' ');
}
}
}
}