Skip to content

Commit

Permalink
Logging - revise LogMessageCallback
Browse files Browse the repository at this point in the history
- introduce MessageCallback to separate logic for message methods
(@message) and logger methods (@LogMessage)
- fix incorrect callback usage in ValidatorLogger
  • Loading branch information
mkouba authored and jharting committed Nov 14, 2014
1 parent 6abd47c commit a0d0e30
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 50 deletions.
Expand Up @@ -104,7 +104,7 @@ protected void validateObserverMethods(Iterable<ObserverInitializationContext<?,
protected void doWork(ObserverInitializationContext<?, ?> observerMethod) {
for (InjectionPoint ip : observerMethod.getObserver().getInjectionPoints()) {
validateInjectionPointForDefinitionErrors(ip, ip.getBean(), beanManager);
validateMetadataInjectionPoint(ip, null, ValidatorLogger.INJECTION_INTO_NON_BEAN_CALLBACK);
validateMetadataInjectionPoint(ip, null, ValidatorLogger.INJECTION_INTO_NON_BEAN);
validateInjectionPointForDeploymentProblems(ip, ip.getBean(), beanManager);
}
}
Expand Down
19 changes: 9 additions & 10 deletions impl/src/main/java/org/jboss/weld/bootstrap/Validator.java
Expand Up @@ -97,7 +97,7 @@
import org.jboss.weld.literal.DefaultLiteral;
import org.jboss.weld.literal.InterceptedLiteral;
import org.jboss.weld.logging.BeanLogger;
import org.jboss.weld.logging.LogMessageCallback;
import org.jboss.weld.logging.MessageCallback;
import org.jboss.weld.logging.ValidatorLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.metadata.cache.MetaAnnotationStore;
Expand Down Expand Up @@ -188,7 +188,7 @@ protected void validateRIBean(CommonBean<?> bean, BeanManagerImpl beanManager, C
for (InjectionPoint ip : producer.getDisposalMethod().getInjectionPoints()) {
// pass the producer bean instead of the disposal method bean
validateInjectionPointForDefinitionErrors(ip, null, beanManager);
validateMetadataInjectionPoint(ip, null, ValidatorLogger.INJECTION_INTO_DISPOSER_METHOD_CALLBACK);
validateMetadataInjectionPoint(ip, null, ValidatorLogger.INJECTION_INTO_DISPOSER_METHOD);
validateEventMetadataInjectionPoint(ip);
validateInjectionPointForDeploymentProblems(ip, null, beanManager);
}
Expand Down Expand Up @@ -288,7 +288,7 @@ private void validateDecorators(BeanManagerImpl beanManager, DecorableBean<?> be
*/
public void validateInjectionPoint(InjectionPoint ij, BeanManagerImpl beanManager) {
validateInjectionPointForDefinitionErrors(ij, ij.getBean(), beanManager);
validateMetadataInjectionPoint(ij, ij.getBean(), ValidatorLogger.INJECTION_INTO_NON_DEPENDENT_BEAN_CALLBACK);
validateMetadataInjectionPoint(ij, ij.getBean(), ValidatorLogger.INJECTION_INTO_NON_BEAN);
validateEventMetadataInjectionPoint(ij);
validateInjectionPointForDeploymentProblems(ij, ij.getBean(), beanManager);
}
Expand All @@ -299,7 +299,6 @@ public void validateInjectionPoint(InjectionPoint ij, BeanManagerImpl beanManage
public void validateInjectionPointForDefinitionErrors(InjectionPoint ij, Bean<?> bean, BeanManagerImpl beanManager) {
if (ij.getAnnotated().getAnnotation(New.class) != null && ij.getQualifiers().size() > 1) {
throw ValidatorLogger.LOG.newWithQualifiers(ij);
// throw new DefinitionException(NEW_WITH_QUALIFIERS, ij);
}
if (ij.getType() instanceof TypeVariable<?>) {
throw ValidatorLogger.LOG.injectionPointWithTypeVariable(ij);
Expand Down Expand Up @@ -331,18 +330,18 @@ public void validateInjectionPointForDefinitionErrors(InjectionPoint ij, Bean<?>
}
}

public void validateMetadataInjectionPoint(InjectionPoint ij, Bean<?> bean, LogMessageCallback messageCallback) {
public void validateMetadataInjectionPoint(InjectionPoint ij, Bean<?> bean, MessageCallback<DefinitionException> messageCallback) {
// metadata injection points
if (ij.getType().equals(InjectionPoint.class) && bean == null) {
throw new DefinitionException(messageCallback.invoke(ij));
throw messageCallback.construct(ij);
}
if (ij.getType().equals(InjectionPoint.class) && !Dependent.class.equals(bean.getScope())) {
throw new DefinitionException(ValidatorLogger.LOG.injectionIntoNonDependentBean(ij));
throw ValidatorLogger.LOG.injectionIntoNonDependentBean(ij);
}
Class<?> rawType = Reflections.getRawType(ij.getType());
if (Bean.class.equals(rawType) || Interceptor.class.equals(rawType) || Decorator.class.equals(rawType)) {
if (bean == null) {
throw new DefinitionException(messageCallback.invoke(ij));
throw messageCallback.construct(ij);
}
if (bean instanceof AbstractClassBean<?>) {
checkBeanMetadataInjectionPoint(bean, ij, AnnotatedTypes.getDeclaringAnnotatedType(ij.getAnnotated()).getBaseType());
Expand Down Expand Up @@ -762,7 +761,7 @@ protected void validateObserverMethods(Iterable<ObserverInitializationContext<?,
for (ObserverInitializationContext<?, ?> omi : observers) {
for (InjectionPoint ip : omi.getObserver().getInjectionPoints()) {
validateInjectionPointForDefinitionErrors(ip, ip.getBean(), beanManager);
validateMetadataInjectionPoint(ip, null, ValidatorLogger.INJECTION_INTO_NON_DEPENDENT_BEAN_CALLBACK);
validateMetadataInjectionPoint(ip, null, ValidatorLogger.INJECTION_INTO_NON_BEAN);
validateInjectionPointForDeploymentProblems(ip, ip.getBean(), beanManager);
}
}
Expand Down Expand Up @@ -798,7 +797,7 @@ public static void checkBeanMetadataInjectionPoint(Object bean, InjectionPoint i
Type typeArgument = parameterizedType.getActualTypeArguments()[0];

if (bean == null) {
throw new DefinitionException(ValidatorLogger.LOG.injectionIntoNonBean(ip));
throw ValidatorLogger.LOG.injectionIntoNonBean(ip);
}
/*
* If an Interceptor instance is injected into a bean instance other than an interceptor instance, the container
Expand Down
Expand Up @@ -34,7 +34,7 @@
import org.jboss.weld.bootstrap.spi.Metadata;
import org.jboss.weld.exceptions.DeploymentException;
import org.jboss.weld.logging.BootstrapLogger;
import org.jboss.weld.logging.LogMessageCallback;
import org.jboss.weld.logging.MessageCallback;
import org.jboss.weld.logging.ValidatorLogger;
import org.jboss.weld.resources.spi.ResourceLoader;
import org.jboss.weld.resources.spi.ResourceLoadingException;
Expand Down Expand Up @@ -224,14 +224,16 @@ public ModuleEnablement createModuleEnablement(BeanDeployment deployment) {
moduleDecoratorsBuilder.addAll(getDecoratorList());

if (beansXml != null) {
List<Class<?>> localInterceptors = transform(checkForDuplicates(beansXml.getEnabledInterceptors(), ValidatorLogger.INTERCEPTOR_SPECIFIED_TWICE_CALLBACK), loader);

List<Class<?>> localInterceptors = transform(checkForDuplicates(beansXml.getEnabledInterceptors(), ValidatorLogger.INTERCEPTOR_SPECIFIED_TWICE), loader);
moduleInterceptorsBuilder.addAll(localInterceptors);

List<Class<?>> localDecorators = transform(checkForDuplicates(beansXml.getEnabledDecorators(), ValidatorLogger.DECORATOR_SPECIFIED_TWICE_CALLBACK), loader);
List<Class<?>> localDecorators = transform(checkForDuplicates(beansXml.getEnabledDecorators(), ValidatorLogger.DECORATOR_SPECIFIED_TWICE), loader);
moduleDecoratorsBuilder.addAll(localDecorators);

alternativeClasses = ImmutableSet.copyOf(transform(checkForDuplicates(beansXml.getEnabledAlternativeClasses(), ValidatorLogger.ALTERNATIVE_CLASS_SPECIFIED_MULTIPLE_TIMES_CALLBACK), loader));
alternativeStereotypes = cast(ImmutableSet.copyOf(transform(checkForDuplicates(beansXml.getEnabledAlternativeStereotypes(), ValidatorLogger.ALTERNATIVE_STEREOTYPE_SPECIFIED_MULTIPLE_TIMES_CALLBACK), loader)));
alternativeClasses = ImmutableSet.copyOf(transform(checkForDuplicates(beansXml.getEnabledAlternativeClasses(), ValidatorLogger.ALTERNATIVE_CLASS_SPECIFIED_MULTIPLE_TIMES), loader));
alternativeStereotypes = cast(ImmutableSet.copyOf(transform(checkForDuplicates(beansXml.getEnabledAlternativeStereotypes(), ValidatorLogger.ALTERNATIVE_STEREOTYPE_SPECIFIED_MULTIPLE_TIMES), loader)));

} else {
alternativeClasses = Collections.emptySet();
alternativeStereotypes = Collections.emptySet();
Expand All @@ -242,12 +244,12 @@ public ModuleEnablement createModuleEnablement(BeanDeployment deployment) {
return new ModuleEnablement(moduleInterceptorsBuilder.build(), moduleDecoratorsBuilder.build(), globalAlternatives, alternativeClasses, alternativeStereotypes);
}

private static <T> List<Metadata<T>> checkForDuplicates(List<Metadata<T>> list, LogMessageCallback messageCallback) {
private static <T> List<Metadata<T>> checkForDuplicates(List<Metadata<T>> list, MessageCallback<DeploymentException> messageCallback) {
Map<T, Metadata<T>> map = new HashMap<T, Metadata<T>>();
for (Metadata<T> item : list) {
Metadata<T> previousOccurrence = map.put(item.getValue(), item);
if (previousOccurrence != null) {
throw new DeploymentException(messageCallback.invoke(item.getValue(), item, previousOccurrence));
throw messageCallback.construct(item.getValue(), item, previousOccurrence);
}
}
return list;
Expand Down
16 changes: 12 additions & 4 deletions impl/src/main/java/org/jboss/weld/logging/LogMessageCallback.java
Expand Up @@ -16,17 +16,25 @@
*/
package org.jboss.weld.logging;

import org.jboss.logging.annotations.LogMessage;
import org.jboss.logging.annotations.Message;

/**
* Since Weld migrated to jboss-logging it's no longer possible to reference message enum keys and construct localized log messages lazily - use this
* callback as a workaround.
* JBoss Logging is not using message keys and so it's not possible to reference the log message (a logger method annotated with {@link LogMessage} and
* {@link Message}) and use it as a method parameter or construct it lazily. This callback should be used to work around this limitation.
*
* Note that the method parameters are not checked and so the invocation may result in {@link ArrayIndexOutOfBoundsException}.
*
* @author Martin Kouba
* @see LogMessage
*/
public interface LogMessageCallback {

/**
* @return the localized log message
* Invokes the logger method.
*
* @param params
*/
String invoke(Object... params);
void log(Object... params);

}
41 changes: 41 additions & 0 deletions impl/src/main/java/org/jboss/weld/logging/MessageCallback.java
@@ -0,0 +1,41 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2014, Red Hat, Inc., and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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.jboss.weld.logging;

import org.jboss.logging.annotations.Message;

/**
* JBoss Logging is not using message keys and so it's not possible to reference the message (a message method annotated with {@link Message}) and use it as a
* method parameter or construct it lazily. This callback should be used to work around this limitation.
*
* Note that the method parameters are not checked and so the invocation may result in {@link ArrayIndexOutOfBoundsException}.
*
* @author Martin Kouba
* @param <T> The type of the return value (either {@link String} or {@link Throwable})
* @see Message
*/
public interface MessageCallback<T> {

/**
* Constructs the message or Throwable.
*
* @param params
* @return the return value
*/
T construct(Object... params);

}
49 changes: 21 additions & 28 deletions impl/src/main/java/org/jboss/weld/logging/ValidatorLogger.java
Expand Up @@ -42,51 +42,44 @@ public interface ValidatorLogger extends WeldLogger {

ValidatorLogger LOG = Logger.getMessageLogger(ValidatorLogger.class, Category.VALIDATOR.getName());

LogMessageCallback INJECTION_INTO_NON_DEPENDENT_BEAN_CALLBACK = new LogMessageCallback() {
MessageCallback<DefinitionException> INJECTION_INTO_DISPOSER_METHOD = new MessageCallback<DefinitionException>() {
@Override
public String invoke(Object... params) {
return ValidatorLogger.LOG.injectionIntoNonDependentBean(params[0]);
}
};

LogMessageCallback INJECTION_INTO_DISPOSER_METHOD_CALLBACK = new LogMessageCallback() {
@Override
public String invoke(Object... params) {
public DefinitionException construct(Object... params) {
return ValidatorLogger.LOG.injectionIntoDisposerMethod(params[0]);
}
};

LogMessageCallback INJECTION_INTO_NON_BEAN_CALLBACK = new LogMessageCallback() {
MessageCallback<DefinitionException> INJECTION_INTO_NON_BEAN = new MessageCallback<DefinitionException>() {
@Override
public String invoke(Object... params) {
public DefinitionException construct(Object... params) {
return ValidatorLogger.LOG.injectionIntoNonBean(params[0]);
}
};

LogMessageCallback INTERCEPTOR_SPECIFIED_TWICE_CALLBACK = new LogMessageCallback() {
MessageCallback<DeploymentException> INTERCEPTOR_SPECIFIED_TWICE = new MessageCallback<DeploymentException>() {
@Override
public String invoke(Object... params) {
public DeploymentException construct(Object... params) {
return ValidatorLogger.LOG.interceptorSpecifiedTwice(params[0], params[1], params[2]);
}
};

LogMessageCallback DECORATOR_SPECIFIED_TWICE_CALLBACK = new LogMessageCallback() {
MessageCallback<DeploymentException> DECORATOR_SPECIFIED_TWICE = new MessageCallback<DeploymentException>() {
@Override
public String invoke(Object... params) {
public DeploymentException construct(Object... params) {
return ValidatorLogger.LOG.decoratorSpecifiedTwice(params[0], params[1], params[2]);
}
};

LogMessageCallback ALTERNATIVE_CLASS_SPECIFIED_MULTIPLE_TIMES_CALLBACK = new LogMessageCallback() {
MessageCallback<DeploymentException> ALTERNATIVE_CLASS_SPECIFIED_MULTIPLE_TIMES = new MessageCallback<DeploymentException>() {
@Override
public String invoke(Object... params) {
return ValidatorLogger.LOG.alternativeClassSpecifiedMultipleTimes(params[0]);
public DeploymentException construct(Object... params) {
return ValidatorLogger.LOG.alternativeClassSpecifiedMultipleTimes(params[0], params[1], params[2]);
}
};

LogMessageCallback ALTERNATIVE_STEREOTYPE_SPECIFIED_MULTIPLE_TIMES_CALLBACK = new LogMessageCallback() {
MessageCallback<DeploymentException> ALTERNATIVE_STEREOTYPE_SPECIFIED_MULTIPLE_TIMES = new MessageCallback<DeploymentException>() {
@Override
public String invoke(Object... params) {
public DeploymentException construct(Object... params) {
return ValidatorLogger.LOG.alternativeStereotypeSpecifiedMultipleTimes(params[0], params[1], params[2]);
}
};
Expand All @@ -104,10 +97,10 @@ public String invoke(Object... params) {
DefinitionException newWithQualifiers(Object param1);

@Message(id = 1405, value = "Cannot inject {0} in a class which isn't a bean", format = Format.MESSAGE_FORMAT)
String injectionIntoNonBean(Object param1);
DefinitionException injectionIntoNonBean(Object param1);

@Message(id = 1406, value = "Cannot inject {0} in a non @Dependent scoped bean", format = Format.MESSAGE_FORMAT)
String injectionIntoNonDependentBean(Object param1);
DefinitionException injectionIntoNonDependentBean(Object param1);

@Message(id = 1407, value = "Cannot declare an injection point with a type variable: {0}", format = Format.MESSAGE_FORMAT)
DefinitionException injectionPointWithTypeVariable(Object param1);
Expand Down Expand Up @@ -145,13 +138,13 @@ public String invoke(Object... params) {
DeploymentException beanNameIsPrefix(Object param1);

@Message(id = 1416, value = "Enabled interceptor class {0} specified twice:\n - {1},\n - {2}", format = Format.MESSAGE_FORMAT)
String interceptorSpecifiedTwice(Object param1, Object param2, Object param3);
DeploymentException interceptorSpecifiedTwice(Object param1, Object param2, Object param3);

@Message(id = 1417, value = "Enabled interceptor class {0} does not match an interceptor bean: the class is not found, or not annotated with @Interceptor and still not registered through a portable extension, or not annotated with @Dependent inside an implicit bean archive", format = Format.MESSAGE_FORMAT)
DeploymentException interceptorClassDoesNotMatchInterceptorBean(Object param1);

@Message(id = 1418, value = "Enabled decorator class {0} specified twice:\n - {1},\n - {2}", format = Format.MESSAGE_FORMAT)
String decoratorSpecifiedTwice(Object param1, Object param2, Object param3);
DeploymentException decoratorSpecifiedTwice(Object param1, Object param2, Object param3);

@Message(id = 1419, value = "Enabled decorator class {0} is not the bean class of at least one decorator bean (detected decorator beans: {1})", format = Format.MESSAGE_FORMAT)
DeploymentException decoratorClassNotBeanClassOfDecorator(Object param1, Object param2);
Expand All @@ -160,7 +153,7 @@ public String invoke(Object... params) {
DeploymentException alternativeStereotypeNotStereotype(Object param1);

@Message(id = 1421, value = "Cannot enable the same alternative stereotype {0} in beans.xml:\n - {1},\n - {2}", format = Format.MESSAGE_FORMAT)
String alternativeStereotypeSpecifiedMultipleTimes(Object param1, Object param2, Object param3);
DeploymentException alternativeStereotypeSpecifiedMultipleTimes(Object param1, Object param2, Object param3);

@Message(id = 1422, value = "Enabled alternative {0} is not an alternative", format = Format.MESSAGE_FORMAT)
DeploymentException alternativeBeanClassNotAnnotated(Object param1);
Expand Down Expand Up @@ -280,8 +273,8 @@ public String invoke(Object... params) {
@Message(id = 1456, value = "Argument {0} must not be null", format = Format.MESSAGE_FORMAT)
IllegalArgumentException argumentNull(Object param1);

@Message(id = 1457, value = "Cannot enable the same alternative class {0} in beans.xml", format = Format.MESSAGE_FORMAT)
String alternativeClassSpecifiedMultipleTimes(Object param1);
@Message(id = 1457, value = "Cannot enable the same alternative class {0} in beans.xml:\n - {1},\n - {2}", format = Format.MESSAGE_FORMAT)
DeploymentException alternativeClassSpecifiedMultipleTimes(Object param1, Object param2, Object param3);

/**
* @deprecated Not in use
Expand Down Expand Up @@ -325,7 +318,7 @@ public String invoke(Object... params) {
UnserializableDependencyException builtinBeanWithNonserializableDecorator(Object param1, Object param2);

@Message(id = 1466, value = "Cannot inject {0} in a disposer method", format = Format.MESSAGE_FORMAT)
String injectionIntoDisposerMethod(Object param1);
DefinitionException injectionIntoDisposerMethod(Object param1);

@Message(id = 1467, value = "Method {0} defined on class {1} is not defined according to the specification. It is annotated with @{2} but it does not return {3} or {4}.", format = Format.MESSAGE_FORMAT)
DefinitionException interceptorMethodDoesNotReturnObjectOrVoid(Object param1, Object param2, Object param3, Object param4, Object param5);
Expand Down

0 comments on commit a0d0e30

Please sign in to comment.