private static <T> T newInstance(ConfigurationMetadata<T> configurationMetadata) { try { return configurationMetadata.getConstructor().newInstance(); } catch (Throwable e) { if (e instanceof InvocationTargetException && e.getCause() != null) { e = e.getCause(); } throw exceptionFor(e, "Error creating instance of configuration class [%s]", configurationMetadata.getConfigClass().getName()); } }
public static <T> ConfigurationMetadata<T> getValidConfigurationMetadata(Class<T> configClass) throws ConfigurationException { return getValidConfigurationMetadata(configClass, Problems.NULL_MONITOR); }
static <T> ConfigurationMetadata<T> getConfigurationMetadata(Class<T> configClass, Problems.Monitor monitor) { return new ConfigurationMetadata<>(configClass, monitor); }
public static <T> void assertDefaults(Map<String, Object> expectedAttributeValues, Class<T> configClass) ConfigurationMetadata<?> metadata = ConfigurationMetadata.getValidConfigurationMetadata(configClass); if (!metadata.getAttributes().keySet().containsAll(expectedAttributeValues.keySet())) { TreeSet<String> unsupportedAttributes = new TreeSet<>(expectedAttributeValues.keySet()); unsupportedAttributes.removeAll(metadata.getAttributes().keySet()); fail("Unsupported attributes: " + unsupportedAttributes); for (AttributeMetadata attribute : metadata.getAttributes().values()) { if (attribute.getInjectionPoint().getProperty() != null) { nonDeprecatedAttributes.add(attribute.getName()); for (AttributeMetadata attribute : metadata.getAttributes().values()) { Method getter = attribute.getGetter(); if (getter == null) {
@Test public void testIsMethodMultipleSettersClass() throws Exception { TestMonitor monitor = new TestMonitor(); ConfigurationMetadata<?> metadata = ConfigurationMetadata.getConfigurationMetadata(IsMethodMultipleSettersClass.class, monitor); Map<String, Set<String>> expectedAttributes = new HashMap<>(); expectedAttributes.put("Value", ImmutableSet.of("value")); verifyMetaData(metadata, IsMethodMultipleSettersClass.class, null, false, expectedAttributes); monitor.assertNumberOfErrors(0); monitor.assertNumberOfWarnings(0); }
private void verifyMetaData(ConfigurationMetadata<?> metadata, Class<?> configClass, String description, Map<String, Set<String>> attributeProperties) throws Exception { Assert.assertEquals(metadata.getConfigClass(), configClass); if (metadata.getConstructor() != null) { Assert.assertEquals(metadata.getConstructor(), configClass.getDeclaredConstructor()); } else { try { configClass.getDeclaredConstructor(); Assert.fail(String.format("Expected configClass [%s] not to have a constructor", configClass.getName())); } catch (NoSuchMethodException expected) { } } Assert.assertEquals(metadata.getAttributes().size(), attributeProperties.keySet().size()); for (String name : attributeProperties.keySet()) { AttributeMetadata attribute = metadata.getAttributes().get(name); Assert.assertEquals(attribute.getConfigClass(), configClass); Set<String> namesToTest = Sets.newHashSet(); namesToTest.add(attribute.getInjectionPoint().getProperty()); for (ConfigurationMetadata.InjectionPointMetaData legacyInjectionPoint : attribute.getLegacyInjectionPoints()) { namesToTest.add(legacyInjectionPoint.getProperty()); } Assert.assertEquals(namesToTest, attributeProperties.get(name)); Assert.assertEquals(attribute.getDescription(), description); } }
@Test public void testEquivalence() { equivalenceTester() .addEquivalentGroup( ConfigurationMetadata.getConfigurationMetadata(SetterSubConfigClass.class), ConfigurationMetadata.getConfigurationMetadata(SetterSubConfigClass.class)) .addEquivalentGroup( ConfigurationMetadata.getConfigurationMetadata(SetterConfigClass.class), ConfigurationMetadata.getConfigurationMetadata(SetterConfigClass.class)) .check(); equivalenceTester() .addEquivalentGroup( ConfigurationMetadata.getConfigurationMetadata(SetterSubConfigClass.class).getAttributes().get("Value"), ConfigurationMetadata.getConfigurationMetadata(SetterSubConfigClass.class).getAttributes().get("Value")) .addEquivalentGroup( ConfigurationMetadata.getConfigurationMetadata(SetterConfigClass.class).getAttributes().get("Value"), ConfigurationMetadata.getConfigurationMetadata(SetterConfigClass.class).getAttributes().get("Value")) .check(); }
private Map<String, AttributeMetadata> buildAttributeMetadata(Class<T> configClass) { Map<String, AttributeMetadata> attributes = Maps.newHashMap(); for (Method configMethod : findConfigMethods(configClass)) { AttributeMetadata attribute = buildAttributeMetadata(configClass, configMethod); if (attribute != null) { if (attributes.containsKey(attribute.getName())) { problems.addError("Configuration class [%s] Multiple methods are annotated for @Config attribute [%s]", configClass.getName(), attribute.getName()); } attributes.put(attribute.getName(), attribute); } } // Find orphan @LegacyConfig methods, in order to report errors Collection<Method> legacyMethods = findLegacyConfigMethods(configClass); for (AttributeMetadata attribute : attributes.values()) { for (InjectionPointMetaData injectionPoint : attribute.getLegacyInjectionPoints()) { if (legacyMethods.contains(injectionPoint.getSetter())) { // Don't care about legacy methods which are related to current attributes legacyMethods.remove(injectionPoint.getSetter()); } } } for (Method method : legacyMethods) { if (!method.isAnnotationPresent(Config.class)) { validateSetter(method); problems.addError("@LegacyConfig method [%s] is not associated with any valid @Config attribute.", method.toGenericString()); } } return attributes; }
@Test public void testNotPublicConstructorClass() throws Exception { TestMonitor monitor = new TestMonitor(); ConfigurationMetadata<?> metadata = ConfigurationMetadata.getConfigurationMetadata(NotPublicConstructorClass.class, monitor); Map<String, Set<String>> expectedAttributes = new HashMap<>(); expectedAttributes.put("Value", ImmutableSet.of("value")); verifyMetaData(metadata, NotPublicConstructorClass.class, null, false, expectedAttributes); monitor.assertNumberOfErrors(1); monitor.assertNumberOfWarnings(0); monitor.assertMatchingErrorRecorded("not public", metadata.getConfigClass().getName() + "()"); }
private static <T> void assertAttributesEqual(ConfigurationMetadata<T> metadata, T actual, T expected) { for (AttributeMetadata attribute : metadata.getAttributes().values()) { Method getter = attribute.getGetter(); if (getter == null) { continue; } Object actualAttributeValue = invoke(actual, getter); Object expectedAttributeValue = invoke(expected, getter); assertEquals(actualAttributeValue, expectedAttributeValue, attribute.getName()); } }
configurationMetadata.getProblems().throwIfHasErrors(); for (AttributeMetadata attribute : configurationMetadata.getAttributes().values()) { try { setConfigProperty(instance, attribute, prefix, problems); AttributeMetadata attribute = configurationMetadata.getAttributes().get(attributeName); if (attribute != null && attribute.getInjectionPoint() != null) { String propertyName = attribute.getInjectionPoint().getProperty();
private static Collection<Method> findSensitiveConfigMethods(Class<?> configClass) { return findAnnotatedMethods(configClass, ConfigSecuritySensitive.class); }
public static Method findAnnotatedMethod(Class<?> configClass, Class<? extends java.lang.annotation.Annotation> annotation, String methodName, Class<?>... paramTypes) { try { Method method = configClass.getDeclaredMethod(methodName, paramTypes); if (method != null && method.isAnnotationPresent(annotation)) { return method; } } catch (NoSuchMethodException e) { // ignore } if (configClass.getSuperclass() != null) { Method managedMethod = findAnnotatedMethod(configClass.getSuperclass(), annotation, methodName, paramTypes); if (managedMethod != null) { return managedMethod; } } for (Class<?> iface : configClass.getInterfaces()) { Method managedMethod = findAnnotatedMethod(iface, annotation, methodName, paramTypes); if (managedMethod != null) { return managedMethod; } } return null; }
this.attributes = ImmutableSortedMap.copyOf(buildAttributeMetadata(configClass));
public static <T> void assertDefaults(Map<String, Object> expectedAttributeValues, Class<T> configClass) ConfigurationMetadata<?> metadata = ConfigurationMetadata.getValidConfigurationMetadata(configClass); if (!metadata.getAttributes().keySet().containsAll(expectedAttributeValues.keySet())) { TreeSet<String> unsupportedAttributes = new TreeSet<>(expectedAttributeValues.keySet()); unsupportedAttributes.removeAll(metadata.getAttributes().keySet()); Assert.fail("Unsupported attributes: " + unsupportedAttributes); for (AttributeMetadata attribute : metadata.getAttributes().values()) { if (attribute.getInjectionPoint().getProperty() != null) { nonDeprecatedAttributes.add(attribute.getName()); for (AttributeMetadata attribute : metadata.getAttributes().values()) { Method getter = attribute.getGetter(); if (getter == null) {
@Test public void testCurrentAndLegacyConfigOnSetterClass() throws Exception { TestMonitor monitor = new TestMonitor(); ConfigurationMetadata<?> metadata = ConfigurationMetadata.getConfigurationMetadata(CurrentAndLegacyConfigOnSetterClass.class, monitor); Map<String, Set<String>> expectedAttributes = new HashMap<>(); expectedAttributes.put("Value", ImmutableSet.of("value", "replacedValue")); verifyMetaData(metadata, CurrentAndLegacyConfigOnSetterClass.class, "description", false, expectedAttributes); monitor.assertNumberOfErrors(0); monitor.assertNumberOfWarnings(0); }
private void verifyMetaData(ConfigurationMetadata<?> metadata, Class<?> configClass, String description, boolean securitySensitive, Map<String, Set<String>> attributeProperties) throws Exception { assertEquals(metadata.getConfigClass(), configClass); if (metadata.getConstructor() != null) { assertEquals(metadata.getConstructor(), configClass.getDeclaredConstructor()); } else { try { configClass.getDeclaredConstructor(); fail(String.format("Expected configClass [%s] not to have a constructor", configClass.getName())); } catch (NoSuchMethodException expected) { } } assertEquals(metadata.getAttributes().size(), attributeProperties.keySet().size()); for (String name : attributeProperties.keySet()) { AttributeMetadata attribute = metadata.getAttributes().get(name); assertEquals(attribute.getConfigClass(), configClass); Set<String> namesToTest = new HashSet<>(); namesToTest.add(attribute.getInjectionPoint().getProperty()); for (ConfigurationMetadata.InjectionPointMetaData legacyInjectionPoint : attribute.getLegacyInjectionPoints()) { namesToTest.add(legacyInjectionPoint.getProperty()); } assertEquals(namesToTest, attributeProperties.get(name)); assertEquals(attribute.getDescription(), description); assertEquals(attribute.isSecuritySensitive(), securitySensitive); } }
@Test public void testEquivalence() { equivalenceTester() .addEquivalentGroup( ConfigurationMetadata.getConfigurationMetadata(SetterSubConfigClass.class), ConfigurationMetadata.getConfigurationMetadata(SetterSubConfigClass.class)) .addEquivalentGroup( ConfigurationMetadata.getConfigurationMetadata(SetterConfigClass.class), ConfigurationMetadata.getConfigurationMetadata(SetterConfigClass.class)) .check(); equivalenceTester() .addEquivalentGroup( ConfigurationMetadata.getConfigurationMetadata(SetterSubConfigClass.class).getAttributes().get("Value"), ConfigurationMetadata.getConfigurationMetadata(SetterSubConfigClass.class).getAttributes().get("Value")) .addEquivalentGroup( ConfigurationMetadata.getConfigurationMetadata(SetterConfigClass.class).getAttributes().get("Value"), ConfigurationMetadata.getConfigurationMetadata(SetterConfigClass.class).getAttributes().get("Value")) .check(); }
private Map<String, AttributeMetadata> buildAttributeMetadata(Class<T> configClass) for (Method configMethod : findConfigMethods(configClass)) { AttributeMetadata attribute = buildAttributeMetadata(configClass, configMethod); Collection<Method> legacyMethods = findLegacyConfigMethods(configClass); for (AttributeMetadata attribute : attributes.values()) { for (InjectionPointMetaData injectionPoint : attribute.getLegacyInjectionPoints()) { validateSetter(method); problems.addError("@LegacyConfig method [%s] is not associated with any valid @Config attribute.", method.toGenericString()); Collection<Method> sensitiveMethods = findSensitiveConfigMethods(configClass); for (Method method : sensitiveMethods) { if (!method.isAnnotationPresent(Config.class)) {
@Test public void testNotPublicConstructorClass() throws Exception { TestMonitor monitor = new TestMonitor(); ConfigurationMetadata<?> metadata = ConfigurationMetadata.getConfigurationMetadata(NotPublicConstructorClass.class, monitor); Map<String, Set<String>> expectedAttributes = new HashMap<>(); expectedAttributes.put("Value", ImmutableSet.of("value")); verifyMetaData(metadata, NotPublicConstructorClass.class, null, false, expectedAttributes); monitor.assertNumberOfErrors(1); monitor.assertNumberOfWarnings(0); monitor.assertMatchingErrorRecorded("not public", metadata.getConfigClass().getName() + "()"); }