pax_global_header00006660000000000000000000000064125517600100014507gustar00rootroot0000000000000052 comment=2220c252663bbb8e6b1994c2881847881ceabbc4 jboss-logging-tools-2.0.1.Final/000077500000000000000000000000001255176001000164415ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/.gitignore000066400000000000000000000003761255176001000204370ustar00rootroot00000000000000#Ignore Maven target folder target/ #Ignore Eclipse files .settings/ .classpath .project #Ignore Intellij files *.iml *.iws *.ipr .idea/ #Ignore Mac files .DS_Store /core/target/ /base/target/ nb-configuration.xml /processor/target/ /generator/target/jboss-logging-tools-2.0.1.Final/annotations/000077500000000000000000000000001255176001000207765ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/pom.xml000066400000000000000000000034671255176001000223250ustar00rootroot00000000000000 4.0.0 org.jboss.logging jboss-logging-tools-parent 2.0.1.Final ../pom.xml jboss-logging-annotations jar JBoss Logging I18n Annotations Apache License, version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo org.jboss.logging jboss-logging provided jboss-logging-tools-2.0.1.Final/annotations/src/000077500000000000000000000000001255176001000215655ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/000077500000000000000000000000001255176001000225115ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/000077500000000000000000000000001255176001000234325ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/000077500000000000000000000000001255176001000242215ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/000077500000000000000000000000001255176001000253415ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/000077500000000000000000000000001255176001000267675ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/000077500000000000000000000000001255176001000313245ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/Cause.java000066400000000000000000000023361255176001000332330ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Mark a parameter as being the "exception cause" parameter rather than a positional format parameter. * * @author David M. Lloyd */ @Retention(CLASS) @Target(PARAMETER) @Documented public @interface Cause { } ConstructType.java000066400000000000000000000031251255176001000347370ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Indicates the value of this annotation should be constructed and returned. This does not change the return type of * the method. *

* This annotation is only allowed on bundle messages that have a throwable return type. The value must be assignable * to the return type. *

* * @author James R. Perkins * @since 2.0.0 */ @Retention(CLASS) @Target(METHOD) @Documented public @interface ConstructType { /** * The actual type that should be constructed for the return type. * * @return the class to construct */ Class value(); } jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/Field.java000066400000000000000000000026221255176001000332140ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Indicate that a method parameter value should be applied to a field on the resultant exception object. * * @author David M. Lloyd */ @Retention(CLASS) @Target(PARAMETER) @Documented public @interface Field { /** * The field name. If not specified, the parameter name is assumed to be the field name. * * @return the field name */ String name() default ""; } FormatWith.java000066400000000000000000000034171255176001000342010ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Indicate that the given parameter should be wrapped with a formatting object of the given class. The class * must have a one-argument constructor which unambiguously accepts a value of this parameter's type. The resultant * object will be passed in as a parameter to the underlying format type; thus its {@link Object#toString() toString()} * method will be invoked (or, if the format style is {@link Message.Format#PRINTF PRINTF}, the object may implement * {@link java.util.Formattable Formattable} to get extra functionality). * * @author David M. Lloyd */ @Target(PARAMETER) @Retention(CLASS) @Documented public @interface FormatWith { /** * The class of the formatting object to use. * * @return the class */ Class value(); } LogMessage.java000066400000000000000000000032511255176001000341370ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import org.jboss.logging.Logger; /** * A typed logger method. Indicates that this method will log the associated {@link Message} to the logger system, as * opposed to being a simple message lookup. * * @author David M. Lloyd */ @Retention(CLASS) @Target(METHOD) @Documented public @interface LogMessage { /** * The log level at which this message should be logged. Defaults to {@code INFO}. * * @return the log level */ Logger.Level level() default Logger.Level.INFO; /** * The logging class name to use for this message, if any. * * @return the logging class name */ Class loggingClass() default Void.class; } LoggingClass.java000066400000000000000000000023711255176001000344670ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Mark a parameter as specifying the name of the logging class to use. The parameter * may have a type of {@link Class}. * * @author David M. Lloyd */ @Retention(CLASS) @Target(PARAMETER) @Documented public @interface LoggingClass { } jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/Message.java000066400000000000000000000045321255176001000335570ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Assigns a message string to a resource method. The method arguments are used to supply the positional parameter * values for the method. * * @author David M. Lloyd */ @Target(METHOD) @Retention(CLASS) @Documented public @interface Message { /** * Indicates that this message has no ID. */ int NONE = 0; /** * Indicates that this message should inherit the ID from another message with the same name. */ int INHERIT = -1; /** * The message ID number. Only one message with a given name may specify an ID other than {@link #INHERIT}. * * @return the message ID number */ int id() default INHERIT; /** * The default format string of this message. * * @return the format string */ String value(); /** * The format type of this method (defaults to {@link Format#PRINTF}). * * @return the format type */ Format format() default Format.PRINTF; /** * The possible format types. */ enum Format { /** * A {@link java.util.Formatter}-type format string. */ PRINTF, /** * A {@link java.text.MessageFormat}-type format string. */ MESSAGE_FORMAT, /** * Indicates the message should not be formatted. */ NO_FORMAT, } } MessageBundle.java000066400000000000000000000035661255176001000346400ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Signify that an interface is a message bundle interface. * * @author David M. Lloyd */ @Target(TYPE) @Retention(CLASS) @Documented public @interface MessageBundle { /** * Get the project code for messages that have an associated code. If no project code is associated * with this bundle, specify {@code ""} (the empty string). * * @return the project code */ String projectCode(); /** * The length of the padding used for each id in the message bundle. For example given the default padding length * of 6 and a message with an id of 100 would result would be {@code "000100"}. *

* Valid values a range of 3 to 8. Any value less than 0 turns off padding. Any other value will result in an error * being produced. * * @return the length the id should be padded */ int length() default 6; } MessageLogger.java000066400000000000000000000041441255176001000346370ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Signify that an interface is a typed logger interface. A message logger interface may optionally extend other * message logger interfaces and message bundle interfaces (see {@link org.jboss.logging.annotations.MessageBundle}, as * well as the {@link org.jboss.logging.BasicLogger} interface. * * @author David M. Lloyd */ @Retention(CLASS) @Target(TYPE) @Documented public @interface MessageLogger { /** * Get the project code for messages that have an associated code. If no project code is associated * with this logger, specify {@code ""} (the empty string). * * @return the project code */ String projectCode(); /** * The length of the padding used for each id in the message bundle. For example given the default padding length * of 6 and a message with an id of 100 would result would be {@code "000100"}. *

* Valid values a range of 3 to 8. Any value less than 0 turns off padding. Any other value will result in an error * being produced. * * @return the length the id should be padded */ int length() default 6; } jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/Once.java000066400000000000000000000026741255176001000330640ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Indicates a message should only be logged once. *

* Methods that use this annotation must be {@linkplain org.jboss.logging.annotations.LogMessage logger methods}. Overloaded * methods also annotated with {@code @Once} will inherit the same check only logging the message from the first * overloaded method invoked. *

* * @author James R. Perkins */ @Target(METHOD) @Retention(CLASS) @Documented public @interface Once { } jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/Param.java000066400000000000000000000034541255176001000332350ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Identifies a parameter is to be used for constructing an exception and excluded from the formatting of the message. *

* Parameters will be order-matched first, then type-matched to resolve ambiguity. If a match fails an error should * occur. *

* The {@link #value()} option will allow an optional class to be specified which will have to match the exact type of * the parameter in question, to enable unambiguous resolution. The value must be the fully qualified class name. * * @author James R. Perkins */ @Target(PARAMETER) @Retention(CLASS) @Documented public @interface Param { /** * Defines an exact class the parameter must match for unambiguous resolution. * * @return the class the parameter must match. */ Class value() default Object.class; } jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/Pos.java000066400000000000000000000027301255176001000327320ustar00rootroot00000000000000/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * @author James R. Perkins * @since 1.1.0 */ @Retention(CLASS) @Target(PARAMETER) @Documented public @interface Pos { /** * The positions the value should be used at. * * @return an array of the positions for the parameter */ int[] value(); /** * The transform types used on the parameter. * * @return an array of the transformer types * * @see Transform */ Transform[] transform() default {}; } Property.java000066400000000000000000000026711255176001000337420ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Indicate that a method parameter value should be applied to a property (with a setter method) on the resultant exception object. * * @author David M. Lloyd */ @Retention(CLASS) @Target(PARAMETER) @Documented public @interface Property { /** * The property name. If not specified, the parameter name is assumed to be the property name. * * @return the property name */ String name() default ""; } Transform.java000066400000000000000000000055741255176001000340760ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Indicate the given parameter should be transformed in each of the {@link org.jboss.logging.annotations.Transform.TransformType transform types} * provided. The parameter cannot be a primitive type. *

* For the {@link TransformType#SIZE} type, the object must be a {@link String}, a {@link java.util.Collection}, a * {@link java.util.Map} or an array. *

* The type {@link TransformType#GET_CLASS} can be used with {@link TransformType#HASH_CODE} or {@link * TransformType#IDENTITY_HASH_CODE}. The type {@link TransformType#SIZE} must be used on it's own. * * @author James R. Perkins * @since 1.1.0 */ @Retention(CLASS) @Target(PARAMETER) @Documented public @interface Transform { /** * The transform type */ public enum TransformType { /** * Gets the class of the object object passed, {@link Object#getClass()}. */ GET_CLASS, /** * Gets the hash code of the object, {@link Object#hashCode()}. */ HASH_CODE, /** * Gets the identity hash code of the object, {@link System#identityHashCode(Object)}. */ IDENTITY_HASH_CODE, /** * Gets the size or length of a {@link String}, {@link java.util.Collection}, {@link java.util.Map} or array. */ SIZE, } /** * The transform types used on the parameter. *

* Valid combinations: *

* * @return an array of the transform types */ TransformType[] value(); } ValidIdRange.java000066400000000000000000000045651255176001000344130ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * Sets a range of valid id's allowed on the {@link org.jboss.logging.annotations.Message#id() message id}. Both {@link * Message#INHERIT} and {@link Message#NONE} are ignored when validating. *

* Note: Message id's from inherited interfaces are not validated within the range provided. Super interfaces * would need their own annotation for range validation. *

* *

 *          @MessageLogger(projectCode = "EXAMPLE")
 *          @ValidIdRange(min = 100, max = 200)
 *          public interface ExampleLogger {
 *
 *              @LogMessage
 *              @Message(id = 100, value = "Example message")
 *              void example();
 *          }
 * 
* * * @author James R. Perkins */ @Target(TYPE) @Retention(CLASS) @Documented public @interface ValidIdRange { /** * The minimum id allowed in the {@link org.jboss.logging.annotations.Message#id() message id}. Both {@link * Message#INHERIT} and {@link Message#NONE} are ignored when validating. * * @return the minimum id allowed */ int min() default 1; /** * The maximum id allowed in the {@link org.jboss.logging.annotations.Message#id() message id}. Both {@link * Message#INHERIT} and {@link Message#NONE} are ignored when validating. * * @return the maximum id allowed */ int max() default 999999; } ValidIdRanges.java000066400000000000000000000023631255176001000345700ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/annotations/src/main/java/org/jboss/logging/annotations/* * JBoss, Home of Professional Open Source. * * Copyright 2015 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.logging.annotations; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; /** * @author James R. Perkins */ @Target(TYPE) @Retention(CLASS) @Documented public @interface ValidIdRanges { /** * An array of valid id ranges. * * @return an array of valid id ranges */ ValidIdRange[] value(); } jboss-logging-tools-2.0.1.Final/pom.xml000066400000000000000000000075751255176001000177740ustar00rootroot00000000000000 4.0.0 org.jboss jboss-parent 14 org.jboss.logging jboss-logging-tools-parent 2.0.1.Final pom JBoss Logging Tools Parent James R. Perkins jperkins@redhat.com Kevin Pollet kevin.pollet@serli.com UTF-8 2.0.0.Final 3.1.2.GA 1.3.2.Final 6.3.1 lgpl http://repository.jboss.org/licenses/lgpl-2.1.txt repo org.jboss.logging jboss-logging-annotations ${project.version} org.jboss.logging jboss-logging ${version.org.jboss.logging} org.jboss.jdeparser jdeparser ${version.org.jboss.jdeparser} org.jboss.logmanager jboss-logmanager ${version.org.jboss.logmanager} org.testng testng ${version.org.testng} annotations processor processor-tests jboss-logging-tools-2.0.1.Final/processor-tests/000077500000000000000000000000001255176001000216205ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor-tests/pom.xml000066400000000000000000000126601255176001000231420ustar00rootroot00000000000000 4.0.0 org.jboss.logging jboss-logging-tools-parent 2.0.1.Final ../pom.xml jboss-logging-processor-tests jar JBoss Logging Processor tests Tests the current plugin currently with a legacy version of JBoss Logging org.jboss.logging jboss-logging-annotations test org.jboss.logging jboss-logging-processor ${project.parent.version} test org.jboss.logging jboss-logging test org.jboss.logmanager jboss-logmanager test org.testng testng test ../processor/src/test/java ../processor/src/test/resources org.apache.maven.plugins maven-install-plugin true org.apache.maven.plugins maven-deploy-plugin true org.apache.maven.plugins maven-compiler-plugin **/LegacyLogger.java **/LegacyLoggerTest.java **/LegacyMessages.java **/LegacyMessagesTest.java **/GeneratedSourceAnalysisTest.java org.apache.maven.plugins maven-surefire-plugin org.jboss.logmanager.LogManager logging30 true 3.0.1.GA org.apache.maven.plugins maven-compiler-plugin -AloggingVersion=3.0 jboss-logging-tools-2.0.1.Final/processor/000077500000000000000000000000001255176001000204605ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/pom.xml000066400000000000000000000100231255176001000217710ustar00rootroot00000000000000 4.0.0 org.jboss.logging jboss-logging-tools-parent 2.0.1.Final ../pom.xml jboss-logging-processor jar JBoss Logging I18n Annotation Processor org.jboss.logging jboss-logging-annotations org.jboss.logging jboss-logging provided org.jboss.jdeparser jdeparser org.jboss.logmanager jboss-logmanager test org.testng testng test org.apache.maven.plugins maven-compiler-plugin default-compile compile compile -proc:none org.apache.maven.plugins maven-surefire-plugin org.jboss.logmanager.LogManager ${project.build.testSourceDirectory} ${project.build.directory}/generated-test-sources/test-annotations jboss-logging-tools-2.0.1.Final/processor/src/000077500000000000000000000000001255176001000212475ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/000077500000000000000000000000001255176001000221735ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/000077500000000000000000000000001255176001000231145ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/000077500000000000000000000000001255176001000237035ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/000077500000000000000000000000001255176001000250235ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/000077500000000000000000000000001255176001000264515ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/000077500000000000000000000000001255176001000304705ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/000077500000000000000000000000001255176001000312545ustar00rootroot00000000000000AbstractGenerator.java000066400000000000000000000077151255176001000354640ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.annotation.processing.Filer; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.SupportedOptions; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import org.jboss.logging.processor.model.MessageInterface; /** * An abstract processor used process annotations. * * @author James R. Perkins * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ public abstract class AbstractGenerator { private final ToolLogger logger; private final ProcessingEnvironment processingEnv; /** * Constructs a new processor. * * @param processingEnv the processing environment. */ AbstractGenerator(final ProcessingEnvironment processingEnv) { this.logger = ToolLogger.getLogger(processingEnv); this.processingEnv = processingEnv; } /** * Processes a type element. * * @param annotation the annotation who trigger the processing * @param element the element that contains the methods. * @param messageInterface the message interface to implement. */ public abstract void processTypeElement(final TypeElement annotation, final TypeElement element, final MessageInterface messageInterface); /** * Returns the logger to log messages with. * * @return the logger to log messages with. */ final ToolLogger logger() { return logger; } /** * Returns the filer. * * @return the filer */ final Filer filer() { return processingEnv.getFiler(); } /** * Returns the element utils. * * @return the utils */ final Elements elementUtils() { return processingEnv.getElementUtils(); } /** * Returns the type utils. * * @return the utils */ public final Types typeUtils() { return processingEnv.getTypeUtils(); } /** * Returns the processing environment. * * @return the processing environment being used. */ public final ProcessingEnvironment processingEnv() { return processingEnv; } /** * Returns the name of the processor. * * @return the name of the processor. */ public final String getName() { return this.getClass().getSimpleName(); } /** * Returns the supported options set. * * @return the supported options set or empty set if none */ public final Set getSupportedOptions() { SupportedOptions options = this.getClass().getAnnotation(SupportedOptions.class); if (options != null) { return new HashSet(Arrays.asList(options.value())); } return Collections.emptySet(); } } AbstractMessageObjectType.java000066400000000000000000000037761255176001000371160ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/aptpackage org.jboss.logging.processor.apt; import static org.jboss.logging.processor.util.ElementHelper.typeToString; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.lang.model.element.Element; import javax.lang.model.element.TypeParameterElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.WildcardType; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import org.jboss.logging.processor.model.MessageObjectType; /** * @author James R. Perkins */ abstract class AbstractMessageObjectType implements MessageObjectType { protected final Elements elements; protected final Types types; protected final TypeMirror typeMirror; protected AbstractMessageObjectType(final Elements elements, final Types types, final TypeMirror typeMirror) { this.elements = elements; this.types = types; this.typeMirror = typeMirror; } protected AbstractMessageObjectType(final Elements elements, final Types types, final Element element) { this.elements = elements; this.types = types; this.typeMirror = element.asType(); } @Override public String type() { return name(); } @Override public final boolean isAssignableFrom(final Class type) { final TypeMirror typeMirror = elements.getTypeElement(typeToString(type)).asType(); return types.isAssignable(types.erasure(typeMirror), types.erasure(this.typeMirror)); } @Override public final boolean isSubtypeOf(final Class type) { final TypeMirror typeMirror = elements.getTypeElement(typeToString(type)).asType(); return types.isSubtype(types.erasure(this.typeMirror), types.erasure(typeMirror)); } @Override public final boolean isSameAs(final Class type) { return type().equals(typeToString(type)); } } ImplementationClassGenerator.java000066400000000000000000000053511255176001000376660ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import java.io.IOException; import java.util.Map; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.TypeElement; import org.jboss.logging.processor.generator.model.ClassModel; import org.jboss.logging.processor.generator.model.ClassModelFactory; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.util.VersionComparator; /** * A generator for creating implementations of message bundle and logging * interfaces. * * @author James R. Perkins */ final class ImplementationClassGenerator extends AbstractGenerator { private static final String LOGGING_VERSION = "loggingVersion"; private final boolean useLogging31; /** * @param processingEnv the processing environment. */ public ImplementationClassGenerator(ProcessingEnvironment processingEnv) { super(processingEnv); final Map options = processingEnv.getOptions(); if (options.containsKey(LOGGING_VERSION)) { final String loggingVersion = options.get(LOGGING_VERSION); useLogging31 = (VersionComparator.compareVersion(loggingVersion, "3.1") >= 0); } else { useLogging31 = true; } } @Override public void processTypeElement(final TypeElement annotation, final TypeElement element, final MessageInterface messageInterface) { try { final ClassModel classModel = ClassModelFactory.implementation(filer(), messageInterface, useLogging31); classModel.generateAndWrite(); } catch (IllegalStateException | IOException e) { logger().error(element, e); } } } LoggingToolsProcessor.java000066400000000000000000000203771255176001000363600ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import static javax.lang.model.util.ElementFilter.typesIn; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedOptions; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.Field; import org.jboss.logging.annotations.FormatWith; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.LoggingClass; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageBundle; import org.jboss.logging.annotations.MessageLogger; import org.jboss.logging.annotations.Param; import org.jboss.logging.annotations.Pos; import org.jboss.logging.annotations.Property; import org.jboss.logging.annotations.Transform; import org.jboss.logging.annotations.ValidIdRange; import org.jboss.logging.annotations.ValidIdRanges; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.util.ElementHelper; import org.jboss.logging.processor.validation.ValidationMessage; import org.jboss.logging.processor.validation.Validator; /** * The main annotation processor for JBoss Logging Tooling. * * @author James R. Perkins * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ @SupportedOptions({ LoggingToolsProcessor.DEBUG_OPTION }) public class LoggingToolsProcessor extends AbstractProcessor { public static final String DEBUG_OPTION = "debug"; private final List interfaceAnnotations = Arrays.asList(MessageBundle.class.getName(), MessageLogger.class.getName()); private final List generators; private final Set supportedAnnotations; private ToolLogger logger; /** * Default constructor. */ public LoggingToolsProcessor() { this.generators = new ArrayList<>(); final Set annotations = new HashSet<>(); // Interface annotations annotations.addAll(interfaceAnnotations); // Other annotations annotations.add(Cause.class.getName()); annotations.add(Field.class.getName()); annotations.add(FormatWith.class.getName()); annotations.add(LoggingClass.class.getName()); annotations.add(LogMessage.class.getName()); annotations.add(Message.class.getName()); annotations.add(Param.class.getName()); annotations.add(Pos.class.getName()); annotations.add(Property.class.getName()); annotations.add(Transform.class.getName()); annotations.add(ValidIdRange.class.getName()); annotations.add(ValidIdRanges.class.getName()); this.supportedAnnotations = Collections.unmodifiableSet(annotations); } @Override public Set getSupportedOptions() { Set supportedOptions = new HashSet(); //Add global options SupportedOptions globalOptions = this.getClass().getAnnotation(SupportedOptions.class); if (globalOptions != null) { supportedOptions.addAll(Arrays.asList(globalOptions.value())); } //Add tool processors options for (AbstractGenerator generator : generators) { supportedOptions.addAll(generator.getSupportedOptions()); } return supportedOptions; } @Override public Set getSupportedAnnotationTypes() { return supportedAnnotations; } @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } @Override public synchronized void init(final ProcessingEnvironment processingEnv) { super.init(processingEnv); logger = ToolLogger.getLogger(processingEnv); //Tools generator - Note the order these are executed in. generators.add(new ImplementationClassGenerator(processingEnv)); generators.add(new TranslationClassGenerator(processingEnv)); generators.add(new TranslationFileGenerator(processingEnv)); } @Override public boolean process(final Set annotations, final RoundEnvironment roundEnv) { boolean process = true; final Validator validator = new Validator(); //Call jboss logging tools for (TypeElement annotation : annotations) { // We only want to process the interface annotations if (interfaceAnnotations.contains(annotation.getQualifiedName().toString())) { try { final Set interfaces = typesIn(roundEnv.getElementsAnnotatedWith(annotation)); for (TypeElement interfaceElement : interfaces) { try { final MessageInterface messageInterface = MessageInterfaceFactory.of(processingEnv, interfaceElement); final Collection validationMessages = validator.validate(messageInterface); for (ValidationMessage message : validationMessages) { final Element element = ElementHelper.fromMessageObject(message.getMessageObject()); switch (message.type()) { case ERROR: { logger.error(element, message.getMessage()); process = false; break; } case WARN: { logger.warn(element, message.getMessage()); break; } default: { logger.note(element, message.getMessage()); } } } if (process) { if (interfaceElement.getKind().isInterface() && !interfaceElement.getModifiers().contains(Modifier.PRIVATE)) { for (AbstractGenerator processor : generators) { logger.debug("Executing processor %s", processor.getName()); processor.processTypeElement(annotation, interfaceElement, messageInterface); } } } } catch (ProcessingException e) { logger.error(e.getElement(), e.getMessage()); } } } catch (Throwable t) { logger.error(annotation, t); } } } return process; } } MessageInterfaceFactory.java000066400000000000000000000332521255176001000366020ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import static org.jboss.logging.processor.util.Objects.HashCodeBuilder; import static org.jboss.logging.processor.util.Objects.ToStringBuilder; import static org.jboss.logging.processor.util.Objects.areEqual; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import org.jboss.logging.BasicLogger; import org.jboss.logging.annotations.MessageBundle; import org.jboss.logging.annotations.MessageLogger; import org.jboss.logging.annotations.ValidIdRange; import org.jboss.logging.annotations.ValidIdRanges; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.util.ElementHelper; /** * A factory to create a {@link org.jboss.logging.processor.model.MessageInterface} for annotation processors. * * @author James R. Perkins */ public final class MessageInterfaceFactory { private static final Object LOCK = new Object(); private static volatile LoggerInterface LOGGER_INTERFACE; /** * Private constructor for factory. */ private MessageInterfaceFactory() { } /** * Creates a message interface from the {@link javax.lang.model.element.TypeElement} specified by the {@code * interfaceElement} parameter. * * @param processingEnvironment the annotation processing environment. * @param interfaceElement the interface element to parse. * * @return a message interface for the interface element. */ public static MessageInterface of(final ProcessingEnvironment processingEnvironment, final TypeElement interfaceElement) { final Types types = processingEnvironment.getTypeUtils(); final Elements elements = processingEnvironment.getElementUtils(); if (types.isSameType(interfaceElement.asType(), elements.getTypeElement(BasicLogger.class.getName()).asType())) { MessageInterface result = LOGGER_INTERFACE; if (result == null) { synchronized (LOCK) { result = LOGGER_INTERFACE; if (result == null) { LOGGER_INTERFACE = LoggerInterface.of(elements, types); result = LOGGER_INTERFACE; } } } return result; } final AptMessageInterface result = new AptMessageInterface(interfaceElement, types, elements); result.init(); for (TypeMirror typeMirror : interfaceElement.getInterfaces()) { final MessageInterface extended = MessageInterfaceFactory.of(processingEnvironment, (TypeElement) types.asElement(typeMirror)); result.extendedInterfaces.add(extended); result.extendedInterfaces.addAll(extended.extendedInterfaces()); } return result; } /** * Message interface implementation. */ private static class AptMessageInterface extends AbstractMessageObjectType implements MessageInterface { private final TypeElement interfaceElement; private final Set extendedInterfaces; private final List messageMethods; private final List validIdRanges; private String projectCode; private String packageName; private String simpleName; private String qualifiedName; private String fqcn; private int idLen; private AptMessageInterface(final TypeElement interfaceElement, final Types types, final Elements elements) { super(elements, types, interfaceElement); this.interfaceElement = interfaceElement; this.messageMethods = new LinkedList(); this.extendedInterfaces = new LinkedHashSet(); if (ElementHelper.isAnnotatedWith(interfaceElement, ValidIdRanges.class)) { validIdRanges = Arrays.asList(interfaceElement.getAnnotation(ValidIdRanges.class).value()); } else if (ElementHelper.isAnnotatedWith(interfaceElement, ValidIdRange.class)) { validIdRanges = Arrays.asList(interfaceElement.getAnnotation(ValidIdRange.class)); } else { validIdRanges = Collections.emptyList(); } } @Override public boolean extendsLoggerInterface() { return LOGGER_INTERFACE != null && extendedInterfaces.contains(LOGGER_INTERFACE); } @Override public String name() { return qualifiedName; } @Override public Set extendedInterfaces() { return Collections.unmodifiableSet(extendedInterfaces); } @Override public int hashCode() { return HashCodeBuilder.builder().add(name()).toHashCode(); } @Override public Collection methods() { return messageMethods; } @Override public int compareTo(final MessageInterface o) { return this.name().compareTo(o.name()); } @Override public String projectCode() { return projectCode; } private void init() { // Keeping below for now final Collection methods = ElementFilter.methodsIn(interfaceElement.getEnclosedElements()); final MessageMethodBuilder builder = MessageMethodBuilder.create(elements, types); for (ExecutableElement param : methods) { builder.add(param); } final Collection m = builder.build(); if (m != null) this.messageMethods.addAll(m); final MessageBundle messageBundle = interfaceElement.getAnnotation(MessageBundle.class); final MessageLogger messageLogger = interfaceElement.getAnnotation(MessageLogger.class); if (messageBundle != null) { projectCode = messageBundle.projectCode(); idLen = messageBundle.length(); } else if (messageLogger != null) { projectCode = messageLogger.projectCode(); idLen = messageLogger.length(); } // TODO (jrp) this should cause an error qualifiedName = elements.getBinaryName(interfaceElement).toString(); final int lastDot = qualifiedName.lastIndexOf("."); if (lastDot > 0) { packageName = qualifiedName.substring(0, lastDot); simpleName = qualifiedName.substring(lastDot + 1); } else { packageName = null; simpleName = qualifiedName; } // Get the FQCN final TypeElement loggingClass = ElementHelper.getClassAnnotationValue(interfaceElement, MessageLogger.class, "loggingClass"); if (loggingClass != null) { final String value = loggingClass.getQualifiedName().toString(); if (!value.equals(Void.class.getName())) { fqcn = value; } } } @Override public String type() { return name(); } @Override public String packageName() { return packageName; } @Override public String getComment() { return elements.getDocComment(interfaceElement); } @Override public String simpleName() { return simpleName; } @Override public String loggingFQCN() { return fqcn; } @Override public AnnotatedType getAnnotatedType() { if (ElementHelper.isAnnotatedWith(interfaceElement, MessageLogger.class)) { return AnnotatedType.MESSAGE_LOGGER; } else if (ElementHelper.isAnnotatedWith(interfaceElement, MessageBundle.class)) { return AnnotatedType.MESSAGE_BUNDLE; } return AnnotatedType.NONE; } @Override public List validIdRanges() { return validIdRanges; } @Override public int getIdLength() { return idLen; } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof AptMessageInterface)) { return false; } final AptMessageInterface other = (AptMessageInterface) obj; return areEqual(name(), other.name()); } @Override public String toString() { return ToStringBuilder.of(this).add(qualifiedName).toString(); } @Override public TypeElement reference() { return interfaceElement; } } private static class LoggerInterface extends AbstractMessageObjectType implements MessageInterface { private final TypeElement loggerInterface; private final Set messageMethods; private LoggerInterface(final Elements elements, final Types types) { // TODO (jrp) BasicLogger type can likely be initialized once super(elements, types, elements.getTypeElement(BasicLogger.class.getName())); messageMethods = new LinkedHashSet(); this.loggerInterface = elements.getTypeElement(BasicLogger.class.getName()); } private void init() { final MessageMethodBuilder builder = MessageMethodBuilder.create(elements, types); List methods = ElementFilter.methodsIn(loggerInterface.getEnclosedElements()); for (ExecutableElement method : methods) { builder.add(method); } final Collection m = builder.build(); this.messageMethods.addAll(m); } static LoggerInterface of(final Elements elements, final Types types) { final LoggerInterface result = new LoggerInterface(elements, types); result.init(); return result; } @Override public boolean extendsLoggerInterface() { return false; } @Override public Set extendedInterfaces() { return Collections.emptySet(); } @Override public Collection methods() { return messageMethods; } @Override public String projectCode() { return null; } @Override public String name() { return BasicLogger.class.getName(); } @Override public String packageName() { return BasicLogger.class.getPackage().getName(); } @Override public String simpleName() { return BasicLogger.class.getSimpleName(); } @Override public String loggingFQCN() { return null; } @Override public AnnotatedType getAnnotatedType() { return AnnotatedType.NONE; } @Override public List validIdRanges() { return Collections.emptyList(); } @Override public int getIdLength() { return -1; } @Override public TypeElement reference() { return loggerInterface; } @Override public int hashCode() { return HashCodeBuilder.builder().add(name()).toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof AptMessageInterface)) { return false; } final AptMessageInterface other = (AptMessageInterface) obj; return areEqual(name(), other.name()); } @Override public int compareTo(final MessageInterface o) { return this.name().compareTo(o.name()); } @Override public String toString() { return ToStringBuilder.of(this).add(name()).toString(); } @Override public String getComment() { return elements.getDocComment(loggerInterface); } } } MessageMethodBuilder.java000066400000000000000000000376321255176001000361070ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import static java.util.Collections.unmodifiableSet; import static org.jboss.logging.processor.util.ElementHelper.findByName; import static org.jboss.logging.processor.util.ElementHelper.inheritsMessage; import static org.jboss.logging.processor.util.ElementHelper.isOverloaded; import static org.jboss.logging.processor.util.ElementHelper.parameterCount; import static org.jboss.logging.processor.util.Objects.HashCodeBuilder; import static org.jboss.logging.processor.util.Objects.ToStringBuilder; import static org.jboss.logging.processor.util.Objects.areEqual; import java.util.Collection; import java.util.Collections; import java.util.EnumMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import javax.lang.model.element.ExecutableElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import org.jboss.logging.Logger; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.Message.Format; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.model.Parameter; import org.jboss.logging.processor.model.Parameter.ParameterType; import org.jboss.logging.processor.model.ReturnType; import org.jboss.logging.processor.model.ThrowableType; import org.jboss.logging.processor.util.Comparison; import org.jboss.logging.processor.util.ElementHelper; /** * Date: 29.07.2011 * * @author James R. Perkins */ final class MessageMethodBuilder { private static final String MESSAGE_METHOD_SUFFIX = "$str"; private final List methods; private final Elements elements; private final Types types; private MessageMethodBuilder(final Elements elements, final Types types) { this.elements = elements; this.types = types; methods = new LinkedList<>(); } MessageMethodBuilder add(final ExecutableElement method) { methods.add(method); return this; } Set build() { final Set result = new LinkedHashSet<>(); for (ExecutableElement elementMethod : methods) { final AptMessageMethod resultMethod = new AptMessageMethod(elements, elementMethod); resultMethod.inheritsMessage = inheritsMessage(methods, elementMethod); resultMethod.message = findMessage(methods, elementMethod); resultMethod.isOverloaded = isOverloaded(methods, elementMethod); for (TypeMirror thrownType : elementMethod.getThrownTypes()) { resultMethod.thrownTypes.add(ThrowableTypeFactory.of(elements, types, thrownType)); } // Create a list of parameters for (Parameter parameter : ParameterFactory.of(elements, types, resultMethod.method)) { resultMethod.add(parameter); } // Check to see if the method is overloaded if (resultMethod.isOverloaded()) { resultMethod.messageMethodName = resultMethod.name() + resultMethod.formatParameterCount() + MESSAGE_METHOD_SUFFIX; resultMethod.translationKey = resultMethod.name() + "." + resultMethod.formatParameterCount(); } else { resultMethod.messageMethodName = resultMethod.name() + MESSAGE_METHOD_SUFFIX; resultMethod.translationKey = resultMethod.name(); } // Set the return type resultMethod.returnType = ReturnTypeFactory.of(elements, types, elementMethod.getReturnType(), resultMethod); result.add(resultMethod); } return Collections.unmodifiableSet(result); } private MessageMethod.Message findMessage(final Collection methods, final ExecutableElement method) { AptMessage result = null; Message message = method.getAnnotation(Message.class); if (message != null) { result = new AptMessage(message); result.hasId = hasMessageId(message); result.inheritsId = message.id() == Message.INHERIT; if (result.inheritsId()) { result.id = findMessageId(methods, method); if (result.id > 0) { result.hasId = true; } } else { result.id = message.id(); } } else { final Collection allMethods = findByName(methods, method.getSimpleName(), parameterCount(method.getParameters())); for (ExecutableElement m : allMethods) { message = m.getAnnotation(Message.class); if (message != null) { result = new AptMessage(message); result.hasId = hasMessageId(message); result.inheritsId = message.id() == Message.INHERIT; if (result.inheritsId()) { result.id = findMessageId(methods, m); if (result.id > 0) { result.hasId = true; } } else { result.id = message.id(); } break; } } } return result; } private int findMessageId(final Collection methods, final ExecutableElement method) { int result = -2; final Collection allMethods = findByName(methods, method.getSimpleName()); for (ExecutableElement m : allMethods) { final Message message = m.getAnnotation(Message.class); if (message != null) { if (message.id() != Message.INHERIT) { result = message.id(); } } } return result; } private boolean hasMessageId(final Message message) { return message != null && (message.id() != Message.NONE && message.id() != Message.INHERIT); } static MessageMethodBuilder create(final Elements elements, final Types types) { return new MessageMethodBuilder(elements, types); } /** * An implementation for the MessageMethod interface. */ private static class AptMessageMethod implements MessageMethod { private final Elements elements; private final Map> parameters; private final Set thrownTypes; private final ExecutableElement method; private ReturnType returnType; private Parameter cause; private boolean inheritsMessage; private boolean isOverloaded; private Message message; private String messageMethodName; private String translationKey; /** * Private constructor for the * * @param elements the elements utility. * @param method the method to describe. */ AptMessageMethod(final Elements elements, final ExecutableElement method) { this.elements = elements; this.method = method; inheritsMessage = false; isOverloaded = false; parameters = new EnumMap<>(ParameterType.class); thrownTypes = new LinkedHashSet<>(); } void add(final Parameter parameter) { if (parameters.containsKey(ParameterType.ANY)) { parameters.get(ParameterType.ANY).add(parameter); } else { final Set any = new LinkedHashSet<>(); any.add(parameter); parameters.put(ParameterType.ANY, any); } if (parameters.containsKey(parameter.parameterType())) { parameters.get(parameter.parameterType()).add(parameter); } else { final Set set = new LinkedHashSet<>(); set.add(parameter); parameters.put(parameter.parameterType(), set); } if (parameter.parameterType() == ParameterType.CAUSE) { cause = parameter; } } @Override public String name() { return method.getSimpleName().toString(); } @Override public Set parameters(final ParameterType parameterType) { if (parameters.containsKey(parameterType)) { return parameters.get(parameterType); } return Collections.emptySet(); } @Override public Set parameters(final ParameterType parameterType, final ParameterType... parameterTypes) { final Set result = new LinkedHashSet(); if (parameters.containsKey(parameterType)) { result.addAll(parameters.get(parameterType)); } for (ParameterType pt : parameterTypes) { if (parameters.containsKey(pt)) { result.addAll(parameters.get(pt)); } } return result; } @Override public ReturnType returnType() { return returnType; } @Override public Set thrownTypes() { return unmodifiableSet(thrownTypes); } @Override public Message message() { return message; } @Override public boolean inheritsMessage() { return inheritsMessage; } @Override public String messageMethodName() { return messageMethodName; } @Override public String translationKey() { return translationKey; } @Override public boolean hasCause() { return cause != null; } @Override public boolean isOverloaded() { return isOverloaded; } @Override public Parameter cause() { return cause; } @Override public String loggerMethod() { switch (message.format()) { case MESSAGE_FORMAT: return "logv"; case NO_FORMAT: return "log"; case PRINTF: return "logf"; default: // Should never be hit return "log"; } } @Override public String logLevel() { // TODO (jrp) possibly return the actual level final LogMessage logMessage = method.getAnnotation(LogMessage.class); final Logger.Level logLevel = (logMessage.level() == null ? Logger.Level.INFO : logMessage.level()); return String.format("%s.%s.%s", Logger.class.getName(), Logger.Level.class.getSimpleName(), logLevel.name()); } @Override public int formatParameterCount() { int result = parameters(ParameterType.FORMAT, ParameterType.TRANSFORM).size(); for (Parameter params : parameters(ParameterType.POS)) { result += params.pos().value().length; } return result; } @Override public boolean isLoggerMethod() { return ElementHelper.isAnnotatedWith(method, LogMessage.class); } @Override public int hashCode() { return HashCodeBuilder.builder() .add(name()) .add(parameters(ParameterType.ANY)) .add(returnType()).toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof AptMessageMethod)) { return false; } final AptMessageMethod other = (AptMessageMethod) obj; return areEqual(name(), other.name()) && areEqual(parameters, parameters) && areEqual(returnType, other.returnType); } @Override public String toString() { return ToStringBuilder.of(this) .add("name", name()) .add("returnType", returnType()) .add("parameters", parameters(ParameterType.ANY)) .add("loggerMethod", loggerMethod()).toString(); } @Override public ExecutableElement reference() { return method; } @Override public int compareTo(final MessageMethod o) { int result = name().compareTo(o.name()); result = (result != Comparison.EQUAL) ? result : returnType.name().compareTo(o.returnType().name()); // Size does matter result = (result != Comparison.EQUAL) ? result : parameters(ParameterType.ANY).size() - o.parameters(ParameterType.ANY).size(); if (result == Comparison.EQUAL) { // Check element by element final Iterator params1 = parameters(ParameterType.ANY).iterator(); final Iterator params2 = o.parameters(ParameterType.ANY).iterator(); while (params1.hasNext()) { if (params2.hasNext()) { final Parameter param1 = params1.next(); final Parameter param2 = params2.next(); result = param1.compareTo(param2); } else { result = Comparison.GREATER; } // Short circuit if (result != Comparison.EQUAL) break; } } return result; } @Override public String getComment() { return elements.getDocComment(method); } } private static class AptMessage implements MessageMethod.Message { private final Message message; private int id; private boolean hasId; private boolean inheritsId; private AptMessage(final Message message) { this.message = message; } @Override public int id() { return id; } @Override public boolean hasId() { return hasId; } @Override public boolean inheritsId() { return inheritsId; } @Override public String value() { return message.value(); } @Override public Format format() { return message.format(); } @Override public String toString() { return ToStringBuilder.of(this) .add("hasId", hasId) .add("id", id()) .add("inheritsId", inheritsId) .add("value", value()) .add("formatType", format()).toString(); } } } ParameterFactory.java000066400000000000000000000320701255176001000353120ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import static org.jboss.logging.processor.util.Objects.HashCodeBuilder; import static org.jboss.logging.processor.util.Objects.ToStringBuilder; import static org.jboss.logging.processor.util.Objects.areEqual; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.Field; import org.jboss.logging.annotations.FormatWith; import org.jboss.logging.annotations.LoggingClass; import org.jboss.logging.annotations.Param; import org.jboss.logging.annotations.Pos; import org.jboss.logging.annotations.Property; import org.jboss.logging.annotations.Transform; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.model.Parameter; import org.jboss.logging.processor.util.Comparison; import org.jboss.logging.processor.util.ElementHelper; /** * @author James R. Perkins - 20.Feb.2011 */ final class ParameterFactory { /** * Private constructor for factory. */ private ParameterFactory() { } public static Set of(final Elements elements, final Types types, final ExecutableElement method) { final Set result = new LinkedHashSet(); final List params = method.getParameters(); int index = 0; for (VariableElement param : params) { final TypeElement formatClassType = ElementHelper.getClassAnnotationValue(param, FormatWith.class); final String formatClass = formatClassType == null ? null : formatClassType.getQualifiedName().toString(); final String qualifiedType; if (param.asType().getKind().isPrimitive()) { qualifiedType = param.asType().toString(); } else { switch ((param.asType().getKind())) { case ARRAY: qualifiedType = param.asType().toString().replace("[]", ""); break; default: qualifiedType = types.asElement(param.asType()).toString(); break; } } if (method.isVarArgs()) { result.add(new AptParameter(elements, types, qualifiedType, param, formatClass, (++index == params.size()))); } else { result.add(new AptParameter(elements, types, qualifiedType, param, formatClass, false)); } } return result; } public static Parameter forMessageMethod(final MessageMethod messageMethod) { return new Parameter() { @Override public String formatterClass() { return null; } @Override public Class paramClass() { return null; } @Override public String targetName() { return ""; } @Override public Transform transform() { return null; } @Override public Pos pos() { return null; } @Override public String type() { return String.class.getName(); } @Override public String name() { return messageMethod.messageMethodName(); } @Override public boolean isArray() { return false; } @Override public boolean isPrimitive() { return false; } @Override public boolean isVarArgs() { return false; } @Override public ParameterType parameterType() { return ParameterType.MESSAGE; } @Override public int hashCode() { return HashCodeBuilder.builder() .add(type()) .add(name()).toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof AptParameter)) { return false; } final AptParameter other = (AptParameter) obj; return areEqual(type(), other.type()) && areEqual(name(), other.name()); } @Override public int compareTo(final Parameter other) { return Comparison.begin() .compare(this.type(), other.type()) .compare(this.name(), other.name()).result(); } @Override public String toString() { return ToStringBuilder.of(this) .add("name", name()) .add("type", type()).toString(); } @Override public MessageMethod reference() { return messageMethod; } @Override public boolean isAssignableFrom(final Class type) { return String.class.isAssignableFrom(type); } @Override public boolean isSubtypeOf(final Class type) { return type.isAssignableFrom(String.class); } @Override public boolean isSameAs(final Class type) { return type().equals(type.getName()); } }; } private static class AptParameter extends AbstractMessageObjectType implements Parameter { private final VariableElement param; private final String qualifiedType; private final String formatterClass; private final Class paramClass; private final boolean isVarArgs; private final ParameterType parameterType; private final Transform transform; private final Pos pos; /** * Only allow construction from within the parent class. * * @param elements the element utilities from the annotation processor. * @param types the type utilities from the annotation processor. * @param qualifiedType the qualified type name of the parameter. * @param param the parameter. * @param formatterClass the formatter class, or {@code null} if none * @param isVarArgs {@code true} if this is a vararg parameter, otherwise {@code false}. */ AptParameter(final Elements elements, final Types types, final String qualifiedType, final VariableElement param, final String formatterClass, final boolean isVarArgs) { super(elements, types, param); this.qualifiedType = qualifiedType; this.param = param; this.formatterClass = formatterClass; if (ElementHelper.isAnnotatedWith(param, Param.class)) { paramClass = Object.class; parameterType = ParameterType.CONSTRUCTION; transform = null; pos = null; } else if (ElementHelper.isAnnotatedWith(param, Cause.class)) { paramClass = null; parameterType = ParameterType.CAUSE; transform = null; pos = null; } else if (ElementHelper.isAnnotatedWith(param, Field.class)) { paramClass = null; parameterType = ParameterType.FIELD; transform = null; pos = null; } else if (ElementHelper.isAnnotatedWith(param, Property.class)) { paramClass = null; parameterType = ParameterType.PROPERTY; transform = null; pos = null; } else if (ElementHelper.isAnnotatedWith(param, LoggingClass.class)) { paramClass = null; parameterType = ParameterType.FQCN; transform = null; pos = null; } else if (ElementHelper.isAnnotatedWith(param, Transform.class)) { paramClass = null; parameterType = ParameterType.TRANSFORM; transform = param.getAnnotation(Transform.class); pos = null; } else if (ElementHelper.isAnnotatedWith(param, Pos.class)) { paramClass = null; parameterType = ParameterType.POS; transform = null; pos = param.getAnnotation(Pos.class); } else { parameterType = ParameterType.FORMAT; paramClass = null; transform = null; pos = null; } this.isVarArgs = isVarArgs; } @Override public String type() { return qualifiedType; } @Override public String formatterClass() { return formatterClass; } @Override public String name() { return param.getSimpleName().toString(); } @Override public boolean isArray() { return param.asType().getKind() == TypeKind.ARRAY; } @Override public boolean isPrimitive() { return param.asType().getKind().isPrimitive(); } @Override public boolean isVarArgs() { return isVarArgs; } @Override public ParameterType parameterType() { return parameterType; } @Override public Class paramClass() { return paramClass; } @Override public String targetName() { String result = ""; final Field field = param.getAnnotation(Field.class); final Property property = param.getAnnotation(Property.class); if (field != null) { final String name = field.name(); if (name.isEmpty()) { result = param.getSimpleName().toString(); } else { result = name; } } else if (property != null) { final String name = property.name(); if (name.isEmpty()) { result = param.getSimpleName().toString(); } else { result = name; } result = "set" + Character.toUpperCase(result.charAt(0)) + result.substring(1); } return result; } @Override public Transform transform() { return transform; } @Override public Pos pos() { return pos; } @Override public int hashCode() { return HashCodeBuilder.builder() .add(qualifiedType) .add(param).toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof AptParameter)) { return false; } final AptParameter other = (AptParameter) obj; return areEqual(this.param, other.param) && areEqual(this.qualifiedType, other.qualifiedType); } @Override public int compareTo(final Parameter other) { return Comparison.begin() .compare(this.type(), other.type()) .compare(this.name(), other.name()).result(); } @Override public String toString() { return ToStringBuilder.of(this) .add("name", name()) .add("type", type()).toString(); } @Override public VariableElement reference() { return param; } } } ProcessingException.java000066400000000000000000000042061255176001000360350ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2015, Red Hat, Inc., 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.processor.apt; import javax.lang.model.element.Element; /** * An exception that can be used to log which element caused the error. * * @author James R. Perkins */ class ProcessingException extends RuntimeException { private final Element element; /** * Creates a new exception. * * @param element the element the error occurs on * @param message the message */ public ProcessingException(final Element element, final String message) { super(message); this.element = element; } /** * Creates a new exception. * * @param element the element the error occurs on * @param format the format for the message * @param args the arguments for the format */ public ProcessingException(final Element element, final String format, final Object... args) { super(String.format(format, args)); this.element = element; } /** * The element the error occurred on. * * @return the element */ public Element getElement() { return element; } } ReturnTypeFactory.java000066400000000000000000000210111255176001000355040ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import static org.jboss.logging.processor.util.Objects.HashCodeBuilder; import static org.jboss.logging.processor.util.Objects.areEqual; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.PrimitiveType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import org.jboss.logging.annotations.ConstructType; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.model.Parameter; import org.jboss.logging.processor.model.ReturnType; import org.jboss.logging.processor.model.ThrowableType; import org.jboss.logging.processor.util.ElementHelper; import org.jboss.logging.processor.util.Objects; /** * Date: 29.07.2011 * * @author James R. Perkins */ final class ReturnTypeFactory { /** * Private constructor for factory. */ private ReturnTypeFactory() { } public static ReturnType of(final Elements elements, final Types types, final TypeMirror returnType, final MessageMethod method) { if (returnType.getKind() == TypeKind.VOID) { return ReturnType.VOID; } final AptReturnType result = new AptReturnType(elements, types, returnType, method); result.init(); return result; } /** * Implementation of return type. */ private static class AptReturnType extends AbstractMessageObjectType implements ReturnType { private final Map fields; private final Map methods; private final TypeMirror returnType; private final MessageMethod method; private ThrowableType throwableType; AptReturnType(final Elements elements, final Types types, final TypeMirror returnType, final MessageMethod method) { super(elements, types, returnType); this.returnType = returnType; this.method = method; throwableType = null; fields = new LinkedHashMap(); methods = new LinkedHashMap(); } @Override public boolean hasFieldFor(final Parameter parameter) { return fields.containsKey(parameter.targetName()) && checkType(parameter, fields.get(parameter.targetName())); } @Override public boolean hasMethodFor(final Parameter parameter) { return methods.containsKey(parameter.targetName()) && checkType(parameter, methods.get(parameter.targetName())); } @Override public boolean isThrowable() { return isSubtypeOf(Throwable.class); } @Override public boolean isPrimitive() { return returnType.getKind().isPrimitive(); } @Override public String name() { return returnType.toString(); } @Override public ThrowableType throwableReturnType() { return throwableType; } private void init() { if (isThrowable()) { TypeMirror returnType = this.returnType; if (ElementHelper.isAnnotatedWith(method.reference(), ConstructType.class)) { final TypeElement constructTypeValue = ElementHelper.getClassAnnotationValue(method.reference(), ConstructType.class); // Shouldn't be null if (constructTypeValue == null) { throw new ProcessingException(method.reference(), "Class not defined for the ConstructType"); } returnType = constructTypeValue.asType(); if (!types.isAssignable(returnType, this.returnType)) { throw new ProcessingException(method.reference(), "The requested type %s can not be assigned to %s.", returnType, this.returnType); } } throwableType = ThrowableTypeFactory.forReturnType(elements, types, returnType, method); } final Element e = types.asElement(returnType); if (e instanceof TypeElement) { final List returnTypeMethods = ElementFilter.methodsIn(elements.getAllMembers((TypeElement) e)); for (ExecutableElement executableElement : returnTypeMethods) { if (executableElement.getModifiers().contains(Modifier.PUBLIC) && executableElement.getParameters().size() == 1) { methods.put(executableElement.getSimpleName().toString(), executableElement.getParameters().get(0).asType()); } } for (Element element : ElementFilter.fieldsIn(elements.getAllMembers((TypeElement) e))) { if (element.getModifiers().contains(Modifier.PUBLIC) && !element.getModifiers().contains(Modifier.FINAL)) { fields.put(element.getSimpleName().toString(), element.asType()); } } } } @Override public int hashCode() { return HashCodeBuilder.builder().add(name()).toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof AptReturnType)) { return false; } final AptReturnType other = (AptReturnType) obj; return areEqual(name(), other.name()); } @Override public String toString() { return Objects.ToStringBuilder.of(this) .add("name", name()) .add("primitive", isPrimitive()) .add("throwable", isThrowable()) .add("throwableType", throwableType).toString(); } @Override public TypeMirror reference() { return returnType; } private boolean checkType(final Parameter parameter, final TypeMirror type) { if (parameter.isPrimitive()) { if (type.getKind().isPrimitive()) { return parameter.type().equalsIgnoreCase(type.getKind().name()); } return types.isAssignable(elements.getTypeElement(unbox(parameter)).asType(), type); } if (type.getKind().isPrimitive()) { final TypeElement primitiveType = types.boxedClass((PrimitiveType) type); return types.isAssignable(elements.getTypeElement(parameter.type()).asType(), primitiveType.asType()); } return types.isAssignable(elements.getTypeElement(parameter.type()).asType(), type); } private String unbox(final Parameter parameter) { String result = parameter.type(); if (parameter.isPrimitive()) { if ("int".equals(result)) { result = Integer.class.getName(); } else if ("char".equals(result)) { result = Character.class.getName(); } else { result = "java.lang." + Character.toUpperCase(result.charAt(0)) + result.substring(1); } } return result; } } } ThrowableTypeFactory.java000066400000000000000000000323611255176001000361660ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import static org.jboss.logging.processor.model.Parameter.ParameterType; import static org.jboss.logging.processor.util.Objects.HashCodeBuilder; import static org.jboss.logging.processor.util.Objects.areEqual; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.model.Parameter; import org.jboss.logging.processor.model.ThrowableType; import org.jboss.logging.processor.util.Objects; /** * Describes information about the return type. * * @author James R. Perkins */ final class ThrowableTypeFactory { private ThrowableTypeFactory() { } /** * Creates a new descriptor that is not primitive. * * @param elements the element utilities from the annotation processor. * @param types the type utilities from the annotation process. * @param type the class name of the return type. * @param messageMethod the message method. * * @return the return type descriptor. */ public static ThrowableType forReturnType(final Elements elements, final Types types, final TypeMirror type, final MessageMethod messageMethod) { final AptReturnThrowableType result = new AptReturnThrowableType(elements, types, messageMethod, type); result.init(); return result; } /** * Creates a new descriptor that is not primitive. * * @param elements the element utilities from the annotation processor. * @param types the type utilities from the annotation process. * @param type the class name of the return type. * * @return the return type descriptor. */ public static ThrowableType of(final Elements elements, final Types types, final TypeMirror type) { final AptThrowableType result = new AptThrowableType(elements, types, type); result.init(); return result; } private static class AptThrowableType extends AbstractMessageObjectType implements ThrowableType { private final TypeMirror type; private final boolean isChecked; private boolean defaultConstructor = false; private boolean stringConstructor = false; private boolean throwableConstructor = false; private boolean stringAndThrowableConstructor = false; private boolean throwableAndStringConstructor = false; protected final TypeMirror stringType; protected final TypeMirror throwableType; /** * Creates a new descriptor that is not primitive. * * @param types the type utilities from the annotation processor. * @param elements the element utilities from the annotation processor. * @param type the class name of the return type. */ private AptThrowableType(final Elements elements, final Types types, final TypeMirror type) { super(elements, types, type); this.type = type; stringType = elements.getTypeElement(String.class.getName()).asType(); throwableType = elements.getTypeElement(Throwable.class.getName()).asType(); final TypeMirror runtimeException = elements.getTypeElement(RuntimeException.class.getName()).asType(); final TypeMirror error = elements.getTypeElement(Error.class.getName()).asType(); isChecked = !(types.isAssignable(runtimeException, type) && types.isAssignable(error, type)); } /** * Initializes the object. */ protected final void init() { if (!type.getKind().isPrimitive() && type.getKind() != TypeKind.VOID) { final Element element = types.asElement(type); final List constructors = ElementFilter.constructorsIn(element.getEnclosedElements()); for (ExecutableElement constructor : constructors) { // Only allow public constructors if (!constructor.getModifiers().contains(Modifier.PUBLIC)) { continue; } final List params = constructor.getParameters(); switch (params.size()) { case 0: defaultConstructor = true; break; case 1: if (types.isAssignable(stringType, params.get(0).asType())) { stringConstructor = true; } else if (types.isAssignable(params.get(0).asType(), throwableType)) { throwableConstructor = true; } break; case 2: if (types.isAssignable(stringType, params.get(0).asType()) && types.isAssignable(params.get(1).asType(), throwableType)) { stringAndThrowableConstructor = true; } else if (types.isAssignable(params.get(0).asType(), throwableType) && types.isAssignable(stringType, params.get(1).asType())) { throwableAndStringConstructor = true; } break; } init(params); } } } /** * Allows for additional processing of parameters. * * @param params the parameters to be processed. */ protected void init(final List params) { } @Override public boolean hasDefaultConstructor() { return defaultConstructor; } @Override public boolean hasStringAndThrowableConstructor() { return stringAndThrowableConstructor; } @Override public boolean hasStringConstructor() { return stringConstructor; } @Override public boolean hasThrowableAndStringConstructor() { return throwableAndStringConstructor; } @Override public boolean hasThrowableConstructor() { return throwableConstructor; } @Override public boolean useConstructionParameters() { return false; } @Override public Set constructionParameters() { return Collections.emptySet(); } @Override public boolean isChecked() { return isChecked; } @Override public String name() { return type.toString(); } @Override public int hashCode() { return HashCodeBuilder.builder().add(type).toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof AptThrowableType)) { return false; } final AptThrowableType other = (AptThrowableType) obj; return areEqual(this.type, other.type); } @Override public String toString() { return Objects.ToStringBuilder.of(this) .add("type", type) .add("stringConstructor", stringConstructor) .add("throwableConstructor", throwableConstructor) .add("stringAndThrowableConstructor", stringAndThrowableConstructor) .add("throwableAndStringConstructor", throwableAndStringConstructor).toString(); } @Override public TypeMirror reference() { return type; } @Override public int compareTo(final ThrowableType o) { return name().compareTo(o.name()); } } private static class AptReturnThrowableType extends AptThrowableType { private final MessageMethod messageMethod; private final Set constructionParameters; private boolean useConstructionParameters = false; /** * Creates a new descriptor that is not primitive. * * @param types the type utilities from the annotation processor. * @param elements the element utilities from the annotation processor. * @param messageMethod the message method. * @param type the class name of the return type. */ private AptReturnThrowableType(final Elements elements, final Types types, final MessageMethod messageMethod, final TypeMirror type) { super(elements, types, type); this.messageMethod = messageMethod; constructionParameters = new LinkedHashSet(); } @Override protected void init(final List params) { final Set methodConstructorParameters = messageMethod.parameters(ParameterType.CONSTRUCTION); // If there are no construction parameters or a constructor was already found, no need to process if (methodConstructorParameters.isEmpty() || useConstructionParameters) { return; } // The number of parameters needed has to include the cause, if specified, and the message it self final int neededParamSize = methodConstructorParameters.size() + (messageMethod.hasCause() ? 2 : 1); if (neededParamSize == params.size()) { // Checks for the first constructor that can be used. The compiler will end-up determining the constructor // to use, so a best guess should work. final Iterator methodParameterIterator = methodConstructorParameters.iterator(); final Set matchedParams = new LinkedHashSet(); boolean match = false; boolean causeFound = false; boolean messageFound = false; for (VariableElement param : params) { if (!causeFound && messageMethod.hasCause() && types.isAssignable(throwableType, param.asType())) { causeFound = true; matchedParams.add(messageMethod.cause()); continue; } if (!messageFound && types.isAssignable(param.asType(), stringType)) { messageFound = true; matchedParams.add(ParameterFactory.forMessageMethod(messageMethod)); continue; } if (methodParameterIterator.hasNext()) { final Parameter parameter = methodParameterIterator.next(); if (parameter.reference() instanceof VariableElement) { final VariableElement refType = (VariableElement) parameter.reference(); match = types.isAssignable(refType.asType(), param.asType()); } if (match) { matchedParams.add(parameter); } } // Short circuit if (!match) break; } if (match) { constructionParameters.clear(); useConstructionParameters = true; constructionParameters.addAll(matchedParams); } } } @Override public boolean useConstructionParameters() { return useConstructionParameters; } @Override public Set constructionParameters() { return constructionParameters; } } } ToolLogger.java000066400000000000000000000274051255176001000341250ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; import javax.tools.Diagnostic.Kind; /** * A logger for logging messages for annotation processors. * * @author James R. Perkins * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ public final class ToolLogger { private final Messager messager; private final boolean isDebugEnabled; private ToolLogger(final Messager messager, final boolean isDebugEnabled) { this.messager = messager; this.isDebugEnabled = isDebugEnabled; } /** * Creates a new tool logger. * * @param processingEnv the processing environment * * @return a new tool logger */ public static ToolLogger getLogger(final ProcessingEnvironment processingEnv) { String debug = processingEnv.getOptions().get(LoggingToolsProcessor.DEBUG_OPTION); boolean isDebugEnabled = Boolean.parseBoolean(debug); return new ToolLogger(processingEnv.getMessager(), isDebugEnabled); } /** * Returns {@code true} if debugging is enabled, otherwise {@code false}. *

* It is not necessary to invoke this method before invoking {@code debug} * methods. The debug methods will only log messages if debugging is * enabled. *

* * @return {@code true} if debugging is enabled, otherwise {@code false}. */ public boolean isDebugEnabled() { return isDebugEnabled; } /** * Prints a note message. * * @param element the element to print with the note. * @param message the message. */ public void note(final Element element, final String message) { log(Kind.NOTE, element, message); } /** * Prints a formatted note message. * * @param element the element to print with the note. * @param messageFormat the message format. * @param args the format arguments. */ public void note(final Element element, final String messageFormat, final Object... args) { log(Kind.NOTE, element, messageFormat, args); } /** * Prints a formatted debug message if debugging is enabled. * * @param messageFormat the message format. * @param args the format arguments. */ public void debug(final String messageFormat, final Object... args) { if (isDebugEnabled) { debug(null, messageFormat, args); } } /** * Prints a debug message. * * @param element the element to print with the note. * @param message the message. */ public void debug(final Element element, final String message) { if (isDebugEnabled) { other(element, message); } } /** * Prints a formatted debug message if debugging is enabled. * * @param element the element to print with the note. * @param messageFormat the message format. * @param args the format arguments. */ public void debug(final Element element, final String messageFormat, final Object... args) { if (isDebugEnabled) { other(null, messageFormat, element, args); } } /** * Prints a warning message. * * @param element the element to print with the message. * @param message the message. */ public void warn(final Element element, final String message) { log(Kind.WARNING, element, message); } /** * Prints a formatted warning message. * * @param element the element that caused the warning. * @param messageFormat the message format. * @param args the format arguments. */ public void warn(final Element element, final String messageFormat, final Object... args) { log(Kind.WARNING, element, messageFormat, args); } /** * Prints a warning message. * * @param element the element to print with the message. * @param message the message. */ public void mandatoryWarning(final Element element, final String message) { log(Kind.MANDATORY_WARNING, element, message); } /** * Prints a formatted warning message. * * @param element the element that caused the warning. * @param messageFormat the message format. * @param args the format arguments. */ public void mandatoryWarning(final Element element, final String messageFormat, final Object... args) { log(Kind.MANDATORY_WARNING, element, messageFormat, args); } /** * Prints a formatted error message. * * @param messageFormat the message format. * @param args the format arguments. */ public void error(final String messageFormat, final Object... args) { log(Kind.ERROR, null, messageFormat, args); } /** * Prints a error message. * * @param element the element to print with the message. * @param message the message. */ public void error(final Element element, final String message) { log(Kind.ERROR, element, message); } /** * Prints a formatted error message. * * @param messageFormat the message format. * @param element the element that caused the warning. * @param args the format arguments. */ public void error(final Element element, final String messageFormat, final Object... args) { log(Kind.ERROR, element, messageFormat, args); } /** * Prints an error message. * * @param cause the cause of the error. */ public void error(final Throwable cause) { error(null, cause); } /** * Prints a error message. * * @param cause the cause of the error. * @param element the element to print with the message. * @param message the message. */ public void error(final Throwable cause, final Element element, final String message) { log(Kind.ERROR, element, cause, message); } /** * Prints an error message. * * @param cause the cause of the error. * @param messageFormat the message format. * @param args the format arguments. */ public void error(final Throwable cause, final String messageFormat, final Object... args) { error(null, cause, messageFormat, args); } /** * Prints an error message. * * @param cause the cause of the error. * @param element the element that caused the error. */ public void error(final Element element, final Throwable cause) { log(Kind.ERROR, element, cause, null); } /** * Prints an error message. * * @param cause the cause of the error. * @param messageFormat the message format. * @param element the element that caused the warning. * @param args the format arguments. */ public void error(final Element element, final Throwable cause, final String messageFormat, final Object... args) { log(Kind.ERROR, element, cause, messageFormat, args); } /** * Prints a message that does not fit the other types. * * @param element the element to print with the message. * @param message the message. */ public void other(final Element element, final String message) { log(Kind.OTHER, element, message); } /** * Prints a formatted message that does not fit the other types. * * @param element the element to print with the note. * @param messageFormat the message format. * @param args the format arguments. */ public void other(final Element element, final String messageFormat, final Object... args) { log(Kind.OTHER, element, messageFormat, args); } private void log(final Kind kind, final Element element, final String message) { if (element == null) { messager.printMessage(kind, message); } else { messager.printMessage(kind, message, element); } } private void log(final Kind kind, final Element element, final String messageFormat, final Object... args) { try { String message = ((args == null || args.length == 0) ? messageFormat : String.format(messageFormat, args)); if (element == null) { messager.printMessage(kind, message); } else { messager.printMessage(kind, message, element); } // Fail gracefully } catch (Throwable t) { if (element == null) { messager.printMessage(Kind.ERROR, "Error logging original message: " + messageFormat); } else { messager.printMessage(Kind.ERROR, "Error logging original message: " + messageFormat, element); } } } private void log(final Kind kind, final Element element, final Throwable cause, final String messageFormat, final Object... args) { String stringCause = stackTraceToString(cause); if (messageFormat == null) { log(kind, element, stringCause); } else { String messageWithCause = messageFormat.concat(", cause : %s"); List newArgs = new ArrayList(); newArgs.addAll(Arrays.asList(args)); newArgs.add(stringCause); //Add cause to error message logging log(kind, element, messageWithCause, newArgs.toArray()); } } private void log(final Kind kind, final Element element, final Throwable cause, final String message) { String stringCause = stackTraceToString(cause); if (message == null) { log(kind, element, stringCause); } else { String messageWithCause = message.concat(", cause : %s"); //Add cause to error message logging log(kind, element, messageWithCause); } } /** * Converts a stack trace to string output. * * @param t the stack trace to convert. * * @return a string version of the stack trace. */ public static String stackTraceToString(final Throwable t) { final StringWriter stringWriter = new StringWriter(); final PrintWriter printWriter = new PrintWriter(stringWriter, true); t.printStackTrace(printWriter); printWriter.flush(); stringWriter.flush(); printWriter.close(); try { stringWriter.close(); } catch (IOException e) { // Do nothing } return stringWriter.toString(); } } TranslationClassGenerator.java000066400000000000000000000324271255176001000372030ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import static org.jboss.logging.processor.util.TranslationHelper.getEnclosingTranslationFileName; import static org.jboss.logging.processor.util.TranslationHelper.getTranslationClassNameSuffix; import java.io.File; import java.io.FileInputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.regex.Pattern; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.SupportedOptions; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.tools.FileObject; import javax.tools.StandardLocation; import org.jboss.logging.annotations.Message; import org.jboss.logging.processor.generator.model.ClassModel; import org.jboss.logging.processor.generator.model.ClassModelFactory; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageInterface.AnnotatedType; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.util.ElementHelper; import org.jboss.logging.processor.validation.FormatValidator; import org.jboss.logging.processor.validation.FormatValidatorFactory; import org.jboss.logging.processor.validation.StringFormatValidator; /** * The translation class generator. *

* The aim of this generator is to generate * the classes corresponding to translation * files of a MessageLogger or MessageBundle. *

* * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ @SupportedOptions({ TranslationClassGenerator.TRANSLATION_FILES_PATH_OPTION, TranslationClassGenerator.SKIP_TRANSLATIONS }) final class TranslationClassGenerator extends AbstractGenerator { public static final String TRANSLATION_FILES_PATH_OPTION = "translationFilesPath"; public static final String SKIP_TRANSLATIONS = "skipTranslations"; /** * The properties file pattern. The property file must * match the given pattern org.pkgname.InterfaceName.i18n_locale.properties where locale is : *
    *
  • xx - where xx is the language like (e.g. en)
  • *
  • xx_YY - where xx is the language and YY is the country like (e.g. en_US)
  • *
  • xx_YY_ZZ - where xx is the language, YY is the country and ZZ is the variant like (e.g. en_US_POSIX)
  • *
*/ private static final String TRANSLATION_FILE_EXTENSION_PATTERN = ".i18n_[a-z]*(_[A-Z]*){0,2}\\.properties"; private final String translationFilesPath; private final boolean skipTranslations; /** * Construct an instance of the Translation * Class Generator. * * @param processingEnv the processing environment */ public TranslationClassGenerator(final ProcessingEnvironment processingEnv) { super(processingEnv); Map options = processingEnv.getOptions(); this.translationFilesPath = options.get(TRANSLATION_FILES_PATH_OPTION); final String value = options.get(SKIP_TRANSLATIONS); this.skipTranslations = (options.containsKey(SKIP_TRANSLATIONS) && (value == null ? true : Boolean.valueOf(value))); } @Override public void processTypeElement(final TypeElement annotation, final TypeElement element, final MessageInterface messageInterface) { if (skipTranslations) { logger().debug(element, "Skipping processing of translation implementation"); return; } try { final List files = findTranslationFiles(messageInterface); final Map> validTranslations = allInterfaceTranslations(messageInterface, files); if (files != null) { for (File file : files) { generateSourceFileFor(messageInterface, file, validTranslations.get(file)); } } } catch (IOException e) { logger().error(e, "Cannot read %s package files", messageInterface.packageName()); } } private Map> allInterfaceTranslations(final MessageInterface messageInterface, final List files) throws IOException { final Map> validTranslations = new LinkedHashMap>(); for (MessageInterface superInterface : messageInterface.extendedInterfaces()) { validTranslations.putAll(allInterfaceTranslations(superInterface, findTranslationFiles(superInterface))); } if (files != null) { for (File file : files) { validTranslations.put(file, validateTranslationMessages(messageInterface, file)); } } return validTranslations; } private List findTranslationFiles(final MessageInterface messageInterface) throws IOException { final String packageName = messageInterface.packageName(); final String interfaceName = messageInterface.simpleName(); final String classTranslationFilesPath; //User defined if (translationFilesPath != null) { classTranslationFilesPath = translationFilesPath + packageName.replace('.', File.separatorChar); //By default use the class output folder } else { FileObject fObj = filer().getResource(StandardLocation.CLASS_OUTPUT, packageName, interfaceName); classTranslationFilesPath = fObj.toUri().getPath().replace(interfaceName, ""); } final List result; File[] files = new File(classTranslationFilesPath).listFiles(new TranslationFileFilter(interfaceName)); if (files == null) { result = Collections.emptyList(); } else { result = Arrays.asList(files); Collections.sort(result, new Comparator() { public int compare(final File o1, final File o2) { int result = o1.getAbsolutePath().compareTo(o2.getAbsolutePath()); result = (result != 0 ? result : Integer.signum(o1.getName().length() - o2.getName().length())); return result; } }); } return result; } /** * Returns only the valid translations message corresponding * to the declared {@link org.jboss.logging.processor.model.MessageMethod} methods in the * {@link org.jboss.logging.annotations.MessageBundle} or {@link org.jboss.logging.annotations.MessageLogger} * interface. * * @param messageInterface the message interface. * @param file the translation file * * @return the valid translations messages */ private Map validateTranslationMessages(final MessageInterface messageInterface, final File file) { Map validTranslations = new LinkedHashMap(); try { //Load translations Properties translations = new Properties(); translations.load(new InputStreamReader(new FileInputStream(file), "utf-8")); final Set messageMethods = new LinkedHashSet(); messageMethods.addAll(messageInterface.methods()); for (MessageInterface msgIntf : messageInterface.extendedInterfaces()) { // Handle logger interface if (msgIntf.getAnnotatedType() == AnnotatedType.NONE) { continue; } messageMethods.addAll(msgIntf.methods()); } for (MessageMethod messageMethod : messageMethods) { final String key = messageMethod.translationKey(); final Element methodElement = ElementHelper.fromMessageObject(messageMethod); if (translations.containsKey(key)) { final String translationMessage = translations.getProperty(key); if (!translationMessage.trim().isEmpty()) { final FormatValidator validator = getValidatorFor(messageMethod, translationMessage); if (validator.isValid()) { if (validator.argumentCount() == messageMethod.formatParameterCount()) { validTranslations.put(messageMethod, translationMessage); } else { logger().warn(methodElement, "The parameter count for the format (%d) and the number of format parameters (%d) do not match.", validator.argumentCount(), messageMethod.formatParameterCount()); } } else { logger().warn(methodElement, "%s Resource Bundle: %s", validator.summaryMessage(), file.getAbsolutePath()); } } else { logger().warn(methodElement, "The translation message with key %s is ignored because value is empty or contains only whitespace", key); } } else { logger().warn(methodElement, "The translation message with key %s have no corresponding messageMethod.", key); } } } catch (IOException e) { logger().error(e, "Cannot read the %s translation file", file.getName()); } return validTranslations; } /** * Generate a class for the given translation file. * * @param messageInterface the message interface * @param translationFile the translation file * @param translations the translations message */ private void generateSourceFileFor(final MessageInterface messageInterface, final File translationFile, final Map translations) { //Generate empty translation super class if needed //Check if enclosing translation file exists, if not generate an empty super class final String enclosingTranslationFileName = getEnclosingTranslationFileName(translationFile); final File enclosingTranslationFile = new File(translationFile.getParent(), enclosingTranslationFileName); if (!enclosingTranslationFileName.equals(translationFile.getName()) && !enclosingTranslationFile.exists()) { generateSourceFileFor(messageInterface, enclosingTranslationFile, Collections.emptyMap()); } //Create source file final ClassModel classModel = ClassModelFactory.translation(filer(), messageInterface, getTranslationClassNameSuffix(translationFile.getName()), translations); try { classModel.generateAndWrite(); } catch (IllegalStateException | IOException e) { logger().error(e, "Cannot generate %s source file", classModel.qualifiedClassName()); } } private static FormatValidator getValidatorFor(final MessageMethod messageMethod, final String translationMessage) { FormatValidator result = FormatValidatorFactory.create(messageMethod.message().format(), translationMessage); if (result.isValid()) { if (messageMethod.message().format() == Message.Format.PRINTF) { result = StringFormatValidator.withTranslation(messageMethod.message().value(), translationMessage); } } return result; } /** * Translation file Filter. */ private class TranslationFileFilter implements FilenameFilter { private final String className; /** * The property file filter. * * @param className the class that have i18n property file */ public TranslationFileFilter(final String className) { this.className = className; } @Override public boolean accept(final File dir, final String name) { boolean isGenerated = name.endsWith(TranslationFileGenerator.GENERATED_FILE_EXTENSION); boolean isTranslationFile = name.matches(Pattern.quote(className) + TRANSLATION_FILE_EXTENSION_PATTERN); return !isGenerated && isTranslationFile; } } } TranslationFileGenerator.java000066400000000000000000000350411255176001000370100ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/apt/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.apt; import static org.jboss.logging.processor.util.ElementHelper.getPrimaryClassNamePrefix; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.SupportedOptions; import javax.lang.model.element.TypeElement; import javax.tools.FileObject; import javax.tools.StandardLocation; import org.jboss.logging.annotations.Transform.TransformType; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.model.Parameter; import org.jboss.logging.processor.model.Parameter.ParameterType; import org.jboss.logging.processor.util.Strings; /** * The generator of skeletal * translations files. * * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) * @author James R. Perkins */ @SupportedOptions(TranslationFileGenerator.GENERATED_FILES_PATH_OPTION) final class TranslationFileGenerator extends AbstractGenerator { private static final Map levels = new HashMap(); private static final Pattern PATTERN = Pattern.compile("((@[a-zA-Z_0-9]+)\\s+([a-zA-Z_][a-zA-Z_0-9]*)\\s+([a-zA-Z_][a-zA-Z_0-9].*)\\s*)"); public static final String EMPTY_STRING = ""; public static final String JAVA_DOC_PARAM = "@param"; public static final String GENERATED_FILES_PATH_OPTION = "generatedTranslationFilesPath"; public static final String LEVEL_OPTION = "org.jboss.logging.tools.level"; public static final String GENERATED_FILE_EXTENSION = ".i18n_locale_COUNTRY_VARIANT.properties"; public static final String DEFAULT_FILE_EXTENSION = ".i18n.properties"; private static final String DEFAULT_FILE_COMMENT = "# This file is for reference only, changes have no effect on the generated interface implementations."; static { levels.put("ALL", Integer.MIN_VALUE); levels.put("CONFIG", 700); levels.put("DEBUG", 500); levels.put("ERROR", 1000); levels.put("FATAL", 1100); levels.put("FINE", 500); levels.put("FINER", 400); levels.put("FINEST", 300); levels.put("INFO", 800); levels.put("OFF", Integer.MAX_VALUE); levels.put("SEVERE", 1000); levels.put("TRACE", 400); levels.put("WARN", 900); levels.put("WARNING", 900); } private final String generatedFilesPath; private final LevelComparator comparator; /** * The constructor. * * @param processingEnv the processing env */ public TranslationFileGenerator(final ProcessingEnvironment processingEnv) { super(processingEnv); Map options = processingEnv.getOptions(); this.generatedFilesPath = options.get(GENERATED_FILES_PATH_OPTION); String highLevel = options.get(LEVEL_OPTION); if (highLevel == null) { // Check for a system property highLevel = AccessController.doPrivileged(new PrivilegedAction() { public String run() { return System.getProperty(LEVEL_OPTION); } }); } if (highLevel != null) { if (!levels.containsKey(highLevel)) { logger().error("Invalid property '%s' defined. The value %s is invalid.", LEVEL_OPTION, highLevel); } comparator = new LevelComparator(highLevel); } else { comparator = null; } } @Override public void processTypeElement(final TypeElement annotation, final TypeElement element, final MessageInterface messageInterface) { if (generatedFilesPath != null) { if (element.getKind().isInterface()) { String packageName = elementUtils().getPackageOf(element).getQualifiedName().toString(); String relativePath = packageName.replace('.', File.separatorChar); String fileName = getPrimaryClassNamePrefix(element) + GENERATED_FILE_EXTENSION; this.generateSkeletalTranslationFile(relativePath, fileName, messageInterface); } } // Always generate an Interface.i18n.properties file. generateDefaultTranslationFile(messageInterface); } /** * Generate the translation file containing the given * translations. * * @param relativePath the relative path * @param fileName the file name * @param messageInterface the message interface */ void generateSkeletalTranslationFile(final String relativePath, final String fileName, final MessageInterface messageInterface) { if (messageInterface == null) { throw new IllegalArgumentException("The translations parameter cannot be null"); } File pathFile = new File(generatedFilesPath, relativePath); pathFile.mkdirs(); File file = new File(pathFile, fileName); BufferedWriter writer = null; try { writer = new BufferedWriter(new FileWriter(file)); final Set processed = new HashSet(); for (MessageMethod messageMethod : messageInterface.methods()) { if (isMethodWritable(messageMethod)) { if (processed.add(messageMethod.translationKey())) { writeSkeletonMessageMethod(writer, messageMethod); } } } } catch (IOException e) { logger().error(e, "Cannot write generated skeletal translation file %s", fileName); } finally { try { if (writer != null) { writer.close(); } } catch (IOException e) { logger().error(e, "Cannot close generated skeletal translation file %s", fileName); } } } /** * Generates a default i18n properties file. * * @param messageInterface the message interface */ private void generateDefaultTranslationFile(final MessageInterface messageInterface) { final String fileName = messageInterface.simpleName() + DEFAULT_FILE_EXTENSION; BufferedWriter writer = null; try { if (generatedFilesPath == null) { final FileObject fileObject = filer().createResource(StandardLocation.CLASS_OUTPUT, messageInterface.packageName(), fileName); // Note the FileObject#openWriter() is used here. The FileObject#openOutputStream() returns an output stream // that writes each byte separately which results in poor performance. writer = new BufferedWriter(fileObject.openWriter()); } else { String relativePath = messageInterface.packageName().replace('.', File.separatorChar); final File path = new File(generatedFilesPath, relativePath); path.mkdirs(); final File file = new File(path, fileName); writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8")); } // Write comments writer.write(Strings.fill("#", DEFAULT_FILE_COMMENT.length())); writer.newLine(); writer.write("#"); writer.newLine(); writer.write(DEFAULT_FILE_COMMENT); writer.newLine(); writer.write("#"); writer.newLine(); writer.write(Strings.fill("#", DEFAULT_FILE_COMMENT.length())); writer.newLine(); writer.newLine(); final Set processed = new HashSet(); for (MessageMethod messageMethod : messageInterface.methods()) { if (isMethodWritable(messageMethod)) { if (processed.add(messageMethod.translationKey())) { writeSkeletonMessageMethod(writer, messageMethod); } } } } catch (IOException e) { logger().error(e, "Cannot write generated default translation file %s", fileName); } finally { try { if (writer != null) { writer.close(); } } catch (IOException e) { logger().error(e, "Cannot write generated default translation file %s", fileName); } } } private void writeSkeletonMessageMethod(final BufferedWriter writer, final MessageMethod messageMethod) throws IOException { final MessageMethod.Message msg = messageMethod.message(); writer.write(String.format("# Id: %s", (msg.hasId() ? msg.id() : "none"))); writer.newLine(); if (messageMethod.isLoggerMethod()) { writer.write(String.format("# Level: %s", messageMethod.logLevel())); writer.newLine(); } writer.write(String.format("# Message: %s", msg.value())); writer.newLine(); final Map parameterComments = parseParameterComments(messageMethod); final Set parameters = messageMethod.parameters(ParameterType.FORMAT, ParameterType.TRANSFORM); int i = 0; for (Parameter parameter : parameters) { final String name = parameter.name(); final String comment = (parameterComments.containsKey(name) ? parameterComments.get(name) : EMPTY_STRING); if (parameter.parameterType() == ParameterType.TRANSFORM) { final List transformTypes = Arrays.asList(parameter.transform().value()); if (transformTypes.contains(TransformType.GET_CLASS)) { if (transformTypes.size() == 1) { writer.write(String.format("# @param class of %s - %s", name, comment)); } else if (transformTypes.contains(TransformType.HASH_CODE)) { writer.write(String.format("# @param hashCode of class of %s - %s", name, comment)); } else if (transformTypes.contains(TransformType.IDENTITY_HASH_CODE)) { writer.write(String.format("# @param identityHashCode of class of %s - %s", name, comment)); } } else if (transformTypes.contains(TransformType.HASH_CODE)) { writer.write(String.format("# @param hashCode of %s - %s", name, comment)); } else if (transformTypes.contains(TransformType.IDENTITY_HASH_CODE)) { writer.write(String.format("# @param identityHashCode of %s - %s", name, comment)); } else if (transformTypes.contains(TransformType.SIZE)) { if (parameter.isArray() || parameter.isVarArgs() || parameter.isSubtypeOf(String.class)) { writer.write(String.format("# @param length of %s - %s", name, comment)); } else { writer.write(String.format("# @param size of %s - %s", name, comment)); } } writer.newLine(); } else { writer.write(String.format("# @param %d: %s - %s", ++i, name, comment)); writer.newLine(); } } writer.write(String.format("%s=", messageMethod.translationKey())); writer.write(messageMethod.message().value()); writer.newLine(); } private Map parseParameterComments(final MessageMethod messageMethod) throws IOException { final Map result = new LinkedHashMap(); final String comment = messageMethod.getComment(); if (comment != null) { final Matcher matcher = PATTERN.matcher(comment); while (matcher.find()) { if (matcher.groupCount() > 3) { final String annotation = matcher.group(2); if (annotation != null && annotation.trim().equals(JAVA_DOC_PARAM)) result.put(matcher.group(3), matcher.group(4)); } } } return result; } private boolean isMethodWritable(final MessageMethod method) { return !(comparator != null && method.isLoggerMethod()) || (comparator.compareTo(method.logLevel()) >= 0); } private static final class LevelComparator implements Comparable { private final Integer levelIntValue; private LevelComparator(final String level) { levelIntValue = levels.get(level); if (levelIntValue == null) { throw new IllegalArgumentException(String.format("Level %s is invalid.", level)); } } @Override public int compareTo(final String o) { String cmpLevel = o; // Get the actual level final int lastDot = o.lastIndexOf("."); if (lastDot > -1) { cmpLevel = o.substring(lastDot + 1); } final Integer level = levels.get(cmpLevel); if (level == null) { throw new IllegalArgumentException(String.format("Level %s is invalid.", cmpLevel)); } return level.compareTo(levelIntValue); } } } jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/000077500000000000000000000000001255176001000324565ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/model/000077500000000000000000000000001255176001000335565ustar00rootroot00000000000000ClassModel.java000066400000000000000000000234271255176001000364000ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generator.model; import static org.jboss.jdeparser.JExprs.$v; import static org.jboss.jdeparser.JMod.FINAL; import static org.jboss.jdeparser.JTypes.$t; import static org.jboss.logging.processor.util.ElementHelper.typeToString; import java.io.IOException; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.Properties; import javax.annotation.Generated; import javax.annotation.processing.Filer; import org.jboss.jdeparser.FormatPreferences; import org.jboss.jdeparser.JClassDef; import org.jboss.jdeparser.JDeparser; import org.jboss.jdeparser.JExprs; import org.jboss.jdeparser.JFiler; import org.jboss.jdeparser.JMethodDef; import org.jboss.jdeparser.JMod; import org.jboss.jdeparser.JSourceFile; import org.jboss.jdeparser.JSources; import org.jboss.jdeparser.JType; import org.jboss.jdeparser.JTypes; import org.jboss.jdeparser.JVarDeclaration; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageMethod; /** * The basic java class model. * * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) * @author James R. Perkins */ public abstract class ClassModel { private static final String INSTANCE_FIELD_NAME = "INSTANCE"; private static final String GET_INSTANCE_METHOD_NAME = "readResolve"; private final JSources sources; private final JClassDef classDef; protected final JSourceFile sourceFile; private final MessageInterface messageInterface; private final String className; private final String superClassName; private final String format; private final Map messageMethods; private final Map messageFields; /** * Construct a class model. * * @param filer the filer used to create the source file * @param messageInterface the message interface to implement. * @param superClassName the super class used for the translation implementations. */ ClassModel(final Filer filer, final MessageInterface messageInterface, final String className, final String superClassName) { this.messageInterface = messageInterface; this.className = messageInterface.packageName() + "." + className; this.superClassName = superClassName; sources = JDeparser.createSources(JFiler.newInstance(filer), new FormatPreferences(new Properties())); sourceFile = sources.createSourceFile(messageInterface.packageName(), className); classDef = sourceFile._class(JMod.PUBLIC, className); final int idLen = messageInterface.getIdLength(); if (idLen > 0) { format = "%s%0" + messageInterface.getIdLength() + "d: %s"; } else { format = "%s%d: %s"; } messageMethods = new HashMap<>(); messageFields = new HashMap<>(); } /** * Returns the message interface being used. * * @return the message interface. */ public final MessageInterface messageInterface() { return messageInterface; } /** * Writes the generated source file to the file system. * * @throws java.io.IOException if the file could not be written */ public final void generateAndWrite() throws IOException { generateModel(); sources.writeSources(); JDeparser.dropCaches(); } /** * Generate the code corresponding to this * class model * * @return the generated code * * @throws IllegalStateException if the class has already been defined. */ JClassDef generateModel() throws IllegalStateException { // Add generated annotation final JType generatedType = $t(Generated.class); sourceFile._import(generatedType); classDef.annotate(generatedType) .value("value", getClass().getName()) .value("date", JExprs.str(ClassModelHelper.generatedDateValue())); // Create the default JavaDoc classDef.docComment().text("Warning this class consists of generated code."); // Add extends if (superClassName != null) { classDef._extends(superClassName); } // Always implement the interface // TODO - Temporary fix for implementing nested interfaces. classDef._implements(typeToString(messageInterface.name())); //Add implements if (!messageInterface.extendedInterfaces().isEmpty()) { for (MessageInterface intf : messageInterface.extendedInterfaces()) { // TODO - Temporary fix for implementing nested interfaces. final JType interfaceName = $t(typeToString(intf.name())); sourceFile._import(interfaceName); classDef._implements(interfaceName); } } final JType serializable = $t(Serializable.class); sourceFile._import(serializable); classDef._implements(serializable); classDef.field(JMod.PRIVATE | JMod.STATIC | FINAL, JType.LONG, "serialVersionUID", JExprs.decimal(1L)); return classDef; } /** * Adds a method to return the message value. The method name should be the * method name annotated {@code org.jboss.logging.Message}. This method will * be appended with {@code $str}. *

*

* If the message method has already been defined the previously created * method is returned. *

*

* * @param messageMethod the message method * * @return the newly created method. * * @throws IllegalStateException if this method is called before the generateModel method */ JMethodDef addMessageMethod(final MessageMethod messageMethod) { return addMessageMethod(messageMethod, messageMethod.message().value()); } /** * Adds a method to return the message value. The method name should be the * method name annotated {@code org.jboss.logging.Message}. This method will * be appended with {@code $str}. *

*

* If the message method has already been defined the previously created * method is returned. *

*

* * @param messageMethod the message method. * @param messageValue the message value. * * @return the newly created method. * * @throws IllegalStateException if this method is called before the generateModel method */ JMethodDef addMessageMethod(final MessageMethod messageMethod, final String messageValue) { // Values could be null and we shouldn't create message methods for null values. if (messageValue == null) { return null; } final String methodName; if (messageMethod.isOverloaded()) { methodName = messageMethod.name() + messageMethod.formatParameterCount(); } else { methodName = messageMethod.name(); } // Create the method that returns the string message for formatting JMethodDef method = messageMethods.get(messageMethod.messageMethodName()); if (method == null) { JVarDeclaration field = messageFields.get(methodName); if (field == null) { final String msg; if (messageInterface.projectCode() != null && !messageInterface.projectCode().isEmpty() && messageMethod.message().hasId()) { // Prefix the id to the string message msg = String.format(format, messageInterface.projectCode(), messageMethod.message().id(), messageValue); } else { msg = messageValue; } field = classDef.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, String.class, methodName, JExprs.str(msg)); messageFields.put(field.name(), field); } method = classDef.method(JMod.PROTECTED, String.class, messageMethod.messageMethodName()); method.body()._return($v(field)); messageMethods.put(messageMethod.messageMethodName(), method); } return method; } /** * Get the class name. * * @return the class name */ public final String qualifiedClassName() { return className; } /** * Creates the read resolve method and instance field. * * @return the read resolve method. */ protected JMethodDef createReadResolveMethod() { final JType type = JTypes.typeOf(classDef); final JVarDeclaration instance = classDef.field(JMod.PUBLIC | JMod.STATIC | JMod.FINAL, type, INSTANCE_FIELD_NAME, type._new()); final JMethodDef readResolveMethod = classDef.method(JMod.PROTECTED, Object.class, GET_INSTANCE_METHOD_NAME); readResolveMethod.body()._return($v(instance)); return readResolveMethod; } } ClassModelFactory.java000066400000000000000000000113211255176001000377160ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generator.model; import static org.jboss.logging.processor.generator.model.ClassModelHelper.implementationClassName; import static org.jboss.logging.processor.util.TranslationHelper.getEnclosingTranslationClassName; import java.util.Map; import javax.annotation.processing.Filer; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageMethod; /** * Creates a class model for the message interface. * * @author James R. Perkins */ public class ClassModelFactory { /** * Private constructor for the factory. */ private ClassModelFactory() { } /** * Creates an implementation code model from the message interface. * * @param filer the filer used to create the source file * @param messageInterface the message interface to implement * @param useLogging31 whether or not jboss-logging 3.1 or higher is used * * @return the class model used to implement the interface. * * @throws IllegalArgumentException if {@link org.jboss.logging.processor.model.MessageInterface#getAnnotatedType()} * returns {@link org.jboss.logging.processor.model.MessageInterface.AnnotatedType#NONE} */ public static ClassModel implementation(final Filer filer, final MessageInterface messageInterface, final boolean useLogging31) throws IllegalArgumentException { switch (messageInterface.getAnnotatedType()) { case MESSAGE_BUNDLE: return new MessageBundleImplementor(filer, messageInterface); case MESSAGE_LOGGER: return new MessageLoggerImplementor(filer, messageInterface, useLogging31); } throw new IllegalArgumentException(String.format("Message interface %s is not a valid message logger or message bundle.", messageInterface)); } /** * Creates a class model for created translation implementations of the message interface. *

* Note: The implementation class must exist before the translation implementations can be created. * * @param filer the filer used to create the source file * @param messageInterface the message interface to implement. * @param translationSuffix the translation locale suffix. * @param translations a map of the translations for the methods. * * @return the class model used to create translation implementations of the interface. * * @throws IllegalArgumentException if {@link org.jboss.logging.processor.model.MessageInterface#getAnnotatedType()} * returns {@link org.jboss.logging.processor.model.MessageInterface.AnnotatedType#NONE} */ public static ClassModel translation(final Filer filer, final MessageInterface messageInterface, final String translationSuffix, final Map translations) throws IllegalArgumentException { final String generatedClassName = implementationClassName(messageInterface, translationSuffix); final String superClassName = getEnclosingTranslationClassName(generatedClassName); switch (messageInterface.getAnnotatedType()) { case MESSAGE_BUNDLE: return new MessageBundleTranslator(filer, messageInterface, generatedClassName, superClassName, translations); case MESSAGE_LOGGER: return new MessageLoggerTranslator(filer, messageInterface, generatedClassName, superClassName, translations); } throw new IllegalArgumentException(String.format("Message interface %s is not a valid message logger or message bundle.", messageInterface)); } } ClassModelHelper.java000066400000000000000000000075451255176001000375430ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generator.model; import java.text.SimpleDateFormat; import java.util.Date; import org.jboss.logging.processor.model.MessageInterface; /** * Utilities for the code model. * * @author James R. Perkins */ public final class ClassModelHelper { private static final String STRING_ID_FORMAT2 = "%s%06d: "; /** * Constructor for singleton model. */ private ClassModelHelper() { } /** * Returns the current date formatted in the ISO 8601 format. * * @return the current date formatted in ISO 8601. */ static String generatedDateValue() { final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); return sdf.format(new Date()); } /** * Formats message id. * * @param projectCode the project code for the message * @param messageId the message id to format * * @return the formatted message id */ public static String formatMessageId(final String projectCode, final int padLength, final int messageId) { return String.format(STRING_ID_FORMAT2, projectCode, messageId); } /** * Creates the implementation class name for the message interface. * * @param messageInterface the message interface to generate the implementation name for. * * @return the implementation class name * * @throws IllegalArgumentException if the message interface is not a message bundle or a message logger. */ public static String implementationClassName(final MessageInterface messageInterface) throws IllegalArgumentException { final StringBuilder result = new StringBuilder(messageInterface.simpleName()); switch (messageInterface.getAnnotatedType()) { case MESSAGE_BUNDLE: result.append("_$bundle"); break; case MESSAGE_LOGGER: result.append("_$logger"); break; default: throw new IllegalArgumentException(String.format("Message interface %s is not a message bundle or message logger.", messageInterface)); } return result.toString(); } /** * Creates the implementation class name for the message interface. * * @param messageInterface the message interface to generate the implementation name for. * @param translationSuffix the local suffix for the translation. * * @return the implementation class name * * @throws IllegalArgumentException if the message interface is not a message bundle or a message logger. */ public static String implementationClassName(final MessageInterface messageInterface, final String translationSuffix) throws IllegalArgumentException { return implementationClassName(messageInterface) + translationSuffix; } } ImplementationClassModel.java000066400000000000000000000474011255176001000413040ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generator.model; import static org.jboss.jdeparser.JExpr.NULL; import static org.jboss.jdeparser.JExprs.$v; import static org.jboss.jdeparser.JMod.FINAL; import static org.jboss.jdeparser.JTypes.$t; import static org.jboss.logging.processor.generator.model.ClassModelHelper.implementationClassName; import static org.jboss.logging.processor.model.Parameter.ParameterType; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.processing.Filer; import javax.lang.model.element.Element; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; import org.jboss.jdeparser.JAssignableExpr; import org.jboss.jdeparser.JBlock; import org.jboss.jdeparser.JBlock.Braces; import org.jboss.jdeparser.JCall; import org.jboss.jdeparser.JClassDef; import org.jboss.jdeparser.JExpr; import org.jboss.jdeparser.JExprs; import org.jboss.jdeparser.JIf; import org.jboss.jdeparser.JMethodDef; import org.jboss.jdeparser.JMod; import org.jboss.jdeparser.JParamDeclaration; import org.jboss.jdeparser.JType; import org.jboss.jdeparser.JTypes; import org.jboss.jdeparser.JVarDeclaration; import org.jboss.logging.annotations.Pos; import org.jboss.logging.annotations.Transform; import org.jboss.logging.annotations.Transform.TransformType; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.model.Parameter; import org.jboss.logging.processor.model.ThrowableType; /** * An abstract code model to create the source file that implements the * interface. *

*

* Essentially this uses the org.jboss.jdeparser.JDeparser to generate the * source files with. This class is for convenience in generating default source * files. *

* * @author James R. Perkins */ abstract class ImplementationClassModel extends ClassModel { /** * Class constructor. * * @param filer the filer used to create the source file * @param messageInterface the message interface to implement. */ ImplementationClassModel(final Filer filer, final MessageInterface messageInterface) { super(filer, messageInterface, implementationClassName(messageInterface), null); } /** * Create the bundle method body. * * @param classDef the class definition * @param messageMethod the message method. */ void createBundleMethod(final JClassDef classDef, final MessageMethod messageMethod) { // Add the message messageMethod. addMessageMethod(messageMethod); final JType returnType = $t(messageMethod.returnType().name()); sourceFile._import(returnType); final JMethodDef method = classDef.method(JMod.PUBLIC | FINAL, returnType, messageMethod.name()); method.annotate(Override.class); addThrownTypes(messageMethod, method); // Create the body of the method and add the text final JBlock body = method.body(); final MessageMethod.Message message = messageMethod.message(); final JCall formatterCall; final boolean noFormatParameters = messageMethod.parameters(ParameterType.FORMAT).isEmpty(); switch (message.format()) { case MESSAGE_FORMAT: { if (noFormatParameters) { formatterCall = JExprs.call(messageMethod.messageMethodName()); } else { final JType formatter = $t(MessageFormat.class); formatterCall = formatter.call("format"); formatterCall.arg(JExprs.call(messageMethod.messageMethodName())); } break; } case PRINTF: { final JType formatter = $t(String.class); formatterCall = formatter.call("format").arg(JExprs.call(messageMethod.messageMethodName())); break; } default: formatterCall = JExprs.call(messageMethod.messageMethodName()); break; } // Create maps for the fields and properties. Key is the field or setter method, value is the parameter to set // the value to. final Set allParameters = messageMethod.parameters(ParameterType.ANY); final Map fields = new LinkedHashMap<>(); final Map properties = new LinkedHashMap<>(); // First load the parameter names final List parameterNames = new ArrayList<>(allParameters.size()); for (Parameter param : allParameters) { parameterNames.add(param.name()); } final List args = new ArrayList<>(); // Create the parameters for (Parameter param : allParameters) { final JParamDeclaration var = addMethodParameter(method, param); final String formatterClass = param.formatterClass(); switch (param.parameterType()) { case FORMAT: { if (formatterCall == null) { // This should never happen, but let's safe guard against it throw new IllegalStateException("No format parameters are allowed when NO_FORMAT is specified."); } else { if (formatterClass == null) { if (param.isArray() || param.isVarArgs()) { final JType arrays = $t(Arrays.class); sourceFile._import(arrays); args.add(arrays.call("toString").arg($v(var))); } else { args.add($v(var)); } } else { args.add($t(formatterClass)._new().arg($v(var))); } } break; } case TRANSFORM: { if (formatterCall == null) { // This should never happen, but let's safe guard against it throw new IllegalStateException("No format parameters are allowed when NO_FORMAT is specified."); } else { final JAssignableExpr transformVar = createTransformVar(parameterNames, body, param, $v(var)); if (formatterClass == null) { args.add(transformVar); } else { args.add($t(formatterClass)._new().arg(transformVar)); } } break; } case POS: { if (formatterCall == null) { // This should never happen, but let's safe guard against it throw new IllegalStateException("No format parameters are allowed when NO_FORMAT is specified."); } else { final Pos pos = param.pos(); final int[] positions = pos.value(); final Transform[] transform = pos.transform(); for (int i = 0; i < positions.length; i++) { final int index = positions[i] - 1; if (transform != null && transform.length > 0) { final JAssignableExpr tVar = createTransformVar(parameterNames, method.body(), param, transform[i], $v(var)); if (index < args.size()) { args.add(index, tVar); } else { args.add(tVar); } } else { if (index < args.size()) { args.add(index, $v(var)); } else { args.add($v(var)); } } } } break; } case FIELD: { fields.put(param.targetName(), var); break; } case PROPERTY: { properties.put(param.targetName(), var); break; } } } // If a format method, add the arguments for (JExpr arg : args) { formatterCall.arg(arg); } // Setup the return type final JExpr result; if (messageMethod.returnType().isThrowable()) { result = $v(createReturnType(messageMethod, body, formatterCall)); } else { result = formatterCall; } // Set the fields and properties of the return type for (Map.Entry entry : fields.entrySet()) { body.assign(result.field(entry.getKey()), $v(entry.getValue())); } for (Map.Entry entry : properties.entrySet()) { body.add(result.call(entry.getKey()).arg($v(entry.getValue()))); } body._return(result); } JAssignableExpr createTransformVar(final List parameterNames, final JBlock methodBody, final Parameter param, final JExpr var) { return createTransformVar(parameterNames, methodBody, param, param.transform(), var); } JAssignableExpr createTransformVar(final List parameterNames, final JBlock methodBody, final Parameter param, final Transform transform, final JExpr var) { final List transformTypes = Arrays.asList(transform.value()); // GET_CLASS should always be processed first final JAssignableExpr result; if (transformTypes.contains(TransformType.GET_CLASS)) { // Determine the result field type if (transformTypes.size() == 1) { // Get the parameter name final String paramName = getUniqueName(parameterNames, param, "Class"); parameterNames.add(paramName); result = $v(methodBody.var(FINAL, $t(Class.class).typeArg(JType.WILDCARD), paramName)); final JIf stmt = methodBody._if(var.eq(NULL)); stmt.block(Braces.REQUIRED).assign(result, NULL); stmt._else().assign(result, var.call("getClass")); } else { // Get the parameter name final String paramName = getUniqueName(parameterNames, param, "HashCode"); parameterNames.add(paramName); result = $v(methodBody.var(FINAL, JType.INT, paramName)); final JIf stmt = methodBody._if(var.eq(NULL)); stmt.assign(result, JExpr.ZERO); if (transformTypes.contains(TransformType.HASH_CODE)) { stmt._else().assign(result, var.call("getClass").call("hashCode")); } else if (transformTypes.contains(TransformType.IDENTITY_HASH_CODE)) { stmt._else().assign(result, $t(System.class).call("identityHashCode").arg(var.call("getClass"))); } else { throw new IllegalStateException(String.format("Invalid transform type combination: %s", transformTypes)); } } } else if (transformTypes.contains(TransformType.HASH_CODE)) { // Get the parameter name final String paramName = getUniqueName(parameterNames, param, "HashCode"); parameterNames.add(paramName); result = $v(methodBody.var(FINAL, JType.INT, paramName)); final JIf stmt = methodBody._if(var.eq(NULL)); stmt.assign(result, JExpr.ZERO); if (param.isArray() || param.isVarArgs()) { final JType arrays = $t(Arrays.class); sourceFile._import(arrays); stmt._else().assign(result, arrays.call("hashCode").arg(var)); } else { stmt._else().assign(result, var.call("hashCode")); } } else if (transformTypes.contains(TransformType.IDENTITY_HASH_CODE)) { // Get the parameter name final String paramName = getUniqueName(parameterNames, param, "HashCode"); parameterNames.add(paramName); result = $v(methodBody.var(FINAL, JType.INT, paramName)); final JIf stmt = methodBody._if(var.eq(NULL)); stmt.assign(result, JExpr.ZERO); stmt._else().assign(result, $t(System.class).call("identityHashCode").arg(var)); } else if (transformTypes.contains(TransformType.SIZE)) { // Get the parameter name final String paramName = getUniqueName(parameterNames, param, "Size"); parameterNames.add(paramName); result = $v(methodBody.var(FINAL, JType.INT, paramName)); final JIf stmt = methodBody._if(var.eq(NULL)); stmt.assign(result, JExpr.ZERO); if (param.isArray() || param.isVarArgs()) { stmt._else().assign(result, var.field("length")); } else if (param.isSubtypeOf(Map.class) || param.isSubtypeOf(Collection.class)) { stmt._else().assign(result, var.call("size")); } else if (param.isSubtypeOf(CharSequence.class)) { stmt._else().assign(result, var.call("length")); } else { throw new IllegalStateException(String.format("Invalid type for %s. Must be an array, %s, %s or %s.", TransformType.SIZE, Collection.class.getName(), Map.class.getName(), CharSequence.class.getName())); } } else { throw new IllegalStateException(String.format("Invalid transform type: %s", transformTypes)); } return result; } private String getUniqueName(final List parameterNames, final Parameter parameter, final String suffix) { String result = (suffix == null ? parameter.name() : parameter.name().concat(suffix)); if (parameterNames.contains(result)) { return getUniqueName(parameterNames, new StringBuilder(result), 0); } return result; } private String getUniqueName(final List parameterNames, final StringBuilder sb, final int index) { String result = sb.append(index).toString(); if (parameterNames.contains(result)) { return getUniqueName(parameterNames, sb, index + 1); } return result; } private JVarDeclaration createReturnType(final MessageMethod messageMethod, final JBlock body, final JCall format) { boolean callInitCause = false; final ThrowableType returnType = messageMethod.returnType().throwableReturnType(); final JType type = $t(returnType.name()); // Import once more as the throwable return type may be different than the actual return type sourceFile._import(type); final JCall result = type._new(); final JVarDeclaration resultField = body.var(FINAL, type, "result", result); if (returnType.useConstructionParameters()) { for (Parameter param : returnType.constructionParameters()) { switch (param.parameterType()) { case MESSAGE: result.arg(format); break; default: result.arg($v(param.name())); break; } } } else if (returnType.hasStringAndThrowableConstructor() && messageMethod.hasCause()) { result.arg(format).arg($v(messageMethod.cause().name())); } else if (returnType.hasThrowableAndStringConstructor() && messageMethod.hasCause()) { result.arg($v(messageMethod.cause().name())).arg(format); } else if (returnType.hasStringConstructor()) { result.arg(format); if (messageMethod.hasCause()) { callInitCause = true; } } else if (returnType.hasThrowableConstructor() && messageMethod.hasCause()) { result.arg($v(messageMethod.cause().name())); } else if (returnType.hasStringAndThrowableConstructor() && !messageMethod.hasCause()) { result.arg(format).arg(NULL); } else if (returnType.hasThrowableAndStringConstructor() && !messageMethod.hasCause()) { result.arg(NULL).arg(format); } else if (messageMethod.hasCause()) { callInitCause = true; } // Assign the result field the result value if (callInitCause) { body.add($v(resultField).call("initCause").arg($v(messageMethod.cause().name()))); } // Remove this caller from the stack trace final JType arrays = $t(Arrays.class); sourceFile._import(arrays); final JVarDeclaration st = body.var(FINAL, $t(StackTraceElement.class).array(), "st", $v(resultField).call("getStackTrace")); body.add($v(resultField).call("setStackTrace").arg(arrays.call("copyOfRange").arg($v(st)).arg(JExpr.ONE).arg($v(st).field("length")))); return resultField; } protected final void addThrownTypes(final MessageMethod messageMethod, final JMethodDef jMethod) { for (ThrowableType thrownType : messageMethod.thrownTypes()) { jMethod._throws(thrownType.name()); } } /** * Adds the parameter to the method returning the reference to the parameter. * * @param method the method to add the parameter to * @param param the parameter to add * * @return the reference to the parameter on the method */ protected JParamDeclaration addMethodParameter(final JMethodDef method, final Parameter param) { final JParamDeclaration var; JType paramType = $t(param.type()); if (!param.isPrimitive()) { sourceFile._import(paramType); } if (param.isVarArgs()) { var = method.varargParam(FINAL, paramType, param.name()); } else if (param.isArray()) { var = method.param(JMod.FINAL, paramType.array(), param.name()); } else { final TypeMirror t = ((Element) param.reference()).asType(); if (t instanceof DeclaredType) { final Collection genericTypes = ((DeclaredType) t).getTypeArguments(); for (TypeMirror tm : genericTypes) { final JType gt = JTypes.typeOf(tm); sourceFile._import(gt); paramType = paramType.typeArg(gt); } } var = method.param(FINAL, paramType, param.name()); } return var; } } MessageBundleImplementor.java000066400000000000000000000060331255176001000412760ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generator.model; import java.util.LinkedHashSet; import java.util.Set; import javax.annotation.processing.Filer; import org.jboss.jdeparser.JClassDef; import org.jboss.jdeparser.JMod; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageInterface.AnnotatedType; import org.jboss.logging.processor.model.MessageMethod; /** * Used to generate a message bundle implementation. *

* Creates an implementation of the interface passed in. *

* * @author James R. Perkins * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ class MessageBundleImplementor extends ImplementationClassModel { /** * Creates a new message bundle code model. * * @param filer the filer used to create the source file * @param messageInterface the message interface to implement. */ public MessageBundleImplementor(final Filer filer, final MessageInterface messageInterface) { super(filer, messageInterface); } @Override protected JClassDef generateModel() throws IllegalStateException { final JClassDef classDef = super.generateModel(); // Add default constructor classDef.constructor(JMod.PROTECTED); createReadResolveMethod(); final Set messageMethods = new LinkedHashSet(); messageMethods.addAll(messageInterface().methods()); for (MessageInterface messageInterface : messageInterface().extendedInterfaces()) { // Handle logger interface if (messageInterface.getAnnotatedType() == AnnotatedType.NONE) { continue; } messageMethods.addAll(messageInterface.methods()); } // Process the method descriptors and add to the model before // writing. for (MessageMethod messageMethod : messageMethods) { createBundleMethod(classDef, messageMethod); } return classDef; } } MessageBundleTranslator.java000066400000000000000000000064311255176001000411360ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generator.model; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import javax.annotation.processing.Filer; import org.jboss.jdeparser.JClassDef; import org.jboss.jdeparser.JMethodDef; import org.jboss.jdeparser.JMod; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageMethod; /** * The java message bundle class model. * * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ class MessageBundleTranslator extends ClassModel { /** * The translation map. */ private final Map translations; /** * Create a MessageBundle with super class and interface. * * @param filer the filer used to create the source file * @param messageInterface the message interface to implement. * @param className the implementation class name. * @param superClassName the super class name * @param translations the translation map. */ public MessageBundleTranslator(final Filer filer, final MessageInterface messageInterface, final String className, final String superClassName, final Map translations) { super(filer, messageInterface, className, superClassName); if (translations != null) { this.translations = translations; } else { this.translations = Collections.emptyMap(); } } @Override public JClassDef generateModel() throws IllegalStateException { JClassDef classDef = super.generateModel(); JMethodDef constructor = classDef.constructor(JMod.PROTECTED); constructor.body().callSuper(); JMethodDef readResolve = createReadResolveMethod(); readResolve.annotate(Override.class); final Set> entries = translations.entrySet(); final Set methodNames = new LinkedHashSet<>(); for (Map.Entry entry : entries) { JMethodDef method = addMessageMethod(entry.getKey(), entry.getValue()); if (methodNames.add(method)) { method.annotate(Override.class); } } return classDef; } } MessageLoggerImplementor.java000066400000000000000000000636701255176001000413160ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generator.model; import static org.jboss.jdeparser.JExpr.NULL; import static org.jboss.jdeparser.JExpr.THIS; import static org.jboss.jdeparser.JExprs.$v; import static org.jboss.jdeparser.JTypes.$t; import static org.jboss.logging.processor.model.Parameter.ParameterType; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.processing.Filer; import org.jboss.jdeparser.JAssignableExpr; import org.jboss.jdeparser.JBlock; import org.jboss.jdeparser.JBlock.Braces; import org.jboss.jdeparser.JCall; import org.jboss.jdeparser.JClassDef; import org.jboss.jdeparser.JExpr; import org.jboss.jdeparser.JExprs; import org.jboss.jdeparser.JMethodDef; import org.jboss.jdeparser.JMod; import org.jboss.jdeparser.JParamDeclaration; import org.jboss.jdeparser.JType; import org.jboss.jdeparser.JVarDeclaration; import org.jboss.logging.DelegatingBasicLogger; import org.jboss.logging.Logger; import org.jboss.logging.Logger.Level; import org.jboss.logging.annotations.Message.Format; import org.jboss.logging.annotations.Once; import org.jboss.logging.annotations.Pos; import org.jboss.logging.annotations.Transform; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageInterface.AnnotatedType; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.model.Parameter; import org.jboss.logging.processor.util.ElementHelper; /** * Used to generate a message logger implementation. *

* Creates an implementation of the interface passed in. *

* * @author James R. Perkins * @author David M. Lloyd */ final class MessageLoggerImplementor extends ImplementationClassModel { private static final String LOG_FIELD_NAME = "log"; private static final String FQCN_FIELD_NAME = "FQCN"; private final boolean useLogging31; private final Map logOnceVars = new HashMap<>(); /** * Creates a new message logger code model. * * @param filer the filer used to create the source file * @param messageInterface the message interface to implement. * @param useLogging31 {@code true} to use logging 3.1, {@code false} to remain compatible with 3.0 */ public MessageLoggerImplementor(final Filer filer, final MessageInterface messageInterface, final boolean useLogging31) { super(filer, messageInterface); this.useLogging31 = useLogging31; } /** * Determine whether to use JBoss Logging 3.1 constructs. Defaults to {@code true}. * * @return {@code true} to use JBoss Logging 3.1 constructs, {@code false} to remain compatible with 3.0 */ public boolean isUseLogging31() { return useLogging31; } @Override protected JClassDef generateModel() throws IllegalStateException { final JClassDef classDef = super.generateModel(); // Add FQCN final JVarDeclaration fqcn; if (messageInterface().loggingFQCN() == null) { fqcn = classDef.field(JMod.PRIVATE | JMod.FINAL | JMod.STATIC, String.class, FQCN_FIELD_NAME, $t(classDef)._class().call("getName")); } else { fqcn = classDef.field(JMod.PRIVATE | JMod.FINAL | JMod.STATIC, String.class, FQCN_FIELD_NAME, $t(messageInterface().loggingFQCN())._class().call("getName")); } // Add default constructor final JMethodDef constructor = classDef.constructor(JMod.PUBLIC); final JType loggerType = $t(Logger.class); // Import the logger type and the level type sourceFile._import(loggerType); sourceFile._import(Logger.Level.class); final JParamDeclaration constructorParam = constructor.param(JMod.FINAL, loggerType, LOG_FIELD_NAME); final JBlock constructorBody = constructor.body(); final JAssignableExpr logger; if (messageInterface().extendsLoggerInterface()) { if (useLogging31) { sourceFile._import(DelegatingBasicLogger.class); classDef._extends(DelegatingBasicLogger.class); constructorBody.callSuper().arg($v(constructorParam)); logger = $v("super").field("log"); } else { JVarDeclaration logVar = classDef.field(JMod.PROTECTED | JMod.FINAL, loggerType, LOG_FIELD_NAME); constructorBody.assign(THIS.field(logVar.name()), $v(constructorParam)); logger = $v(logVar); generateDelegatingLoggerMethods(classDef, logger, fqcn); } } else { JVarDeclaration logVar = classDef.field(JMod.PROTECTED | JMod.FINAL, loggerType, LOG_FIELD_NAME); constructorBody.assign(THIS.field(logVar.name()), $v(constructorParam)); logger = $v(logVar); } // Process the method descriptors and add to the model before writing. final Set messageMethods = new LinkedHashSet(); messageMethods.addAll(messageInterface().methods()); for (MessageInterface messageInterface : messageInterface().extendedInterfaces()) { // Handle logger interface if (messageInterface.getAnnotatedType() == AnnotatedType.NONE) { continue; } messageMethods.addAll(messageInterface.methods()); } for (MessageMethod messageMethod : messageMethods) { // Create the messageMethod body if (messageMethod.isLoggerMethod()) { createLoggerMethod(messageMethod, classDef, logger); } else { createBundleMethod(classDef, messageMethod); } } return classDef; } private void generateDelegatingLoggerMethods(final JClassDef classDef, final JAssignableExpr logVar, JVarDeclaration fqcn) { final JType logLevelClass = $t(Logger.Level.class); // Generate these methods so they look the same as they appear in DelegatedBasicLogger. for (String level : Arrays.asList("TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL")) { // string prep String firstUppered = level.charAt(0) + level.substring(1).toLowerCase(Locale.US); String lowered = level.toLowerCase(Locale.US); if ("TRACE".equals(level) || "DEBUG".equals(level) || "INFO".equals(level)) { // isXxxEnabled... final String isXxxEnabledStr = "is" + firstUppered + "Enabled"; final JMethodDef isXxxEnabled = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.BOOLEAN, isXxxEnabledStr); isXxxEnabled.annotate(Override.class); isXxxEnabled.body()._return(logVar.call(isXxxEnabledStr)); } // now, the four "raw" level-specific methods final JMethodDef xxx1 = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, lowered); xxx1.annotate(Override.class); final JParamDeclaration xxx1message = xxx1.param(Object.class, "message"); xxx1.body().add( logVar.call(lowered).arg($v(fqcn)) .arg($v(xxx1message)) .arg(NULL) ); final JMethodDef xxx2 = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, lowered); xxx2.annotate(Override.class); final JParamDeclaration xxx2message = xxx2.param(Object.class, "message"); final JParamDeclaration xxx2t = xxx2.param(Throwable.class, "t"); xxx2.body().add( logVar.call(lowered).arg($v(fqcn)) .arg($v(xxx2message)) .arg($v(xxx2t)) ); final JMethodDef xxx3 = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, lowered); xxx3.annotate(Override.class); final JParamDeclaration xxx3loggerFqcn = xxx3.param(String.class, "loggerFqcn"); final JParamDeclaration xxx3message = xxx3.param(Object.class, "message"); final JParamDeclaration xxx3t = xxx3.param(Throwable.class, "t"); xxx3.body().add( logVar.call(lowered) .arg($v(xxx3loggerFqcn)) .arg($v(xxx3message)) .arg($v(xxx3t)) ); final JMethodDef xxx4 = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, lowered); xxx4.annotate(Override.class); final JParamDeclaration xxx4loggerFqcn = xxx4.param(String.class, "loggerFqcn"); final JParamDeclaration xxx4message = xxx4.param(Object.class, "message"); final JParamDeclaration xxx4params = xxx4.param($t(Object.class).array(), "params"); final JParamDeclaration xxx4t = xxx4.param(Throwable.class, "t"); xxx4.body().add( logVar.call(lowered) .arg($v(xxx4loggerFqcn)) .arg($v(xxx4message)) .arg($v(xxx4params)) .arg($v(xxx4t)) ); // 8 methods each for v and f for (String affix : Arrays.asList("v", "f")) { final String name = lowered + affix; final String target = "log" + affix; // 4 methods each for with- and without-throwable for (boolean renderThr : new boolean[] {false, true}) { JParamDeclaration thr = null; final JMethodDef xxx1x = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, name); xxx1x.annotate(Override.class); if (renderThr) thr = xxx1x.param(Throwable.class, "t"); final JParamDeclaration xxx1xFormat = xxx1x.param(String.class, "format"); final JParamDeclaration xxx1xParams = xxx1x.varargParam(Object.class, "params"); xxx1x.body().add( logVar.call(target) .arg($v(fqcn)) .arg(logLevelClass.$v(level)) .arg(renderThr ? $v(thr) : NULL) .arg($v(xxx1xFormat)) .arg($v(xxx1xParams)) ); // 3 methods for 3 parameter counts for (int i = 1; i <= 3; i++) { final JMethodDef xxx2x = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, name); xxx2x.annotate(Override.class); if (renderThr) thr = xxx2x.param(Throwable.class, "t"); final JParamDeclaration xxx2xFormat = xxx2x.param(String.class, "format"); final JParamDeclaration[] params = new JParamDeclaration[i]; for (int j = 0; j < i; j++) { params[j] = xxx2x.param(Object.class, "param" + (j + 1)); } final JCall xxx2xCaller = logVar.call(target); xxx2xCaller.arg($v(fqcn)) .arg(logLevelClass.$v(level)) .arg(renderThr ? $v(thr) : NULL) .arg($v(xxx2xFormat)); for (int j = 0; j < i; j++) { xxx2xCaller.arg($v(params[j])); } xxx2x.body().add(xxx2xCaller); } } } } // Now the plain "log" methods which take a level // isEnabled... final JMethodDef isEnabled = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.BOOLEAN, "isEnabled"); isEnabled.annotate(Override.class); final JParamDeclaration isEnabledLevel = isEnabled.param(logLevelClass, "level"); isEnabled.body()._return( logVar.call("isEnabled") .arg($v(isEnabledLevel)) ); // now, the four "raw" log methods final JMethodDef log1 = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, "log"); log1.annotate(Override.class); final JParamDeclaration log1Level = log1.param(logLevelClass, "level"); final JParamDeclaration log1Message = log1.param(Object.class, "message"); log1.body().add( logVar.call("log") .arg($v(fqcn)) .arg($v(log1Level)) .arg($v(log1Message)) .arg(NULL) .arg(NULL) ); final JMethodDef log2 = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, "log"); log2.annotate(Override.class); final JParamDeclaration log2Level = log2.param(logLevelClass, "level"); final JParamDeclaration log2message = log2.param(Object.class, "message"); final JParamDeclaration log2t = log2.param(Throwable.class, "t"); log2.body().add( logVar.call("log") .arg($v(fqcn)) .arg($v(log2Level)) .arg($v(log2message)) .arg(NULL) .arg($v(log2t)) ); final JMethodDef log3 = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, "log"); log3.annotate(Override.class); final JParamDeclaration log3Level = log3.param(logLevelClass, "level"); final JParamDeclaration log3loggerFqcn = log3.param(String.class, "loggerFqcn"); final JParamDeclaration log3message = log3.param(Object.class, "message"); final JParamDeclaration log3t = log3.param(Throwable.class, "t"); log3.body().add( logVar.call("log") .arg($v(log3Level)) .arg($v(log3loggerFqcn)) .arg($v(log3message)) .arg($v(log3t)) ); final JMethodDef log4 = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, "log"); log4.annotate(Override.class); final JParamDeclaration log4loggerFqcn = log4.param(String.class, "loggerFqcn"); final JParamDeclaration log4Level = log4.param(logLevelClass, "level"); final JParamDeclaration log4message = log4.param(Object.class, "message"); final JParamDeclaration log4params = log4.param($t(Object.class).array(), "params"); final JParamDeclaration log4t = log4.param(Throwable.class, "t"); log4.body().add( logVar.call("log") .arg($v(log4loggerFqcn)) .arg($v(log4Level)) .arg($v(log4message)) .arg($v(log4params)) .arg($v(log4t)) ); // 12 methods each for v and f for (String affix : Arrays.asList("v", "f")) { final String name = "log" + affix; // 4 methods each for with- and without-throwable and fqcn for (RenderLog render : RenderLog.values()) { JParamDeclaration logFqcn = null; JParamDeclaration thr = null; final boolean renderThr = render.isThr(); final boolean renderFqcn = render.isFqcn(); final JMethodDef log1x = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, name); log1x.annotate(Override.class); if (renderFqcn) logFqcn = log1x.param(String.class, "loggerFqcn"); final JParamDeclaration log1xLevel = log1x.param(logLevelClass, "level"); if (renderThr) thr = log1x.param(Throwable.class, "t"); final JParamDeclaration log1xFormat = log1x.param(String.class, "format"); final JParamDeclaration log1xParams = log1x.varargParam(Object.class, "params"); log1x.body().add( logVar.call(name) .arg(renderFqcn ? $v(logFqcn) : $v(fqcn)) .arg($v(log1xLevel)) .arg(renderThr ? $v(thr) : NULL) .arg($v(log1xFormat)) .arg($v(log1xParams)) ); // 3 methods for 3 parameter counts for (int i = 1; i <= 3; i++) { final JMethodDef log2x = classDef.method(JMod.PUBLIC | JMod.FINAL, JType.VOID, name); log2x.annotate(Override.class); if (renderFqcn) logFqcn = log2x.param(String.class, "loggerFqcn"); final JParamDeclaration log2xLevel = log2x.param(logLevelClass, "level"); if (renderThr) thr = log2x.param(Throwable.class, "t"); final JParamDeclaration log2xFormat = log2x.param(String.class, "format"); final JParamDeclaration[] params = new JParamDeclaration[i]; for (int j = 0; j < i; j++) { params[j] = log2x.param(Object.class, "param" + (j + 1)); } final JCall log2xCaller = logVar.call(name); log2xCaller.arg(renderFqcn ? $v(logFqcn) : $v(fqcn)) .arg($v(log2xLevel)) .arg(renderThr ? $v(thr) : NULL) .arg($v(log2xFormat)); for (int j = 0; j < i; j++) { log2xCaller.arg($v(params[j])); } log2x.body().add(log2xCaller); } } } } /** * Create the logger method body. * * @param messageMethod the message method. * @param classDef the class definition used to create the method on * @param logger the logger to use. */ private void createLoggerMethod(final MessageMethod messageMethod, final JClassDef classDef, final JAssignableExpr logger) { final String msgMethodName = messageMethod.messageMethodName(); final JMethodDef method = classDef.method(JMod.PUBLIC | JMod.FINAL, messageMethod.returnType().name(), messageMethod.name()); method.annotate(Override.class); addMessageMethod(messageMethod); addThrownTypes(messageMethod, method); // Initialize the method parameters final Map params = createParameters(messageMethod, method); // First load the parameter names final List parameterNames = new ArrayList<>(params.size()); for (Parameter param : params.keySet()) { parameterNames.add(param.name()); } // Check for the @Once annotation final JBlock body; if (ElementHelper.isAnnotatedWith(messageMethod.reference(), Once.class) && messageMethod.isLoggerMethod()) { final JType atomicBoolean = $t(AtomicBoolean.class); sourceFile._import(atomicBoolean); // The variable will be shared with overloaded methods final String varName = messageMethod.name() + "_$Once"; final JVarDeclaration var; if (logOnceVars.containsKey(varName)) { var = logOnceVars.get(varName); } else { var = classDef.field(JMod.PRIVATE | JMod.STATIC | JMod.FINAL, atomicBoolean, varName, atomicBoolean._new().arg(JExpr.FALSE)); logOnceVars.put(varName, var); } body = method.body()._if( logger.call("isEnabled").arg($v(messageMethod.logLevel())).and( $v(var).call("compareAndSet").arg(JExpr.FALSE).arg(JExpr.TRUE))) .block(Braces.REQUIRED); } else if (!messageMethod.parameters(ParameterType.TRANSFORM).isEmpty()) { body = method.body()._if(logger.call("isEnabled").arg($v(messageMethod.logLevel()))).block(Braces.REQUIRED); } else { body = method.body(); } // Determine which logger method to invoke final JCall logCaller = logger.call(messageMethod.loggerMethod()); if (messageMethod.parameters(ParameterType.FQCN).isEmpty()) { logCaller.arg($v(FQCN_FIELD_NAME)); } else { logCaller.arg($v(params.get(messageMethod.parameters(ParameterType.FQCN).iterator().next())).call("getName")); } logCaller.arg($v(messageMethod.logLevel())); final MessageMethod.Message message = messageMethod.message(); // No format log messages need the message before the cause if (message.format() == Format.NO_FORMAT) { logCaller.arg(JExprs.call(msgMethodName)); // Next for no format should always be null logCaller.arg(NULL); // The cause is the final argument if (messageMethod.hasCause()) { logCaller.arg($v(messageMethod.cause().name())); } else { logCaller.arg(NULL); } } else { if (messageMethod.hasCause()) { logCaller.arg($v(messageMethod.cause().name())); } else { logCaller.arg(NULL); } // The next parameter is the message. Should be accessed via the // message retrieval method. logCaller.arg(JExprs.call(msgMethodName)); final List args = new ArrayList<>(); // Create the parameters for (Map.Entry entry : params.entrySet()) { final Parameter param = entry.getKey(); final String formatterClass = param.formatterClass(); final JParamDeclaration var = entry.getValue(); switch (param.parameterType()) { case FORMAT: if (formatterClass == null) { if (param.isArray() || param.isVarArgs()) { args.add($t(Arrays.class).call("toString").arg($v(var))); } else { args.add($v(var)); } } else { args.add($t(formatterClass)._new().arg($v(var))); } break; case TRANSFORM: final JAssignableExpr transformVar = createTransformVar(parameterNames, body, param, $v(var)); if (formatterClass == null) { args.add(transformVar); } else { args.add($t(formatterClass)._new().arg(transformVar)); } break; case POS: final Pos pos = param.pos(); final int[] positions = pos.value(); final Transform[] transform = pos.transform(); for (int i = 0; i < positions.length; i++) { final int index = positions[i] - 1; if (transform != null && transform.length > 0) { final JAssignableExpr tVar = createTransformVar(parameterNames, body, param, transform[i], $v(var)); if (index < args.size()) { args.add(index, tVar); } else { args.add(tVar); } } else { if (index < args.size()) { args.add(index, $v(var)); } else { args.add($v(var)); } } } break; } } for (JExpr arg : args) { logCaller.arg(arg); } } body.add(logCaller); } private Map createParameters(final MessageMethod messageMethod, final JMethodDef method) { final Map result = new LinkedHashMap<>(); // Create the parameters for (Parameter param : messageMethod.parameters(ParameterType.ANY)) { final JParamDeclaration var = addMethodParameter(method, param); result.put(param, var); } return result; } enum RenderLog { NONE(false, false), CAUSE(true, false), FQCN(true, true),; private final boolean thr; private final boolean fqcn; private RenderLog(boolean thr, boolean fqcn) { this.thr = thr; this.fqcn = fqcn; } public boolean isThr() { return thr; } public boolean isFqcn() { return fqcn; } } } MessageLoggerTranslator.java000066400000000000000000000071041255176001000411420ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/generator/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generator.model; import static org.jboss.jdeparser.JExprs.$v; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import javax.annotation.processing.Filer; import org.jboss.jdeparser.JBlock; import org.jboss.jdeparser.JClassDef; import org.jboss.jdeparser.JMethodDef; import org.jboss.jdeparser.JMod; import org.jboss.logging.Logger; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageMethod; /** * The java message logger translation class model. * * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ class MessageLoggerTranslator extends ClassModel { /** * The logger parameter name. */ private static final String LOGGER_PARAMETER_NAME = "logger"; /** * The translation map. */ private final Map translations; /** * Create a MessageLogger with super class and interface. * * @param filer the filer used to create the source file * @param messageInterface the message interface to implement. * @param className the implementation class name. * @param superClassName the super class name * @param translations the translation map. */ public MessageLoggerTranslator(final Filer filer, final MessageInterface messageInterface, final String className, final String superClassName, final Map translations) { super(filer, messageInterface, className, superClassName); if (translations != null) { this.translations = translations; } else { this.translations = Collections.emptyMap(); } } @Override public JClassDef generateModel() throws IllegalStateException { JClassDef classDef = super.generateModel(); JMethodDef constructor = classDef.constructor(JMod.PUBLIC); constructor.param(JMod.FINAL, Logger.class, LOGGER_PARAMETER_NAME); JBlock constructorBody = constructor.body(); constructorBody.callSuper().arg($v(LOGGER_PARAMETER_NAME)); final Set> entries = this.translations.entrySet(); final Set methodNames = new LinkedHashSet<>(); for (Map.Entry entry : entries) { JMethodDef method = addMessageMethod(entry.getKey(), entry.getValue()); if (methodNames.add(method)) { method.annotate(Override.class); } } return classDef; } } jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/model/000077500000000000000000000000001255176001000315705ustar00rootroot00000000000000JavaDocComment.java000066400000000000000000000026251255176001000352130ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.model; /** * Represents the {@code JavaDoc's} documentation. * * @author James R. Perkins */ public interface JavaDocComment { /** * The JavaDoc comments if available or {@code null} if there are no JavaDoc's present. * * @return the JavaDoc comments or {@code null}. */ String getComment(); } MessageInterface.java000066400000000000000000000076671255176001000356010ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.model; import java.util.Collection; import java.util.List; import java.util.Set; import org.jboss.logging.annotations.ValidIdRange; /** * Date: 28.07.2011 * * @author James R. Perkins */ public interface MessageInterface extends Comparable, MessageObject, MessageObjectType, JavaDocComment { public enum AnnotatedType { /** * Indicates the interface is annotated with {@code @MessageBundle} */ MESSAGE_BUNDLE, /** * Indicates the interface is annotated with {@code @MessageLogger} */ MESSAGE_LOGGER, /** * Indicates the interface is not annotated with {@code MessageBundle} or {@code @MessageLogger} */ NONE, } /** * Checks the interface to see if the {@link org.jboss.logging.BasicLogger logger interface} is being extended in * this interface. * * @return {@code true} if this interface extends the logger interface, otherwise {@code false}. */ boolean extendsLoggerInterface(); /** * A set of qualified interface names this interface extends or an empty set. * * @return a set of interface names or an empty set. */ Set extendedInterfaces(); /** * A collection of all the methods this interface needs to implement. * * @return a collection of methods. */ Collection methods(); /** * The project code for the message interface or {@code null} if {@link #getAnnotatedType()} returns {@link * AnnotatedType#NONE}. * * @return the project code or {@code null} if {@link #getAnnotatedType()} returns {@link AnnotatedType#NONE} */ String projectCode(); /** * The qualified name of the message interface. * * @return the qualified name. */ @Override String name(); /** * The package name of the message interface. * * @return the package name. */ String packageName(); /** * The name of the interface without the package. * * @return the simple interface name. */ String simpleName(); /** * The fully qualified class name to use for log methods. This will generally be the same result as {@link * #name()}. * * @return the fully qualified class name to use for logging. */ String loggingFQCN(); /** * Returns the annotation type on the interface. * * @return the annotated type */ AnnotatedType getAnnotatedType(); /** * Returns a list of {@link ValidIdRange valid id ranges}. * * @return a list of valid id ranges or an empty list */ List validIdRanges(); /** * The length to pad the id with. A value of less than 0 indicates no padding. * * @return the length to pad the id with */ int getIdLength(); } MessageMethod.java000066400000000000000000000150061255176001000351030ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.model; import java.util.Set; import javax.lang.model.element.ExecutableElement; import org.jboss.logging.annotations.Message.Format; import org.jboss.logging.processor.model.Parameter.ParameterType; /** * Date: 29.07.2011 * * @author James R. Perkins */ public interface MessageMethod extends Comparable, MessageObject, JavaDocComment { /** * Returns the method name. * * @return the method name. */ @Override String name(); /** * Returns an unmodifiable collection of the parameters specified by the parameter type or an empty set. * * @param parameterType the parameter type to look-up the parameters for. * * @return a collection of the parameters or an empty set. */ Set parameters(ParameterType parameterType); /** * Returns an unmodifiable collection of the parameters specified by the parameter type or an empty set. * * @param parameterType the parameter type to look-up the parameters for. * @param parameterTypes an array of types to look-up parameters for. * * @return a collection of the parameters or an empty set. */ Set parameters(ParameterType parameterType, ParameterType... parameterTypes); /** * Returns the return type for the method. * * @return the return type for the method. */ ReturnType returnType(); /** * Returns a collection of throwable types the method throws. If the method throws no exceptions an empty * collection is returned. * * @return a collection of throwable types or an empty collection. */ Set thrownTypes(); /** * The {@link Message} to be used for the method. * * @return the message. */ Message message(); /** * Indicates whether the message was inherited from another message or not. If {@code true} is returned the * {@link Message} was inherited from a different method, otherwise {@code false}. *

* Note: {@code false} does not indicate the method has a {@link org.jboss.logging.annotations.Message} * annotation. * * @return {@code true} if the message was inherited from a different method, otherwise {@code false}. */ boolean inheritsMessage(); /** * Returns the name of the method used to retrieve the message. * * @return the name of the message method. */ String messageMethodName(); /** * Returns the name of the key used in the translation files for the message translation. * * @return the name of the key in the translation files. */ String translationKey(); /** * Returns {@code true} if there is a cause element, otherwise {@code false}. * * @return {@code true} if there is a cause element, otherwise {@code false} */ boolean hasCause(); /** * Returns {@code true} if the method is overloaded, otherwise {@code false} * . * * @return {@code true} if the method is overloaded, otherwise {@code false} */ boolean isOverloaded(); /** * Returns the cause element if {@link #hasCause()} returns {@code true}, otherwise {@code null}. * * @return the cause element, otherwise {@code null}. */ Parameter cause(); /** * Returns the LogMessage annotation associated with this method only if {@link #isLoggerMethod()} returns * {@code true}. * * @return the log message annotation */ String loggerMethod(); /** * Returns the log level parameter associated with the method only if {@link #isLoggerMethod()} returns * {@code true}. * * @return the log level annotation */ String logLevel(); /** * Returns the number of parameters minus the cause parameter count for the method. * * @return the number of parameters minus the cause parameter count for the method. */ int formatParameterCount(); /** * Returns {@code true} if this is a logger method, otherwise {@code false}. * * @return {@code true} if this is a logger method, otherwise {@code false}. */ boolean isLoggerMethod(); @Override ExecutableElement reference(); /** * Represents a {@link org.jboss.logging.annotations.Message} annotation on a method. */ public interface Message { /** * The message id for the message to use. Any id less than 0 will be ignored. * * @return the message id. */ int id(); /** * Checks if the message has an id that was provided. Returns {@code true} if the message id was specified or * inherited, otherwise returns {@code false}. * * @return {@code true} if the message id was provided, otherwise {@code false}. */ boolean hasId(); /** * Checks if the message id was inherited. Returns {@code true} only if the message id is inherited, otherwise * {@code false} is returned. * * @return {@code true} if the message id was inherited, otherwise {@code false}. */ boolean inheritsId(); /** * A format string that can be used with the {@link #format()}. * * @return a format string. */ String value(); /** * The message format type for the message. * * @return the format type. */ Format format(); } } MessageObject.java000066400000000000000000000040461255176001000350730ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.model; /** * A generic interface for returning basic information about parts of a message bundle or message logger interface. * * @author James R. Perkins */ public interface MessageObject { /** * Returns a name for the object. *

* For an interface or class this will return the qualified class name. For a method this will return the name of * the method. For a parameter the name of the parameter will be returned. * * @return the name of the object. */ String name(); /** * The object used to extract information for the message logger or message bundle, if applicable. The reference is * not used for the implementation and is provided for convenience. *

* For example, in an annotation processor implementation a {@link javax.lang.model.element.ExecutableElement} * might be returned. * * @return the reference object used to extract information. */ Object reference(); } MessageObjectType.java000066400000000000000000000052261255176001000357360ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.model; /** * Date: 23.08.2011 * * @author James R. Perkins */ public interface MessageObjectType extends MessageObject { /** * Returns the qualified type name of the object. *

* Equivalent to {@code Object.class.getName()} * * @return the qualified class name. */ String type(); /** * Determines if this type is either the same as, or is a supertype of, the class represented by the {@code type} * parameter. If this type is assignable from the class {@code true} is returned, otherwise {@code false}. * * @param type the class type to check. * * @return {@code true} if this type is the same as or a superclass of the class, otherwise {@code false}. */ boolean isAssignableFrom(Class type); /** * Determines if this type is a subtype of the class represented by the {@code type} parameter. If this type is a * subtype of the class {@code true} is returned, otherwise {@code false}. * * @param type the class type to check. * * @return {@code true} if this type is a subtype of the class, otherwise {@code false}. */ boolean isSubtypeOf(Class type); /** * Determines if this type is the same type as the class represented by the {@code type} parameter. If this type is * the same type as the class {@code true} is returned, otherwise {@code false}. * * @param type the class type to check. * * @return {@code true} if this type is the same type as the class, otherwise {@code false}. */ boolean isSameAs(Class type); } Parameter.java000066400000000000000000000132251255176001000342770ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.model; import org.jboss.logging.annotations.Pos; import org.jboss.logging.annotations.Transform; /** * @author James R. Perkins - 20.Feb.2011 */ public interface Parameter extends Comparable, MessageObjectType { /** * The types of parameters. */ public enum ParameterType { /** * Indicates the parameter can be any other type. All parameters fall under this category. */ ANY, /** * Indicates the parameter is a cause parameter and needs to be set in the {@link Throwable throwable} return * type. */ CAUSE, /** * Indicates the parameter should be used as a format parameter. */ FORMAT, /** * Indicates the parameter should be used as the fully qualified class name for the logger. */ FQCN, /** * Indicates the parameter is the message. */ MESSAGE, /** * Indicates the parameter should be used in the construction of a {@link Throwable throwable} return type. */ CONSTRUCTION, /** * Indicates the parameter is a instance field that should be set in the {@link Throwable throwable} return * type. */ FIELD, /** * Indicates the parameter is a property and should be set via its setter in the {@link Throwable throwable} * return type. */ PROPERTY, /** * Transforms the parameter using the {@link org.jboss.logging.annotations.Transform.TransformType transform * type}. */ TRANSFORM, /** * Indicates the parameter is a positional parameter. */ POS, } /** * The full type name of the parameter. For example * {@code java.lang.String} if the parameter is a string. If the * parameter is a primitive, the primitive name is returned. * * @return the qualified type of the parameter. */ @Override String type(); /** * The variable name of the parameter. * * @return the variable name of the parameter. */ @Override String name(); /** * Returns {@code true} if the type is an array, otherwise {@code false}. * * @return {@code true} if an array, otherwise {@code false} */ boolean isArray(); /** * Returns {@code true} if the type is a primitive type, otherwise {@code false}. * * @return {@code true} if primitive type, otherwise {@code false} */ boolean isPrimitive(); /** * Returns {@code true} if the parameter is a var args parameter, otherwise {@code false}. * * @return {@code true} if var args parameter, otherwise {@code false}. */ boolean isVarArgs(); /** * Returns the {@link ParameterType parameter type} of the parameter. * * @return the parameter type of the parameter. */ ParameterType parameterType(); /** * The formatter class, or {@code null} if there is none. * * @return the formatter class */ String formatterClass(); /** * Returns the class if the parameter is annotated with {@link org.jboss.logging.annotations.Param}. * If the annotation is not present, {@code null} is returned. * * @return the parameter class or {@code null}. */ Class paramClass(); /** * Returns the name of the target field or method. For example if the {@link #parameterType()} returns * {@link ParameterType#FIELD}, the target name is the name of the field to set on the * {@link org.jboss.logging.processor.model.ReturnType return type}. If no target name is defined an empty String * is * returned. * * @return the target field name, method name or an empty string. */ String targetName(); /** * The transform type if this the {@link #parameterType()} is {@link ParameterType#TRANSFORM}. * * @return the transform annotation or {@code null} if not a transform parameter */ Transform transform(); /** * The position annotation if this the {@link #parameterType()} is {@link ParameterType#POS}. *

* This works the same way the {@link java.util.Formatter formatter} positional characters work. *

*

     *      String.format("Numeric value %1$d (%1$x)");
     *
     *      @Message(""Numeric value %d (%x)"")
     *      void logNumericValue(@Pos(1) int value);
     * 
* * @return the position annotation or {@code null} if not a position parameter */ Pos pos(); } ReturnType.java000066400000000000000000000121301255176001000344720ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.model; import static org.jboss.logging.processor.util.Objects.HashCodeBuilder; import static org.jboss.logging.processor.util.Objects.ToStringBuilder; import static org.jboss.logging.processor.util.Objects.areEqual; /** * Date: 29.07.2011 * * @author James R. Perkins */ public interface ReturnType extends MessageObject, MessageObjectType { public static final ReturnType VOID = new VoidReturnType(); /** * Checks to see if the return type has a field with the name with the same name and type as the * {@link Parameter parameter}. * * @param parameter the parameter to check. * * @return {@code true} if the field exists, is accessible, mutable and is assignable from the type otherwise * {@code false}. */ boolean hasFieldFor(final Parameter parameter); /** * Checks to see if the return type has a method with the name with the same name and parameter type as the * {@link Parameter parameter}. * * @param parameter the parameter to check. * * @return {@code true} if the method exists, is accessible and its parameter is assignable from the type, otherwise * {@code false}. */ boolean hasMethodFor(final Parameter parameter); /** * Checks to see if the return type is an exception, extends Throwable. * * @return {@code true} if the return type is an exception, otherwise * {@code false}. */ boolean isThrowable(); /** * Indicates whether or not the return type is a primitive. * * @return {@code true} if a primitive, otherwise {@code false}. */ boolean isPrimitive(); /** * Returns the qualified class name of the return type. * * @return the qualified class name fo the return type. */ @Override String name(); /** * Returns the exception return type if {@link #isThrowable()} returns {@code true}. Otherwise {@code null} is * returned. * * @return an exception return type, otherwise {@code null}. */ ThrowableType throwableReturnType(); /** * Default type if the return type is void. */ final static class VoidReturnType implements ReturnType { private VoidReturnType() { } @Override public boolean hasFieldFor(final Parameter parameter) { return false; } @Override public boolean hasMethodFor(final Parameter parameter) { return false; } @Override public boolean isThrowable() { return false; } @Override public boolean isPrimitive() { return false; } @Override public String name() { return "void"; } @Override public ThrowableType throwableReturnType() { return null; } @Override public int hashCode() { return HashCodeBuilder.builder().add(name()).toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof VoidReturnType)) { return false; } final VoidReturnType other = (VoidReturnType) obj; return areEqual(this.name(), other.name()); } @Override public String toString() { return ToStringBuilder.of(this).add(name()).toString(); } @Override public Class reference() { return Void.TYPE; } @Override public String type() { return "void"; } @Override public boolean isAssignableFrom(final Class type) { return type.equals(Void.TYPE); } @Override public boolean isSubtypeOf(final Class type) { return false; } @Override public boolean isSameAs(final Class type) { return type.equals(Void.TYPE); } } } ThrowableType.java000066400000000000000000000077161255176001000351600ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/model/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.model; import java.util.Set; /** * Date: 27.09.2011 * * @author James R. Perkins */ public interface ThrowableType extends MessageObject, MessageObjectType, Comparable { /** * Checks to see the throwable has a default constructor. * * @return {@code true} if the throwable has a default constructor, otherwise {@code false}. */ boolean hasDefaultConstructor(); /** * Checks to see if the throwable has a string and throwable ({@code Throwable(String, Throwable)}) constructor. * * @return {@code true} if the throwable has both a string and throwable constructor, otherwise {@code false}. */ boolean hasStringAndThrowableConstructor(); /** * Checks to see if the throwable has a string ({@code Throwable(String)}) constructor. *

* If {@code true}, {@link Throwable#initCause(Throwable)} can be used to set the throwable. * * @return {@code true} if the throwable has a string constructor, otherwise {@code false}. */ boolean hasStringConstructor(); /** * Checks to see if the throwable has a throwable and string ({@code Throwable(Throwable, String)}) constructor. * * @return {@code true} if the throwable has both a throwable and string constructor, otherwise {@code false}. */ boolean hasThrowableAndStringConstructor(); /** * Checks to see if the throwable has a string and throwable ({@code Throwable(String, Throwable)}) constructor. * * @return {@code true} if the throwable has a throwable constructor, otherwise {@code false}. */ boolean hasThrowableConstructor(); /** * Checks to see if the throwable has and can use a custom constructor. *

* If {@code true}, the constructor parameters can be retrieved from the {@link #constructionParameters()} method. * * @return {@code true} if the throwable has a custom constructor that can be used, otherwise {@code false}. */ boolean useConstructionParameters(); /** * The parameters needed to construct the throwable, if not using the default constructor. If the default * constructor should be used an empty set should be returned. *

* The order the set is returned is the order in which the parameters must be in for the constructor. * * @return a set of construction parameters or an empty set. */ Set constructionParameters(); /** * Checks if the throwable is a checked exception. If the throwable is a checked exception, {@code true} is * returned, otherwise {@code false}. * * @return {@code true} if the throwable is a checked exception, otherwise {@code false}. */ boolean isChecked(); /** * Returns the qualified class name of the return type. * * @return the qualified class name fo the return type. */ @Override String name(); } jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/util/000077500000000000000000000000001255176001000314455ustar00rootroot00000000000000Comparison.java000066400000000000000000000235571255176001000343570ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/util/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.util; import java.util.Comparator; /** * Date: 30.08.2011 * * @author James R. Perkins */ public abstract class Comparison { public static final int EQUAL = 0; public static final int LESS = -1; public static final int GREATER = 1; private static final Comparison LESS_COMPARISON = new DeadComparison(-1); private static final Comparison GREATER_COMPARISON = new DeadComparison(1); private static final Comparison ALLOW_NULL_INSTANCE = new Comparison() { @Override @SuppressWarnings("unchecked") public Comparison compare(final Comparable left, final Comparable right) { final int result; if (left == null && right == null) { result = EQUAL; } else if (left == null) { result = LESS; } else if (right == null) { result = GREATER; } else { result = left.compareTo(right); } return super.checkResult(result); } @Override public Comparison compare(final T left, final T right, final Comparator comparator) { final int result; if (left == null && right == null) { result = EQUAL; } else if (left == null) { result = LESS; } else if (right == null) { result = GREATER; } else { result = comparator.compare(left, right); } return super.checkResult(result); } @Override public Comparison getInstance() { return ALLOW_NULL_INSTANCE; } }; private static final Comparison INSTANCE = new Comparison() { @Override @SuppressWarnings("unchecked") public Comparison compare(final Comparable left, final Comparable right) { return super.checkResult(left.compareTo(right)); } @Override public Comparison compare(final T left, final T right, final Comparator comparator) { return super.checkResult(comparator.compare(left, right)); } @Override public Comparison getInstance() { return INSTANCE; } }; private static final class DeadComparison extends Comparison { private final int result; public DeadComparison(final int result) { this.result = result; } @Override public Comparison compare(final Comparable left, final Comparable right) { return this; } @Override public Comparison compare(final T left, final T right, final Comparator comparator) { return this; } @Override public Comparison compare(final int left, final int right) { return this; } @Override public Comparison compare(final long left, final long right) { return this; } @Override public Comparison compare(final float left, final float right) { return this; } @Override public Comparison compare(final double left, final double right) { return this; } @Override public Comparison compare(final boolean left, final boolean right) { return this; } @Override public int result() { return result; } @Override public Comparison getInstance() { return this; } } /** * Private constructor for singleton pattern. */ private Comparison() { } /** * Begins a new comparison. * * @return the comparison. */ public static Comparison begin() { return INSTANCE; } /** * Begins a new comparison, but allows for {@code null} values to be passed. *

*

* If the first value is {@code null} and the second value is * {@code non-null}, the comparison will return -1. If the first value is * {@code non-null} and the second value is {@code null}, the comparison * will return 1. If both values are {@code null} 0 is returned. *

* * @return the comparison. */ public static Comparison beginAllowNull() { return ALLOW_NULL_INSTANCE; } /** * Compares the left comparable to the right as specified by the {@link * Comparable#compareTo(Object)} interface. * * @param left the object to compare to the right. * @param right the object compared to the left. * * @return the the same instance if the objects are equal, otherwise a * comparison that will return a defined value. */ public abstract Comparison compare(Comparable left, Comparable right); /** * Compares the left object to the right object as specified by the {@link * java.util.Comparator#compare(Object, Object)} * interface. * * @param the type of the object to the compared. * @param left the object to compare to the right. * @param right the object compared to the left. * @param comparator the comparator used to compare the objects. * * @return the the same instance if the objects are equal, otherwise a * comparison that will return a defined value. */ public abstract Comparison compare(T left, T right, Comparator comparator); /** * Compares the left integer to the right integer. * * @param left the integer to compare to the right. * @param right the integer compared to the left. * * @return the the same instance if the integers are equal, otherwise a * comparison that will return a defined value. */ public Comparison compare(int left, int right) { int result = EQUAL; if (left < right) { result = LESS; } else if (left > right) { result = GREATER; } return checkResult(result); } /** * Compares the left long to the right long. * * @param left the long to compare to the right. * @param right the long compared to the left. * * @return the the same instance if the longs are equal, otherwise a * comparison that will return a defined value. */ public Comparison compare(long left, long right) { int result = EQUAL; if (left < right) { result = LESS; } else if (left > right) { result = GREATER; } return checkResult(result); } /** * Compares the left float to the float integer. * * @param left the float to compare to the right. * @param right the float compared to the left. * * @return the the same instance if the floats are equal, otherwise a * comparison that will return a defined value. */ public Comparison compare(float left, float right) { return checkResult(Float.compare(left, right)); } /** * Compares the left double to the double integer. * * @param left the double to compare to the right. * @param right the double compared to the left. * * @return the the same instance if the doubles are equal, otherwise a * comparison that will return a defined value. */ public Comparison compare(double left, double right) { return checkResult(Double.compare(left, right)); } /** * Compares the left boolean to the double boolean. * * @param left the boolean to compare to the right. * @param right the boolean compared to the left. * * @return the the same instance if the booleans are equal, otherwise a * comparison that will return a defined value. */ public Comparison compare(boolean left, boolean right) { return checkResult((left == right) ? EQUAL : (left ? GREATER : LESS)); } /** * Ends the comparison and returns 0 if all comparisons were equal, -1 if * the any of the left comparisons were less than the right comparisons or * 1 if any of the right comparisons were less than the left. * * @return zero if equal, otherwise the a value with the same sign as the first * non-equal comparison. */ public int result() { return EQUAL; } /** * Returns the comparison instance being used. * * @return the comparison instance being used. */ protected abstract Comparison getInstance(); /** * Checks to see which comparison to return. * * @param result the result of the comparison. * * @return the comparison that should be used. */ private Comparison checkResult(final int result) { return (result < 0) ? LESS_COMPARISON : (result > 0) ? GREATER_COMPARISON : getInstance(); } } ElementHelper.java000066400000000000000000000334671255176001000347770ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/util/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.util; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.DeclaredType; import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.Field; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.Param; import org.jboss.logging.annotations.Property; import org.jboss.logging.processor.model.MessageObject; /** * An utility class to work with element. * * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) * @author James R. Perkins */ public final class ElementHelper { /** * Disable instantiation. */ private ElementHelper() { } /** * Check if an element is annotated with the given annotation. * * @param element the element to look for the annotation on. * @param clazz the annotation class * * @return {@code true} if the element is annotated, otherwise {@code false} * * @throws IllegalArgumentException if element parameter is null */ public static boolean isAnnotatedWith(final Element element, final Class clazz) { if (element == null) { throw new IllegalArgumentException("The element parameter is null"); } Annotation annotation = element.getAnnotation(clazz); return (annotation != null); } /** * Returns the primary class simple name prefix for an element * who represents a MessageBundle or MessageLogger interface. * * @param element the element * * @return the translation file name prefix * * @throws IllegalArgumentException if element is null or the element is not an interface */ public static String getPrimaryClassNamePrefix(final TypeElement element) { if (element == null) { throw new IllegalArgumentException("The element parameter cannot be null"); } if (!element.getKind().isInterface()) { throw new IllegalArgumentException("The element parameter is not an interface"); } String translationFileName = element.getSimpleName().toString(); //Check if it's an inner interface Element enclosingElt = element.getEnclosingElement(); while (enclosingElt != null && enclosingElt instanceof TypeElement) { translationFileName = String.format("%s$%s", enclosingElt.getSimpleName().toString(), translationFileName); enclosingElt = enclosingElt.getEnclosingElement(); } return translationFileName; } /** * Returns a collection of methods with the same name. * * @param methods the methods to process. * @param methodName the method name to find. * * @return a collection of methods with the same name. */ public static Collection findByName(final Collection methods, final Name methodName) { final List result = new ArrayList(); for (ExecutableElement method : methods) { if (methodName.equals(method.getSimpleName())) { result.add(method); } } return result; } /** * Returns a collection of methods with the same name. * * @param methods the methods to process. * @param methodName the method name to find. * @param paramCount the number of parameters the method must have. * * @return a collection of methods with the same name. */ public static Collection findByName(final Collection methods, final Name methodName, final int paramCount) { final List result = new ArrayList(); for (ExecutableElement method : methods) { if (methodName.equals(method.getSimpleName()) && parameterCount(method.getParameters()) == paramCount) { result.add(method); } } return result; } /** * Checks to see if there is a cause parameter. * * @param params the parameters to check. * * @return {@code true} if there is a cause, otherwise {@code false}. */ public static boolean hasCause(final Collection params) { // Look for cause for (VariableElement param : params) { if (isAnnotatedWith(param, Cause.class)) { return true; } } return false; } /** * Returns the number of parameters excluding the {@link org.jboss.logging.annotations.Cause} parameter * and any {@link org.jboss.logging.annotations.Param} parameters if found. * * @param params the parameters to get the count for. * * @return the number of parameters. */ public static int parameterCount(final Collection params) { int result = params.size(); for (VariableElement param : params) { if (isAnnotatedWith(param, Param.class) || isAnnotatedWith(param, Field.class) || isAnnotatedWith(param, Property.class)) { --result; } } return (result - (hasCause(params) ? 1 : 0)); } /** * Checks to see if the method has or inherits a {@link org.jboss.logging.annotations.Message} * annotation. * * @param methods the method to search. * @param method the method to check. * * @return {@code true} if the method has or inherits a message annotation, otherwise {@code false}. */ public static boolean inheritsMessage(final Collection methods, final ExecutableElement method) { if (isAnnotatedWith(method, Message.class)) { return false; } final Collection allMethods = findByName(methods, method.getSimpleName()); for (ExecutableElement m : allMethods) { if (isAnnotatedWith(m, Message.class)) { return true; } } return false; } /** * Checks to see if the method is overloaded. An overloaded method has a different parameter count based on the * format parameters only. Parameters annotated with {@link org.jboss.logging.annotations.Cause} or * {@link org.jboss.logging.annotations.Param} * are not counted. * * @param methods the method to search. * @param method the method to check. * * @return {@code true} if the method is overloaded, otherwise {@code false}. */ public static boolean isOverloaded(final Collection methods, final ExecutableElement method) { final Collection allMethods = findByName(methods, method.getSimpleName()); for (ExecutableElement m : allMethods) { if (method.getSimpleName().equals(m.getSimpleName()) && parameterCount(method.getParameters()) != parameterCount(m.getParameters())) { return true; } } return false; } /** * Converts a class type to a string recognizable by the * {@link javax.lang.model.util.Elements#getTypeElement(CharSequence)}. Essentially replaces any {@literal $}'s to * {@literal .} (dots). * * @param type the type to convert. * * @return the qualified name of the type. */ public static String typeToString(final Class type) { return typeToString(type.getName()); } /** * Converts a qualified type name to a string recognizable by the * {@link javax.lang.model.util.Elements#getTypeElement(CharSequence)}. Essentially replaces any {@literal $}'s to * {@literal .} (dots). * * @param qualifiedType the qualified type name. * * @return the qualified name of the type. */ public static String typeToString(final String qualifiedType) { return qualifiedType.replace("$", "."); } /** * If the {@link org.jboss.logging.processor.model.MessageObject#reference()} is an instance of {@link * Element}, then the value is returned, otherwise {@code null} is returned. * * @param object the object to check the reference on * * @return the element reference or {@code null} */ public static Element fromMessageObject(final MessageObject object) { if (object.reference() instanceof Element) { return (Element) object.reference(); } return null; } /** * Retrieves the first attribute value from the annotation and assumes it's a {@link Class class} type. * * @param element the element the annotation is on * @param annotation the annotation to get the value from * * @return a {@link TypeElement} representing the value for the first annotation attribute or {@code null} if no * attributes were found */ public static TypeElement getClassAnnotationValue(final Element element, final Class annotation) { for (AnnotationMirror mirror : element.getAnnotationMirrors()) { final DeclaredType annotationType = mirror.getAnnotationType(); if (annotationType.toString().equals(annotation.getName())) { final AnnotationValue value = mirror.getElementValues().values().iterator().next(); return ((TypeElement) (((DeclaredType) value.getValue()).asElement())); } } return null; } /** * Retrieves the attribute value from the annotation and assumes it's a {@link Class class} type. * * @param element the element the annotation is on * @param annotation the annotation to get the value from * @param attributeName the name of the attribute to retrieve the class value for * * @return a {@link TypeElement} representing the value for the annotation attribute or {@code null} if the * attribute was not found */ public static TypeElement getClassAnnotationValue(final Element element, final Class annotation, final String attributeName) { for (AnnotationMirror mirror : element.getAnnotationMirrors()) { final DeclaredType annotationType = mirror.getAnnotationType(); if (annotationType.toString().equals(annotation.getName())) { final Map map = mirror.getElementValues(); for (ExecutableElement key : map.keySet()) { if (key.getSimpleName().contentEquals(attributeName)) { return ((TypeElement) (((DeclaredType) map.get(key).getValue()).asElement())); } } } } return null; } /** * Retrieves the attribute value from the annotation and assumes it's an array {@link Class classes}. * * @param element the element the annotation is on * @param annotation the annotation to get the value from * @param attributeName the name of the attribute to retrieve the class value array for * * @return a list of {@link TypeElement} representing the value for the annotation attribute or an empty list */ public static List getClassArrayAnnotationValue(final Element element, final Class annotation, final String attributeName) { for (AnnotationMirror mirror : element.getAnnotationMirrors()) { final DeclaredType annotationType = mirror.getAnnotationType(); if (annotationType.toString().equals(annotation.getName())) { final Map map = mirror.getElementValues(); for (ExecutableElement key : map.keySet()) { if (key.getSimpleName().contentEquals(attributeName)) { @SuppressWarnings("unchecked") final List annotationValues = (List) map.get(key).getValue(); final List result = new ArrayList<>(annotationValues.size()); for (AnnotationValue value : annotationValues) { result.add((TypeElement) ((DeclaredType) value.getValue()).asElement()); } return result; } } } } return Collections.emptyList(); } } Objects.java000066400000000000000000000331601255176001000336250ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/util/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.util; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; /** * Date: 30.08.2011 * * @author James R. Perkins */ public final class Objects { /** * Not used */ private Objects() { } /** * Checks to see if two booleans are equal. * * @param first the first boolean. * @param second the second boolean. * * @return {@code true} if the first is equal to the second, otherwise * {@code false}. */ public static boolean areEqual(final boolean first, final boolean second) { return first == second; } /** * Checks to see if two characters are equal. * * @param first the first character. * @param second the second character. * * @return {@code true} if the first is equal to the second, otherwise * {@code false}. */ public static boolean areEqual(final char first, final char second) { return first == second; } /** * Checks to see if two longs are equal. This method is also used for int's, * shorts, and bytes. * * @param first the first long. * @param second the second long. * * @return {@code true} if the first is equal to the second, otherwise * {@code false}. */ public static boolean areEqual(final long first, final long second) { return first == second; } /** * Checks to see if two floats are equal. * * @param first the first float. * @param second the second float. * * @return {@code true} if the first is equal to the second, otherwise * {@code false}. */ public static boolean areEqual(final float first, final float second) { return Float.floatToIntBits(first) == Float.floatToIntBits(second); } /** * Checks to see if two doubles are equal. * * @param first the first double. * @param second the second double. * * @return {@code true} if the first is equal to the second, otherwise * {@code false}. */ public static boolean areEqual(final double first, final double second) { return Double.doubleToLongBits(first) == Double.doubleToLongBits(second); } /** * Checks to see if two objects are equal. *

*

* Note this method does not handle arrays. The {@link java.util.Arrays} * class has utilities for equality of arrays. *

* * @param first the first optionally {@code null} object. * @param second the second optionally {@code null} object. * * @return {@code true} if the first is equal to the second, otherwise * {@code false}. */ public static boolean areEqual(final Object first, final Object second) { return (first == null ? second == null : first.equals(second)); } /** * Checks to see if an object is {@code null}, otherwise throws an * {@link IllegalArgumentException}. * * @param the type of the object. * @param ref the reference to the object. * * @return the reference if it is not {@code null}. */ public static T checkNonNull(final T ref) { if (ref == null) { throw new IllegalArgumentException(); } return ref; } /** * Checks to see if an object is {@code null}, otherwise throws an * {@link IllegalArgumentException}. * * @param the type of the object. * @param ref the reference to the object. * @param message the message used in the {@code IllegalArgumentException} * constructor. * * @return the reference if it is not {@code null}. */ public static T checkNonNull(final T ref, final String message) { if (ref == null) { throw new IllegalArgumentException(message); } return ref; } /** * Checks to see if an object is {@code null}, otherwise throws an * {@link IllegalArgumentException}. * * @param the type of the object. * @param ref the reference to the object. * @param message the message format used in the * {@code IllegalArgumentException} constructor. * @param args the arguments used to format the message. * * @return the reference if it is not {@code null}. */ public static T checkNonNull(final T ref, final String message, final Object... args) { if (ref == null) { throw new IllegalArgumentException(String.format(message, args)); } return ref; } /** * A builder to simplify the building of hash codes. */ public static class HashCodeBuilder { private final int seed; private int hash; /** * Private constructor for builder pattern. * * @param seed the seed for the hash code. */ private HashCodeBuilder(final int seed) { this.seed = seed; hash = 17; } /** * Creates a new builder with 31 as the seed. * * @return the new builder. */ public static HashCodeBuilder builder() { return new HashCodeBuilder(31); } /** * Creates a new builder with the seed that is passed. * * @param seed the seed for the hash code. * * @return the new builder. */ public static HashCodeBuilder builder(final int seed) { return new HashCodeBuilder(seed); } /** * Adds the hash code of a boolean to the final hash code value. * * @param b a boolean to calculate the hash code of. * * @return the current builder. */ public HashCodeBuilder add(final boolean b) { hash = calc() + (b ? 1 : 0); return this; } /** * Adds the hash code of a character to the final hash code value. * * @param c a character to calculate the hash code of. * * @return the current builder. */ public HashCodeBuilder add(final char c) { hash = calc() + (int) c; return this; } /** * Adds the hash code of an integer to the final hash code value. *

*

* Both shorts and bytes use this method to add the hash value. *

* * @param i an integer to calculate the hash code of. * * @return the current builder. */ public HashCodeBuilder add(final int i) { hash = calc() + i; return this; } /** * Adds the hash code of a long to the final hash code value. * * @param lng a long to calculate the hash code of. * * @return the current builder. */ public HashCodeBuilder add(final long lng) { hash = calc() + (int) (lng ^ (lng >>> 32)); return this; } /** * Adds the hash code of a float to the final hash code value. * * @param flt a float to calculate the hash code of. * * @return the current builder. */ public HashCodeBuilder add(final float flt) { return add(Float.floatToIntBits(flt)); } /** * Adds the hash code of a double to the final hash code value. * * @param dbl a double to calculate the hash code of. * * @return the current builder. */ public HashCodeBuilder add(final double dbl) { return add(Double.doubleToLongBits(dbl)); } /** * Adds the hash code of an object to the final hash code value. *

*

* If the {@code obj} is {@code null} the hash code is calculated using * {@link #add(int)} with a value of 0. Otherwise the hash code is * calculated using {@link #add(int)} with a value of * {@code obj.hashCode()}, unless the object is an array. In this case * the array is processed and this is recursively invoked. *

* * @param obj the object to calculate the hash code of. * * @return the current builder. */ public HashCodeBuilder add(final Object obj) { if (obj == null) { add(0); } else if (!obj.getClass().isArray()) { add(obj.hashCode()); } else { final int len = Array.getLength(obj); for (int i = 0; i < len; i++) { final Object arrayObj = Array.get(obj, i); add(arrayObj); } } return this; } /** * Returns the calculated hash code. * * @return the calculated hash code. */ public int toHashCode() { return hash; } /** * This method overrides the default {@code Object#hashCode()}, but does * not return a proper hash of this builder. Returns the value of * {@code toHashCode()} to insure the incorrect hash code is not returned * by mistake. * * @return the value of {@link #toHashCode()}. */ @Override public int hashCode() { return toHashCode(); } /** * Should never be invoked on this object. * * @param obj an object. */ @Override public boolean equals(final Object obj) { return obj == this; } /** * Calculates the default. * * @return the default hash value. */ private int calc() { return seed * hash; } } /** * A builder to build a default {@code Object#toString()} value. *

* Not thread safe. */ public static class ToStringBuilder { private final List fieldValue = new ArrayList(); private final String className; /** * Private constructor for builder pattern. * * @param className the class name to prepend the result with. */ private ToStringBuilder(final String className) { this.className = className; } /** * Creates a new string builder for the {@code clazz}. * * @param clazz the base class for the string result. * * @return the current builder. */ public static ToStringBuilder of(final Class clazz) { return new ToStringBuilder(checkNonNull(clazz.getSimpleName())); } /** * Creates a new string builder for the {@code className}. * * @param className the class name to prepend the string value with. * * @return the current builder. */ public static ToStringBuilder of(final String className) { return new ToStringBuilder(checkNonNull(className)); } /** * Creates a new string builder for the {@code self}. * * @param self the object to create the builder for. * * @return the current builder. */ public static ToStringBuilder of(final Object self) { return of(checkNonNull(self.getClass())); } public ToStringBuilder add(final Object value) { fieldValue.add((value == null ? "null" : value.toString())); return this; } /** * Adds the field and value to the value returned. * * @param field the field for the value. * @param value the value of the field. * * @return the current instance of the builder. */ public ToStringBuilder add(final String field, final Object value) { final String result = checkNonNull(field) + "=" + value; fieldValue.add(result); return this; } @Override public String toString() { final StringBuilder result = new StringBuilder(); result.append(className); result.append("{"); final int size = fieldValue.size(); int count = 0; for (String s : fieldValue) { count++; result.append(s); if (count < size) { result.append(","); } } return result.append("}").toString(); } } } Strings.java000066400000000000000000000044561255176001000336730ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/util/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.util; /** * Date: 19.09.2011 * * @author James R. Perkins */ public class Strings { private Strings() { } /** * Creates a string filled with the with the value of the {@code filler} parameter with a length defined by the * {@code len} parameter. * * @param filler the filler character. * @param len the length to fill. * * @return the generated string. */ public static String fill(final char filler, final int len) { final StringBuilder result = new StringBuilder(len); for (int i = 0; i < len; i++) { result.append(filler); } return result.toString(); } /** * Creates a string filled with the with the value of the {@code filler} parameter with a length defined by the * {@code len} parameter. * * @param filler the filler sequence. * @param len the length to fill. * * @return the generated string. */ public static String fill(final CharSequence filler, final int len) { final StringBuilder result = new StringBuilder((filler.length() * len)); for (int i = 0; i < len; i++) { result.append(filler); } return result.toString(); } } TranslationHelper.java000066400000000000000000000104631255176001000356730ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/util/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.util; import java.io.File; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Utility class to work with translation filename. * * @author Kevin Pollet - SERLI - (kevin.pollet@serli.com) */ public final class TranslationHelper { private static final String TRANSLATION_FILE_NAME_EXTENSION = ".properties"; /** * Private constructor to * disable instantiation. */ private TranslationHelper() { } /** * Get the class name suffix to be added to the * generated class for the given translation file name. * * @param translationFileName the translation file name * * @return the class name suffix corresponding to the given translation filename * * @throws IllegalArgumentException if translationFileName is null or not valid */ public static String getTranslationClassNameSuffix(final String translationFileName) { if (translationFileName == null) { throw new IllegalArgumentException("The translationFileName parameter cannot be null"); } Pattern pattern = Pattern.compile("[^_]*((_[^_.]*){1,3}).*"); Matcher matcher = pattern.matcher(translationFileName); boolean found = matcher.find(); if (!found) { throw new IllegalArgumentException("The given filename is not a valid property filename"); } return matcher.group(1); } /** * Returns the enclosing translation file name for the given * translation file name. *

* If the given translation file name is InterfaceName.i18n_locale * the given translation file name is returned. * * @param translationFile the translation file * * @return the enclosing file name * * @throws IllegalArgumentException if translationFileName is null */ public static String getEnclosingTranslationFileName(final File translationFile) { if (translationFile == null) { throw new IllegalArgumentException("The translationClassName parameter cannot be null"); } final String translationFileName = translationFile.getName(); int lastUnderscore = translationFileName.lastIndexOf('_'); if (translationFileName.indexOf('_') == lastUnderscore) { return translationFileName; } else { return translationFileName.substring(0, lastUnderscore).concat(TRANSLATION_FILE_NAME_EXTENSION); } } /** * Returns the enclosing translation class name for * the given translation class name. If the given translation * class name is the upper class name then the parameter class * name is returned. * * @param translationClassName the translation class name * * @return the enclosing class name * * @throws IllegalArgumentException if translationClassName is null */ public static String getEnclosingTranslationClassName(final String translationClassName) { if (translationClassName == null) { throw new IllegalArgumentException("The translationClassName parameter cannot be null"); } int lastUnderScore = translationClassName.lastIndexOf("_"); return lastUnderScore != -1 ? translationClassName.substring(0, lastUnderScore) : translationClassName; } } VersionComparator.java000066400000000000000000000072371255176001000357170ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/util/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.util; import java.util.ArrayList; import java.util.Comparator; import java.util.List; /** * Compares 2 different version strings. *

* The version strings must be valid integers separated by {@code .} (dots). *

* Date: 09.11.2011 * * @author James R. Perkins */ public class VersionComparator implements Comparator { public static VersionComparator INSTANCE = new VersionComparator(); private VersionComparator() { } /** * Compares the first version to the second version and returns, 0 if they are equal, a value less than 0 if the * first version is less than the second version or a value greater than 0 if the first version is greater than * the second version. * * @param version1 the first version to compare. * @param version2 the second version to compare. * * @return a value of 0 if the versions are equal, less than 0 if {@code version1} is less than {@code version2}, * a value greater than 0 if {@code version1} is greater than {@code version2}. */ public static int compareVersion(final String version1, final String version2) { return INSTANCE.compare(version1, version2); } @Override public int compare(final String o1, final String o2) { final String[] vs1 = o1.split("\\."); final String[] vs2 = o2.split("\\."); final int len = (vs1.length > vs2.length ? vs1.length : vs2.length); final List v1 = convert(vs1, len); final List v2 = convert(vs2, len); int result = 0; for (int i = 0; i < len; i++) { final Integer vi1 = v1.get(i); final Integer vi2 = v2.get(i); result = vi1.compareTo(vi2); if (result != 0) { break; } } return result; } private static List convert(final String[] version, final int len) { final List result = new ArrayList(len); for (int i = 0; i < len; i++) { if (i < version.length) { final String s = version[i]; if ("x".equalsIgnoreCase(s)) { result.add(0); } else { try { result.add(Integer.valueOf(s)); } catch (NumberFormatException e) { throw new IllegalArgumentException(String.format("Version part %s is not a valid integer", s), e); } } } else { result.add(0); } } return result; } } jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/000077500000000000000000000000001255176001000326225ustar00rootroot00000000000000AbstractFormatPart.java000066400000000000000000000037141255176001000371560ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; import org.jboss.logging.processor.util.Comparison; /** * Abstract class that only implements Comparable for convenience. Uses the {@link org.jboss.logging.processor.validation.FormatPart#position()} for * the comparison. *

* Date: 13.06.2011 * * @author James R. Perkins */ abstract class AbstractFormatPart implements FormatPart { @Override public int compareTo(final FormatPart other) { return Comparison.begin(). compare(position(), other.position()).result(); } @Override public String toString() { return new StringBuilder(getClass().getSimpleName()).append("[") .append("index=") .append(index()) .append(", position=") .append(position()) .append(", part=") .append(part()) .toString(); } } AbstractFormatValidator.java000066400000000000000000000041551255176001000401750ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; /** * Date: 12.08.2011 * * @author James R. Perkins */ abstract class AbstractFormatValidator implements FormatValidator { private String summaryMessage; private String detailMessage; AbstractFormatValidator() { detailMessage = ""; summaryMessage = ""; } final void setDetailMessage(final String detailMessage) { this.detailMessage = detailMessage; } final void setDetailMessage(final String format, final Object... args) { this.detailMessage = String.format(format, args); } final void setSummaryMessage(final String summaryMessage) { this.summaryMessage = summaryMessage; } final void setSummaryMessage(final String format, final Object... args) { this.summaryMessage = String.format(format, args); } @Override public final String detailMessage() { return (detailMessage.isEmpty() ? summaryMessage : detailMessage); } @Override public final String summaryMessage() { return summaryMessage; } } FormatPart.java000066400000000000000000000032151255176001000354660ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; /** * Date: 13.06.2011 * * @author James R. Perkins */ interface FormatPart extends Comparable { /** * The default string index. */ int STRING = -2; /** * The parameter index. For default strings (non-parameters) the value is {@code -2}. * * @return the index. */ int index(); /** * The position for the part. * * @return the position. */ int position(); /** * The part of the format. * * @return the part of the format. */ String part(); } FormatValidator.java000066400000000000000000000040151255176001000365040ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; /** * Date: 14.06.2011 * * @author James R. Perkins */ public interface FormatValidator { /** * The number of arguments needed for the format. * * @return the number of arguments needed. */ int argumentCount(); /** * Returns the format string used for validation. * * @return the format string. */ String format(); /** * Returns {@code true} of the format is valid, otherwise {@code false}. * * @return {@code true} of the format is valid, otherwise {@code false}. */ boolean isValid(); /** * A detail message if {@link #isValid()} returns {@code false}, otherwise an empty string. * * @return a detailed message. */ String detailMessage(); /** * A summary message if {@link #isValid()} returns {@code false}, otherwise an empty string. * * @return a summary message. */ String summaryMessage(); } FormatValidatorFactory.java000066400000000000000000000066031255176001000400410ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; import org.jboss.logging.annotations.Message.Format; import org.jboss.logging.processor.model.MessageMethod; /** * Date: 12.08.2011 * * @author James R. Perkins */ public final class FormatValidatorFactory { private FormatValidatorFactory() { } public static FormatValidator create(final MessageMethod messageMethod) throws IllegalStateException { if (messageMethod.message() == null) { return InvalidFormatValidator.of("No message annotation found."); } return create(messageMethod.message().format(), messageMethod.message().value()); } public static FormatValidator create(final Format format, final String message) throws IllegalStateException { if (message == null) { return InvalidFormatValidator.of("A message is required for the format."); } if (format == null) { return InvalidFormatValidator.of("A format is required for the message."); } switch (format) { case MESSAGE_FORMAT: return MessageFormatValidator.of(message); case PRINTF: return StringFormatValidator.of(message); case NO_FORMAT: return NoFormatValidator.INSTANCE; } return InvalidFormatValidator.of(String.format("Format %s is invalid.", format)); } private static final class InvalidFormatValidator extends AbstractFormatValidator { private InvalidFormatValidator() { super(); } static FormatValidator of(final String summaryMessage) { final InvalidFormatValidator result = new InvalidFormatValidator(); result.setSummaryMessage(summaryMessage); return result; } static FormatValidator of(final String summaryMessage, final String detailMessage) { final InvalidFormatValidator result = new InvalidFormatValidator(); result.setDetailMessage(detailMessage); result.setSummaryMessage(summaryMessage); return result; } @Override public String format() { return ""; } @Override public int argumentCount() { return 0; } @Override public boolean isValid() { return false; } } } IdLengthValidator.java000066400000000000000000000051311255176001000367520ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., 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.processor.validation; import static org.jboss.logging.processor.validation.ValidationMessageFactory.createError; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.jboss.logging.processor.model.MessageInterface; /** * @author James R. Perkins */ public class IdLengthValidator { private final Map lengths = new HashMap(); public Collection validate(final MessageInterface messageInterface) { final List messages = new LinkedList(); final String projectCode = messageInterface.projectCode(); final int idLength = messageInterface.getIdLength(); if ((idLength > 0 && idLength < 3) || idLength > 8) { messages.add(createError(messageInterface, "The length of the message id padding must be between 3 and 8. The value %d is invalid.", idLength)); } else { synchronized (this) { // Check the length id's if (lengths.containsKey(projectCode)) { final int len = lengths.get(projectCode); if (len != idLength) { messages.add(createError(messageInterface, "A length of %d was already used for project code '%s'.", len, projectCode)); } } else { lengths.put(projectCode, idLength); } } } return messages; } } IdRangeValidator.java000066400000000000000000000110061255176001000365630ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., 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.processor.validation; import static org.jboss.logging.processor.validation.ValidationMessageFactory.createError; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.jboss.logging.annotations.ValidIdRange; import org.jboss.logging.processor.model.MessageInterface; /** * @author James R. Perkins */ public class IdRangeValidator { private final Map> processed = new HashMap>(); public Collection validate(final MessageInterface messageInterface) { final List messages = new LinkedList(); for (ValidIdRange validIdRange : messageInterface.validIdRanges()) { if (validIdRange.min() > validIdRange.max()) { messages.add(createError(messageInterface, "Minimum id value (%d) cannot be greater than the maximum value (%d).", validIdRange.min(), validIdRange.max())); } else { final Map processed = getProcessed(messageInterface); for (Entry entry : processed.entrySet()) { final ValidIdRange vid = entry.getKey(); if (overlap(validIdRange, vid)) { messages.add(createError(messageInterface, "@ValidIdRange min/max (%d/%d) overlap the range (%d/%d) on '%s'.", validIdRange.min(), validIdRange.max(), vid.min(), vid.max(), entry.getValue().name())); } } final MessageInterface previous = processed.put(validIdRange, messageInterface); if (previous != null) { messages.add(createError(messageInterface, "%s was used on %s", validIdRange, messageInterface.name())); } } } return messages; } private boolean overlap(final ValidIdRange r1, final ValidIdRange r2) { return (r1.min() >= r2.min() && r1.min() <= r2.max()) || (r1.max() >= r2.min() && r1.max() <= r2.max()) || (r2.min() >= r1.min() && r2.min() <= r1.max()) || (r2.max() >= r1.min() && r2.max() <= r1.max()); } private Map findAll(final MessageInterface messageInterface) { final Map result = new HashMap(); for (ValidIdRange validIdRange : messageInterface.validIdRanges()) { result.put(validIdRange, messageInterface); } for (MessageInterface sub : messageInterface.extendedInterfaces()) { result.putAll(findAll(sub)); } return result; } private Map getProcessed(final MessageInterface messageInterface) { final String projectCode = messageInterface.projectCode(); if (projectCode.isEmpty()) { return Collections.emptyMap(); } if (processed.containsKey(projectCode)) { return processed.get(projectCode); } final Map result = new HashMap(); processed.put(projectCode, result); return result; } } MessageFormatPart.java000066400000000000000000000070171255176001000367770ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; /** * The parameter portion of the a {@link java.text.MessageFormat}. *

* **Note: Currently the format type and format style are not validated *

* Date: 14.06.2011 * * @author James R. Perkins */ class MessageFormatPart extends AbstractFormatPart { private final String originalFormat; private final int position; private int index; private String formatType; private String formatStyle; private MessageFormatPart(final int position, final String format) { this.position = position; originalFormat = format; index = 0; } public static MessageFormatPart of(final int position, final String format) { final MessageFormatPart result = new MessageFormatPart(position, format); // The first character and last character must be { and } respectively. if (format.charAt(0) != '{' || format.charAt(format.length() - 1) != '}') { throw new IllegalArgumentException("Format must begin with '{' and end with '}'. Format: " + format); } // Trim off the {} String formatText = format.substring(1, format.length() - 1); // Can't contain any more { or } if (formatText.contains("{") || formatText.contains("}")) { throw new IllegalArgumentException("String contains an invalid character. Cannot specify either '{' or '}'."); } result.init(formatText); return result; } @Override public int index() { return index; } @Override public int position() { return position; } @Override public String part() { return originalFormat; /** Should use something like this when final StringBuilder result = new StringBuilder("{"); if (index >= 0) { result.append(index); } if (formatType != null) { result.append(",").append(formatType); } if (formatStyle != null) { result.append(",").append(formatStyle); } return result.append("}").toString(); **/ } private void init(final String formatText) { if (formatText != null && !formatText.trim().isEmpty()) { try { index = Integer.parseInt(formatText.substring(0, 1)); } catch (NumberFormatException e) { throw new IllegalArgumentException("Invalid index portion of format.", e); } } } } MessageFormatValidator.java000066400000000000000000000134031255176001000400120ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Represents a {@link java.text.MessageFormat} string. *

* **Note: Currently the format type and format style are not validated *

* Date: 14.06.2011 * * @author James R. Perkins */ class MessageFormatValidator extends AbstractFormatValidator { public static final Pattern PATTERN = Pattern.compile("\\{}|\\{.+?}"); private final Set formatParts = new TreeSet(); private final Set formats = new TreeSet(); private int argumentCount; private boolean valid; private final String format; private MessageFormatValidator(final String format) { super(); this.format = format; valid = true; } public static MessageFormatValidator of(final String format) { final MessageFormatValidator result = new MessageFormatValidator(format); result.init(); result.validate(); return result; } public static MessageFormatValidator of(final String format, final Object... parameters) { final MessageFormatValidator result = new MessageFormatValidator(format); result.init(); result.validate(); result.parameterCheck(parameters); return result; } public static MessageFormatValidator of(final String format, final int parameterCount) { final MessageFormatValidator result = new MessageFormatValidator(format); result.init(); result.validate(); result.parameterCheck(parameterCount); return result; } @Override public int argumentCount() { return argumentCount; } @Override public String format() { return format; } @Override public boolean isValid() { return valid; } private void validate() { // Simple argument parser int start = format.indexOf("{"); int end = format.indexOf("}"); while (start != -1 && valid) { if (end < start) { valid = false; setSummaryMessage("Format %s appears to be missing an ending bracket.", format); } start = format.indexOf("{", end); if (start > 0) { end = format.indexOf("}", start); } } } private void parameterCheck(final Object... parameters) { if (argumentCount > 0 && parameters == null) { valid = false; setSummaryMessage("Invalid parameter count. Required %d provided null for format '%s'.", argumentCount, format); setDetailMessage("Required %d parameters, but none were provided for format %s.", argumentCount, format); } else { parameterCheck(parameters.length); } } private void parameterCheck(final int parameterCount) { if (argumentCount != parameterCount) { valid = false; setSummaryMessage("Invalid parameter count. Required: %d provided %d for format '%s'.", argumentCount, parameterCount, format); setDetailMessage("Required %d parameters, but %d were provided for format %s.", argumentCount, parameterCount, format); } } private void init() { final Matcher matcher = PATTERN.matcher(format); int position = 0; int i = 0; while (i < format.length()) { if (matcher.find(i)) { if (matcher.start() != i) { formatParts.add(StringPart.of(position++, format.substring(i, matcher.start()))); } final MessageFormatPart messageFormatPart = MessageFormatPart.of(position++, matcher.group()); formatParts.add(messageFormatPart); formats.add(messageFormatPart); i = matcher.end(); } else { formatParts.add(StringPart.of(position, format.substring(i))); break; } } final Set counted = new HashSet(); // Initialize the argument count for (MessageFormatPart messageFormatPart : formats) { if (messageFormatPart.index() >= 0) { if (counted.add(messageFormatPart.index())) argumentCount++; } } } @Override public String toString() { return new StringBuilder(getClass().getSimpleName()).append("[") .append("formatParts=") .append(formatParts) .append(", argumentCount=") .append(argumentCount) .append("]").toString(); } } MessageIdValidator.java000066400000000000000000000140411255176001000371150ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; import static org.jboss.logging.processor.util.Objects.HashCodeBuilder; import static org.jboss.logging.processor.util.Objects.areEqual; import static org.jboss.logging.processor.validation.ValidationMessageFactory.createError; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.jboss.logging.annotations.ValidIdRange; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.util.Comparison; /** * Date: 16.08.2011 * * @author James R. Perkins */ public final class MessageIdValidator { private final Map usedMessageIds = new HashMap(); MessageIdValidator() { } public Collection validate(final MessageInterface messageInterface, final MessageMethod messageMethod) { final List messages = new LinkedList(); final MessageMethod.Message message = messageMethod.message(); if (message == null) { messages.add(createError(messageMethod, "No message annotation found.")); } else { final Collection interfaceMessageMethods = messageInterface.methods(); if (!messageMethod.inheritsMessage() && !message.inheritsId()) { final int id = message.id(); if (interfaceMessageMethods.contains(messageMethod)) { final List validIdRanges = messageInterface.validIdRanges(); boolean invalidId = !validIdRanges.isEmpty(); for (ValidIdRange validIdRange : validIdRanges) { if (id >= validIdRange.min() && id <= validIdRange.max()) { invalidId = false; break; } } if (invalidId) { final StringBuilder ranges = new StringBuilder(); int count = 0; for (ValidIdRange validIdRange : validIdRanges) { ranges.append(validIdRange.min()).append('-').append(validIdRange.max()); if (++count < validIdRanges.size()) { ranges.append(", "); } } messages.add(createError(messageMethod, "Message id %d on method %s is not within the valid range: %s", id, messageMethod.name(), ranges.toString())); } } final String projectCode = messageInterface.projectCode(); final MessageKey key = createMessageKey(projectCode, id); synchronized (this) { if (usedMessageIds.containsKey(key)) { final MessageMethod previousMethod = usedMessageIds.get(key); // Allow methods with the same name to use the same id, like INHERIT does if (!previousMethod.name().equals(messageMethod.name())) { messages.add(createError(previousMethod, "Message id %s is not unique for messageMethod %s with project code %s.", id, previousMethod.name(), projectCode)); messages.add(createError(messageMethod, "Message id %s is not unique for messageMethod %s with project code %s.", id, messageMethod.name(), projectCode)); } } else { usedMessageIds.put(key, messageMethod); } } } } return messages; } private static MessageKey createMessageKey(final String projectCode, final int messageId) { return new MessageKey(projectCode, messageId); } private static class MessageKey implements Comparable { final String projectCode; final int id; MessageKey(final String projectCode, final int id) { this.projectCode = (projectCode == null ? "" : projectCode); this.id = id; } @Override public int hashCode() { return HashCodeBuilder.builder() .add(projectCode) .add(id).toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof MessageKey)) { return false; } final MessageKey other = (MessageKey) obj; return areEqual(projectCode, other.projectCode) && areEqual(id, other.id); } @Override public int compareTo(final MessageKey other) { return Comparison.begin() .compare(projectCode, other.projectCode) .compare(id, other.id).result(); } } } NoFormatValidator.java000066400000000000000000000027411255176001000370050ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; /** * @author James R. Perkins */ final class NoFormatValidator extends AbstractFormatValidator { static final NoFormatValidator INSTANCE = new NoFormatValidator(); @Override public int argumentCount() { return 0; } @Override public String format() { return "none"; } @Override public boolean isValid() { return true; } } StringFormatPart.java000066400000000000000000000526651255176001000366720ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; import java.util.Collections; import java.util.DuplicateFormatFlagsException; import java.util.IllegalFormatPrecisionException; import java.util.IllegalFormatWidthException; import java.util.LinkedHashSet; import java.util.Set; import java.util.UnknownFormatConversionException; import java.util.UnknownFormatFlagsException; /** * The parameter part of a format for {@link java.util.Formatter}. *

* Represents the following format {@linkplain %[argument_index$][flags][width][.precision]conversion}. *

* Date: 13.06.2011 * * @author James R. Perkins */ class StringFormatPart extends AbstractFormatPart { private int index; private final Set flags; private int width; private int precision; private Conversion conversion; private Character dateTimeConversion; private final int position; /** * Creates a parameter format part. * * @param position the position in the string format. */ private StringFormatPart(final int position) { this.flags = new LinkedHashSet(); this.position = position; } /** * Creates a parameter part of a format string. * * @param position the position of the part. * @param group the group array of the formats (must be a length of 6). * * @return the the parameter part. * * @throws IllegalArgumentException if the length of the group array is not equal to 6 or a format was invalid. */ public static StringFormatPart of(final int position, final String[] group) throws IllegalArgumentException { if (group.length != 6) { throw new IllegalArgumentException("Groups must have a length of 6."); } final StringFormatPart result = new StringFormatPart(position); int charIndex = 0; result.initIndex(group[charIndex++]); result.initFlags(group[charIndex++]); result.initWidth(group[charIndex++]); result.initPrecision(group[charIndex++]); // Handle date/time if (group[charIndex] != null && group[charIndex].equalsIgnoreCase(Conversion.DATE_TIME.asString())) { result.conversion = Conversion.DATE_TIME; result.dateTimeConversion = group[++charIndex].charAt(0); } else { result.conversion = Conversion.fromChar(group[++charIndex].charAt(0)); result.dateTimeConversion = null; } return result; } /** * Returns the format parameter index. *

* If the index is inherited, {@code -1} is returned. * * @return the format parameter index. */ public int index() { return index; } /** * A collection of the flags. * * @return the flags. */ public Set flags() { return Collections.unmodifiableSet(flags); } /** * The width for the format. *

* If the width was not specified, {@code -1} is returned. * * @return the width. */ public int width() { return width; } /** * The precision for the format. *

* If the precision was not specified, {@code -1} is returned. * * @return the precision. */ public int precision() { return precision; } /** * The conversion for the string format. * * @return the conversion. */ public Conversion conversion() { return conversion; } /** * The date/time conversion character. *

* {@code null} if there is not date time conversion character. * * @return the date/time conversion character or {@code null}. */ public char dateTimeChar() { return dateTimeConversion; } /** * Initializes the index field based on the string. * * @param s the index in string form. * * @throws IllegalArgumentException if the string is not a number. */ private void initIndex(final String s) throws IllegalArgumentException { if (s == null) { index = 0; } else { try { index = Integer.parseInt(s.substring(0, s.length() - 1)); } catch (NumberFormatException e) { throw new IllegalArgumentException("Invalid index argument.", e); } } } /** * Initializes the flags based on the string. *

* Will set the {@link org.jboss.logging.processor.validation.StringFormatPart#index} to {@code -1} if the {@link Flag#PREVIOUS} flag is found. * * @param s the flags in string form. * * @throws java.util.DuplicateFormatFlagsException * if the flag is specified more than once. */ private void initFlags(final String s) throws DuplicateFormatFlagsException { final char[] chars = s.toCharArray(); for (char c : chars) { final Flag flag = Flag.parse(c); if (flags.contains(flag)) { throw new DuplicateFormatFlagsException(String.format("Duplicate %s flag found. Current flags: %s", flag, flags)); } flags.add(flag); } if (flags.contains(Flag.PREVIOUS)) { index = -1; } } /** * Initializes the width based on the string. * * @param s the width in string form. * * @throws IllegalArgumentException the string is an invalid number. */ private void initWidth(final String s) throws IllegalArgumentException { if (s == null) { width = -1; } else { try { width = Integer.parseInt(s); if (width < 0) { throw new IllegalFormatWidthException(width); } } catch (NumberFormatException e) { throw new IllegalArgumentException("Invalid width argument.", e); } } } /** * Initializes the precision based on the string. * * @param s the precision in string form. * * @throws IllegalArgumentException if the precision is less than 0 or an invalid number. */ private void initPrecision(final String s) throws IllegalArgumentException { if (s == null) { precision = -1; } else { try { // Remove the '.' from the prevision precision = Integer.parseInt(s.substring(1)); if (precision < 0) throw new IllegalFormatPrecisionException(precision); } catch (NumberFormatException e) { throw new IllegalArgumentException("Invalid precision argument.", e); } } } @Override public int position() { return position; } @Override public String part() { final StringBuilder result = new StringBuilder("%"); if (index > 0) { result.append(index).append("$"); } if (!flags.isEmpty()) { for (Flag flag : flags) { result.append(flag.flag); } } if (width > 0) { result.append(width); } if (precision > 0) { result.append(".").append(precision); } result.append(conversion.asChar()); if (conversion.isDateTime() && dateTimeConversion != null) { result.append(dateTimeConversion); } return result.toString(); } @Override public String toString() { return new StringBuilder(getClass().getSimpleName()).append("[") .append("index=") .append(index) .append(", flags=") .append(flags) .append(", width=") .append(width) .append(", precision=") .append(precision) .append(", conversion=") .append(conversion) .append("]") .toString(); } /** * The flags for the string message format. * * @author James R. Perkins */ public enum Flag { /** * The result will be left-justified. *

* Works on all conversions. */ LEFT_JUSTIFY('-'), /** * The result should use a conversion-dependent alternate form. *

* Works on conversions {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#OCTAL_INTEGER}, {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#HEX_INTEGER}, all floating points * and most general conversions depending on the definition of {@link java.util.Formattable}. */ CONVERSION_DEPENDENT_ALTERNATE('#'), /** * The result will always include a sign. *

* Works on all floating points, {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#DECIMAL_INTEGER}, {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#OCTAL_INTEGER}, * {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#HEX_INTEGER} when applied to {@link java.math.BigInteger} or * {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#DECIMAL_INTEGER} when applied to {@code byte}, {@link Byte}, {@code short}, {@link Short}, * {@code int}, {@link Integer}, {@code long} and {@link Long}. */ INCLUDE_SIGN('+'), /** * The result will include a leading space for positive values. *

* Works on all floating points, {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#DECIMAL_INTEGER}, {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#OCTAL_INTEGER}, * {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#HEX_INTEGER} when applied to {@link java.math.BigInteger} or * {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#DECIMAL_INTEGER} when applied to {@code byte}, {@link Byte}, {@code short}, {@link Short}, * {@code int}, {@link Integer}, {@code long} and {@link Long}. */ SPACE_FOR_POSITIVE_VALUES(' '), /** * The result will be zero-padded. *

* Works on all integrals and floating points. */ ZERO_PADDED('0'), /** * The result will include locale-specific grouping separators. *

* Works only on {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#DECIMAL_INTEGER} integrals and {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#SCIENTIFIC_NOTATION}, * {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#DECIMAL} and {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#SCIENTIFIC_NOTATION_OR_DECIMAL} floating points. */ LOCALE_GROUPING_SEPARATOR(','), /** * The result will enclose negative numbers in parentheses. *

* Works only on {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#DECIMAL_INTEGER}, {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#OCTAL_INTEGER}, * {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#HEX_INTEGER} when applied to {@link java.math.BigInteger} or * {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#DECIMAL_INTEGER} when applied to {@code byte}, {@link Byte}, {@code short}, {@link Short}, * {@code int}, {@link Integer}, {@code long} and {@link Long} integrals and {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#SCIENTIFIC_NOTATION}, * {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#DECIMAL} and {@link org.jboss.logging.processor.validation.StringFormatPart.Conversion#SCIENTIFIC_NOTATION_OR_DECIMAL} floating points. */ PARENTHESES_FOR_NEGATIVES('('), /** * The previous position. */ PREVIOUS('<'); /** * The character flag. */ final char flag; private Flag(final char flag) { this.flag = flag; } @Override public String toString() { return new StringBuilder(name()).append("(").append(flag).append(")").toString(); } /** * Checks to see if the character is a valid flag. * * @param c the character to check. * * @return the corresponding flag for the character. * * @throws java.util.UnknownFormatFlagsException * if the flag is invalid. */ public static Flag parse(final char c) throws UnknownFormatFlagsException { for (Flag flag : Flag.values()) { if (flag.flag == c) { return flag; } } throw new UnknownFormatFlagsException("Invalid flag: " + c); } } /** * The conversions for the string format. * * @author James R. Perkins */ public enum Conversion { /** * A boolean conversion 'c' or 'C'. */ BOOLEAN('b', true) { @Override public boolean isGeneral() { return true; } }, /** * A hexadecimal conversion 'h' or 'H'. */ HEX('h', true) { @Override public boolean isGeneral() { return true; } }, /** * A string conversion 's' or 'S'. */ STRING('s', true) { @Override public boolean isGeneral() { return true; } }, /** * A unicode conversion 'c' or 'C'. */ UNICODE_CHAR('c', true) { @Override public boolean isCharacter() { return true; } }, /** * A decimal integer conversion 'd'. */ DECIMAL_INTEGER('d', false) { @Override public boolean isIntegral() { return true; } }, /** * An octal integer conversion 'o'. */ OCTAL_INTEGER('o', false) { @Override public boolean isIntegral() { return true; } }, /** * A hexadecimal integer conversion 'x' or 'X'. */ HEX_INTEGER('x', true) { @Override public boolean isIntegral() { return true; } }, /** * A scientific notation conversion 'e' or 'E'. */ SCIENTIFIC_NOTATION('e', true) { @Override public boolean isFloatingPoint() { return true; } }, /** * A decimal conversion 'f'. */ DECIMAL('f', false) { @Override public boolean isFloatingPoint() { return true; } }, /** * A scientific notation or decimal 'g' or 'G' */ SCIENTIFIC_NOTATION_OR_DECIMAL('g', true) { @Override public boolean isFloatingPoint() { return true; } }, /** * A hexadecimal floating point number 'a' or 'A'. */ HEX_FLOATING_POINT('a', true) { @Override public boolean isFloatingPoint() { return true; } }, /** * A date or time conversion 't' or 'T'. */ DATE_TIME('t', true) { @Override public boolean isDateTime() { return true; } }, /** * A percentage conversion '%'. */ PERCENT('%', false) { @Override public boolean isPercent() { return true; } }, /** * A line separator conversion 'n'. */ LINE_SEPARATOR('n', false) { @Override public boolean isLineSeparator() { return true; } }; private final char conversion; /** * @code true} for the case should be ignored, otherwise {@code false} */ final boolean ignoreCase; /** * Private enum conversion. * * @param conversion the conversion character. * @param ignoreCase {@code true} for the case should be ignored, otherwise {@code false}. */ private Conversion(final char conversion, final boolean ignoreCase) { this.conversion = conversion; this.ignoreCase = ignoreCase; } /** * If the conversion is a general conversion {@code true} is returned, otherwise {@code false}. * * @return {@code true} if a general conversion, otherwise {@code false}. */ public boolean isGeneral() { return false; } /** * If the conversion is a character {@code true} is returned, otherwise {@code false}. * * @return {@code true} if c character, otherwise {@code false}. */ public boolean isCharacter() { return false; } /** * If the conversion is an integral {@code true} is returned, otherwise {@code false}. * * @return {@code true} if an integral, otherwise {@code false}. */ public boolean isIntegral() { return false; } /** * If the conversion is a floating point {@code true} is returned, otherwise {@code false}. * * @return {@code true} if a line separator, otherwise {@code false}. */ public boolean isFloatingPoint() { return false; } /** * If the conversion is a date or time {@code true} is returned, otherwise {@code false}. * * @return {@code true} if a date or time, otherwise {@code false}. */ public boolean isDateTime() { return false; } /** * If the conversion is a percent {@code true} is returned, otherwise {@code false}. * * @return {@code true} if a percent, otherwise {@code false}. */ public boolean isPercent() { return false; } /** * If the conversion is a line separator {@code true} is returned, otherwise {@code false}. * * @return {@code true} if a line separator, otherwise {@code false}. */ public boolean isLineSeparator() { return false; } /** * Returns the conversion character. * * @return the conversion character. */ public char asChar() { return conversion; } /** * Returns the conversion character as a {@link String} * * @return the conversion character. */ public String asString() { return String.valueOf(conversion); } @Override public String toString() { final StringBuilder result = new StringBuilder(name()); result.append("("); result.append(conversion); if (ignoreCase) { result.append(", ").append(Character.toUpperCase(conversion)); } result.append(")"); return result.toString(); } /** * Converts the character into a conversion descriptor. * * @param c the character to convert. * * @return the conversion descriptor. * * @throws java.util.UnknownFormatConversionException * if the character is not a valid conversion format. */ public static Conversion fromChar(final char c) throws UnknownFormatConversionException { for (Conversion conversion : Conversion.values()) { if (conversion.ignoreCase && conversion.asChar() == Character.toLowerCase(c)) { return conversion; } else if (conversion.asChar() == c) { return conversion; } } throw new UnknownFormatConversionException(String.valueOf(c)); } } } StringFormatValidator.java000066400000000000000000000372571255176001000377110ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.IllegalFormatException; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.UnknownFormatConversionException; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * A string format representation. *

* Date: 13.06.2011 * * @author James R. Perkins */ public final class StringFormatValidator extends AbstractFormatValidator { /** * The Regex pattern. */ public static final Pattern PATTERN = Pattern.compile("%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])"); private final Set formatParts = new TreeSet(); private final Set formats = new TreeSet(); private int argumentCount; private boolean valid; private final String format; /** * Private constructor for the singleton pattern. * * @param format the format. */ private StringFormatValidator(final String format) { super(); this.format = format; this.valid = true; } /** * Creates a string format. * * @param format the format. * * @return the string format. */ public static StringFormatValidator of(final String format) { final StringFormatValidator result = new StringFormatValidator(format); try { result.init(); result.validate(); } catch (RuntimeException e) { if (result.isValid()) { result.valid = false; result.setDetailMessage("Format '%s' appears to be invalid. Error: %s", format, e.getMessage()); } } return result; } /** * Creates a string format. *

* Note: The validator returned is the validator for the translation format. * * @param format the format. * @param translationFormat the format of the translation * * @return the string format. */ public static StringFormatValidator withTranslation(final String format, final String translationFormat) { final StringFormatValidator result = new StringFormatValidator(format); final StringFormatValidator translationResult = new StringFormatValidator(translationFormat); try { result.init(); result.validate(); } catch (RuntimeException e) { if (result.isValid()) { result.valid = false; result.setDetailMessage("Format '%s' appears to be invalid. Error: %s", format, e.getMessage()); } } try { translationResult.init(); translationResult.validate(); } catch (RuntimeException e) { if (translationResult.isValid()) { translationResult.valid = false; translationResult.setDetailMessage("Format '%s' appears to be invalid. Error: %s", format, e.getMessage()); } } // If either is invalid, return the invalid one if (!result.isValid()) return result; if (!translationResult.isValid()) return translationResult; // Sort the formats final List initParts = sortParts(result.formats); final List translationParts = sortParts(translationResult.formats); // The size should be the same as well as the position of each element if (initParts.size() == translationParts.size()) { // Parameters should be in the exact order final Iterator initIter = initParts.iterator(); final Iterator translationIter = translationParts.iterator(); while (initIter.hasNext()) { final StringFormatPart initPart = initIter.next(); final StringFormatPart translationPart = translationIter.next(); if (initPart.conversion() != translationPart.conversion()) { translationResult.valid = false; translationResult.setDetailMessage("The translated message format (%s) does not match the initial message format (%s).", translationFormat, format); translationResult.setSummaryMessage("The translated message format does not match the initial message format."); break; } } } else { translationResult.valid = false; translationResult.setDetailMessage("The translated message format (%s) does not match the initial message format (%s).", translationFormat, format); translationResult.setSummaryMessage("The translated message format does not match the initial message format."); } return translationResult; } /** * Creates a string format. * * @param format the format. * @param parameters the parameters to validate against. * * @return the string format. */ public static StringFormatValidator of(final String format, final Object... parameters) { final StringFormatValidator result = new StringFormatValidator(format); try { result.init(); result.validate(parameters); } catch (RuntimeException e) { if (result.isValid()) { result.valid = false; result.setSummaryMessage("Format '%s' appears to be invalid. Error: %s", format, e.getMessage()); } } return result; } static List sortParts(final Collection parts) { final TreeMap paramMap = new TreeMap(); int index = 0; int count = 0; for (StringFormatPart part : parts) { // Check the index and set appropriately if (part.index() > 0) { index = part.index(); } else if (part.index() == 0) { index = ++count; } if (!paramMap.containsKey(index)) { paramMap.put(index, part); } } return new ArrayList(paramMap.values()); } /** * Validates */ private void validate() { if (!format.equalsIgnoreCase(asFormat())) { valid = false; setSummaryMessage("Formats don't match. Internal error: %s Reconstructed: %s", format, asFormat()); setDetailMessage("The original is '%s' and the reconstructed format is '%s'. This is likely an internal error and should be reported.", format, asFormat()); } else { // Create a multimap to hold the parameter values for sorting final Map> paramMap = new TreeMap>(); int counter = 0; int index = 0; // Initialize the argument count for (StringFormatPart stringFormatPart : formats) { if (counter == argumentCount) { break; } // Check the index and set appropriately if (stringFormatPart.index() > 0 || stringFormatPart.index() == 0) { index = stringFormatPart.index(); } else if (stringFormatPart.index() < -1) { index = 0; } // Find or create the list for the multimap. final List params; if (paramMap.containsKey(index)) { params = paramMap.get(index); // Skip positional if already defined. if (index > 0) { continue; } } else { params = new ArrayList(); paramMap.put(index, params); } counter++; // Add the type. switch (stringFormatPart.conversion()) { case BOOLEAN: params.add(true); break; case DATE_TIME: params.add(new Date()); break; case DECIMAL: case HEX_FLOATING_POINT: params.add(1.5f); break; case DECIMAL_INTEGER: case HEX_INTEGER: case OCTAL_INTEGER: params.add(33); break; case HEX: case STRING: params.add("JBoss"); break; case SCIENTIFIC_NOTATION: case SCIENTIFIC_NOTATION_OR_DECIMAL: params.add(10000.55050d); break; case UNICODE_CHAR: params.add('c'); break; case LINE_SEPARATOR: case PERCENT: counter--; break; default: valid = false; setSummaryMessage("Format not found: %s", stringFormatPart); } } if (valid) { try { // Copy the results in order to a new list. final List params = new ArrayList(); for (Map.Entry> entry : paramMap.entrySet()) { params.addAll(entry.getValue()); } // Test the format String.format(format, params.toArray()); } catch (final IllegalFormatException e) { valid = false; setSummaryMessage("Invalid format for '%s' with parameters '%s'. java.util.Formatter Error: %s", format, paramMap, e.getMessage()); setDetailMessage("Format '%s' with parameters '%s' is invalid. StringFormatValidator: %s", format, paramMap, this); } } } } private void validate(final Object... parameters) { // First perform general validation validate(); // Now test parameters counts final int paramCount = (parameters == null ? 0 : parameters.length); if (argumentCount != paramCount) { valid = false; setSummaryMessage("Parameter lengths do not match. Format (%s) requires %d arguments, supplied %d.", format, argumentCount, paramCount); } // Create a parameter list based on the parameters passed if (valid) { try { String.format(format, parameters); } catch (final IllegalFormatException e) { valid = false; setSummaryMessage("Invalid format for '%s' with parameters '%s'. java.util.Formatter Error: %s", format, Arrays.asList(parameters), e.getMessage()); setDetailMessage("Format '%s' with parameters '%s' is invalid. StringFormatValidator: %s", format, Arrays.asList(parameters), this); } } } @Override public int argumentCount() { return argumentCount; } @Override public String format() { return format; } @Override public boolean isValid() { return valid; } /** * Recreates the format using the internal formatting descriptors. * * @return the format. */ public String asFormat() { final StringBuilder result = new StringBuilder(); for (FormatPart formatPart : formatParts) { result.append(formatPart.part()); } return result.toString(); } @Override public String toString() { return new StringBuilder(getClass().getSimpleName()).append("[") .append("formatParts=") .append(formatParts) .append(", argumentCount=") .append(argumentCount) .append("]").toString(); } /** * Initialize the string format. */ private void init() { final Matcher matcher = PATTERN.matcher(format); int position = 0; int i = 0; while (i < format.length()) { if (matcher.find(i)) { if (matcher.start() != i) { formatParts.add(StringPart.of(position++, format.substring(i, matcher.start()))); } // Pattern should produce 6 groups. final String[] formatGroup = new String[6]; for (int groupIndex = 0; groupIndex < matcher.groupCount(); groupIndex++) { formatGroup[groupIndex] = matcher.group(groupIndex + 1); } final StringFormatPart stringFormatPart = StringFormatPart.of(position++, formatGroup); formatParts.add(stringFormatPart); formats.add(stringFormatPart); i = matcher.end(); } else { // No more formats found, but validate for invalid remaining characters. checkText(format.substring(i)); formatParts.add(StringPart.of(position, format.substring(i))); break; } } final Set counted = new HashSet(); int count = 1; // Initialize the argument count for (StringFormatPart stringFormatPart : formats) { if (stringFormatPart.conversion().isLineSeparator() || stringFormatPart.conversion().isPercent()) continue; if (stringFormatPart.index() > 0) { if (counted.add(stringFormatPart.index())) { argumentCount++; } } else if (stringFormatPart.index() == 0) { if (!counted.contains(count)) { argumentCount++; counted.add(count); count++; } } } } /** * Checks text to make sure we don't have extra garbage. * * @param text the text to check. */ private static void checkText(final String text) { final int index; // If there are any '%' in the given string, we got a bad format // specifier. if ((index = text.indexOf('%')) != -1) { final char c = (index > text.length() - 2 ? '%' : text.charAt(index + 1)); throw new UnknownFormatConversionException(String.valueOf(c)); } } } StringPart.java000066400000000000000000000041011255176001000354770ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; /** * Represents the string portions of a format string. *

* Date: 13.06.2011 * * @author James R. Perkins */ class StringPart extends AbstractFormatPart { private final int position; private final String part; /** * Creates a new string part. * * @param position the position. * @param part the string. */ public StringPart(final int position, final String part) { this.position = position; this.part = part; } /** * Creates a new string part. * * @param position the position. * @param part the string. * * @return the string part. */ public static StringPart of(final int position, final String part) { return new StringPart(position, part); } @Override public int index() { return STRING; } @Override public int position() { return position; } @Override public String part() { return part; } } ValidationMessage.java000066400000000000000000000033721255176001000370120ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; import org.jboss.logging.processor.model.MessageObject; /** * Date: 12.08.2011 * * @author James R. Perkins */ public interface ValidationMessage { /** * Validation message type enum. */ public enum Type { ERROR, WARN } /** * The type of the message. * * @return the type of the message. */ Type type(); /** * Returns the message object that caused the error. * * @return the message object that caused the error. */ MessageObject getMessageObject(); /** * Returns the error message. * * @return the error message. */ String getMessage(); } ValidationMessageFactory.java000066400000000000000000000066031255176001000403420ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; import org.jboss.logging.processor.model.MessageObject; /** * Date: 12.08.2011 * * @author James R. Perkins */ public final class ValidationMessageFactory { /** * Private constructor for factory. */ private ValidationMessageFactory() { } public static ValidationMessage createError(final MessageObject messageObject, final String message) { return new ValidationErrorMessage(messageObject, message); } public static ValidationMessage createError(final MessageObject messageObject, final String format, final Object... args) { return new ValidationErrorMessage(messageObject, String.format(format, args)); } public static ValidationMessage createWarning(final MessageObject messageObject, final String message) { return new ValidationWarningMessage(messageObject, message); } public static ValidationMessage createWarning(final MessageObject messageObject, final String format, final Object... args) { return new ValidationWarningMessage(messageObject, String.format(format, args)); } private static abstract class AbstractValidationMessage implements ValidationMessage { private final MessageObject messageObject; private final String message; AbstractValidationMessage(final MessageObject messageObject, final String message) { this.messageObject = messageObject; this.message = message; } @Override public final MessageObject getMessageObject() { return messageObject; } @Override public final String getMessage() { return message; } } private static class ValidationErrorMessage extends AbstractValidationMessage { private ValidationErrorMessage(final MessageObject messageObject, final String message) { super(messageObject, message); } @Override public Type type() { return Type.ERROR; } } private static class ValidationWarningMessage extends AbstractValidationMessage { private ValidationWarningMessage(final MessageObject messageObject, final String message) { super(messageObject, message); } @Override public Type type() { return Type.WARN; } } } Validator.java000066400000000000000000000476501255176001000353470ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/java/org/jboss/logging/processor/validation/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.validation; import static org.jboss.logging.processor.model.Parameter.ParameterType; import static org.jboss.logging.processor.validation.ValidationMessageFactory.createError; import static org.jboss.logging.processor.validation.ValidationMessageFactory.createWarning; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.jboss.logging.annotations.ConstructType; import org.jboss.logging.annotations.Once; import org.jboss.logging.annotations.Pos; import org.jboss.logging.annotations.Transform; import org.jboss.logging.annotations.Transform.TransformType; import org.jboss.logging.processor.model.MessageInterface; import org.jboss.logging.processor.model.MessageInterface.AnnotatedType; import org.jboss.logging.processor.model.MessageMethod; import org.jboss.logging.processor.model.Parameter; import org.jboss.logging.processor.model.ReturnType; import org.jboss.logging.processor.model.ThrowableType; import org.jboss.logging.processor.util.ElementHelper; /** * Date: 12.08.2011 * * @author James R. Perkins */ public final class Validator { private final MessageIdValidator messageIdValidator; private final IdLengthValidator idLengthValidator; private final IdRangeValidator idRangeValidator; public Validator() { messageIdValidator = new MessageIdValidator(); idLengthValidator = new IdLengthValidator(); idRangeValidator = new IdRangeValidator(); } /** * Validates the message interface and returns a collection of validation messages or an empty collection. * * @param messageInterface the message interface to validate. * * @return a collection of validation messages or an empty collection. */ public final Collection validate(final MessageInterface messageInterface) { final List messages = new ArrayList(); switch (messageInterface.getAnnotatedType()) { case MESSAGE_BUNDLE: { // Get all messageMethods except logger interface messageMethods final Set messageMethods = getAllMethods(messageInterface); messages.addAll(validateCommon(messageInterface, messageMethods)); messages.addAll(validateBundle(messageMethods)); break; } case MESSAGE_LOGGER: { // Get all messageMethods except logger interface messageMethods final Set messageMethods = getAllMethods(messageInterface); messages.addAll(validateCommon(messageInterface, messageMethods)); messages.addAll(validateLogger(messageMethods)); break; } default: messages.add(createError(messageInterface, "Message interface %s is not a message bundle or message logger.", messageInterface.name())); } return messages; } /** * Validate common attributes to all interfaces. * * @param messageInterface the interface. * @param messageMethods the messageMethods to validate. * * @return a collection of validation messages. */ private Collection validateCommon(final MessageInterface messageInterface, final Set messageMethods) { final List messages = new ArrayList(); final Map methodNames = new HashMap(); messages.addAll(idLengthValidator.validate(messageInterface)); messages.addAll(idRangeValidator.validate(messageInterface)); for (MessageMethod messageMethod : messageMethods) { // Check for checked exceptions thrown on the interface messageMethod for (ThrowableType throwableType : messageMethod.thrownTypes()) { if (throwableType.isChecked()) { messages.add(createError(messageMethod, "Interface message methods cannot throw checked exceptions.")); } } final MessageMethod.Message message = messageMethod.message(); if (message == null) { messages.add(createError(messageMethod, "All message bundles and message logger message methods must have or inherit a message.")); continue; } // Check the message id if (message.hasId()) { // Make sure the message id is greater than 0 if (message.id() < 0) { messages.add(createError(messageMethod, "Message id %d is invalid. Must be greater than 0 or inherit another valid id.", message.id())); } else { messages.addAll(messageIdValidator.validate(messageInterface, messageMethod)); } } final FormatValidator formatValidator = FormatValidatorFactory.create(messageMethod); if (formatValidator.isValid()) { final int paramCount = messageMethod.formatParameterCount(); if (messageMethod.formatParameterCount() != formatValidator.argumentCount()) { messages.add(createError(messageMethod, "Parameter count does not match for format '%s'. Required: %d Provided: %d", formatValidator.format(), formatValidator.argumentCount(), paramCount)); } // Validate the transform parameter if (!messageMethod.parameters(ParameterType.TRANSFORM).isEmpty()) { final Set parameters = messageMethod.parameters(ParameterType.TRANSFORM); // Validate each parameter for (Parameter parameter : parameters) { validateTransform(messages, parameter, parameter.transform()); } } // Validate the POS annotated parameters if (!messageMethod.parameters(ParameterType.POS).isEmpty()) { final Map positions = new TreeMap(); final Set parameters = messageMethod.parameters(ParameterType.POS); // Validate each parameter for (Parameter parameter : parameters) { final Pos pos = parameter.pos(); final Transform[] transforms = pos.transform(); if (transforms != null && transforms.length > 0) { if (pos.value().length != transforms.length) { messages.add(createError(parameter, "Positional parameters with transforms must have an equal number of positions and transforms.")); } else { for (Transform transform : transforms) { validateTransform(messages, parameter, transform); } } } // Validate the positions final Set usedPositions = new HashSet(); for (int position : pos.value()) { if (usedPositions.contains(position)) { messages.add(createError(parameter, "Position '%d' already used for this parameter.", position)); } else { usedPositions.add(position); } if (positions.containsKey(position)) { messages.add(createError(parameter, "Position '%d' already defined on parameter '%s'", position, positions.get(position).name())); } else { positions.put(position, parameter); } } } // Check for missing indexed parameters for (int i = 0; i < messageMethod.formatParameterCount(); i++) { final int positionIndex = i + 1; if (!positions.containsKey(positionIndex)) { messages.add(createError(messageMethod, "Missing parameter with position '%d' defined.", positionIndex)); } } } } else { messages.add(createError(messageMethod, formatValidator.summaryMessage())); } // Make sure there is only one @Message annotation per messageMethod name. if (!messageMethod.inheritsMessage()) { final String key = messageMethod.name() + messageMethod.formatParameterCount(); if (methodNames.containsKey(key)) { final MessageMethod previousMethod = methodNames.get(key); messages.add(createError(previousMethod, "Only one message with the same format parameters is allowed.")); messages.add(createError(messageMethod, "Only one message with the same format parameters is allowed.")); } else { methodNames.put(key, messageMethod); } } // Validate the parameters messages.addAll(validateParameters(messageMethod)); } return messages; } private void validateTransform(final List messages, final Parameter parameter, final Transform transform) { final List transformTypes = Arrays.asList(transform.value()); // If annotated with @Transform, must be an Object, primitives are not allowed if (parameter.isPrimitive()) { messages.add(createError(parameter, "Parameters annotated with @Transform cannot be primitives.")); } else if (transformTypes.contains(TransformType.GET_CLASS) && transformTypes.contains(TransformType.SIZE)) { messages.add(createError(parameter, "Transform type '%s' not allowed with type '%s'", TransformType.GET_CLASS, TransformType.SIZE)); } else if (transformTypes.contains(TransformType.HASH_CODE) && transformTypes.contains(TransformType.SIZE)) { messages.add(createError(parameter, "Transform type '%s' not allowed with type '%s'", TransformType.HASH_CODE, TransformType.SIZE)); } else if (transformTypes.contains(TransformType.IDENTITY_HASH_CODE) && transformTypes.contains(TransformType.SIZE)) { messages.add(createError(parameter, "Transform type '%s' not allowed with type '%s'", TransformType.IDENTITY_HASH_CODE, TransformType.SIZE)); } else if (transformTypes.contains(TransformType.IDENTITY_HASH_CODE) && transformTypes.contains(TransformType.HASH_CODE)) { messages.add(createError(parameter, "Transform type '%s' not allowed with type '%s'", TransformType.IDENTITY_HASH_CODE, TransformType.HASH_CODE)); } else if (transformTypes.contains(TransformType.SIZE)) { if (!(parameter.isArray() || parameter.isVarArgs() || parameter.isSubtypeOf(Map.class) || parameter.isSubtypeOf(Collection.class) || parameter.isSubtypeOf(CharSequence.class))) { messages.add(createError(parameter, "Invalid type (%s) for %s. Must be an array, %s, %s or %s.", parameter.type(), TransformType.SIZE, Collection.class.getName(), Map.class.getName(), CharSequence.class.getName())); } } } private Collection validateParameters(final MessageMethod messageMethod) { final List messages = new ArrayList(); boolean foundCause = false; final ReturnType returnType = messageMethod.returnType(); for (Parameter parameter : messageMethod.parameters(ParameterType.ANY)) { switch (parameter.parameterType()) { case CAUSE: { if (foundCause) { messages.add(createError(messageMethod, "Only one cause parameter is allowed.")); } else { foundCause = true; } break; } case FQCN: if (!parameter.type().equals(Class.class.getName())) { messages.add(createError(parameter, "Parameter %s annotated with @LoggingClass on method %s must be of type %s.", parameter.name(), messageMethod.name(), Class.class.getName())); } break; case FIELD: { if (!returnType.hasFieldFor(parameter)) { messages.add(createError(parameter, "No target field found in %s with name %s with type %s.", returnType.type(), parameter.targetName(), parameter.type())); } break; } case PROPERTY: { if (!returnType.hasMethodFor(parameter)) { messages.add(createError(parameter, "No method found in %s with signature %s(%s).", returnType.type(), parameter.targetName(), parameter.type())); } break; } } } // TODO - Check all parameter counts return messages; } /** * Validate message bundle messageMethods. * * @param messageMethods the messageMethods to validate. * * @return a collection of the validation messages. */ private Collection validateBundle(final Set messageMethods) { final List messages = new ArrayList(); for (MessageMethod messageMethod : messageMethods) { messages.addAll(validateBundleMethod(messageMethod)); } return messages; } private Collection validateBundleMethod(final MessageMethod messageMethod) { final List messages = new ArrayList(); // The return type must be a Throwable or String final ReturnType returnType = messageMethod.returnType(); if (returnType.equals(ReturnType.VOID) || returnType.isPrimitive()) { messages.add(createError(messageMethod, "Message bundle messageMethod %s has an invalid return type. Cannot be void or a primitive.", messageMethod.name())); } else if (returnType.isThrowable()) { final ThrowableType throwableReturnType = returnType.throwableReturnType(); if (throwableReturnType.useConstructionParameters()) { // TODO - Check the return type constructor. Currently handled via the ThrowableReturnTypeFactory. } else if (!throwableReturnType.useConstructionParameters() && !messageMethod.parameters(ParameterType.CONSTRUCTION).isEmpty()) { messages.add(createError(messageMethod, "MessageMethod does not have an usable constructor for the return type %s.", returnType.name())); } else { final boolean hasMessageConstructor = (throwableReturnType.hasStringAndThrowableConstructor() || throwableReturnType.hasThrowableAndStringConstructor() || throwableReturnType.hasStringConstructor()); final boolean usableConstructor = (throwableReturnType.hasDefaultConstructor() || throwableReturnType.hasStringAndThrowableConstructor() || throwableReturnType.hasStringConstructor() || throwableReturnType.hasThrowableAndStringConstructor() || throwableReturnType.hasThrowableConstructor()); if (!usableConstructor) { messages.add(createError(messageMethod, "MessageMethod does not have an usable constructor for the return type %s.", returnType.name())); } else if (!hasMessageConstructor) { // Check to see if there is no message constructor messages.add(createWarning(messageMethod, "The message cannot be set via the throwable constructor and will be ignored.")); } } } else { if (!returnType.isAssignableFrom(String.class)) { messages.add(createError(messageMethod, "Message bundle method (%s) has an invalid return type of %s.", messageMethod.name(), returnType.name())); } if (ElementHelper.isAnnotatedWith(messageMethod.reference(), ConstructType.class)) { messages.add(createError(messageMethod, "ConstructType annotation requires a throwable return type")); } } return messages; } /** * Validate message logger messageMethods. * * @param messageMethods the messageMethods to validate. * * @return a collection of the validation messages. */ private Collection validateLogger(final Set messageMethods) { final List messages = new ArrayList(); for (MessageMethod messageMethod : messageMethods) { if (messageMethod.isLoggerMethod()) { messages.addAll(validateLoggerMethod(messageMethod)); } else { messages.addAll(validateBundleMethod(messageMethod)); if (ElementHelper.isAnnotatedWith(messageMethod.reference(), Once.class)) { messages.add(createError(messageMethod, "Only @LogMessage method can be annoted with @Once")); } } } return messages; } private Collection validateLoggerMethod(final MessageMethod messageMethod) { final List messages = new ArrayList(); // The return type must be void if (!ReturnType.VOID.equals(messageMethod.returnType())) { messages.add(createError(messageMethod, "Message logger methods can only have a void return type.")); } return messages; } /** * Finds all methods for the given interface, but ignores logger interface methods. * * @param messageInterface the interface to find all methods for. * * @return a set of all the methods (exception logger interface methods) the interface must implement. */ private Set getAllMethods(final MessageInterface messageInterface) { if (messageInterface.getAnnotatedType() == AnnotatedType.NONE) { return Collections.emptySet(); } final Set messageMethods = new LinkedHashSet(); for (MessageMethod messageMethod : messageInterface.methods()) { messageMethods.add(messageMethod); } for (MessageInterface msgInterface : messageInterface.extendedInterfaces()) { messageMethods.addAll(getAllMethods(msgInterface)); } return messageMethods; } } jboss-logging-tools-2.0.1.Final/processor/src/main/resources/000077500000000000000000000000001255176001000242055ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/resources/META-INF/000077500000000000000000000000001255176001000253455ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/resources/META-INF/services/000077500000000000000000000000001255176001000271705ustar00rootroot00000000000000javax.annotation.processing.Processor000066400000000000000000000000651255176001000364500ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/main/resources/META-INF/servicesorg.jboss.logging.processor.apt.LoggingToolsProcessorjboss-logging-tools-2.0.1.Final/processor/src/test/000077500000000000000000000000001255176001000222265ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/000077500000000000000000000000001255176001000231475ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/000077500000000000000000000000001255176001000237365ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/000077500000000000000000000000001255176001000250565ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/000077500000000000000000000000001255176001000265045ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/000077500000000000000000000000001255176001000305235ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/000077500000000000000000000000001255176001000324615ustar00rootroot00000000000000AbstractLoggerTest.java000066400000000000000000000046671255176001000370250ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generated; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; /** * @author James R. Perkins */ public abstract class AbstractLoggerTest { static final String PROJECT_CODE = "LOGL"; static final MessageListHandler HANDLER = new MessageListHandler(); static final String CATEGORY = AbstractLoggerTest.class.getPackage().getName(); static final String LOGGER_ID_PATTERN = "LOG.*[0-9]:\\s"; @BeforeClass public static void installHandler() { org.jboss.logmanager.Logger.getLogger(CATEGORY).addHandler(HANDLER); } @AfterClass public static void uninstallHandler() { HANDLER.close(); org.jboss.logmanager.Logger.getLogger(CATEGORY).removeHandler(HANDLER); } protected String parseStringLoggerId(final String message) { final Pattern p = Pattern.compile(LOGGER_ID_PATTERN); final Matcher m = p.matcher(message); if (m.find()) { return m.group(); } return null; } protected int parseLoggerId(final String message) { final String stringId = parseStringLoggerId(message); if (stringId != null) { final String s = message.replaceAll("([a-zA-z]|:.*)", ""); return Integer.parseInt(s); } return 0; } } DefaultLogger.java000077500000000000000000000064651255176001000360070ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generated; import org.jboss.logging.BasicLogger; import org.jboss.logging.Logger; import org.jboss.logging.Logger.Level; import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.FormatWith; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.Message.Format; import org.jboss.logging.annotations.MessageLogger; import org.jboss.logging.annotations.ValidIdRange; /** * @author James R. Perkins Jr. (jrp) */ @MessageLogger(projectCode = AbstractLoggerTest.PROJECT_CODE) @ValidIdRange(min = 100, max = 150) interface DefaultLogger extends BasicLogger { final String TEST_MSG = "No format%n"; /** * The default logger. */ DefaultLogger LOGGER = Logger.getMessageLogger(DefaultLogger.class, AbstractLoggerTest.CATEGORY); // Used to test the ambiguous log field in the DelegatingBasicLogger DefaultLogger log = Logger.getMessageLogger(DefaultLogger.class, AbstractLoggerTest.CATEGORY); @LogMessage(level = Level.INFO) @Message(id = 100, value = "Hello %s.") void hello(String name); @LogMessage(level = Level.INFO) @Message(id = 101, value = "How are you %s?") void howAreYou(String name); @LogMessage(level = Level.INFO) @Message(id = 102, format = Format.NO_FORMAT, value = TEST_MSG) void noFormat(); @LogMessage(level = Level.INFO) @Message(id = 103, format = Format.NO_FORMAT, value = TEST_MSG) void noFormatWithCause(@Cause Throwable cause); @LogMessage(level = Level.INFO) @Message(id = 104, value = "Test Message: %s") void formatWith(@FormatWith(CustomFormatter.class) String msg); @LogMessage(level = Level.ERROR) @Message(id = 105, value = "Valid values are; %s") void invalidSelection(String... validValues); @LogMessage(level = Level.ERROR) @Message(id = Message.INHERIT, value = "Invalid value '%s'. Valid values are; %s") void invalidSelection(String selected, String[] validValues); static class CustomFormatter { private final String msg; public CustomFormatter(final String msg) { this.msg = msg; } @Override public String toString() { return String.format("Message: %s", msg); } } } DefaultMessages.java000077500000000000000000000032251255176001000363260ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., 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.processor.generated; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageBundle; import org.jboss.logging.annotations.ValidIdRange; /** * @author James R. Perkins Jr. (jrp) */ @MessageBundle(projectCode = AbstractLoggerTest.PROJECT_CODE) @ValidIdRange(min = 10000, max = 10050) interface DefaultMessages { @Message(id = 10000, value = "Hello %s.") String hello(String name); @Message(id = 10001, value = "How are you %s?") String howAreYou(String name); @Message(id = 10002, value = "Username %s is invalid.") RuntimeException invalidUser(String name); } ExtendedLogger.java000066400000000000000000000031751255176001000361530ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., 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.processor.generated; import org.jboss.logging.Logger.Level; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageLogger; import org.jboss.logging.annotations.ValidIdRange; /** * @author James R. Perkins */ @ValidIdRange(min = 1000, max = 1500) @MessageLogger(projectCode = AbstractLoggerTest.PROJECT_CODE) public interface ExtendedLogger extends DefaultLogger { @LogMessage(level = Level.ERROR) @Message(id = 1000, value = "Extension error") void extensionError(); } GeneratedSourceAnalysisTest.java000066400000000000000000000270531255176001000406770ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., 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.processor.generated; import java.io.BufferedReader; import java.io.Closeable; import java.io.File; import java.io.FileFilter; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** * @author James R. Perkins */ public class GeneratedSourceAnalysisTest { private static String TEST_SRC_PATH = null; private static String TEST_GENERATED_SRC_PATH = null; private final Pattern methodNamePattern = Pattern.compile("((?:\\s?|\\s+?)(?:public final)?\\s+)?([\\w\\.]+)\\s+(\\w+)(\\(.*)"); private final Pattern fieldNamePattern = Pattern.compile("((?:\\s?|\\s+?)private static final\\s+)([\\w\\.]+String|String)(?:\\s+)(\\w+)(.*)"); private final Pattern messageMethodPattern = Pattern.compile("((?:\\s?|\\s+?)protected\\s+)([\\w.]+String|String)(?:\\s+)(\\w+)(\\$str\\(\\))(.*)"); @BeforeClass public static void setUp() { TEST_SRC_PATH = System.getProperty("test.src.path"); TEST_GENERATED_SRC_PATH = System.getProperty("test.generated.src.path"); } @Test public void testGeneratedMethodOrder() throws Exception { compare(DefaultLogger.class); compare(DefaultMessages.class); compare(ValidMessages.class); } private void compare(final Class intf) throws Exception { final Descriptor intfDescriptor = parseInterface(intf); final Descriptors implDescriptors = parseGenerated(intf); final List intfMethods = intfDescriptor.get(Descriptor.Type.METHOD); for (Descriptor implDescriptor : implDescriptors) { if (implDescriptor.filterNames) { List l = new ArrayList(); // We're only testing order, so only test methods that are in the implementation final List implMessageMethods = implDescriptor.get(Descriptor.Type.MESSAGE_METHOD); Assert.assertFalse(implMessageMethods.isEmpty(), "No methods found in " + implDescriptor.filename); for (String s : intfMethods) { if (implMessageMethods.contains(s)) { l.add(s); } } Result result = compare(l, implMessageMethods); if (result.failed) { Assert.fail(String.format("Interface %s (%s) failed on %s; %s", intf.getName(), implDescriptor.filename, Descriptor.Type.MESSAGE_METHOD, result.message)); } l = new ArrayList(); // We're only testing order, so only test methods that are in the implementation final List implFields = implDescriptor.get(Descriptor.Type.FIELD); Assert.assertFalse(implFields.isEmpty(), "No fields found in " + implDescriptor.filename); for (String s : intfMethods) { if (implFields.contains(s)) { l.add(s); } } result = compare(l, implFields); if (result.failed) { Assert.fail(String.format("Interface %s (%s) failed on %s; %s", intf.getName(), implDescriptor.filename, Descriptor.Type.FIELD, result.message)); } } else { Result result = compare(intfMethods, implDescriptor.get(Descriptor.Type.METHOD)); if (result.failed) { Assert.fail(String.format("Interface %s (%s) failed on %s; %s", intf.getName(), implDescriptor.filename, Descriptor.Type.METHOD, result.message)); } result = compare(intfMethods, implDescriptor.get(Descriptor.Type.FIELD)); if (result.failed) { Assert.fail(String.format("Interface %s (%s) failed on %s; %s", intf.getName(), implDescriptor.filename, Descriptor.Type.FIELD, result.message)); } result = compare(intfMethods, implDescriptor.get(Descriptor.Type.MESSAGE_METHOD)); if (result.failed) { Assert.fail(String.format("Interface %s (%s) failed on %s; %s", intf.getName(), implDescriptor.filename, Descriptor.Type.MESSAGE_METHOD, result.message)); } } } } private Result compare(final List list1, final List list2) { // If the size is different there's an error... ...in the test if (list1.size() != list2.size()) { return Result.failure("Expected a size of %d but was a size %d%n%s%n%s", list1.size(), list2.size(), list1, list2); } for (int i = 0; i < list1.size(); i++) { final String value1 = list1.get(i); final String value2 = list2.get(i); if (!value1.equals(value2)) { return Result.failure("Values don't match at %d. Expected '%s' found '%s'.", i, value1, value2); } } return Result.SUCCESS; } private String packageToPath(final Package pkg) { String result = pkg.getName().replace('.', File.separatorChar); return result.endsWith(File.separator) ? result : result + File.separator; } private Descriptors parseGenerated(final Class intf) throws IOException { final Pattern pattern = Pattern.compile(Pattern.quote(intf.getSimpleName()) + ".*\\.java$"); // Find all the files that match final FileFilter filter = new FileFilter() { @Override public boolean accept(final File pathname) { return pattern.matcher(pathname.getName()).find(); } }; final File dir = new File(TEST_GENERATED_SRC_PATH, packageToPath(intf.getPackage())); final File[] files = dir.listFiles(filter); final Descriptors result = new Descriptors(); for (File file : files) { result.add(parse(file, true)); } return result; } private Descriptor parseInterface(final Class intf) throws IOException { final File srcFile = new File(TEST_SRC_PATH, packageToPath(intf.getPackage()) + intf.getSimpleName() + ".java"); return parse(srcFile, false); } private Descriptor parse(final File file, final boolean isImpl) throws IOException { final Descriptor result = new Descriptor(file.getName()); BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader(file)); String line; while ((line = bufferedReader.readLine()) != null) { if (line.isEmpty()) continue; final Matcher methodNameMatcher = methodNamePattern.matcher(line); if (methodNameMatcher.matches()) { final String returnType = methodNameMatcher.group(2); final String methodName = methodNameMatcher.group(3); if (!"public".equals(returnType) || "private".equals(returnType)) { result.addMethod(methodName); } } else if (isImpl) { final Matcher fieldNameMatcher = fieldNamePattern.matcher(line); if (fieldNameMatcher.matches()) { final String fieldName = fieldNameMatcher.group(3); if (!"FQCN".equals(fieldName)) { result.addField(fieldName.replaceAll("\\d+$", "")); } } else { final Matcher messageMethodMatcher = messageMethodPattern.matcher(line); if (messageMethodMatcher.matches()) { final String methodName = messageMethodMatcher.group(3); result.addMessageMethod(methodName.replaceAll("\\d+$", "")); } } } } } finally { safeClose(bufferedReader); } return result; } static void safeClose(final Closeable closeable) { if (closeable != null) try { closeable.close(); } catch (Exception ignore) { } } private static class Result { static final Result SUCCESS = new Result(false, ""); final boolean failed; final String message; private Result(final boolean failed, final String message) { this.failed = failed; this.message = message; } static Result failure(final String format, final Object... args) { return new Result(true, String.format(format, args)); } } private static class Descriptors implements Iterable { private final List descriptors; private Descriptors() { this.descriptors = new ArrayList(); } public boolean add(final Descriptor descriptor) { return descriptors.add(descriptor); } @Override public Iterator iterator() { return descriptors.iterator(); } } private static class Descriptor { static enum Type { METHOD, FIELD, MESSAGE_METHOD } final String filename; final boolean filterNames; private final Map> values; private Descriptor(final String filename) { this.filename = filename; this.filterNames = filename.matches(".*(\\$[a-z]+)(_\\w+)\\.java$"); values = new HashMap>(); } public void addMethod(final String methodName) { getList(Type.METHOD).add(methodName); } public void addField(final String fieldName) { getList(Type.FIELD).add(fieldName); } public void addMessageMethod(final String methodName) { getList(Type.MESSAGE_METHOD).add(methodName); } public List get(final Type type) { return Collections.unmodifiableList(getList(type)); } private List getList(final Type type) { if (values.containsKey(type)) { return values.get(type); } final List result = new ArrayList(); values.put(type, result); return result; } } } LevelIdCheckTest.java000066400000000000000000000037641255176001000364010ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generated; import org.testng.annotations.AfterMethod; import org.testng.Assert; import org.testng.annotations.Test; /** * @author James R. Perkins */ public class LevelIdCheckTest extends AbstractLoggerTest { @AfterMethod public void clearHandler() { HANDLER.close(); } @Test public void inheritedId() throws Exception { ValidLogger.LOGGER.processingError(); ValidLogger.LOGGER.processingError(new IllegalArgumentException()); ValidLogger.LOGGER.processingError(new IllegalArgumentException(), "generated"); ValidLogger.LOGGER.processingError(this, "invalid reference"); Assert.assertEquals(parseLoggerId(HANDLER.getMessage(0)), 203); Assert.assertEquals(parseLoggerId(HANDLER.getMessage(1)), 203); Assert.assertEquals(parseLoggerId(HANDLER.getMessage(2)), 203); Assert.assertEquals(parseLoggerId(HANDLER.getMessage(3)), 203); } } LogOnceLogger.java000066400000000000000000000047551255176001000357460ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2015, Red Hat, Inc., 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.processor.generated; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Collection; import java.util.Map; import org.jboss.logging.Logger; import org.jboss.logging.Logger.Level; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageLogger; import org.jboss.logging.annotations.Once; import org.jboss.logging.annotations.Transform; import org.jboss.logging.annotations.Transform.TransformType; /** * @author James R. Perkins */ @MessageLogger(projectCode = AbstractLoggerTest.PROJECT_CODE) public interface LogOnceLogger { public final LogOnceLogger LOGGER = Logger.getMessageLogger(LogOnceLogger.class, LogOnceLogger.class.getName()); @LogMessage(level = Level.WARN) @Once @Message("'%s' has been deprecated.") void deprecated(String key); @LogMessage(level = Level.WARN) @Once @Message("'%s' has been deprecated. Please use '%s'.") void deprecated(String key, String replacement); @LogMessage void deprecated(Member member); @LogMessage @Once @Message("Cache size changed to '%d'") void cacheSizeChanged(@Transform(TransformType.SIZE) Collection c); @LogMessage void cacheSizeChanged(@Transform(TransformType.SIZE) String... array); @LogMessage @Once void cacheSizeChanged(@Transform(TransformType.SIZE) Map map); } LogOnceTest.java000066400000000000000000000071021255176001000354330ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2015, Red Hat, Inc., 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.processor.generated; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jboss.logging.Logger; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; /** * @author James R. Perkins */ public class LogOnceTest extends AbstractLoggerTest { @AfterMethod public void clearHandler() { HANDLER.close(); } @Test public void logOnce() throws Exception { LogOnceLogger.LOGGER.deprecated("test.property"); LogOnceLogger.LOGGER.deprecated("test.property"); Assert.assertEquals(HANDLER.size(), 1, "Only one message should have been logged"); LogOnceLogger.LOGGER.deprecated("test.property", "new.test.property"); Assert.assertEquals(HANDLER.size(), 1, "Only one message should have been logged"); final Method method = LogOnceTest.class.getMethod("logOnce"); LogOnceLogger.LOGGER.deprecated(method); LogOnceLogger.LOGGER.deprecated(method); Assert.assertEquals(HANDLER.size(), 3, "The message should have been logged twice"); } @Test public void newLogger() throws Exception { final LogOnceLogger logger = Logger.getMessageLogger(LogOnceLogger.class, CATEGORY); logger.deprecated("test.property"); Assert.assertEquals(HANDLER.size(), 0, "No messages should have been logged"); logger.deprecated("test.property", "new.test.property"); Assert.assertEquals(HANDLER.size(), 0, "No messages should have been logged"); } @Test public void transformTests() throws Exception { final List listCache = Arrays.asList("item1", "item2", "item3"); LogOnceLogger.LOGGER.cacheSizeChanged(listCache); LogOnceLogger.LOGGER.cacheSizeChanged(listCache); Assert.assertEquals(HANDLER.size(), 1, "Only one message should have been logged"); final Map mapCache = new HashMap<>(); for (int i = 0; i < 5; i++) { mapCache.put("item" + i, "value " + i); } LogOnceLogger.LOGGER.cacheSizeChanged(mapCache); Assert.assertEquals(HANDLER.size(), 1, "Only one message should have been logged"); LogOnceLogger.LOGGER.cacheSizeChanged("item1", "item2", "item3", "item4"); LogOnceLogger.LOGGER.cacheSizeChanged("item1", "item2", "item3", "item4", "item5", "item6"); Assert.assertEquals(HANDLER.size(), 3, "The message should have been logged twice"); } } LoggerVerificationTest.java000066400000000000000000000156731255176001000377030ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generated; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Date; import java.util.Locale; import java.util.Properties; import org.jboss.logging.Logger; import org.jboss.logging.processor.generated.DefaultLogger.CustomFormatter; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; /** * @author James R. Perkins */ public class LoggerVerificationTest extends AbstractLoggerTest { private static final String NAME = System.getProperty("user.name"); private static final String FILE_NAME_FORMAT = "DefaultLogger.i18n%s.properties"; @AfterMethod public void clearHandler() { HANDLER.close(); } @Test public void defaultTest() throws Exception { DefaultLogger.LOGGER.hello(NAME); DefaultLogger.LOGGER.howAreYou(NAME); DefaultLogger.LOGGER.noFormat(); DefaultLogger.LOGGER.noFormatWithCause(new IllegalArgumentException("No format cause")); final String msg = "This is a test message"; DefaultLogger.LOGGER.formatWith(msg); final String[] values = {"A", "B", "C", "D"}; DefaultLogger.LOGGER.invalidSelection("G", values); DefaultLogger.LOGGER.invalidSelection("A", "B", "C", "D"); final Properties properties = findFile(String.format(FILE_NAME_FORMAT, "")); Assert.assertEquals(properties.size(), HANDLER.size()); compare(0, "hello", properties, NAME); compare(1, "howAreYou", properties, NAME); compare(2, "noFormat", properties); compare(3, "noFormatWithCause", properties); compare(4, "formatWith", properties, new CustomFormatter(msg)); compare(5, "invalidSelection.2", properties, "G", Arrays.toString(values)); compare(6, "invalidSelection.1", properties, Arrays.toString(values)); } @Test public void germanTest() throws Exception { DefaultLogger logger = getLogger(Locale.GERMAN); logger.hello(NAME); logger.howAreYou(NAME); final Properties properties = findFile(String.format(FILE_NAME_FORMAT, "_de")); Assert.assertEquals(properties.size(), HANDLER.size()); compare(0, "hello", properties, NAME); compare(1, "howAreYou", properties, NAME); } @Test public void frenchTest() throws Exception { DefaultLogger logger = getLogger(Locale.FRENCH); logger.hello(NAME); logger.howAreYou(NAME); final Properties properties = findFile(String.format(FILE_NAME_FORMAT, "_fr")); Assert.assertEquals(properties.size(), HANDLER.size()); compare(0, "hello", properties, NAME); compare(1, "howAreYou", properties, NAME); } @Test public void spanishTest() throws Exception { DefaultLogger logger = getLogger(new Locale("es")); logger.hello(NAME); logger.howAreYou(NAME); final Properties properties = findFile(String.format(FILE_NAME_FORMAT, "_es")); Assert.assertEquals(properties.size(), HANDLER.size()); compare(0, "hello", properties, NAME); compare(1, "howAreYou", properties, NAME); } @Test public void japaneseTest() throws Exception { DefaultLogger logger = getLogger(new Locale("ja")); logger.hello(NAME); logger.howAreYou(NAME); final Properties properties = findFile(String.format(FILE_NAME_FORMAT, "_ja")); Assert.assertEquals(properties.size(), HANDLER.size()); compare(0, "hello", properties, NAME); compare(1, "howAreYou", properties, NAME); } @Test public void testStringFormat() throws Exception { final String fileName = "StringFormatLogger.i18n%s.properties"; final Properties en = findFile(String.format(fileName, "")); final Properties es = findFile(String.format(fileName, "_es")); final StringFormatLogger logger = Logger.getMessageLogger(StringFormatLogger.class, CATEGORY, new Locale("es")); final Date date = new Date(); logger.dukesBirthday(date); logger.dukesBirthdayFailure(date); compare(0, "dukesBirthday", es, date); compare(1, "dukesBirthdayFailure", en, date); logger.stringInt("string", 1); logger.stringIntFailure("string", 1); compare(2, "stringInt", es, "string", 1); compare(3, "stringIntFailure", en, "string", 1); logger.repeat("invalid"); logger.repeatFailure("invalid"); compare(4, "repeat", es, "invalid"); compare(5, "repeatFailure", en, "invalid"); } private static DefaultLogger getLogger(final Locale locale) { return Logger.getMessageLogger(DefaultLogger.class, CATEGORY, locale); } private void compare(final int handlerIndex, final String key, final Properties properties, final Object... params) { final String expectedMessage = getFormattedProperty(key, properties, params); final String loggedMessage = HANDLER.getMessage(handlerIndex).replaceAll(LOGGER_ID_PATTERN, ""); Assert.assertEquals(loggedMessage, expectedMessage); } private String getFormattedProperty(final String key, final Properties properties, final Object... params) { final String format = properties.getProperty(key); if (format == null) { return null; } if (params != null && params.length > 0) return String.format(format, params); return format; } private static Properties findFile(final String fileName) throws IOException { final Properties properties = new Properties(); final String name = CATEGORY.replace(".", File.separator) + File.separator + fileName; final InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(name); properties.load(new InputStreamReader(in, "utf-8")); return properties; } } MessageListHandler.java000066400000000000000000000035521255176001000367700ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generated; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.jboss.logmanager.ExtHandler; import org.jboss.logmanager.ExtLogRecord; /** * @author James R. Perkins */ class MessageListHandler extends ExtHandler { private final List messages = new CopyOnWriteArrayList(); @Override protected void doPublish(final ExtLogRecord record) { super.doPublish(record); messages.add(record.getFormattedMessage()); } String getMessage(final int index) { return messages.get(index); } int size() { return messages.size(); } @Override public void flush() { // no-op } @Override public void close() throws SecurityException { messages.clear(); } } MessagesTest.java000066400000000000000000000045201255176001000356550ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generated; import org.jboss.logging.processor.generated.ValidMessages.StringOnlyException; import org.testng.Assert; import org.testng.annotations.Test; /** * @author James R. Perkins */ public class MessagesTest { @Test public void testFormats() { Assert.assertEquals(ValidMessages.MESSAGES.testWithNewLine(), String.format(ValidMessages.TEST_MSG)); Assert.assertEquals(ValidMessages.MESSAGES.noFormat(), ValidMessages.TEST_MSG); Assert.assertEquals(ValidMessages.MESSAGES.noFormatException(new IllegalArgumentException()).getLocalizedMessage(), ValidMessages.TEST_MSG); final int value = 10; Assert.assertEquals(ValidMessages.MESSAGES.fieldMessage(value).value, value); Assert.assertEquals(ValidMessages.MESSAGES.paramMessage(value).value, value); Assert.assertEquals(ValidMessages.MESSAGES.propertyMessage(value).value, value); final StringOnlyException e = ValidMessages.MESSAGES.stringOnlyException(new RuntimeException()); Assert.assertEquals(e.getMessage(), String.format(ValidMessages.TEST_MSG)); Assert.assertNotNull(e.getCause()); Assert.assertTrue(ValidMessages.MESSAGES.invalidCredentials() instanceof IllegalArgumentException, "Incorrect type constructed"); } } SignatureMessages.java000066400000000000000000000167351255176001000367120ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., 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.processor.generated; import static org.jboss.logging.processor.util.Objects.areEqual; import org.jboss.logging.Messages; import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageBundle; import org.jboss.logging.annotations.Param; import org.jboss.logging.processor.util.Objects; import org.jboss.logging.processor.util.Objects.HashCodeBuilder; /** * @author James R. Perkins */ @MessageBundle(projectCode = "SIG") public interface SignatureMessages { final String TEST_MSG = "Test signature message"; final SignatureMessages MESSAGES = Messages.getBundle(SignatureMessages.class); @Message(TEST_MSG) RedirectException redirect(@Param int responseCode, @Param String location); RedirectException redirect(@Cause Throwable cause, @Param int responseCode, @Param String location); @Message(TEST_MSG) TestException test(); TestException test(@Cause Throwable cause); @Message(TEST_MSG) InvalidTextException invalidText(@Param String text); InvalidTextException invalidText(@Cause Throwable cause, @Param String text); @SuppressWarnings("unused") static class RedirectException extends RuntimeException { final int statusCode; final String location; public RedirectException(final String msg, final Throwable cause, final int statusCode, final String location) { super(msg, cause); this.statusCode = statusCode; this.location = location; } public RedirectException(final int statusCode, final String location) { throw new IllegalStateException("Should never be chosen"); } public RedirectException(final Throwable cause, final int statusCode, final String location) { throw new IllegalStateException("Should never be chosen"); } public RedirectException(final String msg, final int statusCode, final String location) { super(msg); this.statusCode = statusCode; this.location = location; } @Override public int hashCode() { return HashCodeBuilder.builder() .add(statusCode) .add(location) .add(getMessage()) .add(getCause()) .toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof RedirectException)) { return false; } final RedirectException other = (RedirectException) obj; return areEqual(statusCode, other.statusCode) && areEqual(location, other.location) && areEqual(getMessage(), other.getMessage()) && areEqual(getCause(), other.getCause()); } @Override public String toString() { return Objects.ToStringBuilder.of(this) .add("statusCode", statusCode) .add("location", location) .add("message", getMessage()) .add("cause", getCause()) .toString(); } } @SuppressWarnings("unused") static class TestException extends RuntimeException { public TestException(final String message) { super(message); } public TestException(final String message, final Throwable cause) { super(message, cause); } public TestException(final Throwable cause) { throw new IllegalStateException("Should never be chosen"); } @Override public int hashCode() { return HashCodeBuilder.builder() .add(getMessage()) .add(getCause()) .toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof TestException)) { return false; } final TestException other = (TestException) obj; return areEqual(getMessage(), other.getMessage()) && areEqual(getCause(), other.getCause()); } @Override public String toString() { return Objects.ToStringBuilder.of(this) .add("message", getMessage()) .add("cause", getCause()) .toString(); } } @SuppressWarnings("unused") static class InvalidTextException extends RuntimeException { final String value; public InvalidTextException(final String value) { this.value = value; } public InvalidTextException(final String msg, final String value) { super(msg); this.value = value; } public InvalidTextException(final Throwable cause) { throw new IllegalStateException("Should never be chosen"); } public InvalidTextException(final String message, final Throwable cause) { throw new IllegalStateException("Should never be chosen"); } public InvalidTextException(final String msg, final Throwable cause, final String value) { super(msg, cause); this.value = value; } @Override public int hashCode() { return HashCodeBuilder.builder() .add(value) .add(getMessage()) .add(getCause()) .toHashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (!(obj instanceof InvalidTextException)) { return false; } final InvalidTextException other = (InvalidTextException) obj; return areEqual(value, other.value) && areEqual(getMessage(), other.getMessage()) && areEqual(getCause(), other.getCause()); } @Override public String toString() { return Objects.ToStringBuilder.of(this) .add("value", value) .add("message", getMessage()) .add("cause", getCause()) .toString(); } } } StringFormatLogger.java000066400000000000000000000041541255176001000370300ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generated; import java.util.Date; import org.jboss.logging.Logger.Level; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageLogger; /** * @author James R. Perkins */ @MessageLogger(projectCode = "TEST") public interface StringFormatLogger { @LogMessage(level = Level.INFO) @Message("String %s integer %d") void stringInt(String s, int i); @LogMessage(level = Level.INFO) @Message("String %s integer %d") void stringIntFailure(String s, int i); @LogMessage(level = Level.INFO) @Message("Duke's Birthday: %1$tm %James R. Perkins */ public class ThrowableSignatureTest { @Test public void testSignatures() { final String formattedMessage = String.format(SignatureMessages.TEST_MSG); final RuntimeException cause = new RuntimeException("This was the cause"); final int code = 307; final String location = "foo"; RedirectException redirectExpected = new RedirectException(formattedMessage, code, location); Assert.assertEquals(SignatureMessages.MESSAGES.redirect(code, location), redirectExpected); redirectExpected = new RedirectException(formattedMessage, cause, code, location); Assert.assertEquals(SignatureMessages.MESSAGES.redirect(cause, code, location), redirectExpected); TestException testExpected = new TestException(formattedMessage); Assert.assertEquals(SignatureMessages.MESSAGES.test(), testExpected); testExpected = new TestException(formattedMessage, cause); Assert.assertEquals(SignatureMessages.MESSAGES.test(cause), testExpected); final String invalidText = "invalid"; InvalidTextException invalidTextExpected = new InvalidTextException(formattedMessage, invalidText); Assert.assertEquals(SignatureMessages.MESSAGES.invalidText(invalidText), invalidTextExpected); invalidTextExpected = new InvalidTextException(formattedMessage, cause, invalidText); Assert.assertEquals(SignatureMessages.MESSAGES.invalidText(cause, invalidText), invalidTextExpected); } } TransformLogger.java000066400000000000000000000116711255176001000363660ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generatedpackage org.jboss.logging.processor.generated; import java.util.Collection; import java.util.Map; import org.jboss.logging.Logger; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageLogger; import org.jboss.logging.annotations.Pos; import org.jboss.logging.annotations.Transform; import org.jboss.logging.annotations.Transform.TransformType; /** * @author James R. Perkins */ @MessageLogger(projectCode = AbstractLoggerTest.PROJECT_CODE) public interface TransformLogger { final TransformLogger LOGGER = Logger.getMessageLogger(TransformLogger.class, AbstractLoggerTest.CATEGORY); final String HASH_CODE_MSG = "hashCode: %d"; final String IDENTITY_HASH_CODE_MSG = "SystemIdentity: %d"; final String GET_CLASS_MSG = "getClass: %s"; final String SIZE_MSG = "size: %d"; // getClass().hashCode(); @LogMessage @Message(HASH_CODE_MSG) void logClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) String s); @LogMessage void logClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) Collection c); @LogMessage void logClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) String... array); @LogMessage void logClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) Object[] array); @LogMessage void logClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) Map map); // hashCode() @LogMessage @Message(HASH_CODE_MSG) void logObjectHashCode(@Transform(TransformType.HASH_CODE) String s); @LogMessage void logObjectHashCode(@Transform(TransformType.HASH_CODE) Collection c); @LogMessage void logObjectHashCode(@Transform(TransformType.HASH_CODE) String... array); @LogMessage void logObjectHashCode(@Transform(TransformType.HASH_CODE) Object[] array); @LogMessage void logObjectHashCode(@Transform(TransformType.HASH_CODE) Map map); // System.identityHashCode(getClass()) @LogMessage @Message(IDENTITY_HASH_CODE_MSG) void logClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) String s); @LogMessage void logClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) Collection c); @LogMessage void logClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) String... array); @LogMessage void logClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) Object[] array); @LogMessage void logClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) Map map); // System.identityHashCode() @LogMessage @Message(IDENTITY_HASH_CODE_MSG) void logObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) String s); @LogMessage void logObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) Collection c); @LogMessage void logObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) String... array); @LogMessage void logObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) Object[] array); @LogMessage void logObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) Map map); // getClass() @LogMessage @Message(GET_CLASS_MSG) void logObjectClass(@Transform(TransformType.GET_CLASS) String s); @LogMessage void logObjectClass(@Transform(TransformType.GET_CLASS) String... array); @LogMessage void logObjectClass(@Transform(TransformType.GET_CLASS) Object[] array); // length/length()/size() @LogMessage @Message(SIZE_MSG) void logSize(@Transform(TransformType.SIZE) String s); @LogMessage void logSize(@Transform(TransformType.SIZE) Collection c); @LogMessage void logSize(@Transform(TransformType.SIZE) String... array); @LogMessage void logSize(@Transform(TransformType.SIZE) Object[] array); @LogMessage void logSize(@Transform(TransformType.SIZE) Map map); // Position tests String POS_MSG_1 = "size %d hashCode %d identityHashCode %d"; @LogMessage @Message(POS_MSG_1) void posTest1(@Pos(value = {2, 3}, transform = {@Transform(TransformType.HASH_CODE), @Transform(TransformType.IDENTITY_HASH_CODE)}) String msg1, @Pos(value = 1, transform = @Transform(TransformType.SIZE)) String msg2); String POS_MSG_2 = "size %d s1=%s s2=%s getClass() %s"; @LogMessage @Message(POS_MSG_2) void posTest2(@Pos(value = 4, transform = @Transform(TransformType.GET_CLASS)) Object type, @Pos(value = 1, transform = @Transform(TransformType.SIZE)) String msg, @Pos(2) String s1, @Pos(3) String s2); } TransformMessages.java000066400000000000000000000107751255176001000367220ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generatedpackage org.jboss.logging.processor.generated; import java.util.Collection; import java.util.Map; import org.jboss.logging.Messages; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageBundle; import org.jboss.logging.annotations.Pos; import org.jboss.logging.annotations.Transform; import org.jboss.logging.annotations.Transform.TransformType; /** * @author James R. Perkins */ @MessageBundle(projectCode = AbstractLoggerTest.PROJECT_CODE) public interface TransformMessages { final TransformMessages MESSAGES = Messages.getBundle(TransformMessages.class); final String HASH_CODE_MSG = "hashCode: %d"; final String IDENTITY_HASH_CODE_MSG = "SystemIdentity: %d"; final String GET_CLASS_MSG = "getClass: %s"; final String SIZE_MSG = "size: %d"; // getClass().hashCode(); @Message(HASH_CODE_MSG) String msgClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) String s); String msgClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) Collection c); String msgClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) String... array); String msgClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) Object[] array); String msgClassHashCode(@Transform({TransformType.GET_CLASS, TransformType.HASH_CODE}) Map map); // hashCode() @Message(HASH_CODE_MSG) String msgObjectHashCode(@Transform(TransformType.HASH_CODE) String s); String msgObjectHashCode(@Transform(TransformType.HASH_CODE) Collection c); String msgObjectHashCode(@Transform(TransformType.HASH_CODE) String... array); String msgObjectHashCode(@Transform(TransformType.HASH_CODE) Object[] array); String msgObjectHashCode(@Transform(TransformType.HASH_CODE) Map map); // System.identityHashCode(getClass()) @Message(IDENTITY_HASH_CODE_MSG) String msgClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) String s); String msgClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) Collection c); String msgClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) String... array); String msgClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) Object[] array); String msgClassIdentityHashCode(@Transform({TransformType.GET_CLASS, TransformType.IDENTITY_HASH_CODE}) Map map); // System.identityHashCode() @Message(IDENTITY_HASH_CODE_MSG) String msgObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) String s); String msgObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) Collection c); String msgObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) String... array); String msgObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) Object[] array); String msgObjectIdentityHashCode(@Transform(TransformType.IDENTITY_HASH_CODE) Map map); // getClass() @Message(GET_CLASS_MSG) String msgObjectClass(@Transform(TransformType.GET_CLASS) String s); String msgObjectClass(@Transform(TransformType.GET_CLASS) String... array); String msgObjectClass(@Transform(TransformType.GET_CLASS) Object[] array); // length/length()/size() @Message(SIZE_MSG) String msgSize(@Transform(TransformType.SIZE) String s); String msgSize(@Transform(TransformType.SIZE) Collection c); String msgSize(@Transform(TransformType.SIZE) String... array); String msgSize(@Transform(TransformType.SIZE) Object[] array); String msgSize(@Transform(TransformType.SIZE) Map map); // Position tests String POS_MSG_1 = "size %d hashCode %d identityHashCode %d"; @Message(POS_MSG_1) String posTest1(@Pos(value = {2, 3}, transform = {@Transform(TransformType.HASH_CODE), @Transform(TransformType.IDENTITY_HASH_CODE)}) String msg1, @Pos(value = 1, transform = @Transform(TransformType.SIZE)) String msg2); String POS_MSG_2 = "size %d s1=%s s2=%s getClass() %s"; @Message(POS_MSG_2) String posTest2(@Pos(value = 4, transform = @Transform(TransformType.GET_CLASS)) Object type, @Pos(value = 1, transform = @Transform(TransformType.SIZE)) String msg, @Pos(2) String s1, @Pos(3) String s2); } TransformTest.java000066400000000000000000000273721255176001000360730ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generatedpackage org.jboss.logging.processor.generated; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.testng.Assert; import org.testng.annotations.Test; /** * @author James R. Perkins */ public class TransformTest extends AbstractLoggerTest { int pos = 0; @Test public void testLog() throws Exception { // Log strings final String s = "This is a test string"; TransformLogger.LOGGER.logClassHashCode(s); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, s.getClass().hashCode())); TransformLogger.LOGGER.logClassIdentityHashCode(s); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(s.getClass()))); TransformLogger.LOGGER.logObjectClass(s); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.GET_CLASS_MSG, s.getClass())); TransformLogger.LOGGER.logObjectHashCode(s); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, s.hashCode())); TransformLogger.LOGGER.logObjectIdentityHashCode(s); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(s))); TransformLogger.LOGGER.logSize(s); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.SIZE_MSG, s.length())); // Log collections final Collection c = Arrays.asList("test"); TransformLogger.LOGGER.logClassHashCode(c); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, c.getClass().hashCode())); TransformLogger.LOGGER.logClassIdentityHashCode(c); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(c.getClass()))); TransformLogger.LOGGER.logObjectHashCode(c); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, c.hashCode())); TransformLogger.LOGGER.logObjectIdentityHashCode(c); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(c))); TransformLogger.LOGGER.logSize(c); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.SIZE_MSG, c.size())); // Log an array final Object[] array = {"test1", "test2", "test3"}; TransformLogger.LOGGER.logClassHashCode(array); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, array.getClass().hashCode())); TransformLogger.LOGGER.logClassIdentityHashCode(array); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(array.getClass()))); TransformLogger.LOGGER.logObjectClass(array); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.GET_CLASS_MSG, array.getClass())); TransformLogger.LOGGER.logObjectHashCode(array); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, Arrays.hashCode(array))); TransformLogger.LOGGER.logObjectIdentityHashCode(array); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(array))); TransformLogger.LOGGER.logSize(array); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.SIZE_MSG, array.length)); // Log vararg array final String[] sArray = {"test1", "test2", "test3"}; TransformLogger.LOGGER.logClassHashCode(sArray); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, sArray.getClass().hashCode())); TransformLogger.LOGGER.logClassIdentityHashCode(sArray); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(sArray.getClass()))); TransformLogger.LOGGER.logObjectClass(sArray); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.GET_CLASS_MSG, sArray.getClass())); TransformLogger.LOGGER.logObjectHashCode(sArray); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, Arrays.hashCode(sArray))); TransformLogger.LOGGER.logObjectIdentityHashCode(sArray); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(sArray))); TransformLogger.LOGGER.logSize(sArray); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.SIZE_MSG, sArray.length)); // Log a map final Map map = new HashMap(); for (int i = 0; i < 10; i++) { map.put("key" + i, "value" + i); } TransformLogger.LOGGER.logClassHashCode(map); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, map.getClass().hashCode())); TransformLogger.LOGGER.logClassIdentityHashCode(map); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(map.getClass()))); TransformLogger.LOGGER.logObjectHashCode(map); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.HASH_CODE_MSG, map.hashCode())); TransformLogger.LOGGER.logObjectIdentityHashCode(map); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(map))); TransformLogger.LOGGER.logSize(map); Assert.assertEquals(HANDLER.getMessage(pos++), String.format(TransformLogger.SIZE_MSG, map.size())); } @Test public void testMessage() throws Exception { // Log strings final String s = "This is a test string"; Assert.assertEquals(TransformMessages.MESSAGES.msgClassHashCode(s), String.format(TransformLogger.HASH_CODE_MSG, s.getClass().hashCode())); Assert.assertEquals(TransformMessages.MESSAGES.msgClassIdentityHashCode(s), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(s.getClass()))); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectClass(s), String.format(TransformLogger.GET_CLASS_MSG, s.getClass())); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectHashCode(s), String.format(TransformLogger.HASH_CODE_MSG, s.hashCode())); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectIdentityHashCode(s), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(s))); Assert.assertEquals(TransformMessages.MESSAGES.msgSize(s), String.format(TransformLogger.SIZE_MSG, s.length())); // Log collections final Collection c = Arrays.asList("test"); Assert.assertEquals(TransformMessages.MESSAGES.msgClassHashCode(c), String.format(TransformLogger.HASH_CODE_MSG, c.getClass().hashCode())); Assert.assertEquals(TransformMessages.MESSAGES.msgClassIdentityHashCode(c), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(c.getClass()))); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectHashCode(c), String.format(TransformLogger.HASH_CODE_MSG, c.hashCode())); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectIdentityHashCode(c), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(c))); Assert.assertEquals(TransformMessages.MESSAGES.msgSize(c), String.format(TransformLogger.SIZE_MSG, c.size())); // Log an array final Object[] array = {"test1", "test2", "test3"}; Assert.assertEquals(TransformMessages.MESSAGES.msgClassHashCode(array), String.format(TransformLogger.HASH_CODE_MSG, array.getClass().hashCode())); Assert.assertEquals(TransformMessages.MESSAGES.msgClassIdentityHashCode(array), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(array.getClass()))); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectClass(array), String.format(TransformLogger.GET_CLASS_MSG, array.getClass())); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectHashCode(array), String.format(TransformLogger.HASH_CODE_MSG, Arrays.hashCode(array))); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectIdentityHashCode(array), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(array))); Assert.assertEquals(TransformMessages.MESSAGES.msgSize(array), String.format(TransformLogger.SIZE_MSG, array.length)); // Log vararg array final String[] sArray = {"test1", "test2", "test3"}; Assert.assertEquals(TransformMessages.MESSAGES.msgClassHashCode(sArray), String.format(TransformLogger.HASH_CODE_MSG, sArray.getClass().hashCode())); Assert.assertEquals(TransformMessages.MESSAGES.msgClassIdentityHashCode(sArray), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(sArray.getClass()))); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectClass(sArray), String.format(TransformLogger.GET_CLASS_MSG, sArray.getClass())); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectHashCode(sArray), String.format(TransformLogger.HASH_CODE_MSG, Arrays.hashCode(sArray))); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectIdentityHashCode(sArray), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(sArray))); Assert.assertEquals(TransformMessages.MESSAGES.msgSize(sArray), String.format(TransformLogger.SIZE_MSG, sArray.length)); // Log a map final Map map = new HashMap(); for (int i = 0; i < 10; i++) { map.put("key" + i, "value" + i); } Assert.assertEquals(TransformMessages.MESSAGES.msgClassHashCode(map), String.format(TransformLogger.HASH_CODE_MSG, map.getClass().hashCode())); Assert.assertEquals(TransformMessages.MESSAGES.msgClassIdentityHashCode(map), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(map.getClass()))); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectHashCode(map), String.format(TransformLogger.HASH_CODE_MSG, map.hashCode())); Assert.assertEquals(TransformMessages.MESSAGES.msgObjectIdentityHashCode(map), String.format(TransformLogger.IDENTITY_HASH_CODE_MSG, System.identityHashCode(map))); Assert.assertEquals(TransformMessages.MESSAGES.msgSize(map), String.format(TransformLogger.SIZE_MSG, map.size())); } @Test public void testPositions() throws Exception { // Log strings final String msg1 = "Test message 1"; final String msg2 = "Test message 2"; String expected = String.format(TransformLogger.POS_MSG_1, msg2.length(), msg1.hashCode(), System.identityHashCode(msg1)); TransformLogger.LOGGER.posTest1(msg1, msg2); Assert.assertEquals(HANDLER.getMessage(pos++), expected); Assert.assertEquals(TransformMessages.MESSAGES.posTest1(msg1, msg2), expected); final Object obj = "Test"; final String msg = "This is a test message"; final String s1 = "s1"; final String s2 = "s2"; expected = String.format(TransformLogger.POS_MSG_2, msg.length(), s1, s2, obj.getClass()); TransformLogger.LOGGER.posTest2(obj, msg, s1, s2); Assert.assertEquals(HANDLER.getMessage(pos++), expected); Assert.assertEquals(TransformMessages.MESSAGES.posTest2(obj, msg, s1, s2), expected); } } ValidLogger.java000066400000000000000000000051101255176001000354410ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generatedpackage org.jboss.logging.processor.generated; import org.jboss.logging.Logger; import org.jboss.logging.Logger.Level; import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.LogMessage; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.Message.Format; import org.jboss.logging.annotations.MessageLogger; import org.jboss.logging.annotations.ValidIdRange; import org.jboss.logging.annotations.ValidIdRanges; /** * @author James R. Perkins */ @MessageLogger(projectCode = AbstractLoggerTest.PROJECT_CODE) @ValidIdRanges({ @ValidIdRange(min = 200, max = 202), @ValidIdRange(min = 203, max = 204) }) public interface ValidLogger { final ValidLogger LOGGER = Logger.getMessageLogger(ValidLogger.class, AbstractLoggerTest.CATEGORY); @LogMessage(level = Level.INFO, loggingClass = ValidLogger.class) @Message(id = 200, value = "This is a generated message.") void testInfoMessage(); @LogMessage(level = Level.INFO) @Message(id = 201, value = "Test message format message. Test value: {0}", format = Format.MESSAGE_FORMAT) void testMessageFormat(Object value); /** * Logs a default informational greeting. * * @param name the name. */ @LogMessage @Message(id = 202, value = "Greetings %s") void greeting(String name); /** * Logs an error message indicating a processing error. */ @LogMessage(level = Level.ERROR) @Message(id = 203, value = "Processing error") void processingError(); /** * Logs an error message indicating a processing error. * * @param cause the cause of the error. */ @LogMessage(level = Level.ERROR) void processingError(@Cause Throwable cause); /** * Logs an error message indicating there was a processing error. * * @param cause the cause of the error. * @param moduleName the module that caused the error. */ @LogMessage(level = Level.ERROR) @Message(id = Message.INHERIT, value = "Processing error in module '%s'") void processingError(@Cause Throwable cause, String moduleName); /** * Logs an error message indicating a processing error. * * @param on the object the error occurred on * @param message the error message */ @LogMessage(level = Level.ERROR) @Message(id = 203, value = "Processing error on '%s' with error '%s'") void processingError(Object on, String message); @Message(id = 204, value = "Bundle message inside a logger") String bundleMessage(); } ValidMessages.java000066400000000000000000000070531255176001000360010ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/generated/* * JBoss, Home of Professional Open Source. * Copyright 2012, Red Hat, Inc., 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.processor.generated; import org.jboss.logging.Messages; import org.jboss.logging.annotations.Cause; import org.jboss.logging.annotations.ConstructType; import org.jboss.logging.annotations.Field; import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.Message.Format; import org.jboss.logging.annotations.MessageBundle; import org.jboss.logging.annotations.Param; import org.jboss.logging.annotations.Property; /** * @author James R. Perkins */ @MessageBundle(projectCode = "MSG") public interface ValidMessages { final String TEST_MSG = "Test%n"; final ValidMessages MESSAGES = Messages.getBundle(ValidMessages.class); @Message(value = TEST_MSG) String testWithNewLine(); @Message(format = Format.NO_FORMAT, value = TEST_MSG) String noFormat(); @Message(format = Format.NO_FORMAT, value = TEST_MSG) RuntimeException noFormatException(@Cause Throwable cause); @Message(TEST_MSG) CustomException fieldMessage(@Field(name = "value") int value); @Message(TEST_MSG) CustomException paramMessage(@Param int value); @Message(TEST_MSG) CustomException propertyMessage(@Property int value); @Message(TEST_MSG) LoggingException loggingException(@Cause Exception e); @Message(TEST_MSG) StringOnlyException stringOnlyException(@Cause Exception e); @ConstructType(IllegalArgumentException.class) @Message("Invalid user id or password") RuntimeException invalidCredentials(); class CustomException extends RuntimeException { public int value; public CustomException() { } public CustomException(final int value, final String msg) { super(msg); this.value = value; } public CustomException(final String msg) { super(msg); } public CustomException(final Throwable t) { super(t); } public CustomException(final String msg, final Throwable t) { super(msg, t); } public void setValue(final int value) { this.value = value; } } class LoggingException extends RuntimeException { public LoggingException(final Exception e) { super(e); } public LoggingException(final Exception e, final String msg) { super(msg, e); } } class StringOnlyException extends RuntimeException { public StringOnlyException(final String msg) { super(msg); } } } jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/util/000077500000000000000000000000001255176001000315005ustar00rootroot00000000000000VersionComparatorTest.java000066400000000000000000000014771255176001000366120ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/utilpackage org.jboss.logging.processor.util; import org.testng.Assert; import org.testng.annotations.Test; /** * Date: 09.11.2011 * * @author James R. Perkins */ public class VersionComparatorTest { @Test public void testComparator() { final String version = "3.1"; Assert.assertTrue(VersionComparator.compareVersion("3.1.1", version) > 0); Assert.assertTrue(VersionComparator.compareVersion("3.1", version) == 0); Assert.assertTrue(VersionComparator.compareVersion("3.0", version) < 0); Assert.assertTrue(VersionComparator.compareVersion("3.0.1", version) < 0); Assert.assertTrue(VersionComparator.compareVersion("3.0.1", version) < 0); Assert.assertTrue(VersionComparator.compareVersion("3.1.x", version) == 0); } } jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/validation/000077500000000000000000000000001255176001000326555ustar00rootroot00000000000000MessageFormatValidatorTest.java000066400000000000000000000024631255176001000407110ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/validationpackage org.jboss.logging.processor.validation; import static org.testng.Assert.*; import org.testng.annotations.Test; /** * Date: 14.06.2011 * * @author James R. Perkins */ public class MessageFormatValidatorTest { @Test public void validFormats() { MessageFormatValidator validator = MessageFormatValidator.of("Message {} is valid."); assertTrue(validator.isValid(), validator.detailMessage()); validator = MessageFormatValidator.of("Parameter {1} is not compatible with {2}."); assertTrue(validator.isValid(), validator.detailMessage()); } @Test public void invalidFormats() { MessageFormatValidator validator = MessageFormatValidator.of("Invalid parameter { is not valid."); assertFalse(validator.isValid()); } @Test public void validateParameterCount() { MessageFormatValidator validator = MessageFormatValidator.of("{}", "Test"); assertTrue(validator.isValid(), validator.detailMessage()); validator = MessageFormatValidator.of("{1} {0}", "Test", "Test2"); assertTrue(validator.isValid(), validator.detailMessage()); validator = MessageFormatValidator.of("{0} {0}", "Test"); assertTrue(validator.isValid(), validator.detailMessage()); } } StringFormatValidatorTest.java000066400000000000000000000060021255176001000405640ustar00rootroot00000000000000jboss-logging-tools-2.0.1.Final/processor/src/test/java/org/jboss/logging/processor/validationpackage org.jboss.logging.processor.validation; import static org.testng.Assert.*; import java.util.Date; import org.testng.annotations.Test; /** * Date: 14.06.2011 * * @author James R. Perkins */ public class StringFormatValidatorTest { @Test public void validFormats() { final StringBuilder sb = new StringBuilder(); for (StringFormatPart.Conversion conversion : StringFormatPart.Conversion.values()) { sb.append("%").append(conversion.asChar()); if (conversion.isDateTime()) { sb.append("m "); } else { sb.append(" "); } } StringFormatValidator validator = StringFormatValidator.of(sb.toString()); assertTrue(validator.isValid(), validator.detailMessage()); final String[] validFormats = { "%1$s %1$s %1$s", "Duke's Birthday: %1$tm %1$te,%1$tY", "Duke's Birthday: %1$tm %