You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2015/01/26 15:16:50 UTC
[34/47] incubator-nifi git commit: NIFI-6: Rebase from develop to
include renaming of directory structure
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/716e03b5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/ReflectionUtils.java
----------------------------------------------------------------------
diff --cc nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/ReflectionUtils.java
index 0000000,e15e00a..a8a4596
mode 000000,100644..100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/ReflectionUtils.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/ReflectionUtils.java
@@@ -1,0 -1,157 +1,285 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ package org.apache.nifi.util;
+
+ import java.lang.annotation.Annotation;
+ import java.lang.reflect.InvocationTargetException;
+ import java.lang.reflect.Method;
++import java.util.ArrayList;
++import java.util.List;
++
++import org.apache.nifi.logging.ProcessorLog;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ public class ReflectionUtils {
+
+ private final static Logger LOG = LoggerFactory.getLogger(ReflectionUtils.class);
+
+ /**
+ * Invokes all methods on the given instance that have been annotated with
+ * the given Annotation. If the signature of the method that is defined in
+ * <code>instance</code> uses 1 or more parameters, those parameters must be
+ * specified by the <code>args</code> parameter. However, if more arguments
+ * are supplied by the <code>args</code> parameter than needed, the extra
+ * arguments will be ignored.
+ *
+ * @param annotation
+ * @param instance
+ * @param args
+ * @throws InvocationTargetException
+ * @throws IllegalArgumentException
+ * @throws IllegalAccessException
+ */
+ public static void invokeMethodsWithAnnotation(final Class<? extends Annotation> annotation, final Object instance, final Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- try {
- for (final Method method : instance.getClass().getMethods()) {
- if (method.isAnnotationPresent(annotation)) {
- final boolean isAccessible = method.isAccessible();
- method.setAccessible(true);
-
- try {
- final Class<?>[] argumentTypes = method.getParameterTypes();
- if (argumentTypes.length > args.length) {
- throw new IllegalArgumentException(String.format("Unable to invoke method %1$s on %2$s because method expects %3$s parameters but only %4$s were given",
- method.getName(), instance, argumentTypes.length, args.length));
- }
++ invokeMethodsWithAnnotation(annotation, null, instance, args);
++ }
++
+
- for (int i = 0; i < argumentTypes.length; i++) {
- final Class<?> argType = argumentTypes[i];
- if (!argType.isAssignableFrom(args[i].getClass())) {
- throw new IllegalArgumentException(String.format(
- "Unable to invoke method %1$s on %2$s because method parameter %3$s is expected to be of type %4$s but argument passed was of type %5$s",
- method.getName(), instance, i, argType, args[i].getClass()));
++ /**
++ * Invokes all methods on the given instance that have been annotated with
++ * the given preferredAnnotation and if no such method exists will invoke all
++ * methods on the given instance that have been annotated with the given
++ * alternateAnnotation, if any exists. If the signature of the method that is defined in
++ * <code>instance</code> uses 1 or more parameters, those parameters must be
++ * specified by the <code>args</code> parameter. However, if more arguments
++ * are supplied by the <code>args</code> parameter than needed, the extra
++ * arguments will be ignored.
++ *
++ * @param preferredAnnotation
++ * @param alternateAnnotation
++ * @param instance
++ * @param args
++ * @throws InvocationTargetException
++ * @throws IllegalArgumentException
++ * @throws IllegalAccessException
++ */
++ public static void invokeMethodsWithAnnotation(final Class<? extends Annotation> preferredAnnotation, final Class<? extends Annotation> alternateAnnotation, final Object instance, final Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
++ final List<Class<? extends Annotation>> annotationClasses = new ArrayList<>(alternateAnnotation == null ? 1 : 2);
++ annotationClasses.add(preferredAnnotation);
++ if ( alternateAnnotation != null ) {
++ annotationClasses.add(alternateAnnotation);
++ }
++
++ boolean annotationFound = false;
++ for ( final Class<? extends Annotation> annotationClass : annotationClasses ) {
++ if ( annotationFound ) {
++ break;
++ }
++
++ try {
++ for (final Method method : instance.getClass().getMethods()) {
++ if (method.isAnnotationPresent(annotationClass)) {
++ annotationFound = true;
++ final boolean isAccessible = method.isAccessible();
++ method.setAccessible(true);
++
++ try {
++ final Class<?>[] argumentTypes = method.getParameterTypes();
++ if (argumentTypes.length > args.length) {
++ throw new IllegalArgumentException(String.format("Unable to invoke method %1$s on %2$s because method expects %3$s parameters but only %4$s were given",
++ method.getName(), instance, argumentTypes.length, args.length));
+ }
- }
-
- if (argumentTypes.length == args.length) {
- method.invoke(instance, args);
- } else {
- final Object[] argsToPass = new Object[argumentTypes.length];
- for (int i = 0; i < argsToPass.length; i++) {
- argsToPass[i] = args[i];
++
++ for (int i = 0; i < argumentTypes.length; i++) {
++ final Class<?> argType = argumentTypes[i];
++ if (!argType.isAssignableFrom(args[i].getClass())) {
++ throw new IllegalArgumentException(String.format(
++ "Unable to invoke method %1$s on %2$s because method parameter %3$s is expected to be of type %4$s but argument passed was of type %5$s",
++ method.getName(), instance, i, argType, args[i].getClass()));
++ }
++ }
++
++ if (argumentTypes.length == args.length) {
++ method.invoke(instance, args);
++ } else {
++ final Object[] argsToPass = new Object[argumentTypes.length];
++ for (int i = 0; i < argsToPass.length; i++) {
++ argsToPass[i] = args[i];
++ }
++
++ method.invoke(instance, argsToPass);
++ }
++ } finally {
++ if (!isAccessible) {
++ method.setAccessible(false);
+ }
-
- method.invoke(instance, argsToPass);
- }
- } finally {
- if (!isAccessible) {
- method.setAccessible(false);
+ }
+ }
+ }
- }
- } catch (final InvocationTargetException ite) {
- if ( ite.getCause() instanceof RuntimeException ) {
- throw (RuntimeException) ite.getCause();
- } else {
- throw ite;
++ } catch (final InvocationTargetException ite) {
++ if ( ite.getCause() instanceof RuntimeException ) {
++ throw (RuntimeException) ite.getCause();
++ } else {
++ throw ite;
++ }
+ }
+ }
+ }
+
++
+ /**
+ * Invokes all methods on the given instance that have been annotated with
+ * the given Annotation. If the signature of the method that is defined in
+ * <code>instance</code> uses 1 or more parameters, those parameters must be
+ * specified by the <code>args</code> parameter. However, if more arguments
+ * are supplied by the <code>args</code> parameter than needed, the extra
+ * arguments will be ignored.
+ *
+ * @param annotation
+ * @param instance
+ * @param args
+ * @return <code>true</code> if all appropriate methods were invoked and
+ * returned without throwing an Exception, <code>false</code> if one of the
+ * methods threw an Exception or could not be invoked; if <code>false</code>
+ * is returned, an error will have been logged.
+ */
+ public static boolean quietlyInvokeMethodsWithAnnotation(final Class<? extends Annotation> annotation, final Object instance, final Object... args) {
- for (final Method method : instance.getClass().getMethods()) {
- if (method.isAnnotationPresent(annotation)) {
- final boolean isAccessible = method.isAccessible();
- method.setAccessible(true);
-
- try {
- final Class<?>[] argumentTypes = method.getParameterTypes();
- if (argumentTypes.length > args.length) {
- LOG.error("Unable to invoke method {} on {} because method expects {} parameters but only {} were given",
- new Object[]{method.getName(), instance, argumentTypes.length, args.length});
- return false;
- }
-
- for (int i = 0; i < argumentTypes.length; i++) {
- final Class<?> argType = argumentTypes[i];
- if (!argType.isAssignableFrom(args[i].getClass())) {
- LOG.error("Unable to invoke method {} on {} because method parameter {} is expected to be of type {} but argument passed was of type {}",
- new Object[]{method.getName(), instance, i, argType, args[i].getClass()});
++ return quietlyInvokeMethodsWithAnnotation(annotation, null, instance, null, args);
++ }
++
++
++ /**
++ * Invokes all methods on the given instance that have been annotated with
++ * the given Annotation. If the signature of the method that is defined in
++ * <code>instance</code> uses 1 or more parameters, those parameters must be
++ * specified by the <code>args</code> parameter. However, if more arguments
++ * are supplied by the <code>args</code> parameter than needed, the extra
++ * arguments will be ignored.
++ *
++ * @param annotation
++ * @param instance
++ * @param args
++ * @return <code>true</code> if all appropriate methods were invoked and
++ * returned without throwing an Exception, <code>false</code> if one of the
++ * methods threw an Exception or could not be invoked; if <code>false</code>
++ * is returned, an error will have been logged.
++ */
++ public static boolean quietlyInvokeMethodsWithAnnotation(final Class<? extends Annotation> annotation, final Object instance, final ProcessorLog logger, final Object... args) {
++ return quietlyInvokeMethodsWithAnnotation(annotation, null, instance, logger, args);
++ }
++
++
++ /**
++ * Invokes all methods on the given instance that have been annotated with
++ * the given preferredAnnotation and if no such method exists will invoke all methods
++ * on the given instance that have been annotated with the given
++ * alternateAnnotation, if any exists. If the signature of the method that is defined in
++ * <code>instance</code> uses 1 or more parameters, those parameters must be
++ * specified by the <code>args</code> parameter. However, if more arguments
++ * are supplied by the <code>args</code> parameter than needed, the extra
++ * arguments will be ignored.
++ *
++ * @param preferredAnnotation
++ * @param alternateAnnotation
++ * @param instance
++ * @param logger the ProcessorLog to use for logging any errors. If null, will use own logger, but that will not generate bulletins
++ * or easily tie to the Processor's log messages.
++ * @param args
++ * @return <code>true</code> if all appropriate methods were invoked and
++ * returned without throwing an Exception, <code>false</code> if one of the
++ * methods threw an Exception or could not be invoked; if <code>false</code>
++ * is returned, an error will have been logged.
++ */
++ public static boolean quietlyInvokeMethodsWithAnnotation(final Class<? extends Annotation> preferredAnnotation, final Class<? extends Annotation> alternateAnnotation, final Object instance, final ProcessorLog logger, final Object... args) {
++ final List<Class<? extends Annotation>> annotationClasses = new ArrayList<>(alternateAnnotation == null ? 1 : 2);
++ annotationClasses.add(preferredAnnotation);
++ if ( alternateAnnotation != null ) {
++ annotationClasses.add(alternateAnnotation);
++ }
++
++ boolean annotationFound = false;
++ for ( final Class<? extends Annotation> annotationClass : annotationClasses ) {
++ if ( annotationFound ) {
++ break;
++ }
++
++ for (final Method method : instance.getClass().getMethods()) {
++ if (method.isAnnotationPresent(annotationClass)) {
++ annotationFound = true;
++
++ final boolean isAccessible = method.isAccessible();
++ method.setAccessible(true);
++
++ try {
++ final Class<?>[] argumentTypes = method.getParameterTypes();
++ if (argumentTypes.length > args.length) {
++ if ( logger == null ) {
++ LOG.error("Unable to invoke method {} on {} because method expects {} parameters but only {} were given",
++ new Object[]{method.getName(), instance, argumentTypes.length, args.length});
++ } else {
++ logger.error("Unable to invoke method {} on {} because method expects {} parameters but only {} were given",
++ new Object[]{method.getName(), instance, argumentTypes.length, args.length});
++ }
++
+ return false;
+ }
- }
-
- try {
- if (argumentTypes.length == args.length) {
- method.invoke(instance, args);
- } else {
- final Object[] argsToPass = new Object[argumentTypes.length];
- for (int i = 0; i < argsToPass.length; i++) {
- argsToPass[i] = args[i];
++
++ for (int i = 0; i < argumentTypes.length; i++) {
++ final Class<?> argType = argumentTypes[i];
++ if (!argType.isAssignableFrom(args[i].getClass())) {
++ if ( logger == null ) {
++ LOG.error("Unable to invoke method {} on {} because method parameter {} is expected to be of type {} but argument passed was of type {}",
++ new Object[]{method.getName(), instance, i, argType, args[i].getClass()});
++ } else {
++ logger.error("Unable to invoke method {} on {} because method parameter {} is expected to be of type {} but argument passed was of type {}",
++ new Object[]{method.getName(), instance, i, argType, args[i].getClass()});
++ }
++
++ return false;
+ }
-
- method.invoke(instance, argsToPass);
+ }
- } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException t) {
- LOG.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, t});
- LOG.error("", t);
- return false;
- }
- } finally {
- if (!isAccessible) {
- method.setAccessible(false);
++
++ try {
++ if (argumentTypes.length == args.length) {
++ method.invoke(instance, args);
++ } else {
++ final Object[] argsToPass = new Object[argumentTypes.length];
++ for (int i = 0; i < argsToPass.length; i++) {
++ argsToPass[i] = args[i];
++ }
++
++ method.invoke(instance, argsToPass);
++ }
++ } catch (final InvocationTargetException ite) {
++ if ( logger == null ) {
++ LOG.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, ite.getCause()});
++ LOG.error("", ite.getCause());
++ } else {
++ logger.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, ite.getCause()});
++ }
++ } catch (final IllegalAccessException | IllegalArgumentException t) {
++ if ( logger == null ) {
++ LOG.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, t});
++ LOG.error("", t);
++ } else {
++ logger.error("Unable to invoke method {} on {} due to {}", new Object[]{method.getName(), instance, t});
++ }
++
++ return false;
++ }
++ } finally {
++ if (!isAccessible) {
++ method.setAccessible(false);
++ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+ }
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/716e03b5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/test/processors/StubAttributeLoggerProcessor.java
----------------------------------------------------------------------
diff --cc nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/test/processors/StubAttributeLoggerProcessor.java
index 0000000,73d38e8..d49db29
mode 000000,100644..100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/test/processors/StubAttributeLoggerProcessor.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/test/processors/StubAttributeLoggerProcessor.java
@@@ -1,0 -1,111 +1,111 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ package org.apache.nifi.test.processors;
+
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.HashSet;
+ import java.util.List;
+ import java.util.Set;
+
++import org.apache.nifi.annotation.behavior.SideEffectFree;
+ import org.apache.nifi.components.PropertyDescriptor;
+ import org.apache.nifi.processor.AbstractProcessor;
+ import org.apache.nifi.processor.ProcessContext;
+ import org.apache.nifi.processor.ProcessSession;
+ import org.apache.nifi.processor.ProcessorInitializationContext;
+ import org.apache.nifi.processor.Relationship;
-import org.apache.nifi.processor.annotation.SideEffectFree;
+
+ @SideEffectFree
+ public class StubAttributeLoggerProcessor extends AbstractProcessor {
+
+ //@formatter:off
+ public static final PropertyDescriptor LOG_LEVEL = new PropertyDescriptor.Builder()
+ .required(false)
+ .description("log.level")
+ .defaultValue("debug")
+ .name("log.level")
+ .allowableValues("trace", "info", "warn", "debug", "error")
+ .sensitive(false)
+ .build();
+ public static final PropertyDescriptor ATTRIBUTES_TO_LOG_CSV = new PropertyDescriptor.Builder()
+ .required(false)
+ .description("attributes.to.log.csv")
+ .name("attributes.to.log.csv")
+ .sensitive(false)
+ .build();
+ public static final PropertyDescriptor ATTRIBUTES_TO_IGNORE_CSV = new PropertyDescriptor.Builder()
+ .required(false)
+ .description("attributes.to.ignore.csv")
+ .name("attributes.to.ignore.csv")
+ .sensitive(false)
+ .build();
+ public static final PropertyDescriptor LOG_PAYLOAD = new PropertyDescriptor.Builder()
+ .required(false)
+ .description("log.payload")
+ .defaultValue("false")
+ .allowableValues("true", "false")
+ .name("log.payload")
+ .sensitive(false)
+ .build();
+ // @formatter:on
+
+ public static enum DebugLevels {
+
+ trace, info, warn, debug, error
+ }
+
+ public static final long ONE_MB = 1024 * 1024;
+ private final Set<Relationship> relationships;
+ public static final Relationship REL_SUCCESS = new Relationship.Builder().description("success").name("success").build();
+
+ private final List<PropertyDescriptor> supportedDescriptors;
+
+ public StubAttributeLoggerProcessor() {
+ // relationships
+ final Set<Relationship> procRels = new HashSet<>();
+ procRels.add(REL_SUCCESS);
+ relationships = Collections.unmodifiableSet(procRels);
+
+ // descriptors
+ final List<PropertyDescriptor> supDescriptors = new ArrayList<>();
+ supDescriptors.add(ATTRIBUTES_TO_IGNORE_CSV);
+ supDescriptors.add(ATTRIBUTES_TO_LOG_CSV);
+ supDescriptors.add(LOG_PAYLOAD);
+ supDescriptors.add(LOG_LEVEL);
+ supportedDescriptors = Collections.unmodifiableList(supDescriptors);
+ }
+
+ @Override
+ public Set<Relationship> getRelationships() {
+ return relationships;
+ }
+
+ @Override
+ protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
+ return supportedDescriptors;
+ }
+
+ @Override
+ public void onTrigger(final ProcessContext context, final ProcessSession session) {
+ }
+
+ @Override
+ protected void init(final ProcessorInitializationContext context) {
+ }
+
+ }