diff options
author | gjoranv <gjoranv@gmail.com> | 2017-06-09 01:40:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-09 01:40:28 +0200 |
commit | 3d0f44f63919702713908b8da56434a5260f18df (patch) | |
tree | d1c053f421fed0fdc70db2982efcd02f3811e668 | |
parent | 03fe521bd2e44e867e97e6ae4e2200542cebfc6f (diff) | |
parent | 5d228e521e445aba9db988d1080341b308560cfa (diff) |
Merge pull request #2680 from yahoo/revert-2675-revert-2672-revert-2445-gjoranv/remove-default-ctor4
Revert "Revert "Revert "Gjoranv/remove default ctor4"""
-rw-r--r-- | config-model/src/main/java/com/yahoo/vespa/model/InstanceResolver.java | 60 | ||||
-rw-r--r-- | configgen/src/main/scala/com/yahoo/config/codegen/ConfigGenerator.scala | 12 |
2 files changed, 52 insertions, 20 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/InstanceResolver.java b/config-model/src/main/java/com/yahoo/vespa/model/InstanceResolver.java index fdb9fdf9796..9c761e425a7 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/InstanceResolver.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/InstanceResolver.java @@ -11,7 +11,6 @@ import com.yahoo.vespa.config.buildergen.ConfigDefinition; import com.yahoo.yolean.Exceptions; import com.yahoo.vespa.config.*; -import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.List; @@ -47,19 +46,13 @@ class InstanceResolver { * @param targetDef the def to use * @return the config instance or null of no producer for this found in model */ - @SuppressWarnings("unchecked") static ConfigInstance resolveToInstance(ConfigKey<?> key, ConfigBuilder builder, InnerCNode targetDef) { + ConfigDefinitionKey defKey = new ConfigDefinitionKey(key); try { if (targetDef != null) applyDef(builder, targetDef); - Class<?> clazz = builder.getClass().getEnclosingClass(); - if (!(ConfigInstance.class.isAssignableFrom(clazz))) { - throw new ConfigurationRuntimeException("Cannot produce config for the name '" + key.getName() + ", as " - + clazz.getName() + " is not a ConfigInstance."); - } - Class<? extends ConfigInstance> configClass = (Class<? extends ConfigInstance>)clazz; - Constructor<? extends ConfigInstance> constructor = configClass.getDeclaredConstructor(builder.getClass(), boolean.class); - constructor.setAccessible(true); - return constructor.newInstance(builder, /*throwIfUninitialized*/ false); + ConfigInstance instance = getInstance(defKey, builder.getClass().getClassLoader()); + Class<? extends ConfigInstance> clazz = instance.getClass(); + return clazz.getConstructor(new Class<?>[]{builder.getClass()}).newInstance(builder); } catch (Exception e) { throw new ConfigurationRuntimeException(e); } @@ -150,6 +143,51 @@ class InstanceResolver { } } + /** + * Create a ConfigBuilder given a definition key and a payload + * @param key The key to use to create the correct builder. + * @param payload The payload to populate the builder with. + * @return A ConfigBuilder initialized with payload. + */ + static ConfigBuilder createBuilderFromPayload(ConfigDefinitionKey key, VespaModel model, ConfigPayload payload, ConfigDefinition targetDef) { + ConfigBuilder builderInstance = model.createBuilder(key, targetDef); + if (builderInstance == null || builderInstance instanceof GenericConfig.GenericConfigBuilder) { + if (log.isLoggable(LogLevel.SPAM)) { + log.log(LogLevel.SPAM, "Creating generic builder for key=" + key); + } + return new GenericConfig.GenericConfigBuilder(key, new ConfigPayloadBuilder(payload)); + } + ConfigTransformer transformer = new ConfigTransformer(builderInstance.getClass().getDeclaringClass()); + return transformer.toConfigBuilder(payload); + } + + /** + * Returns a {@link ConfigInstance} of right type for given key using reflection + * + * @param cKey a ConfigKey + * @return a {@link ConfigInstance} or null if not available in classpath + */ + static ConfigInstance getInstance(ConfigDefinitionKey cKey, ClassLoader instanceLoader) { + String className = ConfigGenerator.createClassName(cKey.getName()); + Class<?> clazz; + String fullClassName = packageName(cKey) + "." + className; + try { + clazz = instanceLoader != null ? instanceLoader.loadClass(fullClassName) : Class.forName(fullClassName); + } catch (ClassNotFoundException e) { + return null; + } + Object i; + try { + i = clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new ConfigurationRuntimeException(e); + } + if (!(i instanceof ConfigInstance)) { + throw new ConfigurationRuntimeException(fullClassName + " is not a ConfigInstance, can not produce config for the name '" + cKey.getName() + "'."); + } + return (ConfigInstance) i; + } + static String packageName(ConfigDefinitionKey cKey) { String prefix = "com.yahoo."; return prefix + (cKey.getNamespace().isEmpty() ? CNode.DEFAULT_NAMESPACE : cKey.getNamespace()); diff --git a/configgen/src/main/scala/com/yahoo/config/codegen/ConfigGenerator.scala b/configgen/src/main/scala/com/yahoo/config/codegen/ConfigGenerator.scala index 533b9b2be23..716f2a60c33 100644 --- a/configgen/src/main/scala/com/yahoo/config/codegen/ConfigGenerator.scala +++ b/configgen/src/main/scala/com/yahoo/config/codegen/ConfigGenerator.scala @@ -180,14 +180,8 @@ object ConfigGenerator { } } - // TODO: The default ctor is possibly still needed for innerArrays, because of InnerNodeVector.createNew() - def defaultConstructorIfArray = { - inner match { - case array: InnerCNode if inner.isArray => defaultConstructor - case scalar: InnerCNode => "" - } - } - + // TODO: The default ctor can be removed if the config library uses builders to set values from payload, but ... + // a default ctor is also needed for all innerArrays, because of InnerNodeVector.createNew() def defaultConstructor = { // TODO @link gives javadoc warnings, although the syntax seems to be valid //def link = "{@link " + {nodeClass(inner)} + "#" + {nodeClass(inner)} + "(Builder)}" @@ -208,7 +202,7 @@ object ConfigGenerator { // TODO: merge these two constructors into one when the config library uses builders to set values from payload. <code> - |{defaultConstructorIfArray} + |{defaultConstructor} | |public {nodeClass(inner)}(Builder builder) {{ | this(builder, true); |