Java tutorial
/* * Copyright 2015 Robert von Burg <eitch@eitchnet.ch> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ch.eitchnet.csvrestendpoint.marshaller; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVRecord; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import ch.eitchnet.csvrestendpoint.model.CsvQuery; import ch.eitchnet.csvrestendpoint.util.CsvFormatBuilder; import ch.eitchnet.utils.collections.Paging; import ch.eitchnet.utils.helper.StringHelper; /** * @author Robert von Burg <eitch@eitchnet.ch> */ public class CsvDataToJsonMarshaller implements CsvDataMarshaller<JsonObject> { private int draw; private String query; private String sortBy; private boolean ascending; private int pageSize; private int page; private List<String> queryFields; private List<String> returnFields; private CSVFormat csvFormat; public Charset charset; public CsvDataToJsonMarshaller(CsvQuery query) { this.draw = query.getDraw(); this.query = StringHelper.isEmpty(query.getQuery()) ? null : query.getQuery().toLowerCase(); this.sortBy = StringHelper.isEmpty(query.getSortBy()) ? null : query.getSortBy(); this.ascending = query.isAscending(); this.pageSize = query.getPageSize(); this.page = query.getPage(); this.queryFields = Arrays.asList(query.parseQueryFields()); this.returnFields = Arrays.asList(query.parseReturnFields()); this.csvFormat = new CsvFormatBuilder(query).build(); if (StringHelper.isEmpty(query.getCharset())) this.charset = Charset.forName("UTF-8"); else this.charset = Charset.forName(query.getCharset()); } @Override public CSVFormat getCsvFormat() { return this.csvFormat; } @Override public Charset getCharset() { return this.charset; } @Override public JsonObject marshall(CSVParser csvParser) { // validate any references to column names Map<String, Integer> headerMap = csvParser.getHeaderMap(); validate(headerMap); // filter List<CSVRecord> allRecords = new ArrayList<>(); long dataSetSize = 0; for (CSVRecord record : csvParser) { dataSetSize++; if (isSelected(headerMap, record)) allRecords.add(record); } // sort if (StringHelper.isNotEmpty(sortBy)) { Integer columnIndex = headerMap.get(sortBy); if (this.ascending) allRecords.sort((r1, r2) -> r1.get(columnIndex).compareTo(r2.get(columnIndex))); else allRecords.sort((r1, r2) -> r2.get(columnIndex).compareTo(r1.get(columnIndex))); } // paging Paging<CSVRecord> paging = Paging.asPage(allRecords, this.pageSize, this.page); // get page List<CSVRecord> page = paging.getPage(); // build JSON response JsonObject root = new JsonObject(); root.addProperty("msg", "-"); root.addProperty("draw", this.draw); root.addProperty("dataSetSize", dataSetSize); root.addProperty("nrOfElements", paging.getNrOfElements()); if (StringHelper.isNotEmpty(sortBy)) root.addProperty("sortBy", this.sortBy); root.addProperty("ascending", this.ascending); root.addProperty("nrOfPages", paging.getNrOfPages()); root.addProperty("pageSize", paging.getPageSize()); root.addProperty("page", paging.getPageToReturn()); // prune any unwanted columns if (!this.returnFields.isEmpty()) { headerMap.keySet().retainAll(this.returnFields); } // add items JsonArray data = new JsonArray(); for (CSVRecord record : page) { JsonObject element = new JsonObject(); for (Entry<String, Integer> entry : headerMap.entrySet()) { String column = entry.getKey(); String value = record.get(entry.getValue()); element.addProperty(column, value); } data.add(element); } root.add("data", data); return root; } private void validate(Map<String, Integer> headerMap) { if (this.query == null) return; if (StringHelper.isNotEmpty(this.sortBy)) { if (!headerMap.containsKey(this.sortBy)) { throw new IllegalArgumentException("SortBy column " + this.sortBy + " does not exist!"); } } if (!this.queryFields.isEmpty()) { for (String field : queryFields) { if (!headerMap.containsKey(field)) { throw new IllegalArgumentException("queryField column " + field + " does not exist!"); } } } if (!this.returnFields.isEmpty()) { for (String field : returnFields) { if (!headerMap.containsKey(field)) { throw new IllegalArgumentException("returnField column " + field + " does not exist!"); } } } } /** * Returns true if the given {@link CSVRecord} is to be selected * * @param headerMap * the map containing the column headers with the column index * * @param record * the {@link CSVRecord} to check * * @return true if the record is to be selected, false if not */ protected boolean isSelected(Map<String, Integer> headerMap, CSVRecord record) { if (StringHelper.isEmpty(this.query)) return true; if (this.queryFields.isEmpty()) { // iterate all possible fields and see if the query matches for (String value : record) { if (value.toLowerCase().contains(this.query)) return true; } } else { // iterate only the query fields for (String queryField : this.queryFields) { String value = record.get(queryField); if (value.toLowerCase().contains(this.query)) return true; } } return false; } }