/*
 * Copyright (C) 2005 Joe Walnes.
 * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2014 XStream Committers.
 * All rights reserved.
 *
 * The software in this package is published under the terms of the BSD
 * style license a copy of which has been included with this distribution in
 * the LICENSE.txt file.
 * 
 * Created on 22. January 2005 by Joe Walnes
 */
package com.thoughtworks.xstream.mapper;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.thoughtworks.xstream.XStreamException;
import com.thoughtworks.xstream.core.Caching;
import com.thoughtworks.xstream.security.ForbiddenClassException;


/**
 * Mapper that caches which names map to which classes. Prevents repetitive searching and class loading.
 * 
 * @author Joe Walnes
 * @author J&ouml;rg Schaible
 */
public class CachingMapper extends MapperWrapper implements Caching {

    private transient Map<String, ? super Object> realClassCache;

    public CachingMapper(final Mapper wrapped) {
        super(wrapped);
        readResolve();
    }

    @Override
    public Class<?> realClass(final String elementName) {
        final Object cached = realClassCache.get(elementName);
        if (cached != null) {
            if (cached instanceof Class) {
                return (Class<?>)cached;
            }
            throw (XStreamException)cached;
        }

        try {
            final Class<?> result = super.realClass(elementName);
            realClassCache.put(elementName, result);
            return result;
        } catch (final ForbiddenClassException e) {
            realClassCache.put(elementName, e);
            throw e;
        } catch (final CannotResolveClassException e) {
            realClassCache.put(elementName, e);
            throw e;
        }
    }

    @Override
    public void flushCache() {
        realClassCache.clear();
    }

    private Object readResolve() {
        realClassCache = Collections.synchronizedMap(new HashMap<String, Object>(128));
        return this;
    }
}

@@ -87,16 +87,22 @@
 13, 2014
+, 2015
  XStream
@@ -313,25 +313,24 @@
 txt file.%0A *
- 
 %0A * Created 
@@ -430,38 +430,29 @@
 til.
-Collections;%0Aimport java.util.
+concurrent.Concurrent
 Hash
@@ -473,16 +473,37 @@
 va.util.
+concurrent.Concurrent
 Map;%0A%0Aim
@@ -775,17 +775,16 @@
 ding.%0A *
- 
 %0A * @aut
@@ -925,16 +925,26 @@
 ansient 
+Concurrent
 Map%3CStri
@@ -1431,31 +1431,47 @@
     
-fin
+re
 al
- 
 Class
-%3C?%3E result =
+Cache.putIfAbsent(elementName,
  sup
@@ -1487,32 +1487,33 @@
 ass(elementName)
+)
 ;%0A            re
@@ -1502,32 +1502,49 @@
 ));%0A            
+return (Class%3C?%3E)
 realClassCache.p
@@ -1534,34 +1534,34 @@
 )realClassCache.
-pu
+ge
 t(elementName, r
@@ -1561,44 +1561,9 @@
 Name
-, result);%0A            return result
+)
 ;%0A  
@@ -1634,32 +1634,40 @@
 alClassCache.put
+IfAbsent
 (elementName, e)
@@ -1775,16 +1775,24 @@
 ache.put
+IfAbsent
 (element
@@ -1987,40 +1987,22 @@
 e = 
-Collections.synchronizedMap(new 
+new Concurrent
 Hash
@@ -2025,17 +2025,16 @@
 ct%3E(128)
-)
 ;%0A      

Use ConcurrentHashMap in CachingMapper (XSTR-727).