com.hp.autonomy.aci.content.printfields.PrintFields Maven / Gradle / Ivy
Show all versions of content-parameter-api Show documentation
/*
* Copyright 2009-2015 Hewlett-Packard Development Company, L.P.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
*/
package com.hp.autonomy.aci.content.printfields;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Helper class for building printfields, such as those used in the printfields parameter of a query.
* Individual field names are represented as Strings and deduplicated where possible in a case-sensitive manner. No
* attempt is currently made to interpret wildcards intelligently.
*
* This class makes no attempt at internal synchronization and is not safe to be used by multiple threads without
* external synchronization.
*/
public class PrintFields implements Iterable {
private static final Pattern INVALID = Pattern.compile(".*[,\\+\\s].*");
private static final Pattern SEPARATORS = Pattern.compile("[,\\+\\s]");
private final Set values = new LinkedHashSet();
/**
* Creates a new instance using the field names provided.
*
* @param fields The field names
*/
public PrintFields(final Iterable fields) {
doAppend(fields);
}
/**
* Creates a new instance using the field names provided.
*
* @param fields The field names
*/
public PrintFields(final String... fields) {
doAppend(Arrays.asList(fields));
}
/**
* Appends the given field names to this instance.
*
* @param fields The names of the fields
* @return {@code this}
*/
public PrintFields append(final Iterable fields) {
return doAppend(fields);
}
/**
* Appends the given field names to this instance.
*
* @param fields The names of the fields
* @return {@code this}
*/
public PrintFields append(final String... fields) {
return doAppend(Arrays.asList(fields));
}
private PrintFields doAppend(final Iterable fields) {
Validate.notNull(fields, "Values must not be null");
// In case of nulls, build a new Set and then add them all
final Set newFields = new LinkedHashSet();
for(final String field : fields) {
Validate.isTrue(StringUtils.isNotBlank(field), "One of the fields provided was blank");
Validate.isTrue(!INVALID.matcher(field).matches(), "A field name cannot contain a plus, comma or whitespace: [" + field + ']');
newFields.add(field);
}
this.values.addAll(newFields);
return this;
}
/**
* {@link Iterator} for the field names. Removing elements is not currently supported.
*
* @return A suitable iterator
*/
@Override
public Iterator iterator() {
return values.iterator();
}
/**
* The number of field names currently in this instance. Note that the number of fields actually returned from a
* query could be considerably different.
*
* @return Number of fields
*/
public int size() {
return values.size();
}
/**
* Whether or not size is 0. An empty {@code PrintFields} will have an empty string representation, which IDOL will
* interpret as matching no content fields.
*
* @return {@code true} if and only if {@code size() == 0}
*/
public boolean isEmpty() {
return values.isEmpty();
}
/**
* Two {@code PrintFields} objects are considered equal if they contain the same set of field names. Equality is
* order invariant but case-sensitive. Note that IDOL can be configured to be either case-sensitive or
* case-insensitive so this class errs on the side of caution.
*
* @param obj A object to test for equality
* @return {@code true} if the {@code obj} is equal to {@code this}
*/
@Override
public boolean equals(final Object obj) {
return this == obj || obj instanceof PrintFields && this.values.equals(((PrintFields) obj).values);
}
/**
* A suitable hashcode implementation.
*
* @return The hashcode
*/
@Override
public int hashCode() {
return values.hashCode();
}
/**
* A {@code String} representation of the databases, suitable for use in a query or getcontent
* action.
*
* @return The string representation
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
for(final String value : this) {
// Oddly, this doesn't need URL encoding
builder.append(value).append('+');
}
if(builder.length() != 0) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
/**
* Converts an iterable of strings into a {@code PrintFields}. This method can be more efficient than using the
* equivalent constructor but the returned object might be backed by the object provided.
*
* @param fields The references to convert
* @return An equivalent instance of {@code PrintFields}
*/
public static PrintFields from(final Iterable fields) {
return (fields instanceof PrintFields) ? (PrintFields)fields : new PrintFields(fields);
}
/**
* Parser for a printfields string.
*
* @param printFields A valid IDOL printfields
* @return A parsed {@code PrintFields}
*/
public static PrintFields parse(final String printFields) {
Validate.notNull(printFields, "PrintFields must not be null");
final Set printFieldsSet = new LinkedHashSet(Arrays.asList(SEPARATORS.split(printFields)));
printFieldsSet.remove("");
return new PrintFields(printFieldsSet);
}
}