
org.dishevelled.venn.model.QuaternaryVennModelImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dsh-venn Show documentation
Show all versions of dsh-venn Show documentation
Lightweight components for venn diagrams.
/*
dsh-venn Lightweight components for venn diagrams.
Copyright (c) 2009-2013 held jointly by the individual authors.
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
> http://www.fsf.org/licensing/licenses/lgpl.html
> http://www.opensource.org/licenses/lgpl-license.php
*/
package org.dishevelled.venn.model;
import java.util.HashSet;
import java.util.Set;
import java.util.HashMap;
import java.util.Map;
import com.google.common.collect.Sets;
import org.dishevelled.bitset.ImmutableBitSet;
import org.dishevelled.observable.ObservableSet;
import org.dishevelled.observable.impl.ObservableSetImpl;
import org.dishevelled.venn.QuaternaryVennModel;
import static org.dishevelled.venn.model.VennModelUtils.toImmutableBitSet;
/**
* Immutable implementation of QuaternaryVennModel.
*
* @param value type
* @author Michael Heuer
* @version $Revision$ $Date$
*/
public final class QuaternaryVennModelImpl
implements QuaternaryVennModel
{
/** First view. */
private final ObservableSet first;
/** Second view. */
private final ObservableSet second;
/** Third view. */
private final ObservableSet third;
/** Fourth view. */
private final ObservableSet fourth;
/** First only view. */
private final Set firstOnly;
/** Second only view. */
private final Set secondOnly;
/** Third only view. */
private final Set thirdOnly;
/** Fourth only view. */
private final Set fourthOnly;
/** First second view. */
private final Set firstSecond;
/** First third view. */
private final Set firstThird;
/** First fourth view. */
private final Set firstFourth;
/** Second third view. */
private final Set secondThird;
/** Second fourth view. */
private final Set secondFourth;
/** Third fourth view. */
private final Set thirdFourth;
/** First second third view. */
private final Set firstSecondThird;
/** First second fourth view. */
private final Set firstSecondFourth;
/** First third fourth view. */
private final Set firstThirdFourth;
/** Second third fourth view. */
private final Set secondThirdFourth;
/** Intersection view. */
private final Set intersection;
/** Union view. */
private final Set union;
/** Selection view. */
private final ObservableSet selection;
/** Map of exclusive set views keyed by bit set. */
private final Map> exclusives;
/**
* Create a new empty quaternary venn model.
*/
public QuaternaryVennModelImpl()
{
this(new HashSet(), new HashSet(), new HashSet(), new HashSet());
}
/**
* Create a new quaternary venn model with the specified sets.
*
* @param first first set, must not be null
* @param second second set, must not be null
* @param third third set, must not be null
* @param fourth fourth set, must not be null
*/
public QuaternaryVennModelImpl(final Set extends E> first,
final Set extends E> second,
final Set extends E> third,
final Set extends E> fourth)
{
if (first == null)
{
throw new IllegalArgumentException("first must not be null");
}
if (second == null)
{
throw new IllegalArgumentException("second must not be null");
}
if (third == null)
{
throw new IllegalArgumentException("third must not be null");
}
if (fourth == null)
{
throw new IllegalArgumentException("fourth must not be null");
}
// todo defensive copy?
this.first = new ObservableSetImpl(first);
this.second = new ObservableSetImpl(second);
this.third = new ObservableSetImpl(third);
this.fourth = new ObservableSetImpl(fourth);
// alias
ObservableSet f = this.first;
ObservableSet s = this.second;
ObservableSet t = this.third;
ObservableSet r = this.fourth;
firstOnly = Sets.difference(Sets.difference(Sets.difference(f, s), t), r); // f - s - t - r
secondOnly = Sets.difference(Sets.difference(Sets.difference(s, f), t), r); // s - f - t - r
thirdOnly = Sets.difference(Sets.difference(Sets.difference(t, f), s), r); // t - f - s - r
fourthOnly = Sets.difference(Sets.difference(Sets.difference(r, f), s), t); // r - f - s - t
firstSecond = Sets.difference(Sets.difference(Sets.intersection(f, s), t), r); // f n s - t - r
firstThird = Sets.difference(Sets.difference(Sets.intersection(f, t), s), r); // f n t - s - r
firstFourth = Sets.difference(Sets.difference(Sets.intersection(f, r), s), t); // f n r - s - t
secondThird = Sets.difference(Sets.difference(Sets.intersection(s, t), f), r); // s n t - f - r
secondFourth = Sets.difference(Sets.difference(Sets.intersection(s, r), f), t); // s n r - f - t
thirdFourth = Sets.difference(Sets.difference(Sets.intersection(t, r), f), s); // t n r - f - s
firstSecondThird = Sets.difference(Sets.intersection(f, Sets.intersection(s, t)), r); // f n s n t - r
firstSecondFourth = Sets.difference(Sets.intersection(f, Sets.intersection(s, r)), t); // f n s n r - t
firstThirdFourth = Sets.difference(Sets.intersection(f, Sets.intersection(t, r)), s); // f n t n r - s
secondThirdFourth = Sets.difference(Sets.intersection(s, Sets.intersection(t, r)), f); // s n t n r - f
intersection = Sets.intersection(f, Sets.intersection(s, Sets.intersection(t, r))); // f n s n t n r
union = Sets.union(f, Sets.union(s, Sets.union(t, r))); // f u s u t u r
selection = new SelectionView(union, f, s, t, r);
exclusives = new HashMap>(15);
exclusives.put(toImmutableBitSet(0), firstOnly);
exclusives.put(toImmutableBitSet(1), secondOnly);
exclusives.put(toImmutableBitSet(2), thirdOnly);
exclusives.put(toImmutableBitSet(3), fourthOnly);
exclusives.put(toImmutableBitSet(0, 1), firstSecond);
exclusives.put(toImmutableBitSet(0, 2), firstThird);
exclusives.put(toImmutableBitSet(0, 3), firstFourth);
exclusives.put(toImmutableBitSet(1, 2), secondThird);
exclusives.put(toImmutableBitSet(1, 3), secondFourth);
exclusives.put(toImmutableBitSet(2, 3), thirdFourth);
exclusives.put(toImmutableBitSet(0, 1, 2), firstSecondThird);
exclusives.put(toImmutableBitSet(0, 1, 3), firstSecondFourth);
exclusives.put(toImmutableBitSet(0, 2, 3), firstThirdFourth);
exclusives.put(toImmutableBitSet(1, 2, 3), secondThirdFourth);
exclusives.put(toImmutableBitSet(0, 1, 2, 3), intersection);
}
/** {@inheritDoc} */
public int size()
{
return 4;
}
/** {@inheritDoc} */
public ObservableSet first()
{
return first;
}
/** {@inheritDoc} */
public ObservableSet second()
{
return second;
}
/** {@inheritDoc} */
public ObservableSet third()
{
return third;
}
/** {@inheritDoc} */
public ObservableSet fourth()
{
return fourth;
}
/** {@inheritDoc} */
public Set get(final int index)
{
if (index < 0 || index > 3)
{
throw new IndexOutOfBoundsException("index out of bounds");
}
switch (index)
{
case 0:
return first;
case 1:
return second;
case 2:
return third;
case 3:
return fourth;
default:
break;
}
throw new IllegalStateException("invalid index " + index);
}
/** {@inheritDoc} */
public Set firstOnly()
{
return firstOnly;
}
/** {@inheritDoc} */
public Set secondOnly()
{
return secondOnly;
}
/** {@inheritDoc} */
public Set thirdOnly()
{
return thirdOnly;
}
/** {@inheritDoc} */
public Set fourthOnly()
{
return fourthOnly;
}
/** {@inheritDoc} */
public Set firstSecond()
{
return firstSecond;
}
/** {@inheritDoc} */
public Set firstThird()
{
return firstThird;
}
/** {@inheritDoc} */
public Set firstFourth()
{
return firstFourth;
}
/** {@inheritDoc} */
public Set secondThird()
{
return secondThird;
}
/** {@inheritDoc} */
public Set secondFourth()
{
return secondFourth;
}
/** {@inheritDoc} */
public Set thirdFourth()
{
return thirdFourth;
}
/** {@inheritDoc} */
public Set firstSecondThird()
{
return firstSecondThird;
}
/** {@inheritDoc} */
public Set firstSecondFourth()
{
return firstSecondFourth;
}
/** {@inheritDoc} */
public Set firstThirdFourth()
{
return firstThirdFourth;
}
/** {@inheritDoc} */
public Set secondThirdFourth()
{
return secondThirdFourth;
}
/** {@inheritDoc} */
public Set intersection()
{
return intersection;
}
/** {@inheritDoc} */
public Set exclusiveTo(final int index, final int... additional)
{
int maxIndex = size() - 1;
if (index < 0 || index > maxIndex)
{
throw new IndexOutOfBoundsException("index out of bounds");
}
if (additional != null && additional.length > 0)
{
if (additional.length > maxIndex)
{
throw new IndexOutOfBoundsException("too many indices provided");
}
for (int i = 0, size = additional.length; i < size; i++)
{
if (additional[i] < 0 || additional[i] > maxIndex)
{
throw new IndexOutOfBoundsException("additional index [" + i + "] out of bounds");
}
}
}
return exclusives.get(toImmutableBitSet(index, additional));
}
/** {@inheritDoc} */
public Set union()
{
return union;
}
/** {@inheritDoc} */
public ObservableSet selection()
{
return selection;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy