All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.gov.gchq.gaffer.data.generator.CsvGenerator Maven / Gradle / Ivy

/*
 * Copyright 2016-2019 Crown Copyright
 *
 * 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 uk.gov.gchq.gaffer.data.generator;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.apache.commons.lang3.StringUtils;

import uk.gov.gchq.gaffer.data.element.Element;
import uk.gov.gchq.gaffer.data.element.IdentifierType;
import uk.gov.gchq.koryphe.Since;
import uk.gov.gchq.koryphe.Summary;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.regex.Pattern;

/**
 * Generates a CSV string for each {@link Element}, based on the fields and constants provided.
 * 

* For example, if you provide:

 *  fields=[prop1, SOURCE, DESTINATION, prop2, GROUP] and constants=["constant1", "constant2"]
 * 
* The output will be:
 *  prop1Value,sourceValue,destinationValue,prop2,groupValue,constant1,constant2
 * 
*/ @Since("1.0.0") @Summary("Generates a CSV string for each element") public class CsvGenerator implements OneToOneObjectGenerator { public static final String GROUP = "GROUP"; public static final String COMMA = ","; private static final Pattern COMMA_PATTERN = Pattern.compile(COMMA); private static final String COMMA_REPLACEMENT_DEFAULT = " "; private LinkedHashMap fields = new LinkedHashMap<>(); private LinkedHashMap constants = new LinkedHashMap<>(); /** * When set to true, each value in the csv will be wrapped in quotes. */ private boolean quoted = false; /** * Replaces commas with this string. If null then no replacement is done. */ private String commaReplacement = COMMA_REPLACEMENT_DEFAULT; /** * Attempts to find the value of a field from a given {@link Element}, * corresponding to a provided key, where the key is the name of the field. * * @param element the Element from which to retrieve a field value * @param key the name of the field to be retrieved * @return the value of the field */ private Object getFieldValue(final Element element, final String key) { final IdentifierType idType = IdentifierType.fromName(key); final Object value; if (null == idType) { if (GROUP.equals(key)) { value = element.getGroup(); } else { value = element.getProperty(key); } } else { value = element.getIdentifier(idType); } return value; } public LinkedHashMap getFields() { return fields; } public void setFields(final LinkedHashMap fields) { if (null == fields) { this.fields = new LinkedHashMap<>(); } this.fields = fields; } public LinkedHashMap getConstants() { return constants; } public void setConstants(final LinkedHashMap constants) { if (null == constants) { this.constants = new LinkedHashMap<>(); } this.constants = constants; } @Override public String _apply(final Element element) { final StringBuilder strBuilder = new StringBuilder(); for (final String field : fields.keySet()) { final Object value = getFieldValue(element, field); if (null != value) { strBuilder.append(quoteString(value)); } strBuilder.append(COMMA); } if (!constants.isEmpty()) { for (final String constant : constants.keySet()) { strBuilder.append(quoteString(constant)); strBuilder.append(COMMA); } } if (strBuilder.length() < 1) { return ""; } return strBuilder.substring(0, strBuilder.length() - 1); } /** * Generates a CSV String from, if present, the fields and constants * * @return a CSV String of all fields, or constants, or both. */ @JsonIgnore public String getHeader() { if (fields.isEmpty()) { if (constants.isEmpty()) { return ""; } return getHeaderFields(constants.values()); } if (constants.isEmpty()) { return getHeaderFields(fields.values()); } return getHeaderFields(fields.values()) + COMMA + getHeaderFields(constants.values()); } private String getHeaderFields(final Collection fields) { return StringUtils.join(fields.stream().map(this::quoteString).toArray(), COMMA); } private String quoteString(final Object s) { String value; if (null == s) { value = ""; } else { value = s.toString(); } if (null != commaReplacement) { value = COMMA_PATTERN.matcher(value).replaceAll(commaReplacement); } if (quoted) { value = "\"" + value + "\""; } return value; } public boolean isQuoted() { return quoted; } public void setQuoted(final boolean quoted) { this.quoted = quoted; } public String getCommaReplacement() { return commaReplacement; } public void setCommaReplacement(final String commaReplacement) { this.commaReplacement = commaReplacement; } public static class Builder { private LinkedHashMap fields = new LinkedHashMap<>(); private LinkedHashMap constants = new LinkedHashMap<>(); private String commaReplacement = COMMA_REPLACEMENT_DEFAULT; private Boolean quoted; /** * Stores the group of an {@link Element}. * * @param columnHeader the group of the {@code Element} * @return a new {@link Builder} */ public Builder group(final String columnHeader) { fields.put(GROUP, columnHeader); return this; } /** * Stores any additional properties of an {@link Element}.
* For example: property("count", "3").
* This would add the "count" property with a value of "3" * * @param propertyName the name of the property * @param columnHeader the value of the property * @return a new {@link Builder} */ public Builder property(final String propertyName, final String columnHeader) { fields.put(propertyName, columnHeader); return this; } /** * Stores the Vertex of an {@link uk.gov.gchq.gaffer.data.element.Entity} * * @param columnHeader the vertex contained within the {@code Entity} * @return a new {@link Builder} */ public Builder vertex(final String columnHeader) { return identifier(IdentifierType.VERTEX, columnHeader); } /** * Stores the Source Vertex of an {@link uk.gov.gchq.gaffer.data.element.Edge}. * * @param columnHeader the source vertex * @return a new {@link Builder} */ public Builder source(final String columnHeader) { return identifier(IdentifierType.SOURCE, columnHeader); } /** * Stores the Destination Vertex of an {@link uk.gov.gchq.gaffer.data.element.Entity} * * @param columnHeader the destination vertex * @return a new {@link Builder} */ public Builder destination(final String columnHeader) { return identifier(IdentifierType.DESTINATION, columnHeader); } /** * Stores the Direction flag, indicating whether or not the {@link uk.gov.gchq.gaffer.data.element.Edge} * is directed. * * @param columnHeader true or false for if the {@code Edge} is directed or not * @return a new {@link Builder} */ public Builder direction(final String columnHeader) { return identifier(IdentifierType.DIRECTED, columnHeader); } /** * Allows an {@link IdentifierType} of an {@link Element} to be stored, such as * an {@link uk.gov.gchq.gaffer.data.element.Edge}'s {@link IdentifierType#MATCHED_VERTEX}. * * @param identifierType the {@code IdentifierType} of the {@code Element} * @param columnHeader the value for the corresponding field * @return a new {@link Builder} */ public Builder identifier(final IdentifierType identifierType, final String columnHeader) { fields.put(identifierType.name(), columnHeader); return this; } /** * Stores any constants specific to a given {@link Element}. * * @param key the name of the constant * @param value the value of the constant * @return a new {@link Builder} */ public Builder constant(final String key, final String value) { constants.put(key, value); return this; } /** * Stores the String with which any encountered commas will be replaced. * * @param commaReplacement the replacement String * @return a new {@link Builder} */ public Builder commaReplacement(final String commaReplacement) { this.commaReplacement = commaReplacement; return this; } /** * Stores the flag for whether or not each distinct value should be wrapped in quotation marks. * * @param quoted true or false * @return a new {@link Builder} */ public Builder quoted(final boolean quoted) { this.quoted = quoted; return this; } /** * Passes all of the configured fields and constants about an {@link Element} to a new {@link CsvGenerator}, * including the comma replacement String, and the flag for whether values should be quoted. * * @return a new {@code CsvGenerator}, containing all configured information */ public CsvGenerator build() { final CsvGenerator generator = new CsvGenerator(); generator.setFields(fields); generator.setConstants(constants); generator.setCommaReplacement(commaReplacement); if (null != quoted) { generator.setQuoted(quoted); } return generator; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy