Skip to content

Commit

Permalink
Add v3 dependency injection default implementation and tests
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Sicker <boards@gmail.com>
  • Loading branch information
jvz committed Feb 23, 2020
1 parent bc2e767 commit 379234d
Show file tree
Hide file tree
Showing 47 changed files with 3,733 additions and 0 deletions.
@@ -0,0 +1,72 @@
/*
* 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.apache.logging.log4j.plugins.defaults.bean;

import org.apache.logging.log4j.plugins.spi.bean.Bean;
import org.apache.logging.log4j.plugins.spi.model.MetaClass;
import org.apache.logging.log4j.plugins.spi.model.Qualifier;
import org.apache.logging.log4j.plugins.spi.model.Variable;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Objects;

abstract class AbstractBean<D, T> implements Bean<T> {
private final Variable<T> variable;
private final MetaClass<D> declaringClass;

AbstractBean(final Variable<T> variable, final MetaClass<D> declaringClass) {
this.variable = Objects.requireNonNull(variable);
this.declaringClass = declaringClass;
}

@Override
public MetaClass<D> getDeclaringClass() {
return declaringClass;
}

@Override
public Collection<Qualifier> getQualifiers() {
return variable.getQualifiers();
}

@Override
public Collection<Type> getTypes() {
return variable.getTypes();
}

@Override
public Class<? extends Annotation> getScopeType() {
return variable.getScopeType();
}

@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final AbstractBean<?, ?> that = (AbstractBean<?, ?>) o;
return variable.equals(that.variable) &&
Objects.equals(declaringClass, that.declaringClass);
}

@Override
public int hashCode() {
return Objects.hash(variable, declaringClass);
}
}
@@ -0,0 +1,71 @@
/*
* 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.apache.logging.log4j.plugins.defaults.bean;

import org.apache.logging.log4j.plugins.spi.bean.Bean;
import org.apache.logging.log4j.plugins.spi.bean.BeanManager;
import org.apache.logging.log4j.plugins.spi.bean.Producer;
import org.apache.logging.log4j.plugins.spi.model.InjectionPoint;
import org.apache.logging.log4j.plugins.spi.model.MetaMethod;
import org.apache.logging.log4j.plugins.spi.scope.InitializationContext;

import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Objects;

abstract class AbstractProducer<D, T> implements Producer<T> {
private final BeanManager beanManager;

private final Bean<D> declaringBean;
private final MetaMethod<D, ?> disposerMethod;
private final Collection<InjectionPoint<?>> disposerInjectionPoints;
final InjectionContext.Factory injectionContextFactory;

AbstractProducer(final BeanManager beanManager, final Bean<D> declaringBean, final MetaMethod<D, ?> disposerMethod,
final Collection<InjectionPoint<?>> disposerInjectionPoints) {
this.beanManager = beanManager;
this.declaringBean = declaringBean;
this.disposerMethod = disposerMethod;
this.disposerInjectionPoints = Objects.requireNonNull(disposerInjectionPoints);
this.injectionContextFactory = new DefaultInjectionContextFactory(beanManager);
}

// context is managed separately as the declaring instance is only used for producing the object and is not a dependent of the bean
InitializationContext<D> createContext() {
return beanManager.createInitializationContext(declaringBean);
}

D getDeclaringInstance(final InitializationContext<D> context) {
return context.getIncompleteInstance(declaringBean).orElseGet(() ->
beanManager.getValue(declaringBean, context.createIndependentContext(declaringBean)));
}

abstract Type getType();

@Override
public void dispose(final T instance) {
if (disposerMethod != null) {
// as producer and disposer bean is unrelated to this bean, we need to recreate it on demand
try (final InitializationContext<D> context = createContext()) {
final D declaringInstance = disposerMethod.isStatic() ? null : getDeclaringInstance(context);
injectionContextFactory.forDisposerMethod(disposerMethod, disposerInjectionPoints, declaringInstance, instance)
.invoke(context);
}
}
}
}
@@ -0,0 +1,42 @@
/*
* 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.apache.logging.log4j.plugins.defaults.bean;

import org.apache.logging.log4j.plugins.spi.bean.Bean;
import org.apache.logging.log4j.plugins.spi.bean.ProducerFactory;
import org.apache.logging.log4j.plugins.spi.model.InjectionPoint;
import org.apache.logging.log4j.plugins.spi.model.MetaMember;
import org.apache.logging.log4j.plugins.spi.model.MetaMethod;

import java.util.Collection;
import java.util.Objects;

abstract class AbstractProducerFactory<D> implements ProducerFactory<D> {
final Bean<D> declaringBean;
final MetaMember<D, ?> producerMember;
final MetaMethod<D, ?> disposerMethod;
final Collection<InjectionPoint<?>> disposerInjectionPoints;

AbstractProducerFactory(final Bean<D> declaringBean, final MetaMember<D, ?> producerMember,
final MetaMethod<D, ?> disposerMethod, final Collection<InjectionPoint<?>> disposerInjectionPoints) {
this.declaringBean = declaringBean;
this.producerMember = Objects.requireNonNull(producerMember);
this.disposerMethod = disposerMethod;
this.disposerInjectionPoints = Objects.requireNonNull(disposerInjectionPoints);
}
}
@@ -0,0 +1,41 @@
/*
* 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.apache.logging.log4j.plugins.defaults.bean;

import org.apache.logging.log4j.plugins.spi.bean.BeanManager;
import org.apache.logging.log4j.plugins.spi.model.InjectionPoint;
import org.apache.logging.log4j.plugins.spi.model.MetaConstructor;
import org.apache.logging.log4j.plugins.spi.scope.InitializationContext;

import java.util.Collection;

class ConstructorInjectionContext<T> extends ExecutableInjectionContext<T> {
private final MetaConstructor<T> constructor;

ConstructorInjectionContext(final BeanManager beanManager,
final Collection<InjectionPoint<?>> injectionPoints,
final MetaConstructor<T> constructor) {
super(beanManager, injectionPoints, constructor.getParameters());
this.constructor = constructor;
}

@Override
public T invoke(final InitializationContext<?> context) {
return constructor.construct(createArguments(context));
}
}

0 comments on commit 379234d

Please sign in to comment.