
org.cip4.jdflib.util.ContainerUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of JDFLibJ Show documentation
Show all versions of JDFLibJ Show documentation
CIP4 JDF Library for JDF 1.x
/*
*
* The CIP4 Software License, Version 1.0
*
*
* Copyright (c) 2001-2025 The International Cooperation for the Integration of Processes in Prepress, Press and Postpress (CIP4). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the The International Cooperation for
* the Integration of Processes in Prepress, Press and Postpress (www.cip4.org)" Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments
* normally appear.
*
* 4. The names "CIP4" and "The International Cooperation for the Integration of Processes in Prepress, Press and Postpress" must not be used to endorse or promote products derived from this software
* without prior written permission. For written permission, please contact [email protected].
*
* 5. Products derived from this software may not be called "CIP4", nor may "CIP4" appear in their name, without prior written permission of the CIP4 organization
*
* Usage of this software in commercial products is subject to restrictions. For details please consult [email protected].
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNATIONAL COOPERATION FOR THE INTEGRATION OF PROCESSES IN PREPRESS, PRESS AND POSTPRESS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE. ====================================================================
*
* This software consists of voluntary contributions made by many individuals on behalf of the The International Cooperation for the Integration of Processes in Prepress, Press and Postpress and was
* originally based on software copyright (c) 1999-2001, Heidelberger Druckmaschinen AG copyright (c) 1999-2001, Agfa-Gevaert N.V.
*
* For more information on The International Cooperation for the Integration of Processes in Prepress, Press and Postpress , please see .
*
*
*/
/**
*
* Copyright (c) 2001 Heidelberger Druckmaschinen AG, All Rights Reserved.
*
* KString.java
*
* Last changes
*
*/
package org.cip4.jdflib.util;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;
import org.cip4.jdflib.core.JDFConstants;
import org.cip4.jdflib.ifaces.IMatches;
/**
* class with utilities for containers, e.g. Vectors, sets etc.
* also simple object utilities
*
* @author Dr. Rainer Prosi, Heidelberger Druckmaschinen AG before June 18, 2009
*/
public class ContainerUtil
{
/**
* create a HashSet from an enumeration
*
* @param the data type of the sets
* @param enumeration the enumeration
* @return a Set created from list
*/
public static Set toHashSet(final Enumeration enumeration)
{
if (enumeration == null)
{
return null;
}
final Set s = new HashSet<>();
while (enumeration.hasMoreElements())
{
s.add(enumeration.nextElement());
}
return s;
}
/**
* return null if c==null or c.isEmpty=true used to zapp empty collections
*
* @param c the Collection to test
* @return the converted Collecion
*/
public static Collection> getNonEmpty(final Collection> c)
{
return c == null || c.isEmpty() ? null : c;
}
/**
* return null if c==null or c.isEmpty=true used to zapp empty collections
*
* @param c the Collection to test
* @return the converted Collecion
*/
public static Map, ?> getNonEmpty(final Map, ?> c)
{
return c == null || c.isEmpty() ? null : c;
}
/**
* return null if c==null or c.isEmpty=true or c contains an empty collection used to zapp empty collections
*
* @param c the Collection to test
* @return the converted Collecion
*/
public static Collection> getNonEmptyCollection(final Collection extends Collection>> c)
{
return c == null || c.isEmpty() || (c.size() == 1 && getNonEmpty(c.iterator().next()) == null) ? null : c;
}
/**
* create a HashSet from a List (Vector...)
*
* @param the data type of the sets
* @param list the list
* @return a Set created from list
*/
public static Set toHashSet(final List list)
{
return toHashSet((Collection) list);
}
/**
* create a HashSet from a List (Vector...)
*
* @param the data type of the sets
* @param list the list
* @return a Set created from list
*/
public static Set toHashSet(final Collection list)
{
if (list == null)
{
return null;
}
final int size = list.size();
final HashSet s = new HashSet<>(size + 10);
final Iterator it = list.iterator();
while (it.hasNext())
{
s.add(it.next());
}
return s;
}
/**
* create a HashSet from an Array
*
* @param datatype
* @param l the array
* @return a Set created from list
*/
public static Set toHashSet(final A[] l)
{
if (l == null)
{
return null;
}
final Set s = new HashSet<>(l.length + 10);
for (final A element : l)
{
s.add(element);
}
return s;
}
/**
* create a Vector from an Array, skipping null elements
*
* @param the type
* @param array the array to convert
* @return a Vector
*/
public static Vector toVector(final A[] array)
{
if (array == null)
{
return null;
}
final Vector v = new Vector<>();
v.ensureCapacity(array.length);
for (final A element : array)
{
if (element != null)
{
v.add(element);
}
}
return v;
}
/**
* create a sorted String - never null
*
* @param
* @param c
* @return
*/
public static String toString(final Collection c)
{
if (c == null)
{
return JDFConstants.EMPTYSTRING;
}
final List l = new ArrayList<>();
l.addAll(c);
l.sort(null);
final StringBuilder b = new StringBuilder();
int i = 0;
for (final A e : l)
{
if (i++ > 0)
{
b.append(JDFConstants.COMMA);
}
b.append(e.toString());
}
return b.toString();
}
/**
* create an ArrayList from an Array, skipping null elements
*
* @param the type
* @param array the array to convert
* @return a Vector
*/
public static List toArrayList(final A[] array)
{
if (array == null)
{
return null;
}
final ArrayList v = new ArrayList<>();
v.ensureCapacity(array.length);
for (final A element : array)
{
if (element != null)
{
v.add(element);
}
}
return v;
}
/**
* null safe addAll
*
* @param c1 first collection
* @param c2 second collection
* @param type
* @return c1 with c2 added, c2 if c1==null
*/
public static Collection addAll(final Collection c1, final Collection c2)
{
if (c1 == null)
{
return c2;
}
if (c2 == null)
{
return c1;
}
c1.addAll(c2);
return c1;
}
/**
* checks whether at least one of a given vector of strings is contained in this
*
* @param others the VSTring of values to test
* @return true if at least one String in other is in this
*/
public static boolean containsAny(final Collection c, final Collection others)
{
if (isEmpty(others))
{
return true;
}
else if (isEmpty(c))
{
return false;
}
for (final A other : others)
{
if (c.contains(other))
{
return true;
}
}
return false;
}
/**
* null safe helper
*
* @param
* @param c
* @param other
* @return
*/
public static boolean contains(final Collection c, final A other)
{
if (other == null || c == null)
{
return false;
}
return c.contains(other);
}
/**
* null safe helper
*
* @param
* @param c
* @param other
* @return
*/
public static int count(final Collection c, final A other)
{
int n = 0;
if (c != null)
{
for (final A a : c)
{
if (equals(a, other))
{
n++;
}
}
}
return n;
}
/**
* null safe helper
*
* @param
* @param c
* @param others
* @return
*/
public static boolean containsAll(final Collection c, final Collection others)
{
if (isEmpty(others))
{
return true;
}
else if (isEmpty(c))
{
return false;
}
return c.containsAll(others);
}
/**
* vector of strings that is contained in this
*
* @param others the VString of values to test
* @return true if at least one String in other is in this
*/
public static List getOverlapping(final Collection c, final Collection others)
{
if (others == null)
{
return null;
}
final List ret = new ArrayList<>();
for (final A s : c)
{
if (others.contains(s))
{
ret.add(s);
}
}
return !ret.isEmpty() ? ret : null;
}
/**
* appends all strings of an array to this
*
* @param strings the array of strings to append to this
*/
public static Collection addAll(final Collection c, final A[] a)
{
if (a != null && c != null)
{
for (final A aa : a)
{
if (aa != null)
{
c.add(aa);
}
}
}
return c;
}
/**
* null safe add
*
* @param strings the array of strings to append to this
*/
public static Collection add(final Collection c, final A a)
{
if (c != null && a != null)
{
c.add(a);
}
return c;
}
/**
* return a matching element from a collection of IMatches
*
* @param the data type
* @param c the collection to search
* @param obj the search key for matches
* @param iSkip which one to grab, may be negative in which case we count -1=last, -2=second last...
* @return the matching {@link IMatches}
*/
public static IMatches getMatch(final Collection extends IMatches> c, final a obj, int iSkip)
{
if (c == null)
{
return null;
}
if (iSkip < 0)
{
final List v = getMatchesList(c, obj);
if (v == null)
{
return null;
}
iSkip = v.size() + iSkip;
if (iSkip < 0)
{
return null;
}
return v.get(iSkip);
}
for (final IMatches m : c)
{
if (m.matches(obj) && iSkip-- <= 0)
{
return m;
}
}
return null;
}
/**
* return a matching element from a collection of IMatches
*
* @param the data type
* @param match the matcher
* @param c the {@link Collection}
* @param iSkip which one to grab, may be negative in which case we count -1=last, -2=second last...
* @return the matching
*/
public static A getMatch(final IMatches match, final Collection c, int iSkip)
{
if (c == null)
{
return null;
}
if (iSkip < 0)
{
final List v = getMatchesList(match, c);
if (v == null)
{
return null;
}
iSkip = v.size() + iSkip;
if (iSkip < 0)
{
return null;
}
return v.get(iSkip);
}
for (final A b : c)
{
if (match.matches(b) && iSkip-- <= 0)
{
return b;
}
}
return null;
}
/**
* return a matching element from a collection of IMatches
*
* @param the data type
* @param c the collection to search
* @param obj the search key for matches
* @return Vector of matching a
*/
public static Vector getMatches(final Collection extends IMatches> c, final A obj)
{
if (c == null)
{
return null;
}
final Vector v = new Vector<>();
for (final IMatches m : c)
{
if (m.matches(obj))
{
v.add(m);
}
}
return v.isEmpty() ? null : v;
}
/**
* return a matching element from a collection of IMatches
*
* @param the data type
* @param c the collection to search
* @param obj the search key for matches
* @return Vector of matching a
*/
public static List getMatchesList(final Collection extends IMatches> c, final A obj)
{
if (c == null)
{
return null;
}
final List l = new ArrayList<>();
for (final IMatches m : c)
{
if (m.matches(obj))
{
l.add(m);
}
}
return l.isEmpty() ? null : l;
}
/**
* return a matching element from a collection
*
* @param the data type
* @param c the collection to search
* @param obj the matches
* @return Vector of matching a
*/
public static Vector getMatches(final IMatches m, final Collection c)
{
if (c == null)
{
return null;
}
final Vector v = new Vector<>();
for (final A b : c)
{
if (m.matches(b))
{
v.add(b);
}
}
return v.isEmpty() ? null : v;
}
/**
* return a matching element from a collection
*
* @param the data type
* @param c the collection to search
* @param obj the matches
* @return Vector of matching a
*/
public static List getMatchesList(final IMatches m, final Collection c)
{
if (c == null)
{
return null;
}
final List v = new ArrayList<>();
for (final A b : c)
{
if (m.matches(b))
{
v.add(b);
}
}
return v.isEmpty() ? null : v;
}
/**
* create a Vector of entry values from a map
*
* @param type of the map key
* @param type of the map entry
* @param m the map to dump to an array
* @param sortByKey , if true, sort the entries by key
* @return the vector
*/
public static , b> Vector toValueVector(final Map m, final boolean sortByKey)
{
if (!sortByKey)
{
return toValueVector(m);
}
if (m == null)
{
return null;
}
synchronized (m)
{
final Set> entrySet = m.entrySet();
if (entrySet.isEmpty())
{
return null;
}
final Vector v = new Vector<>();
v.ensureCapacity(entrySet.size());
final Iterator> it = entrySet.iterator();
final Vector keys = new Vector<>();
keys.ensureCapacity(entrySet.size());
while (it.hasNext())
{
final a key = it.next().getKey();
if (key != null)
{
keys.add(key);
}
}
Collections.sort(keys);
for (final a key : keys)
{
v.add(m.get(key));
}
return v;
}
}
/**
* create a Vector of entry values from a map
*
* @param type of the map key
* @param type of the map entry
* @param m the map to dump to an array
* @param sortByKey , if true, sort the entries by key
* @return the vector
*/
public static , B> List toArrayList(final Map m, final boolean sortByKey)
{
if (!sortByKey)
{
return toArrayList(m);
}
if (m == null)
{
return null;
}
synchronized (m)
{
final Set> entrySet = m.entrySet();
if (entrySet.isEmpty())
{
return null;
}
final ArrayList v = new ArrayList<>();
v.ensureCapacity(entrySet.size());
final Iterator> it = entrySet.iterator();
final ArrayList keys = new ArrayList<>();
keys.ensureCapacity(entrySet.size());
while (it.hasNext())
{
final A key = it.next().getKey();
if (key != null)
{
keys.add(key);
}
}
Collections.sort(keys);
for (final A key : keys)
{
v.add(m.get(key));
}
return v;
}
}
/**
* create a Vector copy of entry values from a map
*
* @param data type of the map key
* @param data type of the map value
* @param m the map to dump to an array
* @return the vector
*/
public static Vector toValueVector(final Map m)
{
if (m == null)
{
return null;
}
synchronized (m)
{
final Vector v = new Vector<>();
final Collection values = m.values();
if (values.isEmpty())
{
return null;
}
v.addAll(values);
return v;
}
}
/**
* create a Vector copy of entry values from a map
*
* @param data type of the map key
* @param data type of the map value
* @param m the map to dump to an array
* @return the vector
*/
public static List toArrayList(final Map m)
{
if (m == null)
{
return null;
}
synchronized (m)
{
final ArrayList v = new ArrayList<>();
final Collection values = m.values();
if (values.size() == 0)
{
return null;
}
v.addAll(values);
return v;
}
}
/**
* create an inverted map with keys and values swapped.
* The new values are vectors since a map may have identical values for different keys
*
* @param data type of the map key
* @param data type of the map value
* @param m the map to invert
* @return the inverted map
* @deprecated
*/
@Deprecated
public static VectorMap getInvertedMap(final Map m)
{
if (m == null)
{
return null;
}
synchronized (m)
{
final VectorMap inv = new VectorMap<>();
final Collection keys = m.keySet();
if (keys.size() == 0)
{
return null;
}
for (final A key : keys)
{
final B val = m.get(key);
if (val != null)
{
inv.putOne(val, key);
}
}
return inv;
}
}
/**
* AppendUnique - append an object but ignore multiple entries
*
* @param a the A to append, if null nothing is added
*/
public static Collection appendUnique(final Collection c, final A a)
{
if (a != null && !c.contains(a))
{
c.add(a);
}
return c;
}
/**
* AppendUnique - append an object but ignore multiple entries
*
* @param a the A to append, if null nothing is added
*/
public static Collection appendUnique(final Collection c, final Collection a)
{
if (c == null)
{
return a;
}
if (!isEmpty(a))
{
c.addAll(a);
unify(c);
}
return c;
}
/**
* @param l
* @param i
* @return
*/
public static int index(final List l, int i)
{
if (l == null)
{
return -1;
}
final int size = l.size();
if (i < 0)
{
i += size;
}
return i >= size ? -2 : i;
}
/**
* @param l
* @param i
* @return
*/
public static A get(final List l, int i)
{
i = index(l, i);
return i >= 0 ? l.get(i) : null;
}
/**
* remove but also implementing the usual neg number syntax
*
* @param index if 0, or positive count from front, else if negative from back
* @see java.util.Vector#remove(int)
*/
public static A remove(final List l, int i)
{
i = index(l, i);
return i >= 0 ? l.remove(i) : null;
}
/**
* create an inverted map with keys and values swapped.
* The new values are vectors since a map may have identical values for different keys
*
* @param data type of the map key
* @param data type of the map value
* @param m the map to invert
* @return the inverted map
*/
public static ListMap getInvertedListMap(final Map m)
{
if (m == null)
{
return null;
}
synchronized (m)
{
final ListMap inv = new ListMap<>();
final Collection keys = m.keySet();
if (keys.size() == 0)
{
return null;
}
for (final A key : keys)
{
final B val = m.get(key);
if (val != null)
{
inv.putOne(val, key);
}
}
return inv;
}
}
/**
* create a Vector of key values from a map
*
* @param data type of the map key
* @param m the map to dump to an array
* @return the vector of keys - note that this Vector goes NOT reflect changes to the map
* @deprecated
*/
@Deprecated
public static Vector getKeyVector(final Map m)
{
if (m == null)
{
return null;
}
synchronized (m)
{
final Set keySet = m.keySet();
if (keySet.isEmpty())
{
return null;
}
final Vector v = new Vector<>();
v.ensureCapacity(keySet.size());
v.addAll(keySet);
return v;
}
}
/**
* return true if a equals b or both are null
*
* @param a Object to compare
* @param b Object to compare
* @return boolean true if a equals b or both are null
*/
public static boolean equals(final Object a, final Object b)
{
if (a == null)
{
return b == null;
}
if (b == null)
{
return false;
}
return a.equals(b);
}
/**
* return true if a matches b or both are null
*
* @param a Object to compare
* @param b Object to compare
* @return boolean true if a matches b or both are null
*/
public static boolean matches(final IMatches a, final Object b)
{
if (a == null)
{
return b == null;
}
if (b == null)
{
return false;
}
return a.matches(b);
}
/**
* return true if a matches b or one of a or b is null
*
* @param a Object to compare
* @param b Object to compare
* @return boolean true if a matches b or both are null
*/
public static boolean matchesExisting(final IMatches a, final Object b)
{
if (a == null || b == null)
{
return true;
}
return a.matches(b);
}
/**
* static implementation of compare for any comparable object that gracefully handles null
* null is always the smallest
*
* @param c0
* @param c1
* @return -1 if c0 < c1, 0 if equal, 1 if c0 > c1;
*/
public static int compare(final Comparable c0, final Comparable c1)
{
if (c0 == null)
{
return c1 == null ? 0 : -1;
}
if (c1 == null)
{
return 1;
}
return c0.compareTo(c1);
}
/**
* ensure that a collection has at least size elements and fill any newly created entries with nulls
*
* @param anything - needed for the cast
* @param size
* @param coll
*/
public static void ensureSize(final int size, final Collection coll)
{
final int s2 = coll.size();
if (s2 < size)
{
for (int i = s2; i < size; i++)
{
coll.add((A) null);
}
}
}
/**
* unify a collection while retaining the initial order (if the input collection is ordered)
*
* @param the data type of the collection
* @param c the collection to unify
* @return the unified collection - always the input collection
*/
public static Collection unify(final Collection c)
{
if (size(c) < 2)
{
return c;
}
final LinkedHashSet lhsIn = new LinkedHashSet<>(c.size());
for (final A el : c)
{
if (!lhsIn.contains(el))
{
lhsIn.add(el);
}
}
if (lhsIn.size() < c.size())
{
c.clear();
c.addAll(lhsIn);
}
return c;
}
/**
* unify a collection while retaining the initial order (if the input collection is ordered)
*
* @param the data type of the collection
* @param c the collection to unify
* @return the unified collection - always the input collection
*/
public static Collection unifyMatches(final Collection c)
{
if (c == null || c.size() < 2)
{
return c;
}
final ArrayList al = new ArrayList<>(c.size());
for (final A el : c)
{
final List mm = getMatchesList(al, el);
if (mm == null)
{
al.add(el);
}
}
if (al.size() < c.size())
{
final List v2 = new ArrayList<>();
for (int i = al.size() - 1; i >= 0; i--)
{
final List mm = getMatchesList(v2, al.get(i));
if (mm == null)
{
v2.add(al.get(i));
}
}
c.clear();
c.addAll(v2);
}
return c;
}
/**
* @param c the collection to check
* @return 0 for null or size
*/
public static int length(final Object[] c)
{
return c == null ? 0 : c.length;
}
/**
* @param c the collection to check
* @return 0 for null or size
*/
public static boolean isEmpty(final Object[] c)
{
return c == null ? true : c.length == 0;
}
/**
* @param c the collection to check
* @return 0 for null or size
*/
public static int size(final Collection> c)
{
return c == null ? 0 : c.size();
}
/**
* @param c the collection to check
* @return 0 for null or size
*/
public static int size(final Map, ?> c)
{
return c == null ? 0 : c.size();
}
/**
* @param c
* @return
*/
public static boolean isEmpty(final Collection> c)
{
return c == null ? true : c.isEmpty();
}
/**
* @param c
* @return
*/
public static boolean isEmpty(final Map, ?> c)
{
return c == null ? true : c.isEmpty();
}
public static Collection getKeyArray(final Map m)
{
if (m == null)
{
return null;
}
final Set keySet = m.keySet();
if (keySet.isEmpty())
{
return null;
}
final ArrayList v = new ArrayList<>();
v.ensureCapacity(keySet.size());
v.addAll(keySet);
return v;
}
public static List getKeyList(final Map m)
{
return (List) getKeyArray(m);
}
/**
* @param
* @param
* @param map
* @param map2
* @return
*/
public static Map putAll(final Map map, final Map map2)
{
if (map == null)
{
return map2;
}
if (map2 != null)
{
map.putAll(map2);
}
return map;
}
/**
* @param
* @param
* @param map
* @param map2
* @return
*/
public static Map retainAll(final Map map, final Collection keep)
{
if (map != null)
{
if (isEmpty(keep))
{
map.clear();
}
else
{
for (final A key : getKeyArray(map))
{
if (!keep.contains(key))
{
map.remove(key);
}
}
}
}
return map;
}
/**
* @param
* @param
* @param map
* @param map2
* @return
*/
public static B put(final Map map, final A key, final B value)
{
if (map != null && key != null && value != null)
{
return map.put(key, value);
}
return null;
}
public static void close(final Closeable w)
{
if (w != null)
{
try
{
w.close();
}
catch (final Exception x)
{
// nop
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy