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

org.carrot2.util.attribute.AttributeValueSets Maven / Gradle / Ivy

Go to download

Carrot2 search results clustering framework. Minimal functional subset (core algorithms and infrastructure, no document sources).

There is a newer version: 3.16.3
Show newest version

/*
 * Carrot2 project.
 *
 * Copyright (C) 2002-2013, Dawid Weiss, Stanisław Osiński.
 * All rights reserved.
 *
 * Refer to the full license file "carrot2.LICENSE"
 * in the root folder of the repository checkout or at:
 * http://www.carrot2.org/carrot2.LICENSE
 */

package org.carrot2.util.attribute;

import java.io.*;
import java.util.*;

import org.simpleframework.xml.ElementMap;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.core.*;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * Maintains a collection of {@link AttributeValueSet}s and provides methods for
 * serializing and deserializing attribute value sets from XML streams.
 */
@Root(name = "attribute-sets")
public class AttributeValueSets
{
    @ElementMap(name = "attribute-sets", entry = "attribute-set", key = "id", inline = true, attribute = true, required = false)
    Map attributeValueSets;

    @org.simpleframework.xml.Attribute(name = "default", required = false)
    String defaultAttributeValueSetId;

    /**
     * Creates an empty collection of attribute value sets.
     */
    public AttributeValueSets()
    {
        this.attributeValueSets = Maps.newLinkedHashMap();
    }

    /**
     * Adds an {@link AttributeValueSet} to this collection.
     * 
     * @param id unique identifier of the {@link AttributeValueSet} within the collection.
     * @param attributeValueSet {@link AttributeValueSet} to be added
     */
    public void addAttributeValueSet(String id, AttributeValueSet attributeValueSet)
    {
        if (attributeValueSets.containsKey(id))
        {
            throw new IllegalArgumentException("Attribute value set with id=" + id
                + " already exists");
        }

        attributeValueSets.put(id, attributeValueSet);
    }

    /**
     * Adds an {@link AttributeValueSet} to this collection replacing its label and
     * description. This method may sometimes be useful because {@link AttributeValueSet}s
     * are immutable with respect to their label and description.
     * 
     * @param id unique identifier of the {@link AttributeValueSet} within the collection.
     * @param attributeValueSet {@link AttributeValueSet} to be added
     * @param newLabel new label for the {@link AttributeValueSet}
     * @param newDescription new description for the {@link AttributeValueSet}
     */
    public void addAttributeValueSet(String id, AttributeValueSet attributeValueSet,
        String newLabel, String newDescription)
    {
        final AttributeValueSet newAttributeValueSet = new AttributeValueSet(newLabel,
            newDescription, attributeValueSet.baseAttributeValueSet);
        newAttributeValueSet.overridenAttributeValues
            .putAll(attributeValueSet.overridenAttributeValues);

        addAttributeValueSet(id, newAttributeValueSet);
    }

    /**
     * Returns identifiers of all {@link AttributeValueSet}s in this collection.
     * 
     * @return identifiers of all {@link AttributeValueSet}s in this collection.
     */
    public Set getAttributeValueSetIds()
    {
        return attributeValueSets.keySet();
    }

    /**
     * Returns the identifier of the default {@link AttributeValueSet} within this
     * {@link AttributeValueSets}. The default identifier can be null.
     */
    public String getDefaultAttributeValueSetId()
    {
        return defaultAttributeValueSetId;
    }

    /**
     * Sets the default attribute value set id for this {@link AttributeValueSets}. An
     * {@link AttributeValueSet} with this id must exist in this
     * {@link AttributeValueSets}.
     */
    public void setDefaultAttributeValueSetId(String defaultAttributeValueSetId)
    {
        if (defaultAttributeValueSetId != null
            && !attributeValueSets.containsKey(defaultAttributeValueSetId))
        {
            throw new IllegalArgumentException("Attribute value set with id: "
                + defaultAttributeValueSetId + " does not exist.");
        }
        this.defaultAttributeValueSetId = defaultAttributeValueSetId;
    }

    /**
     * Returns the {@link AttributeValueSet} corresponding to the provided id
     * or null if no {@link AttributeValueSet} corresponds to the
     * id.
     * 
     * @return the {@link AttributeValueSet} corresponding to the provided id
     *         or null if no {@link AttributeValueSet} corresponds to the
     *         id.
     */
    public AttributeValueSet getAttributeValueSet(String id)
    {
        return getAttributeValueSet(id, false);
    }

    /**
     * Returns the {@link AttributeValueSet} corresponding to the provided id
     * or the default {@link AttributeValueSet} (possibly null) if no
     * {@link AttributeValueSet} corresponds to the id.
     * 
     * @param id identifier of the {@link AttributeValueSet} to return
     * @param useDefault if true, the default {@link AttributeValueSet} will
     *            be returned if the {@link AttributeValueSet} with the provided id does
     *            not exist.
     * @return the {@link AttributeValueSet} corresponding to the provided id
     *         or the default {@link AttributeValueSet} (possibly null) if no
     *         {@link AttributeValueSet} corresponds to the id.
     */
    public AttributeValueSet getAttributeValueSet(String id, boolean useDefault)
    {
        if (attributeValueSets.containsKey(id))
        {
            return attributeValueSets.get(id);
        }
        else
        {
            return (useDefault ? getDefaultAttributeValueSet() : null);
        }
    }

    /**
     * Returns the default {@link AttributeValueSet} of this {@link AttributeValueSets} or
     * the first available {@link AttributeValueSet} if
     * {@link #getDefaultAttributeValueSetId()} is null. If this
     * {@link AttributeValueSets} is empty, null will be returned.
     */
    public AttributeValueSet getDefaultAttributeValueSet()
    {
        AttributeValueSet result = null;
        if (defaultAttributeValueSetId != null)
        {
            result = getAttributeValueSet(defaultAttributeValueSetId);
        }

        // Try the first attribute set
        if (result == null)
        {
            final Iterator iterator = attributeValueSets.values()
                .iterator();
            if (iterator.hasNext())
            {
                result = iterator.next();
            }
        }

        return result;
    }

    /**
     * Removes the {@link AttributeValueSet} corresponding to the provided id
     * from this collection. If any other {@link AttributeValueSet}s in this collection
     * are based on the set being removed, the associations are corrected accordingly,
     * i.e. sets based on the set being removed become based on the set the removed set is
     * based on. Also, if the removed {@link AttributeValueSet} was the default,
     * null will be set as this {@link AttributeValueSets}' default
     * {@link AttributeValueSet}. If no {@link AttributeValueSet} corresponds to the
     * provided id, no action is taken.
     * 
     * @param id identifier of the {@link AttributeValueSet} to be removed
     */
    public void removeAttributeValueSet(String id)
    {
        final AttributeValueSet attributeValueSet = attributeValueSets.get(id);
        if (attributeValueSet == null)
        {
            return;
        }

        attributeValueSets.remove(id);

        // Also, we need to fix the "based on" hierarchy here
        final AttributeValueSet newBaseAttributeValueSet = attributeValueSet.baseAttributeValueSet;
        for (final AttributeValueSet set : attributeValueSets.values())
        {
            set.baseAttributeValueSet = newBaseAttributeValueSet;
        }

        if (id.equals(defaultAttributeValueSetId))
        {
            defaultAttributeValueSetId = null;
        }
    }

    /**
     * Returns all {@link AttributeValueSet}s from this collection that are based,
     * directly or indirectly, on the provided baseAttributeValueSet.
     * 
     * @param baseAttributeValueSet the base attribute value set
     */
    public Set getAttributeValueSetsBasedOn(
        AttributeValueSet baseAttributeValueSet)
    {
        final Set result = Sets.newHashSet();
        for (final AttributeValueSet set : attributeValueSets.values())
        {
            if (set.baseAttributeValueSet == baseAttributeValueSet)
            {
                result.add(set);
                result.addAll(getAttributeValueSetsBasedOn(set));
            }
        }

        return result;
    }

    /**
     * Updates base attribute value set ids before persisting.
     */
    @Persist
    @SuppressWarnings("unused")
    private void updateBaseAttributeValueSetIds()
    {
        // There won't be too many attribute values sets, so nested loops should be fine
        outer: for (final AttributeValueSet attributeValueSet : attributeValueSets
            .values())
        {
            if (attributeValueSet.baseAttributeValueSet == null)
            {
                continue;
            }

            for (final Map.Entry entry : attributeValueSets
                .entrySet())
            {
                if (attributeValueSet.baseAttributeValueSet == entry.getValue())
                {
                    attributeValueSet.baseAttributeValueSetId = entry.getKey();
                    continue outer;
                }
            }
        }
    }

    /**
     * Restores base attribute value set references based on ids on deserialization.
     */
    @Commit
    @SuppressWarnings("unused")
    private void restoreBaseAttributeValueSets()
    {
        for (final AttributeValueSet attributeValueSet : attributeValueSets.values())
        {
            attributeValueSet.baseAttributeValueSet = attributeValueSets
                .get(attributeValueSet.baseAttributeValueSetId);
        }
    }

    /**
     * Serializes this collection of {@link AttributeValueSet}s to an XML stream.
     * 
     * @param stream the stream to serialize this {@link AttributeValueSets} to. The stream
     *            will not be closed.
     * @throws Exception in case of any problems with serialization
     */
    public void serialize(OutputStream stream) throws Exception
    {
        new Persister().write(this, stream);
    }

    /**
     * Deserializes a collection of {@link AttributeValueSet}s from an XML stream.
     * 
     * @param inputStream the {@link InputStream} to deserialize a
     *            {@link AttributeValueSets} from. The stream will not be
     *            closed.
     * @return Deserialized collection of {@link AttributeValueSet}s
     * @throws Exception is case of any problems with deserialization.
     */
    public static AttributeValueSets deserialize(InputStream inputStream)
        throws Exception
    {
        final AttributeValueSets attributeValueSet = new Persister().read(
            AttributeValueSets.class, inputStream);

        checkDefaultAttributeValueSetExists(attributeValueSet);

        return attributeValueSet;
    }

    private static void checkDefaultAttributeValueSetExists(
        final AttributeValueSets attributeValueSet)
    {
        if (attributeValueSet.defaultAttributeValueSetId != null
            && !attributeValueSet.attributeValueSets
                .containsKey(attributeValueSet.defaultAttributeValueSetId))
        {
            throw new RuntimeException("Default attribute value set not found: "
                + attributeValueSet.defaultAttributeValueSetId);
        }
    }

    /*
     * 
     */
    @Override
    public String toString()
    {
        return "AttributeValueSet [set IDs: "
            + Arrays.toString(this.getAttributeValueSetIds().toArray()) + "]";
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy