/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ConfigEntry.java * * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */ package com.sun.electric.util.config.model; import java.lang.reflect.Method; import com.sun.electric.util.config.InjectStrategy; import com.sun.electric.util.config.CreateBy; import com.sun.electric.util.config.annotations.Inject; import com.sun.electric.util.config.annotations.InjectionMethod; import com.sun.electric.util.config.annotations.InjectionMethod.InjectionStrategy; /** * @author Felix Schmidt */ public abstract class ConfigEntry<T> { protected boolean singleton = false; protected T singletonInstance = null; protected ParameterEntry[] parameters; protected Class<T> clazz; public ConfigEntry(Class<T> clazz, boolean singleton, ParameterEntry... parameter) { this.singleton = singleton; this.parameters = parameter; this.clazz = clazz; } public abstract T getInstance() throws Exception; protected void injectSetters(T instance) throws Exception { Method[] methods = clazz.getMethods(); for (Method method : methods) { Inject inject = method.getAnnotation(Inject.class); if (inject != null) { String name = inject.name(); String paramName = ""; if (name.equals("")) { if (method.getName().startsWith("set")) { paramName = method.getName().substring(3).toLowerCase(); } else { paramName = name; } } else { paramName = name; } for (ParameterEntry entry : parameters) { if (entry.getName().equals(paramName)) { method.invoke(instance, entry.getValue().getInstance()); break; } } } } } public static class ConfigEntryConstructor<T> extends ConfigEntry<T> { public ConfigEntryConstructor(Class<T> clazz, boolean singleton, ParameterEntry... parameters) { super(clazz, singleton, parameters); } @Override public T getInstance() throws Exception { T instance = null; if (!(singleton && singletonInstance != null)) { InjectionMethod inWay = clazz.getAnnotation(InjectionMethod.class); InjectStrategy<T> strategy = null; if (inWay != null) { if (inWay.injectionStrategy().equals(InjectionStrategy.initialization)) strategy = InjectStrategy.getForConstructor(clazz); else { strategy = InjectStrategy.getForSetter(clazz, CreateBy.constructor, null); } } else { strategy = InjectStrategy.getDefault(clazz, CreateBy.constructor, null); } instance = strategy.inject(clazz, parameters); if (singleton) { singletonInstance = instance; } } else { instance = singletonInstance; } return instance; } } public static class ConfigEntryFactoryMethod<T> extends ConfigEntry<T> { private String factoryMethod; public ConfigEntryFactoryMethod(Class<T> clazz, String factoryMethod, boolean singleton, ParameterEntry... parameters) { super(clazz, singleton, parameters); this.factoryMethod = factoryMethod; } @Override public T getInstance() throws Exception { T instance = null; if (!(singleton && singletonInstance != null)) { InjectionMethod inWay = clazz.getAnnotation(InjectionMethod.class); InjectStrategy<T> strategy = null; if (inWay != null) { if (inWay.injectionStrategy().equals(InjectionStrategy.initialization)) strategy = InjectStrategy.getForFactoryMethod(clazz, factoryMethod); else strategy = InjectStrategy.getForSetter(clazz, CreateBy.factoryMethod, factoryMethod); } else { strategy = InjectStrategy.getDefault(clazz, CreateBy.factoryMethod, factoryMethod); } instance = strategy.inject(clazz, parameters); if (singleton) { singletonInstance = instance; } } else { instance = singletonInstance; } return instance; } } public static class ConfigEntryPrimitive<T> extends ConfigEntry<T> { private T value; private boolean runtime; public ConfigEntryPrimitive(T value, boolean runtime) { super(null, false); this.value = value; this.runtime = runtime; } @Override public T getInstance() throws Exception { return value; } public boolean getRuntime() { return runtime; } } public static class ConfigEntryEnum<T extends Enum<T>> extends ConfigEntry<T> { private T value; public ConfigEntryEnum(Class<T> clazz, String value) { super(null, false); for (T tmp : clazz.getEnumConstants()) { if (tmp.name().equals(value)) { this.value = tmp; return; } } } @Override public T getInstance() throws Exception { return value; } } public static <T> ConfigEntry<T> createForConstructor(Class<T> clazz, boolean singleton, ParameterEntry... parameters) { return new ConfigEntryConstructor<T>(clazz, singleton, parameters); } public static <T> ConfigEntry<T> createForFactoryMethod(Class<T> clazz, String factoryMethod, boolean singleton, ParameterEntry... parameters) { return new ConfigEntryFactoryMethod<T>(clazz, factoryMethod, singleton, parameters); } public static <T extends Enum<T>> ConfigEntry<T> createForEnum(Class<T> clazz, String value) { return new ConfigEntryEnum<T>(clazz, value); } }