com.diffeo.dossier.fc.StringCounter.java Source code

Java tutorial

Introduction

Here is the source code for com.diffeo.dossier.fc.StringCounter.java

Source

/**
 * dossier.fc Feature Collections
 *
 * This software is released under an MIT/X11 open source license.
 * Copyright 2014 Diffeo, Inc.
 *
 */

package com.diffeo.dossier.fc;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.dataformat.cbor.CBORGenerator;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

/**
 * String multi-set feature.
 *
 * This class is a {@link Feature} implementation that can be stored
 * in a {@link FeatureCollection}, where the feature potentially has
 * multiple values, with counts associated with each.  The count is
 * typically a word frequency or other similar counter; if all strings
 * are equally valid, the counts can all be 1.
 *
 * <pre>
 * FeatureCollection fc = new FeatureCollection();
 * StringCounter name = new StringCounter();
 * // Both of the following set their feature counts to 1
 * name.getStrings().put("Bill Clinton", 1);
 * name.add("William Jefferson Clinton", 1);
 * fc.getFeatures().put("name", name);
 * </pre>
 */
@JsonSerialize(using = StringCounter.Serializer.class)
public class StringCounter implements Feature {
    private Map<String, Integer> strings;
    private boolean readOnly;

    public StringCounter() {
        strings = new HashMap<String, Integer>();
        readOnly = false;
    }

    /**
     * Get the dictionary of strings and counts.
     *
     * If the feature is read-only, the returned map is unmodifiable.
     * Otherwise it can be changed freely.
     *
     * @return  Map from string name to integer count
     */
    @JsonValue
    public Map<String, Integer> getStrings() {
        if (readOnly) {
            return Collections.unmodifiableMap(strings);
        } else {
            return strings;
        }
    }

    /**
     * Completely replace the dictionary of strings and counts.
     *
     * @param s  New map from string to count
     */
    public void setStrings(Map<String, Integer> s) {
        if (readOnly) {
            throw new UnsupportedOperationException();
        }
        strings = s;
    }

    /**
     * Add some value to the count for a key.
     *
     * If the key is not already contained in the collection, add
     * it as though its count was previously 0.  This can raise an
     * exception of the collection is read-only.
     *
     * @param key  String key to update
     * @param n    Amount to add to the count
     */
    public void add(String key, int n) {
        Map<String, Integer> s = getStrings();
        int count = 0;
        Integer oldCount = s.get(key);
        if (oldCount != null) {
            count = oldCount.intValue();
        }
        count += n;
        s.put(key, new Integer(count));
    }

    /**
     * Get the read-only flag.
     *
     * @return  Current value of read-only flag
     */
    public boolean isReadOnly() {
        return readOnly;
    }

    /**
     * Set the read-only flag.
     *
     * @param ro  New value of read-only flag
     */
    public void setReadOnly(boolean ro) {
        readOnly = ro;
    }

    /* Object methods */

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        if (obj.getClass() != getClass()) {
            return false;
        }
        StringCounter rhs = (StringCounter) obj;
        return new EqualsBuilder().append(strings, rhs.strings).isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(43, 79).append(strings).toHashCode();
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this).append("strings", strings).toString();
    }

    /* JSON/CBOR serialization */

    public static class Serializer extends StdSerializer<StringCounter> {
        public Serializer() {
            super(StringCounter.class);
        }

        @Override
        public void serialize(StringCounter value, JsonGenerator jgen, SerializerProvider provider)
                throws IOException {
            if (jgen instanceof CBORGenerator) {
                ((CBORGenerator) jgen).writeTag(FeatureCollection.CBOR_STRING_COUNTER);
            }
            provider.defaultSerializeValue(value.getStrings(), jgen);
        }
    }

    @JsonCreator
    public static StringCounter fromJson(Map<String, Integer> s) {
        StringCounter sc = new StringCounter();
        sc.setStrings(s);
        return sc;
    }
}