/** * * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. * * This library 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 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * **/ package lucee.runtime.op; import java.util.IdentityHashMap; import java.util.Map; import lucee.commons.lang.types.RefBoolean; import lucee.commons.lang.types.RefBooleanImpl; public class ThreadLocalDuplication { private static ThreadLocal<Map<Object,Object>> local=new ThreadLocal<Map<Object,Object>>(); private static ThreadLocal<RefBoolean> inside=new ThreadLocal<RefBoolean>(); public static boolean set(Object o, Object c) { touch(true).put(o,c); return isInside(); } /*public static Map<Object, Object> getMap() { return touch(); } public static void removex(Object o) { touch().remove(o); }*/ /*private static Object get(Object obj) { Map<Object,Object> list = touch(); return list.get(obj); }*/ public static Object get(Object object, RefBoolean before) { if(!isInside()){ reset(); setIsInside(true); before.setValue(false); } else before.setValue(true); Map<Object,Object> list = touch(false); return list==null?null: list.get(object); } private static Map<Object,Object> touch(boolean createIfNecessary) { Map<Object,Object> set = local.get(); if(set==null) { if(!createIfNecessary) return null; set = new IdentityHashMap<Object,Object>();// it is importend to have a reference comparsion here local.set(set); } return set; } public static void reset() { Map<Object,Object> set = local.get(); if(set!=null) set.clear(); setIsInside(false); } private static boolean isInside() { RefBoolean b = inside.get(); return b!=null && b.toBooleanValue(); } private static void setIsInside(boolean isInside) { RefBoolean b = inside.get(); if(b==null)inside.set(new RefBooleanImpl(isInside)); else b.setValue(isInside); } }