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

org.apache.commons.collections.map.TransformedMap Maven / Gradle / Ivy

There is a newer version: 20040616
Show newest version
/*
 *  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.commons.collections.map;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.collections.Transformer;

/**
 * Decorates another Map to transform objects that are added.
 * 

* The Map put methods and Map.Entry setValue method are affected by this class. * Thus objects must be removed or searched for using their transformed form. * For example, if the transformation converts Strings to Integers, you must * use the Integer form to remove objects. *

* Note that TransformedMap is not synchronized and is not thread-safe. * If you wish to use this map from multiple threads concurrently, you must use * appropriate synchronization. The simplest approach is to wrap this map * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw * exceptions when accessed by concurrent threads without synchronization. *

* This class is Serializable from Commons Collections 3.1. * * @since Commons Collections 3.0 * @version $Revision: 646777 $ $Date: 2008-04-10 14:33:15 +0200 (Thu, 10 Apr 2008) $ * * @author Stephen Colebourne */ public class TransformedMap extends AbstractInputCheckedMapDecorator implements Serializable { /** Serialization version */ private static final long serialVersionUID = 7023152376788900464L; /** The transformer to use for the key */ protected final Transformer keyTransformer; /** The transformer to use for the value */ protected final Transformer valueTransformer; /** * Factory method to create a transforming map. *

* If there are any elements already in the map being decorated, they * are NOT transformed. * Constrast this with {@link #decorateTransform}. * * @param map the map to decorate, must not be null * @param keyTransformer the transformer to use for key conversion, null means no transformation * @param valueTransformer the transformer to use for value conversion, null means no transformation * @throws IllegalArgumentException if map is null */ public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) { return new TransformedMap(map, keyTransformer, valueTransformer); } /** * Factory method to create a transforming map that will transform * existing contents of the specified map. *

* If there are any elements already in the map being decorated, they * will be transformed by this method. * Constrast this with {@link #decorate}. * * @param map the map to decorate, must not be null * @param keyTransformer the transformer to use for key conversion, null means no transformation * @param valueTransformer the transformer to use for value conversion, null means no transformation * @throws IllegalArgumentException if map is null * @since Commons Collections 3.2 */ public static Map decorateTransform(Map map, Transformer keyTransformer, Transformer valueTransformer) { TransformedMap decorated = new TransformedMap(map, keyTransformer, valueTransformer); if (map.size() > 0) { Map transformed = decorated.transformMap(map); decorated.clear(); decorated.getMap().putAll(transformed); // avoids double transformation } return decorated; } //----------------------------------------------------------------------- /** * Constructor that wraps (not copies). *

* If there are any elements already in the collection being decorated, they * are NOT transformed. * * @param map the map to decorate, must not be null * @param keyTransformer the transformer to use for key conversion, null means no conversion * @param valueTransformer the transformer to use for value conversion, null means no conversion * @throws IllegalArgumentException if map is null */ protected TransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) { super(map); this.keyTransformer = keyTransformer; this.valueTransformer = valueTransformer; } //----------------------------------------------------------------------- /** * Write the map out using a custom routine. * * @param out the output stream * @throws IOException * @since Commons Collections 3.1 */ private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(map); } /** * Read the map in using a custom routine. * * @param in the input stream * @throws IOException * @throws ClassNotFoundException * @since Commons Collections 3.1 */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); map = (Map) in.readObject(); } //----------------------------------------------------------------------- /** * Transforms a key. *

* The transformer itself may throw an exception if necessary. * * @param object the object to transform * @throws the transformed object */ protected Object transformKey(Object object) { if (keyTransformer == null) { return object; } return keyTransformer.transform(object); } /** * Transforms a value. *

* The transformer itself may throw an exception if necessary. * * @param object the object to transform * @throws the transformed object */ protected Object transformValue(Object object) { if (valueTransformer == null) { return object; } return valueTransformer.transform(object); } /** * Transforms a map. *

* The transformer itself may throw an exception if necessary. * * @param map the map to transform * @throws the transformed object */ protected Map transformMap(Map map) { if (map.isEmpty()) { return map; } Map result = new LinkedMap(map.size()); for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = (Map.Entry) it.next(); result.put(transformKey(entry.getKey()), transformValue(entry.getValue())); } return result; } /** * Override to transform the value when using setValue. * * @param value the value to transform * @return the transformed value * @since Commons Collections 3.1 */ protected Object checkSetValue(Object value) { return valueTransformer.transform(value); } /** * Override to only return true when there is a value transformer. * * @return true if a value transformer is in use * @since Commons Collections 3.1 */ protected boolean isSetValueChecking() { return (valueTransformer != null); } //----------------------------------------------------------------------- public Object put(Object key, Object value) { key = transformKey(key); value = transformValue(value); return getMap().put(key, value); } public void putAll(Map mapToCopy) { mapToCopy = transformMap(mapToCopy); getMap().putAll(mapToCopy); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy