/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.schemarepo.config; import java.io.PrintStream; import java.util.Properties; import javax.inject.Named; import javax.inject.Singleton; import org.schemarepo.CacheRepository; import org.schemarepo.Repository; import org.schemarepo.RepositoryCache; import org.schemarepo.RepositoryUtil; import org.schemarepo.Validator; import org.schemarepo.ValidatorFactory; import org.schemarepo.json.JsonUtil; import com.google.inject.Binder; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; import com.google.inject.Provides; import com.google.inject.TypeLiteral; import com.google.inject.name.Names; /** * A {@link Module} for configuration based on a set of {@link Properties} * <br/> * Binds every property value in the properties provided to the property name * in Guice, making them available with the {@link Named} annotation. Guice * will automatically convert these to constant values, such as Integers, * Strings, or Class constants. * <br/> * Keys starting with "validator." bind {@link Validator} classes * in a {@link ValidatorFactory}, where the name is the remainder of the key * following "schema-repo.validator.". For example, a property * "schema-repo.validator.backwards_compatible=com.foo.BackwardsCompatible" * will set a validator named "backwards_compatible" to an instance of the * class com.foo.BackwardsCompatible. */ public class ConfigModule implements Module { public static void printDefaults(PrintStream writer) { writer.println(Config.DEFAULTS); } private final Properties props; public ConfigModule(Properties props) { Properties copy = new Properties(Config.DEFAULTS); copy.putAll(props); this.props = copy; } @Override public void configure(Binder binder) { Names.bindProperties(binder, props); } @Provides @Singleton Repository provideRepository(Injector injector, @Named(Config.REPO_CLASS) Class<Repository> repoClass, @Named(Config.REPO_CACHE) Class<RepositoryCache> cacheClass) { Repository repo = injector.getInstance(repoClass); RepositoryCache cache = injector.getInstance(cacheClass); return new CacheRepository(repo, cache); } @Provides @Singleton ValidatorFactory provideValidatorFactory(Injector injector, @Named(Config.DEFAULT_SUBJECT_VALIDATORS) String defaultSubjectValidators) { ValidatorFactory.Builder builder = new ValidatorFactory.Builder(); for(String prop : props.stringPropertyNames()) { if (prop.startsWith(Config.VALIDATOR_PREFIX)) { String validatorName = prop.substring(Config.VALIDATOR_PREFIX.length()); Class<Validator> validatorClass = injector.getInstance( Key.<Class<Validator>>get( new TypeLiteral<Class<Validator>>(){}, Names.named(prop))); builder.setValidator(validatorName, injector.getInstance(validatorClass)); } } // assign the default subject validators builder.setDefaultValidators(RepositoryUtil.commaSplit(defaultSubjectValidators)); return builder.build(); } @Provides @Singleton JsonUtil provideJsonUtil(Injector injector, @Named(Config.JSON_UTIL_IMPLEMENTATION) Class<JsonUtil> jsonUtilClass) { return injector.getInstance(jsonUtilClass); } @Provides @Singleton Properties properties() { final Properties copyOfProps = new Properties(); copyOfProps.putAll(props); return copyOfProps; } }