/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.widget.searchandfilter.service.csv; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.UUID; import org.geomajas.configuration.AttributeInfo; import org.geomajas.configuration.PrimitiveAttributeInfo; import org.geomajas.configuration.PrimitiveType; import org.geomajas.layer.VectorLayer; import org.geomajas.layer.feature.Attribute; import org.geomajas.layer.feature.Feature; import org.geomajas.widget.searchandfilter.command.dto.CsvMetadata; import org.geomajas.widget.searchandfilter.service.FileDownloadService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Service to convert features to CSV. * * TODO only Primitive Attributes are supported atm. * * @author Kristof Heirwegh */ @Component public class CsvExportService { private final Logger log = LoggerFactory.getLogger(CsvExportService.class); private final Object lock = new Object(); @Autowired private FileDownloadService downloadService; public String buildCsvDocument(Feature[] features, VectorLayer layer, CsvMetadata metadata) throws IOException { synchronized (lock) { if (features == null || layer == null || metadata == null) { throw new IllegalArgumentException("All parameters are required."); } CsvBuilder cb = new CsvBuilder(metadata); List<AttributeInfo> attrs = layer.getLayerInfo().getFeatureInfo().getAttributes(); List<PrimitiveAttributeInfo> cols = new ArrayList<PrimitiveAttributeInfo>(); for (AttributeInfo ai : attrs) { // clean up list if (!ai.isHidden() && ai instanceof PrimitiveAttributeInfo) { if (metadata.useIdentifyingAttributesOnly()) { if (ai.isIdentifying()) { cols.add((PrimitiveAttributeInfo) ai); } } else { cols.add((PrimitiveAttributeInfo) ai); } } } addHeaderRow(cb, cols); for (Feature f : features) { addFeature(cb, cols, f); } return save(cb, metadata.getFilename(), metadata.getEncoding()); } } private String save(CsvBuilder cb, String description, String encoding) throws IOException { // save to file (might do this immediately, would be more efficient for // very large files) File f = File.createTempFile("geomajas-", ".csv"); String documentId = UUID.randomUUID().toString(); FileOutputStream fos = null; try { fos = new FileOutputStream(f); byte[] buffer = cb.getBuffer().toString().getBytes(encoding); fos.write(buffer); fos.flush(); log.debug("Wrote a temporary downloadfile: " + f.getName() + " - size: " + buffer.length + " bytes."); } finally { if (fos != null) { fos.close(); } } // add to list downloadService.addFile(documentId, f, description); return documentId; } private void addHeaderRow(CsvBuilder cb, List<PrimitiveAttributeInfo> cols) { for (AttributeInfo ai : cols) { cb.addField(ai.getLabel()); } cb.endRecord(); } @SuppressWarnings("rawtypes") private void addFeature(CsvBuilder cb, List<PrimitiveAttributeInfo> cols, Feature feature) { Map<String, Attribute> attrs = feature.getAttributes(); for (PrimitiveAttributeInfo ai : cols) { Object value = attrs.get(ai.getName()).getValue(); if (value == null) { cb.addField(""); } else { if (PrimitiveType.DATE.equals(ai.getType())) { cb.addField((Date) value); } else if (PrimitiveType.DOUBLE.equals(ai.getType())) { cb.addField((Double) value); } else if (PrimitiveType.FLOAT.equals(ai.getType())) { cb.addField((Float) value); } else if (PrimitiveType.INTEGER.equals(ai.getType())) { cb.addField((Integer) value); } else if (PrimitiveType.LONG.equals(ai.getType())) { cb.addField((Long) value); } else if (PrimitiveType.BOOLEAN.equals(ai.getType())) { cb.addField((Boolean) value); } else if (PrimitiveType.STRING.equals(ai.getType())) { cb.addField((String) value); } else { cb.addField(value.toString()); } } } cb.endRecord(); } }