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

com.basistech.rosette.dm.BaseAttribute Maven / Gradle / Ivy

There is a newer version: 3.0.6
Show newest version
/*
* Copyright 2018 Basis Technology Corp.
*
* 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 com.basistech.rosette.dm;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import lombok.EqualsAndHashCode;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Base class for attributes that annotate text.
 * 

* Each attribute contains an extended properties map of {@code String} * to {@code Object} to hold optional "user-defined" elements. An * extended property key should be prefixed with a reversed domain name, * e.g. {@code "com.example.key"}. Keys that are valid Java identifiers * are reserved for use by Basis Technology. */ @EqualsAndHashCode public abstract class BaseAttribute implements Serializable { private static final long serialVersionUID = 250L; protected Map extendedProperties; protected BaseAttribute() { this.extendedProperties = ImmutableMap.of(); } protected BaseAttribute(Map extendedProperties) { if (extendedProperties != null) { if (extendedProperties instanceof ImmutableMap) { this.extendedProperties = extendedProperties; } else { this.extendedProperties = ImmutableMap.copyOf(extendedProperties); } } else { this.extendedProperties = ImmutableMap.of(); } } /** * Returns the extended properties. All attributes store a map of extended * properties. This mechanism is available to add additional data to * attributes. * * @return the map of extended properties */ public Map getExtendedProperties() { return extendedProperties; } /** * Called only from Jackson to implement deserialization via JsonAnySetter. * @param name property name * @param value property value */ protected void setExtendedProperty(String name, Object value) { /* This is only called in deserialization. So we do something * to work around the read-only collection. */ if (extendedProperties.size() > 0) { extendedProperties = ImmutableMap.builder().putAll(extendedProperties).put(name, value).build(); } else { extendedProperties = ImmutableMap.of(name, value); } } protected MoreObjects.ToStringHelper toStringHelper() { return MoreObjects.toStringHelper(this).omitNullValues() .add("extendedProperties", extendedProperties); } @Override public String toString() { return toStringHelper().toString(); } /** * Utility method for the 'no empty lists' convention. Takes a list, * if empty returns null, else returns a copy of the list. Use this * in constructors of the the immutable objects, not in their builders. * @param listToBuild the list * @param the type of the list * @return a list, or null. */ protected static List listOrNull(List listToBuild) { // note: Guava's nullable business is an option here, but it's a lot to drag in at the moment. if (listToBuild == null || listToBuild.size() == 0) { return null; } else { return ImmutableList.copyOf(listToBuild); } } /** * Utility method for the 'no empty sets' convention. Takes a set, * if empty returns null, else returns a copy of the set. Use this * in constructors of the the immutable objects, not in their builders. * @param setToBuild the list * @param the type of the list * @return a list, or null. */ static Set setOrNull(Set setToBuild) { // note: Guava's nullable business is an option here, but it's a lot to drag in at the moment. if (setToBuild == null || setToBuild.size() == 0) { return null; } else { return ImmutableSet.copyOf(setToBuild); } } static Map mapOrNull(Map mapToCopy) { if (mapToCopy == null || mapToCopy.size() == 0) { return null; } else { return ImmutableMap.copyOf(mapToCopy); } } /** * Base class for builders for the subclasses of {@link com.basistech.rosette.dm.BaseAttribute}. */ public abstract static class Builder> { private ImmutableMap.Builder extendedPropertiesBuilder; private ImmutableMap extendedPropertiesToCopy; /** * Constructs a builder with no data. */ protected Builder() { /* Usually we don't have any. So start with an empty map, which the constructor above will 'copy' * cheaply due to optimization inside ImmutableMap. */ this.extendedPropertiesToCopy = ImmutableMap.of(); } /** * Constructs a builder with values derived from an existing object. * * @param toCopy the object to copy */ protected Builder(BaseAttribute toCopy) { /* Just treat the copy as an immutable item until the caller asks us to change it. */ this.extendedPropertiesToCopy = (ImmutableMap) toCopy.extendedProperties; } protected abstract B getThis(); /** * Cook up a map to pass to the constructor. * If we have an unmodified map to 'copy', we just use it. Otherwise, we build from the builder. * @return the map. */ protected Map buildExtendedProperties() { if (extendedPropertiesToCopy != null) { return extendedPropertiesToCopy; } else if (extendedPropertiesBuilder != null) { return extendedPropertiesBuilder.build(); } else { return null; } } /** * Adds an extended value key-value pair. * * @param key the key * @param value the value * @return this */ public B extendedProperty(String key, Object value) { if (extendedPropertiesBuilder == null) { /* if we don't have a builder yet, forget 'toCopy' in favor of a builder. */ extendedPropertiesBuilder = ImmutableMap.builder(); if (extendedPropertiesToCopy != null) { extendedPropertiesBuilder.putAll(extendedPropertiesToCopy); extendedPropertiesToCopy = null; } } this.extendedPropertiesBuilder.put(key, value); return getThis(); } /** * Replace the entire extended property map. * @param properties a map of extended properties. * @return this. */ public B extendedProperties(Map properties) { /* Turn this into the version we copy. */ if (properties instanceof ImmutableMap) { this.extendedPropertiesToCopy = (ImmutableMap) properties; } else { this.extendedPropertiesToCopy = ImmutableMap.copyOf(properties); } /* No builder. */ this.extendedPropertiesBuilder = null; return getThis(); } /** * Add all the entries of a list to another list, but don't NPE if the 'to be added' list is null. * @param list list to add to. * @param toAdd list to add. * @param type of elements. */ protected static void addAllToList(List list, List toAdd) { if (toAdd != null) { list.addAll(toAdd); } } /** * Add all the entries of a set to another set, but don't NPE if the 'to be added' collection is null. * @param set set to add to. * @param toAdd set to add. * @param type of elements. */ protected static void addAllToSet(Set set, Set toAdd) { if (toAdd != null) { set.addAll(toAdd); } } protected static List nullOrList(List newListValue) { if (newListValue == null) { return Lists.newArrayList(); } else { return newListValue; } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy