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

jaxx.compiler.ClassMap Maven / Gradle / Ivy

There is a newer version: 3.0-alpha-6
Show newest version
/*
 * #%L
 * JAXX :: Compiler
 * 
 * $Id: ClassMap.java 2225 2011-02-19 20:15:00Z tchemit $
 * $HeadURL: http://svn.nuiton.org/svn/jaxx/tags/jaxx-2.5.21/jaxx-compiler/src/main/java/jaxx/compiler/ClassMap.java $
 * %%
 * Copyright (C) 2008 - 2010 CodeLutin
 * %%
 * This program 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

package jaxx.compiler;

import jaxx.compiler.reflect.ClassDescriptor;
import jaxx.compiler.reflect.ClassDescriptorHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * A Map implementation which uses Classes as keys.  ClassMap differs from typical maps
 * in that it takes subclasses into account;  mapping a class to a value also maps all subclasses of
 * that class to the value.
 * 

* A get operation will return the value associated with the class itself, or failing * that, with its nearest ancestor for which there exists a mapping. * @param type of the class */ public class ClassMap extends HashMap { private static final long serialVersionUID = 5149779660675529037L; /** * Logger */ protected static final Log log = LogFactory.getLog(ClassMap.class); /** * Keeps track of automatically-added Classes so we can distinguish them from user-added * Classes. Unknown Classes are automatically added to the map during get * calls to speed up subsequent requests, but they must be updated when the mappings * for their superclasses are modified. */ private List autoKeys = new ArrayList(); /** * Returns the value associated with the key Class. If the class itself does not have * a mapping, its superclass will be checked, and so on until an ancestor class with a mapping is * located. If none of the class' ancestors have a mapping, null is returned. * * @param key the class to check * @return the mapping for the class */ @Override public T get(Object key) { T result = null; ClassDescriptor c = (ClassDescriptor) key; while (c != null) { result = super.get(c); if (result != null) { break; } c = c.getSuperclass(); } if (result == null && ((ClassDescriptor) key).isInterface()) { result = get(ClassDescriptorHelper.getClassDescriptor(Object.class)); } if (c != key && result != null) { // no mapping for the class itself, but found one for a superclass put((ClassDescriptor) key, result); autoKeys.add((ClassDescriptor) key); } return result; } /** * Associates a value with a class and all of its descendents. * * @param key the class to map * @param value the value to map to the class * @return the old value associated with the class */ @Override public T put(ClassDescriptor key, T value) { //if (!(key instanceof ClassDescriptor)) { // throw new IllegalArgumentException("expected ClassDescriptor, got " + key); //} if (autoKeys.size() > 0) { // remove all automatic keys which descend from the class being modified Iterator i = autoKeys.iterator(); while (i.hasNext()) { ClassDescriptor auto = i.next(); if (key.isAssignableFrom(auto)) { i.remove(); remove(auto); } } } return super.put(key, value); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy