org.carrot2.util.attribute.AttributeValueSets Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of carrot2-mini Show documentation
Show all versions of carrot2-mini Show documentation
Carrot2 search results clustering framework. Minimal functional subset
(core algorithms and infrastructure, no document sources).
/*
* Carrot2 project.
*
* Copyright (C) 2002-2016, 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 org.carrot2.shaded.guava.common.collect.Maps;
import org.carrot2.shaded.guava.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
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
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()) + "]";
}
}