Add a list of Collection related utitilties

git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@803309 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
rfeng 2009-08-11 22:04:50 +00:00
parent 02ae2d8432
commit e0cfd4c221
5 changed files with 453 additions and 0 deletions

View file

@ -0,0 +1,97 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.common.java.classloader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import org.apache.tuscany.sca.common.java.collection.CompoundEnumeration;
public class ClassLoaderDelegate extends ClassLoader {
private final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
/**
* @param parent The parent classloaders
* @param loaders A list of classloaders to be used to load classes or resources
*/
public ClassLoaderDelegate(ClassLoader parent, ClassLoader... loaders) {
super(parent);
if (loaders != null) {
for (ClassLoader cl : loaders) {
if (cl != null && cl != parent && !classLoaders.contains(cl)) {
this.classLoaders.add(cl);
}
}
}
}
/**
* @param parent The parent classloaders
* @param loaders A list of classloaders to be used to load classes or resources
*/
public ClassLoaderDelegate(ClassLoader parent, Collection<ClassLoader> loaders) {
super(parent);
if (loaders != null) {
for (ClassLoader cl : loaders) {
if (cl != null && cl != parent && !classLoaders.contains(cl)) {
this.classLoaders.add(cl);
}
}
}
}
@Override
protected Class<?> findClass(String className) throws ClassNotFoundException {
for (ClassLoader parent : classLoaders) {
try {
return parent.loadClass(className);
} catch (ClassNotFoundException e) {
continue;
}
}
throw new ClassNotFoundException(className);
}
@Override
protected URL findResource(String resName) {
for (ClassLoader parent : classLoaders) {
URL url = parent.getResource(resName);
if (url != null) {
return url;
}
}
return null;
}
@SuppressWarnings("unchecked")
@Override
protected Enumeration<URL> findResources(String resName) throws IOException {
Enumeration<URL>[] enums = new Enumeration[classLoaders.size()];
int index = 0;
for (ClassLoader parent : classLoaders) {
enums[index++] = parent.getResources(resName);
}
return new CompoundEnumeration<URL>(enums);
}
}

View file

@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.common.java.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
/**
* A Map with Collection values
*/
public class CollectionMap<K, V> extends ConcurrentHashMap<K, Collection<V>> {
private static final long serialVersionUID = -8926174610229029369L;
public boolean putValue(K key, V value) {
Collection<V> collection = get(key);
if (collection == null) {
collection = createCollection();
put(key, collection);
}
return collection.add(value);
}
public boolean putValues(K key, Collection<? extends V> value) {
Collection<V> collection = get(key);
if (collection == null) {
collection = createCollection();
put(key, collection);
}
return collection.addAll(value);
}
public boolean removeValue(K key, V value) {
Collection<V> collection = get(key);
if (collection == null) {
return false;
}
return collection.remove(value);
}
protected Collection<V> createCollection() {
return new ArrayList<V>();
}
}

View file

@ -0,0 +1,93 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.common.java.collection;
import java.util.Enumeration;
import java.util.NoSuchElementException;
public class CompoundEnumeration<T> implements Enumeration<T> {
private Enumeration<T>[] enumerations = null;
private int index = 0;
public CompoundEnumeration(Enumeration<T>... enums) {
enumerations = enums;
}
public boolean hasMoreElements() {
// if the current enum is null that means this enum is finished
if (currentEnumeration() == null) {
// No next enum
return false;
}
// If the current enum has more elements, lets go
return currentEnumeration().hasMoreElements();
}
private Enumeration<T> findNextEnumeration(boolean moveCursor) {
return findNextEnumeration(index, moveCursor);
}
private Enumeration<T> findNextEnumeration(int cursor, boolean moveCursor) {
// next place in the array
int next = cursor + 1;
// If the cursor is still in the array
if (next < enumerations.length) {
// If there is something in that place
// AND the enum is not empty
if (enumerations[next] != null && enumerations[next].hasMoreElements()) {
// OK
if (moveCursor) {
index = next;
}
return enumerations[next];
}
// Try next element
return findNextEnumeration(next, moveCursor);
}
// No more elements available
return null;
}
public T nextElement() {
// ask for the next element of the current enum.
if (currentEnumeration() != null) {
return currentEnumeration().nextElement();
}
// no more elements in this Enum
// We must throw a NoSuchElementException
throw new NoSuchElementException("No more elements");
}
private Enumeration<T> currentEnumeration() {
if (enumerations != null) {
if (index < enumerations.length) {
Enumeration<T> e = enumerations[index];
if (e == null || !e.hasMoreElements()) {
// the current enum is null or empty
// we probably want to switch to the next one
e = findNextEnumeration(true);
}
return e;
}
}
return null;
}
}

View file

@ -0,0 +1,113 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.common.java.collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class CompoundIterator<T> implements Iterator<T> {
private Iterator<T>[] iterators = null;
private int index = 0;
public CompoundIterator(Iterator<T>... iterators) {
this.iterators = iterators;
}
@SuppressWarnings("unchecked")
public CompoundIterator(Collection<T>... collections) {
this.iterators = new Iterator[collections.length];
for (int i = 0; i < collections.length; i++) {
this.iterators[i] = collections[i].iterator();
}
}
public boolean hasNext() {
// if the current enum is null that means this enum is finished
if (currentIterator() == null) {
// No next enum
return false;
}
// If the current enum has more elements, lets go
return currentIterator().hasNext();
}
private Iterator<T> findNextIterator(boolean moveCursor) {
return findNextIterator(index, moveCursor);
}
private Iterator<T> findNextIterator(int cursor, boolean moveCursor) {
// next place in the array
int next = cursor + 1;
// If the cursor is still in the array
if (next < iterators.length) {
// If there is something in that place
// AND the enum is not empty
if (iterators[next] != null && iterators[next].hasNext()) {
// OK
if (moveCursor) {
index = next;
}
return iterators[next];
}
// Try next element
return findNextIterator(next, moveCursor);
}
// No more elements available
return null;
}
public T next() {
// ask for the next element of the current enum.
if (currentIterator() != null) {
return currentIterator().next();
}
// no more elements in this Enum
// We must throw a NoSuchElementException
throw new NoSuchElementException("No more elements");
}
public void remove() {
// ask for the next element of the current enum.
if (currentIterator() != null) {
currentIterator().remove();
}
// no more elements in this Enum
// We must throw a NoSuchElementException
throw new NoSuchElementException("No more elements");
}
private Iterator<T> currentIterator() {
if (iterators != null) {
if (index < iterators.length) {
Iterator<T> e = iterators[index];
if (e == null || !e.hasNext()) {
// the current enum is null or empty
// we probably want to switch to the next one
e = findNextIterator(true);
}
return e;
}
}
return null;
}
}

View file

@ -0,0 +1,88 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.common.java.collection;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* A Simple LRU Cache
*
* @version $Revision$
* @param <K>
* @param <V>
*/
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = -342098639681884413L;
protected int maxCacheSize = 4096;
/**
* Default constructor for an LRU Cache The default capacity is 10000
*/
public LRUCache() {
this(0, 4096, 0.75f, true);
}
/**
* Constructs a LRUCache with a maximum capacity
*
* @param maximumCacheSize
*/
public LRUCache(int maximumCacheSize) {
this(0, maximumCacheSize, 0.75f, true);
}
/**
* Constructs an empty <tt>LRUCache</tt> instance with the specified
* initial capacity, maximumCacheSize,load factor and ordering mode.
*
* @param initialCapacity the initial capacity.
* @param maximumCacheSize
* @param loadFactor the load factor.
* @param accessOrder the ordering mode - <tt>true</tt> for access-order,
* <tt>false</tt> for insertion-order.
* @throws IllegalArgumentException if the initial capacity is negative or
* the load factor is non-positive.
*/
public LRUCache(int initialCapacity, int maximumCacheSize, float loadFactor, boolean accessOrder) {
super(initialCapacity, loadFactor, accessOrder);
this.maxCacheSize = maximumCacheSize;
}
/**
* @return Returns the maxCacheSize.
*/
public int getMaxCacheSize() {
return maxCacheSize;
}
/**
* @param maxCacheSize The maxCacheSize to set.
*/
public void setMaxCacheSize(int maxCacheSize) {
this.maxCacheSize = maxCacheSize;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > maxCacheSize;
}
}