/* Copyright 2012 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arbeitspferde.groningen;
import com.google.inject.AbstractModule;
import com.google.inject.Key;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.ProtocolMessageEnum;
import org.arbeitspferde.groningen.common.BlockScope;
import org.arbeitspferde.groningen.common.SimpleScope;
import org.arbeitspferde.groningen.config.GroningenConfig;
import org.arbeitspferde.groningen.config.NamedConfigParamImpl;
import org.arbeitspferde.groningen.config.PipelineIterationScoped;
import org.arbeitspferde.groningen.proto.Params.GroningenParams;
import java.util.logging.Logger;
/**
* Guice module that handles Groningen's per-pipeline configuration parameters.
*/
public class GroningenConfigParamsModule extends AbstractModule {
private static final Logger log =
Logger.getLogger(GroningenConfigParamsModule.class.getCanonicalName());
/**
* Seeds one particular configuration parameter of the given type into the given scope.
* Suppressing "unchecked" warnings due to generic type being used for type casting.
*/
@SuppressWarnings("unchecked")
private static <T> void nailConfigParamToScope(Class<T> type, FieldDescriptor fd,
GroningenConfig config, BlockScope scope) {
T value = (T) config.getParamBlock().getField(fd);
log.fine(
String.format("nailing %s (%s) to {%s}", fd.getName(), fd.getJavaType().name(), value));
scope.seed(Key.get(type, new NamedConfigParamImpl(fd.getName())), value);
}
/**
* Binds given type annotated by the name of the FieldDescriptor to a
* SimpleScope.seededKeyProvider. This provider throws an exception when the value is
* injected outside of the desired scope.
*/
private <T> void bindConfigParamToSeededKeyProvider(Class<T> type, FieldDescriptor fd) {
bind(Key.get(type, new NamedConfigParamImpl(fd.getName())))
.toProvider(SimpleScope.<T>seededKeyProvider())
.in(PipelineIterationScoped.class);
}
/**
* Nails all the per-pipeline configuration parameters to a given Guice scope.
*
* @param config Configuration parameters to be fixed for the pipeline run duration.
* @param scope Guice scope used to fix the parameters.
*/
public static void nailConfigToScope(GroningenConfig config, BlockScope scope) {
scope.seed(GroningenConfig.class, config);
for (FieldDescriptor fd : GroningenParams.getDescriptor().getFields()) {
switch (fd.getJavaType()) {
case ENUM:
nailConfigParamToScope(ProtocolMessageEnum.class, fd, config, scope);
break;
case INT:
nailConfigParamToScope(Integer.class, fd, config, scope);
break;
case LONG:
nailConfigParamToScope(Long.class, fd, config, scope);
break;
case DOUBLE:
nailConfigParamToScope(Double.class, fd, config, scope);
break;
case STRING:
nailConfigParamToScope(String.class, fd, config, scope);
break;
default:
log.warning(String.format("unrecognized field descriptor type: %s.", fd.getJavaType()));
break;
}
}
}
/**
* GroningenConfigParamsModule binds pipelineIterationScope to a specific SimpleScope
* implementation and binds all the configuration parameters (fields annotated with
* @NamedConfigParam) to a SimpleScope.seededKeyProvider(), which prevents them being
* injected outside of the scope (see bindConfigParamToSeededKeyProvider()).
*/
@Override
protected void configure() {
bind(GroningenConfig.class)
.toProvider(SimpleScope.<GroningenConfig>seededKeyProvider())
.in(PipelineIterationScoped.class);
for (FieldDescriptor fd : GroningenParams.getDescriptor().getFields()) {
switch (fd.getJavaType()) {
case ENUM:
bindConfigParamToSeededKeyProvider(ProtocolMessageEnum.class, fd);
break;
case INT:
bindConfigParamToSeededKeyProvider(Integer.class, fd);
break;
case LONG:
bindConfigParamToSeededKeyProvider(Long.class, fd);
break;
case DOUBLE:
bindConfigParamToSeededKeyProvider(Double.class, fd);
break;
case STRING:
bindConfigParamToSeededKeyProvider(String.class, fd);
break;
default:
log.warning(String.format("unrecognized field descriptor type: %s.", fd.getJavaType()));
break;
}
}
}
}