use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-modules-public by infiniteautomation.
the class ReportChartCreator method createContent.
/**
* Uses the given parameters to create the data for the fields of this class. Once the content has been created the
* getters for the fields can be used to retrieve.
*
* @param host - Mango's hostname
* @param port - Mango's port
* @param reportInstance
* @param reportDao
* @param inlinePrefix
* if this is non-null, it implies that the content should be inline.
* @param createExportFile
*/
public void createContent(String host, int port, ReportInstance reportInstance, ReportDao reportDao, String inlinePrefix, boolean createExportFile) {
this.inlinePrefix = inlinePrefix;
reportInstance.setTranslations(translations);
// Use a stream handler to get the report data from the database.
StreamHandler handler = new StreamHandler(host, port, reportInstance.getXidMap(), reportInstance.getReportStartTime(), reportInstance.getReportEndTime(), IMAGE_WIDTH, createExportFile, translations);
// Process the report content with the handler.
if (Common.databaseProxy.getNoSQLProxy() == null)
reportDao.reportInstanceDataSQL(reportInstance.getId(), handler);
else
reportDao.reportInstanceDataNoSQL(reportInstance.getId(), handler);
pointStatistics = handler.getPointStatistics();
devices = handler.getDevices();
pointMap = handler.getStatisticsMap();
UsedImagesDirective inlineImages = new UsedImagesDirective();
SubjectDirective subjectDirective = new SubjectDirective(translations);
// Prepare the model for the content rendering.
Map<String, Object> model = new HashMap<String, Object>();
model.put("fmt", new MessageFormatDirective(translations));
model.put("subject", subjectDirective);
model.put("img", inlineImages);
model.put("instance", reportInstance);
model.put("timezone", timeZone.getID());
model.put("points", pointStatistics);
model.put("inline", inlinePrefix == null ? "" : "cid:");
model.put("devices", devices);
model.put("mapped", pointMap);
model.put("ALPHANUMERIC", DataTypes.ALPHANUMERIC);
model.put("BINARY", DataTypes.BINARY);
model.put("MULTISTATE", DataTypes.MULTISTATE);
model.put("NUMERIC", DataTypes.NUMERIC);
model.put("IMAGE", DataTypes.IMAGE);
// Create the individual point charts
for (PointStatistics pointStat : pointStatistics) {
PointTimeSeriesCollection ptsc = new PointTimeSeriesCollection(timeZone);
if (pointStat.getNumericTimeSeries() != null)
ptsc.addNumericTimeSeries(pointStat.getNumericTimeSeries());
else if (pointStat.getDiscreteTimeSeries() != null)
ptsc.addDiscreteTimeSeries(pointStat.getDiscreteTimeSeries());
if (ptsc.hasData()) {
if (inlinePrefix != null)
model.put("chartName", inlinePrefix + pointStat.getChartName());
pointStat.setImageData(ImageChartUtils.getChartData(ptsc, POINT_IMAGE_WIDTH, POINT_IMAGE_HEIGHT, reportInstance.getReportStartTime(), reportInstance.getReportEndTime()));
}
// in the report I'll add it here while we are already iterating over the points that are included in the report
if (pointStat.getDataType() == DataTypes.IMAGE) {
ValueChangeCounter pointStatisticsGenerator = (ValueChangeCounter) pointStat.getStats();
ImageValue img = (ImageValue) (pointStatisticsGenerator.getLastValue());
if (img != null) {
try {
pointStat.setImageData(img.getImageData());
if (inlinePrefix != null)
model.put("chartName", inlinePrefix + pointStat.getChartName());
else {
// serve up the image using the reportImageChart servlet instead of the imageValueServlet that is used on flipbook page
// The path comes from the servlet path definition in web.xml.
model.put("chartName", IMAGE_SERVLET + pointStat.getChartName());
}
} catch (IOException e) {
LOG.error("failed to retrieve image data", e);
}
}
}
}
// consolidated chart
PointTimeSeriesCollection ptsc = handler.getPointTimeSeriesCollection();
if (ptsc.hasData()) {
if (inlinePrefix != null)
model.put("chartName", inlinePrefix + IMAGE_CONTENT_ID);
else {
chartName = "r" + reportInstance.getId() + ".png";
// The path comes from the servlet path definition in web.xml.
model.put("chartName", IMAGE_SERVLET + chartName);
}
imageData = ImageChartUtils.getChartData(ptsc, true, IMAGE_WIDTH, IMAGE_HEIGHT, reportInstance.getReportStartTime(), reportInstance.getReportEndTime());
}
List<EventInstance> events = null;
if (reportInstance.getIncludeEvents() != ReportVO.EVENTS_NONE) {
events = reportDao.getReportInstanceEvents(reportInstance.getId());
model.put("includeEvents", true);
model.put("events", events);
} else
model.put("includeEvents", false);
List<ReportUserComment> comments = null;
if (reportInstance.isIncludeUserComments()) {
comments = reportDao.getReportInstanceUserComments(reportInstance.getId());
// Only provide the list of point comments to the report. The event comments have already be correlated
// into the events list.
List<ReportUserComment> pointComments = new ArrayList<ReportUserComment>();
for (ReportUserComment c : comments) {
if (c.getCommentType() == UserCommentVO.TYPE_POINT)
pointComments.add(c);
}
model.put("includeUserComments", true);
model.put("userComments", pointComments);
} else
model.put("includeUserComments", false);
// Create the template.
Template ftl;
StringWriter writer = new StringWriter();
FileReader reader = null;
try {
File templateFile = ReportCommon.instance.getTemplateFile(reportInstance.getTemplateFile());
reader = new FileReader(templateFile);
ftl = new Template(reportInstance.getName(), reader, Common.freemarkerConfiguration);
ftl.process(model, writer);
} catch (FileNotFoundException e) {
LOG.error("Unable to find report template file: " + reportInstance.getName());
} catch (IOException e) {
// Couldn't load the template?
throw new ShouldNeverHappenException(e);
} catch (Exception e) {
// Error processing the FTL?
throw new ShouldNeverHappenException(e);
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e) {
LOG.error("Error closing template file reader: " + e.getMessage(), e);
}
}
// Save the content
html = writer.toString();
subject = subjectDirective.getSubject();
inlineImageList = inlineImages.getImageList();
// Save the export file (if any)
exportFile = handler.exportFile;
if (createExportFile && events != null) {
try {
eventFile = File.createTempFile("tempEventCSV", ".csv");
new EventCsvStreamer(new PrintWriter(new FileWriter(eventFile)), events, translations);
} catch (IOException e) {
LOG.error("Failed to create temp event file", e);
}
}
if (createExportFile && comments != null) {
try {
commentFile = File.createTempFile("tempCommentCSV", ".csv");
new UserCommentCsvStreamer(new PrintWriter(new FileWriter(commentFile)), comments, translations);
} catch (IOException e) {
LOG.error("Failed to create temp comment file", e);
}
}
}
use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-core-public by infiniteautomation.
the class DataPointDetailsDwr method getFlipbookData.
@DwrPermission(user = true)
public ProcessResult getFlipbookData(int limit) {
HttpServletRequest request = WebContextFactory.get().getHttpServletRequest();
DataPointVO vo = Common.getUser(request).getEditPoint();
PointValueFacade facade = new PointValueFacade(vo.getId());
List<PointValueTime> values = facade.getLatestPointValues(limit);
Collections.reverse(values);
List<ImageValueBean> result = new ArrayList<ImageValueBean>();
for (PointValueTime pvt : values) {
ImageValue imageValue = (ImageValue) pvt.getValue();
String uri = ImageValueServlet.servletPath + ImageValueServlet.historyPrefix + pvt.getTime() + "_" + vo.getId() + "." + imageValue.getTypeExtension();
result.add(new ImageValueBean(Functions.getTime(pvt), uri));
}
ProcessResult response = new ProcessResult();
response.addData("images", result);
addAsof(response);
return response;
}
use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-core-public by infiniteautomation.
the class PointValueDaoSQL method savePointValueImpl.
long savePointValueImpl(final int pointId, final PointValueTime pointValue, final SetPointSource source, boolean async) {
DataValue value = pointValue.getValue();
final int dataType = DataTypes.getDataType(value);
double dvalue = 0;
String svalue = null;
if (dataType == DataTypes.IMAGE) {
ImageValue imageValue = (ImageValue) value;
dvalue = imageValue.getType();
if (imageValue.isSaved())
svalue = Long.toString(imageValue.getId());
} else if (value.hasDoubleRepresentation())
dvalue = value.getDoubleValue();
else
svalue = value.getStringValue();
// Check if we need to create an annotation.
long id;
try {
if (svalue != null || source != null || dataType == DataTypes.IMAGE)
async = false;
id = savePointValue(pointId, dataType, dvalue, pointValue.getTime(), svalue, source, async);
} catch (ConcurrencyFailureException e) {
// Still failed to insert after all of the retries. Store the data
synchronized (UNSAVED_POINT_VALUES) {
UNSAVED_POINT_VALUES.add(new UnsavedPointValue(pointId, pointValue, source));
}
return -1;
}
// Check if we need to save an image
if (dataType == DataTypes.IMAGE) {
ImageValue imageValue = (ImageValue) value;
if (!imageValue.isSaved()) {
imageValue.setId(id);
File file = new File(Common.getFiledataPath(), imageValue.getFilename());
// Write the file.
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
StreamUtils.transfer(new ByteArrayInputStream(imageValue.getData()), out);
} catch (IOException e) {
// Rethrow as an RTE
throw new ImageSaveException(e);
} finally {
try {
if (out != null)
out.close();
} catch (IOException e) {
// no op
}
}
// Allow the data to be GC'ed
imageValue.setData(null);
}
}
clearUnsavedPointValues();
clearUnsavedPointUpdates();
return id;
}
use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-core-public by infiniteautomation.
the class PointValueDaoSQL method createDataValue.
DataValue createDataValue(ResultSet rs, int firstParameter) throws SQLException {
int dataType = rs.getInt(firstParameter);
DataValue value;
switch(dataType) {
case (DataTypes.NUMERIC):
value = new NumericValue(rs.getDouble(firstParameter + 1));
break;
case (DataTypes.BINARY):
value = new BinaryValue(rs.getDouble(firstParameter + 1) == 1);
break;
case (DataTypes.MULTISTATE):
value = new MultistateValue(rs.getInt(firstParameter + 1));
break;
case (DataTypes.ALPHANUMERIC):
String s = rs.getString(firstParameter + 2);
if (s == null)
s = rs.getString(firstParameter + 3);
value = new AlphanumericValue(s);
break;
case (DataTypes.IMAGE):
value = new ImageValue(Integer.parseInt(rs.getString(firstParameter + 2)), rs.getInt(firstParameter + 1));
break;
default:
value = null;
}
return value;
}
use of com.serotonin.m2m2.rt.dataImage.types.ImageValue in project ma-core-public by infiniteautomation.
the class ImageValueServlet method doGet.
/**
* @TODO(security): Validate the point access against the user. If anonymous, make sure the view allows public
* access to the point.
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
String imageInfo = request.getPathInfo();
try {
// Remove the / and the extension
int dot = imageInfo.indexOf('.');
String extension = imageInfo.substring(dot + 1, imageInfo.length()).toLowerCase();
imageInfo = imageInfo.substring(1, dot);
// Split by underscore.
String[] imageBits = imageInfo.split("_");
// Get the data.
String timestamp = imageBits[0];
int dataPointId = Integer.parseInt(imageBits[1]);
int scalePercent = getIntRequestParameter(request, "p", -1);
int width = getIntRequestParameter(request, "w", -1);
int height = getIntRequestParameter(request, "h", -1);
// DataPointRT dp = Common.ctx.getRuntimeManager().getDataPoint(dataPointId);
// Permissions.ensureDataPointReadPermission(Common.getUser(request), dp.getVO());
PointValueFacade pointValueFacade = new PointValueFacade(dataPointId);
PointValueTime pvt = null;
if (timestamp.startsWith(historyPrefix)) {
// Find the point with the given timestamp
long time = Long.parseLong(timestamp.substring(historyPrefix.length()));
pvt = pointValueFacade.getPointValueAt(time);
} else
// Use the latest value
pvt = pointValueFacade.getPointValue();
if (pvt == null || pvt.getValue() == null || !(pvt.getValue() instanceof ImageValue)) {
LOG.warn("Invalid pvt: " + pvt);
response.sendError(HttpStatus.SC_NOT_FOUND);
} else {
ImageValue imageValue = (ImageValue) pvt.getValue();
byte[] data = imageValue.getImageData();
if (scalePercent != -1) {
// Definitely going to be JPEG
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
// Scale the image
PercentScaledImage scaler = new PercentScaledImage(((float) scalePercent) / 100);
data = ImageUtils.scaleImage(scaler, data, new JpegImageFormat(0.85f));
} else if (width != -1 && height != -1) {
// Definitely going to be JPEG
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
// Scale the image
BoxScaledImage scaler = new BoxScaledImage(width, height);
data = ImageUtils.scaleImage(scaler, data, new JpegImageFormat(0.85f));
} else {
// Use the Image extension to se the Content Type
if ("jpg".equals(extension))
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
else if ("png".equals(extension))
response.setContentType(MediaType.IMAGE_PNG_VALUE);
else if ("gif".equals(extension))
response.setContentType(MediaType.IMAGE_GIF_VALUE);
}
response.getOutputStream().write(data);
}
} catch (FileNotFoundException e) {
LOG.warn("", e);
} catch (InterruptedException e) {
LOG.warn("", e);
} catch (StringIndexOutOfBoundsException e) {
LOG.warn("", e);
} catch (NumberFormatException e) {
LOG.warn("", e);
} catch (ArrayIndexOutOfBoundsException e) {
LOG.warn("", e);
} catch (IllegalArgumentException e) {
LOG.warn("", e);
}
}
Aggregations