1/** 2 * Copyright 2006-2013 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package org.objenesis; 17 18import java.util.HashMap; 19import java.util.Map; 20 21import org.objenesis.instantiator.ObjectInstantiator; 22import org.objenesis.strategy.InstantiatorStrategy; 23 24/** 25 * Base class to extend if you want to have a class providing your own default strategy. Can also be 26 * instantiated directly. 27 * 28 * @author Henri Tremblay 29 */ 30public class ObjenesisBase implements Objenesis { 31 32 /** Strategy used by this Objenesi implementation to create classes */ 33 protected final InstantiatorStrategy strategy; 34 35 /** Strategy cache. Key = Class, Value = InstantiatorStrategy */ 36 protected Map cache; 37 38 /** 39 * Constructor allowing to pick a strategy and using cache 40 * 41 * @param strategy Strategy to use 42 */ 43 public ObjenesisBase(InstantiatorStrategy strategy) { 44 this(strategy, true); 45 } 46 47 /** 48 * Flexible constructor allowing to pick the strategy and if caching should be used 49 * 50 * @param strategy Strategy to use 51 * @param useCache If {@link ObjectInstantiator}s should be cached 52 */ 53 public ObjenesisBase(InstantiatorStrategy strategy, boolean useCache) { 54 if(strategy == null) { 55 throw new IllegalArgumentException("A strategy can't be null"); 56 } 57 this.strategy = strategy; 58 this.cache = useCache ? new HashMap() : null; 59 } 60 61 public String toString() { 62 return getClass().getName() + " using " + strategy.getClass().getName() 63 + (cache == null ? " without" : " with") + " caching"; 64 } 65 66 /** 67 * Will create a new object without any constructor being called 68 * 69 * @param clazz Class to instantiate 70 * @return New instance of clazz 71 */ 72 public Object newInstance(Class clazz) { 73 return getInstantiatorOf(clazz).newInstance(); 74 } 75 76 /** 77 * Will pick the best instantiator for the provided class. If you need to create a lot of 78 * instances from the same class, it is way more efficient to create them from the same 79 * ObjectInstantiator than calling {@link #newInstance(Class)}. 80 * 81 * @param clazz Class to instantiate 82 * @return Instantiator dedicated to the class 83 */ 84 public synchronized ObjectInstantiator getInstantiatorOf(Class clazz) { 85 if(cache == null) { 86 return strategy.newInstantiatorOf(clazz); 87 } 88 ObjectInstantiator instantiator = (ObjectInstantiator) cache.get(clazz.getName()); 89 if(instantiator == null) { 90 instantiator = strategy.newInstantiatorOf(clazz); 91 cache.put(clazz.getName(), instantiator); 92 } 93 return instantiator; 94 } 95 96} 97