[jboss-svn-commits] JBoss Common SVN: r4684 - jboss-logging/trunk/src/main/java/org/jboss/logging.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Jul 6 22:25:43 EDT 2010
Author: david.lloyd at jboss.com
Date: 2010-07-06 22:25:42 -0400 (Tue, 06 Jul 2010)
New Revision: 4684
Added:
jboss-logging/trunk/src/main/java/org/jboss/logging/Cause.java
jboss-logging/trunk/src/main/java/org/jboss/logging/MessageBundleInvocationHandler.java
jboss-logging/trunk/src/main/java/org/jboss/logging/MessageLoggerInvocationHandler.java
Modified:
jboss-logging/trunk/src/main/java/org/jboss/logging/Logger.java
jboss-logging/trunk/src/main/java/org/jboss/logging/Message.java
Log:
First pass at runtime proxy generation
Added: jboss-logging/trunk/src/main/java/org/jboss/logging/Cause.java
===================================================================
--- jboss-logging/trunk/src/main/java/org/jboss/logging/Cause.java (rev 0)
+++ jboss-logging/trunk/src/main/java/org/jboss/logging/Cause.java 2010-07-07 02:25:42 UTC (rev 4684)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.logging;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Mark a parameter as being the "exception cause" parameter rather than a positional format parameter.
+ *
+ * @author <a href="mailto:david.lloyd at redhat.com">David M. Lloyd</a>
+ */
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target(ElementType.PARAMETER)
+public @interface Cause {
+}
Modified: jboss-logging/trunk/src/main/java/org/jboss/logging/Logger.java
===================================================================
--- jboss-logging/trunk/src/main/java/org/jboss/logging/Logger.java 2010-07-06 22:40:38 UTC (rev 4683)
+++ jboss-logging/trunk/src/main/java/org/jboss/logging/Logger.java 2010-07-07 02:25:42 UTC (rev 4684)
@@ -24,6 +24,9 @@
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Locale;
/**
@@ -35,6 +38,16 @@
private static final String FQCN = Logger.class.getName();
+ private static final boolean GENERATE_PROXIES;
+
+ static {
+ GENERATE_PROXIES = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+ public Boolean run() {
+ return Boolean.valueOf(System.getProperty("jboss.i18n.generate-proxies"));
+ }
+ }).booleanValue();
+ }
+
/**
* Levels used by this logging API.
*/
@@ -2305,6 +2318,9 @@
if (loggerClass == null) try {
loggerClass = Class.forName(join(type.getName(), "$logger", null, null, null), true, type.getClassLoader()).asSubclass(type);
} catch (ClassNotFoundException e) {
+ if (GENERATE_PROXIES) {
+ return type.cast(Proxy.newProxyInstance(type.getClassLoader(), new Class<?>[] { type }, new MessageLoggerInvocationHandler(type, category)));
+ }
throw new IllegalArgumentException("Invalid logger " + type + " (implementation not found)");
}
final Constructor<? extends T> constructor;
Modified: jboss-logging/trunk/src/main/java/org/jboss/logging/Message.java
===================================================================
--- jboss-logging/trunk/src/main/java/org/jboss/logging/Message.java 2010-07-06 22:40:38 UTC (rev 4683)
+++ jboss-logging/trunk/src/main/java/org/jboss/logging/Message.java 2010-07-07 02:25:42 UTC (rev 4684)
@@ -68,14 +68,6 @@
Format format() default Format.PRINTF;
/**
- * The converter to use. Any specified converter must implement the {@code ParameterConverter} interface
- * from JBoss Logging or JBoss I18n.
- *
- * @return the converter
- */
- Class<?> converter() default Object.class;
-
- /**
* The possible format types.
*/
enum Format {
Added: jboss-logging/trunk/src/main/java/org/jboss/logging/MessageBundleInvocationHandler.java
===================================================================
--- jboss-logging/trunk/src/main/java/org/jboss/logging/MessageBundleInvocationHandler.java (rev 0)
+++ jboss-logging/trunk/src/main/java/org/jboss/logging/MessageBundleInvocationHandler.java 2010-07-07 02:25:42 UTC (rev 4684)
@@ -0,0 +1,128 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.logging;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:david.lloyd at redhat.com">David M. Lloyd</a>
+ */
+class MessageBundleInvocationHandler implements InvocationHandler {
+
+ private final String projectCode;
+
+ protected MessageBundleInvocationHandler(final String projectCode) {
+ this.projectCode = projectCode;
+ }
+
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+ final Message message = method.getAnnotation(Message.class);
+ if (message == null) {
+ // nothing to do...
+ return null;
+ }
+ final Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+ ArrayList<Object> newArgs = new ArrayList<Object>();
+ Throwable cause = extractCause(parameterAnnotations, args, newArgs);
+ String result;
+ switch (message.format()) {
+ case PRINTF: {
+ result = String.format(getFormatString(message), newArgs.toArray());
+ break;
+ }
+ case MESSAGE_FORMAT: {
+ result = MessageFormat.format(getFormatString(message), newArgs.toArray());
+ break;
+ }
+ default: throw new IllegalStateException();
+ }
+ final Class<?> returnType = method.getReturnType();
+ if (Throwable.class.isAssignableFrom(returnType)) {
+ // the return type is an exception
+ if (cause != null) {
+ final Constructor<?> constructor = returnType.getConstructor(String.class, Throwable.class);
+ return constructor.newInstance(result, cause);
+ } else {
+ final Constructor<?> constructor = returnType.getConstructor(String.class);
+ return constructor.newInstance(result);
+ }
+ } else {
+ return result;
+ }
+ }
+
+ protected String getFormatString(final Message message) {
+ String formatString = message.value();
+ if (formatString == null) {
+ return null;
+ }
+ final int id = message.id();
+ if (id > 0) {
+ final String projectCode = this.projectCode;
+ if (projectCode != null) {
+ final StringBuilder b = new StringBuilder(32);
+ b.append(projectCode).append('-');
+ if (id < 10) {
+ b.append("0000");
+ } else if (id < 100) {
+ b.append("000");
+ } else if (id < 1000) {
+ b.append("00");
+ } else if (id < 10000) {
+ b.append("0");
+ }
+ b.append(id);
+ b.append(": ");
+ b.append(formatString);
+ formatString = b.toString();
+ }
+ }
+ return formatString;
+ }
+
+ protected static Throwable extractCause(final Annotation[][] parameterAnnotations, final Object[] args, final List<Object> newArgs) {
+ Throwable cause = null;
+ for (int i = 0; i < parameterAnnotations.length; i++) {
+ Annotation[] annotations = parameterAnnotations[i];
+ boolean found = false;
+ for (Annotation annotation : annotations) {
+ if (annotation instanceof Cause) {
+ if (cause == null) {
+ cause = (Throwable) args[i];
+ }
+ found = true;
+ }
+ }
+ if (! found) {
+ newArgs.add(args[i]);
+ }
+ }
+ return cause;
+ }
+}
Added: jboss-logging/trunk/src/main/java/org/jboss/logging/MessageLoggerInvocationHandler.java
===================================================================
--- jboss-logging/trunk/src/main/java/org/jboss/logging/MessageLoggerInvocationHandler.java (rev 0)
+++ jboss-logging/trunk/src/main/java/org/jboss/logging/MessageLoggerInvocationHandler.java 2010-07-07 02:25:42 UTC (rev 4684)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.logging;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+/**
+ * @author <a href="mailto:david.lloyd at redhat.com">David M. Lloyd</a>
+ */
+class MessageLoggerInvocationHandler extends MessageBundleInvocationHandler {
+
+ private final Logger logger;
+
+ MessageLoggerInvocationHandler(final Class<?> type, final String category) {
+ this(type.getAnnotation(MessageLogger.class), category);
+ }
+
+ private MessageLoggerInvocationHandler(final MessageLogger messageLogger, final String category) {
+ super(messageLogger.projectCode());
+ logger = Logger.getLogger(category);
+ }
+
+ public Object invoke(final Object proxy, final Method method, Object[] args) throws Throwable {
+ final Message message = method.getAnnotation(Message.class);
+ if (message == null) {
+ // nothing to do...
+ return null;
+ }
+ final Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+ final LogMessage logMessage = method.getAnnotation(LogMessage.class);
+ if (logMessage != null) {
+
+ try {
+ // See if it's a basic logger method
+ if (method.getDeclaringClass().equals(BasicLogger.class)) {
+ // doesn't cover overrides though!
+ return method.invoke(logger, args);
+ }
+
+ // it's a log message
+ final Logger.Level level = logMessage.level();
+ if (logger.isEnabled(level)) {
+ String formatString = getFormatString(message);
+ if (formatString == null) {
+ return null;
+ }
+ ArrayList<Object> newArgs = new ArrayList<Object>();
+ Throwable cause = extractCause(parameterAnnotations, args, newArgs);
+ final Message.Format format = message.format();
+ switch (format) {
+ case PRINTF: {
+ logger.logf(level, cause, formatString, newArgs.toArray());
+ return null;
+ }
+ case MESSAGE_FORMAT: {
+ logger.logv(level, cause, formatString, newArgs.toArray());
+ return null;
+ }
+ default: {
+ return null;
+ }
+ }
+ }
+ } catch (Throwable ignored) {
+ }
+ } else {
+ return super.invoke(proxy, method, args);
+ }
+ return null;
+ }
+}
More information about the jboss-svn-commits
mailing list