/*
* Copyright 2013 Chris Pheby
*
* Licensed 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.jadira.reflection.cloning.mutability;
import static org.mutabilitydetector.Configurations.OUT_OF_THE_BOX_CONFIGURATION;
import java.util.HashMap;
import java.util.Map;
import org.mutabilitydetector.AnalysisSession;
import org.mutabilitydetector.IsImmutable;
import org.mutabilitydetector.ThreadUnsafeAnalysisSession;
import org.mutabilitydetector.locations.Dotted;
/**
* This class provides a thread safe interface to an {@link org.mutabilitydetector.AnalysisSession}
* for runtime mutability determination.
*/
public final class MutabilityDetector {
private static final Map<Class<?>,IsImmutable> DETECTED_IMMUTABLE_CLASSES = new HashMap<Class<?>,IsImmutable>();
private static final ThreadLocal<AnalysisSession> ANALYSIS_SESSION = new ThreadLocal<AnalysisSession>() {
public AnalysisSession initialValue() {
return ThreadUnsafeAnalysisSession.createWithCurrentClassPath(OUT_OF_THE_BOX_CONFIGURATION);
}
};
private static final MutabilityDetector MUTABILITY_DETECTOR = new MutabilityDetector();
private MutabilityDetector() {
}
/**
* Return the MutabilityDetector instance
* @return A shared instance of {@link MutabilityDetector}
*/
public static final MutabilityDetector getMutabilityDetector() {
return MUTABILITY_DETECTOR;
}
/**
* Return true if immutable or effectively immutable
* @param clazz Class under test
* @return True if immutable or effectively immutable
*/
public boolean isImmutable(Class<?> clazz) {
if (clazz.isPrimitive() || clazz.isEnum()) {
return false;
}
if (clazz.isArray()) {
return false;
}
final IsImmutable isImmutable;
if (DETECTED_IMMUTABLE_CLASSES.containsKey(clazz)) {
isImmutable = DETECTED_IMMUTABLE_CLASSES.get(clazz);
} else {
Dotted dottedClassName = Dotted.fromClass(clazz);
isImmutable = ANALYSIS_SESSION.get().resultFor(dottedClassName).isImmutable;
DETECTED_IMMUTABLE_CLASSES.put(clazz, isImmutable);
}
if (isImmutable.equals(IsImmutable.IMMUTABLE) || isImmutable.equals(IsImmutable.EFFECTIVELY_IMMUTABLE)) {
return true;
} else {
return false;
}
}
}