/**
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* 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.mapstruct.ap.test.callbacks.returning;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.mapstruct.AfterMapping;
import org.mapstruct.BeforeMapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.TargetType;
/**
* @author Pascal GrĂ¼n
*/
public class NodeMapperContext {
private static final ThreadLocal<Integer> LEVEL = new ThreadLocal<Integer>();
private static final ThreadLocal<Map<Object, Object>> MAPPING = new ThreadLocal<Map<Object, Object>>();
/** Only for test-inspection */
private static final List<ContextListener> LISTENERS = new CopyOnWriteArrayList<ContextListener>();
private NodeMapperContext() {
// Only allow static access
}
@BeforeMapping
@SuppressWarnings( "unchecked" )
public static <T> T getInstance(Object source, @TargetType Class<T> type) {
fireMethodCalled( LEVEL.get(), "getInstance", source, null );
Map<Object, Object> mapping = MAPPING.get();
if ( mapping == null ) {
return null;
}
else {
return (T) mapping.get( source );
}
}
@BeforeMapping
public static void setInstance(Object source, @MappingTarget Object target) {
Integer level = LEVEL.get();
fireMethodCalled( level, "setInstance", source, target );
if ( level == null ) {
LEVEL.set( 1 );
MAPPING.set( new IdentityHashMap<Object, Object>() );
}
else {
LEVEL.set( level + 1 );
}
MAPPING.get().put( source, target );
}
@AfterMapping
public static void cleanup() {
Integer level = LEVEL.get();
fireMethodCalled( level, "cleanup", null, null );
if ( level == 1 ) {
MAPPING.set( null );
LEVEL.set( null );
}
else {
LEVEL.set( level - 1 );
}
}
/**
* Only for test-inspection
*/
static void addContextListener(ContextListener contextListener) {
LISTENERS.add( contextListener );
}
/**
* Only for test-inspection
*/
static void removeContextListener(ContextListener contextListener) {
LISTENERS.remove( contextListener );
}
/**
* Only for test-inspection
*/
private static void fireMethodCalled(Integer level, String method, Object source, Object target) {
for ( ContextListener contextListener : LISTENERS ) {
contextListener.methodCalled( level, method, source, target );
}
}
/**
* Only for test-inspection
*/
interface ContextListener {
void methodCalled(Integer level, String method, Object source, Object target);
}
}