You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/07/07 09:18:40 UTC
[06/10] brooklyn-server git commit: tidy/enhancements to javalang
utils
tidy/enhancements to javalang utils
a few more methods which were elsewhere or not present,
better methods using Maybe, and callers updated to use them
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/23ab1c50
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/23ab1c50
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/23ab1c50
Branch: refs/heads/master
Commit: 23ab1c506bdda9a3ac79199146ea9750d18d9005
Parents: 8644003
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jun 24 11:13:18 2016 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jun 24 23:02:48 2016 +0100
----------------------------------------------------------------------
.../creation/BrooklynYamlTypeInstantiator.java | 6 +-
.../spi/dsl/methods/BrooklynDslCommon.java | 2 +-
.../core/mgmt/entitlement/Entitlements.java | 6 +-
.../BasicExternalConfigSupplierRegistry.java | 6 +-
.../core/mgmt/internal/LocalUsageManager.java | 4 +-
.../core/mgmt/rebind/RebindIteration.java | 3 +-
.../core/objs/proxy/InternalFactory.java | 7 +-
.../entity/group/DynamicClusterImpl.java | 4 +-
.../location/jclouds/JcloudsLocation.java | 15 +-
.../java/org/apache/brooklyn/test/Asserts.java | 8 +-
.../util/guava/AnyExceptionSupplier.java | 8 +-
.../apache/brooklyn/util/javalang/Boxing.java | 29 +++
.../apache/brooklyn/util/javalang/Enums.java | 4 +-
.../brooklyn/util/javalang/FieldOrderings.java | 82 +++++++
.../brooklyn/util/javalang/JavaClassNames.java | 18 +-
.../util/javalang/ReflectionPredicates.java | 71 ++++++
.../brooklyn/util/javalang/Reflections.java | 239 ++++++++++++++-----
.../apache/brooklyn/util/javalang/Threads.java | 1 -
.../brooklyn/util/javalang/BoxingTest.java | 5 +
.../brooklyn/util/javalang/ReflectionsTest.java | 13 +-
20 files changed, 422 insertions(+), 109 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
index 01bfaa2..a8f8c5a 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlTypeInstantiator.java
@@ -129,17 +129,17 @@ public abstract class BrooklynYamlTypeInstantiator {
public <T> T newInstance(@Nullable Class<T> supertype) {
Class<? extends T> type = getType(supertype);
Map<String, ?> cfg = getConfigMap();
- Optional<? extends T> result = Reflections.invokeConstructorWithArgs(type, cfg);
+ Maybe<? extends T> result = Reflections.invokeConstructorFromArgs(type, cfg);
if (result.isPresent())
return result.get();
ConfigBag cfgBag = ConfigBag.newInstance(cfg);
- result = Reflections.invokeConstructorWithArgs(type, cfgBag);
+ result = Reflections.invokeConstructorFromArgs(type, cfgBag);
if (result.isPresent())
return result.get();
if (cfg.isEmpty()) {
- result = Reflections.invokeConstructorWithArgs(type);
+ result = Reflections.invokeConstructorFromArgs(type);
if (result.isPresent())
return result.get();
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
index 48ea03f..b88829b 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
@@ -359,7 +359,7 @@ public class BrooklynDslCommon {
try {
bean = (T) TypeCoercions.coerce(fields, type);
} catch (ClassCoercionException ex) {
- bean = Reflections.invokeConstructorWithArgs(type).get();
+ bean = Reflections.invokeConstructorFromArgs(type).get();
BeanUtils.populate(bean, fields);
}
if (bean instanceof Configurable && config.size() > 0) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java
index 7199267..df3f7a8 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java
@@ -21,7 +21,6 @@ package org.apache.brooklyn.core.mgmt.entitlement;
import java.util.Arrays;
import java.util.List;
-import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.brooklyn.api.entity.Entity;
@@ -35,10 +34,10 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.Sanitizer;
import org.apache.brooklyn.core.internal.BrooklynProperties;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.javalang.Reflections;
import org.apache.brooklyn.util.text.Strings;
import org.slf4j.Logger;
@@ -47,7 +46,6 @@ import org.slf4j.LoggerFactory;
import com.google.common.annotations.Beta;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
-import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
@@ -474,7 +472,7 @@ public class Entitlements {
private static Object instantiate(Class<?> clazz, List<Object[]> constructorArgOptions) {
try {
for (Object[] constructorArgOption : constructorArgOptions) {
- Optional<?> result = Reflections.invokeConstructorWithArgs(clazz, constructorArgOption);
+ Maybe<?> result = Reflections.invokeConstructorFromArgs(clazz, constructorArgOption);
if (result.isPresent()) return result.get();
}
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/BasicExternalConfigSupplierRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/BasicExternalConfigSupplierRegistry.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/BasicExternalConfigSupplierRegistry.java
index 6b261db..ac67f22 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/BasicExternalConfigSupplierRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/BasicExternalConfigSupplierRegistry.java
@@ -27,11 +27,11 @@ import org.apache.brooklyn.core.config.ConfigPredicates;
import org.apache.brooklyn.core.config.ConfigUtils;
import org.apache.brooklyn.core.config.external.ExternalConfigSupplier;
import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.javalang.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
import com.google.common.collect.Maps;
/**
@@ -102,9 +102,9 @@ public class BasicExternalConfigSupplierRegistry implements ExternalConfigSuppli
Map<String, Object> config = ConfigUtils.filterForPrefixAndStrip(externalProviderProperties, key + ".");
try {
- Optional<ExternalConfigSupplier> configSupplier = Reflections.invokeConstructorWithArgs(classloader, providerClassname, mgmt, name, config);
+ Maybe<ExternalConfigSupplier> configSupplier = Reflections.invokeConstructorFromArgs(classloader, ExternalConfigSupplier.class, providerClassname, mgmt, name, config);
if (!configSupplier.isPresent()) {
- configSupplier = Reflections.invokeConstructorWithArgs(classloader, providerClassname, mgmt, name);
+ configSupplier = Reflections.invokeConstructorFromArgs(classloader, ExternalConfigSupplier.class, providerClassname, mgmt, name);
}
if (!configSupplier.isPresent()) {
throw new IllegalStateException("No matching constructor found in "+providerClassname);
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalUsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalUsageManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalUsageManager.java
index 7caf958..50df5c8 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalUsageManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalUsageManager.java
@@ -50,6 +50,7 @@ import org.apache.brooklyn.core.mgmt.usage.UsageListener;
import org.apache.brooklyn.core.mgmt.usage.UsageManager;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.javalang.Reflections;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
@@ -57,7 +58,6 @@ import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
-import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
@@ -142,7 +142,7 @@ public class LocalUsageManager implements UsageManager {
@Override public UsageListener apply(String input) {
// TODO Want to use classLoader = mgmt.getCatalog().getRootClassLoader();
ClassLoader classLoader = LocalUsageManager.class.getClassLoader();
- Optional<Object> result = Reflections.invokeConstructorWithArgs(classLoader, input);
+ Maybe<Object> result = Reflections.invokeConstructorFromArgs(classLoader, input);
if (result.isPresent()) {
return (UsageListener) result.get();
} else {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
index 5c77753..6c0bd9d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
@@ -101,7 +101,6 @@ import org.apache.brooklyn.util.time.Time;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableMap;
@@ -1118,7 +1117,7 @@ public abstract class RebindIteration {
protected <T> T invokeConstructor(Reflections reflections, Class<T> clazz, Object[]... possibleArgs) {
for (Object[] args : possibleArgs) {
try {
- Optional<T> v = Reflections.invokeConstructorWithArgs(clazz, args, true);
+ Maybe<T> v = Reflections.invokeConstructorFromArgs(clazz, args, true);
if (v.isPresent()) {
return v.get();
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalFactory.java b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalFactory.java
index f5454fe..0f7e79e 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalFactory.java
@@ -28,10 +28,9 @@ import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.javalang.Reflections;
-import com.google.common.base.Optional;
-
/**
*/
public class InternalFactory {
@@ -142,9 +141,9 @@ public class InternalFactory {
protected <T> T constructOldStyle(Class<T> clazz, Map<String,?> flags) throws InstantiationException, IllegalAccessException, InvocationTargetException {
FactoryConstructionTracker.setConstructing();
- Optional<T> v;
+ Maybe<T> v;
try {
- v = Reflections.invokeConstructorWithArgs(clazz, new Object[] {MutableMap.copyOf(flags)}, true);
+ v = Reflections.invokeConstructorFromArgs(clazz, new Object[] {MutableMap.copyOf(flags)}, true);
} finally {
FactoryConstructionTracker.reset();
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
index d4d5b1d..0271134 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
@@ -115,7 +115,7 @@ public class DynamicClusterImpl extends AbstractGroupImpl implements DynamicClus
@Override
public NodePlacementStrategy apply(final String input) {
ClassLoader classLoader = NodePlacementStrategy.class.getClassLoader();
- Optional<NodePlacementStrategy> strategy = Reflections.<NodePlacementStrategy>invokeConstructorWithArgs(classLoader, input);
+ Maybe<NodePlacementStrategy> strategy = Reflections.invokeConstructorFromArgs(classLoader, NodePlacementStrategy.class, input);
if (strategy.isPresent()) {
return strategy.get();
} else {
@@ -127,7 +127,7 @@ public class DynamicClusterImpl extends AbstractGroupImpl implements DynamicClus
@Override
public ZoneFailureDetector apply(final String input) {
ClassLoader classLoader = ZoneFailureDetector.class.getClassLoader();
- Optional<ZoneFailureDetector> detector = Reflections.<ZoneFailureDetector>invokeConstructorWithArgs(classLoader, input);
+ Maybe<ZoneFailureDetector> detector = Reflections.invokeConstructorFromArgs(classLoader, ZoneFailureDetector.class, input);
if (detector.isPresent()) {
return detector.get();
} else {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
index 51e9d6a..58895a8 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
@@ -58,7 +58,6 @@ import org.apache.brooklyn.api.location.NoMachinesAvailableException;
import org.apache.brooklyn.api.location.PortRange;
import org.apache.brooklyn.api.mgmt.AccessController;
import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
import org.apache.brooklyn.core.BrooklynVersion;
@@ -107,8 +106,6 @@ import org.apache.brooklyn.util.core.task.TaskBuilder;
import org.apache.brooklyn.util.core.task.TaskInternal;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.core.task.ssh.SshTasks;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.core.text.TemplateProcessor;
import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
import org.apache.brooklyn.util.exceptions.Exceptions;
@@ -400,7 +397,7 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
protected CloudMachineNamer getCloudMachineNamer(ConfigBag config) {
String namerClass = config.get(LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS);
if (Strings.isNonBlank(namerClass)) {
- Optional<CloudMachineNamer> cloudNamer = Reflections.invokeConstructorWithArgs(getManagementContext().getCatalogClassLoader(), namerClass);
+ Maybe<CloudMachineNamer> cloudNamer = Reflections.invokeConstructorFromArgs(getManagementContext().getCatalogClassLoader(), CloudMachineNamer.class, namerClass);
if (cloudNamer.isPresent()) {
return cloudNamer.get();
} else {
@@ -425,11 +422,11 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
if (customizer != null) result.add(customizer);
if (customizers != null) result.addAll(customizers);
if (Strings.isNonBlank(customizerType)) {
- Optional<JcloudsLocationCustomizer> customizerByType = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizerType, setup);
+ Maybe<JcloudsLocationCustomizer> customizerByType = Reflections.invokeConstructorFromArgs(catalogClassLoader, JcloudsLocationCustomizer.class, customizerType, setup);
if (customizerByType.isPresent()) {
result.add(customizerByType.get());
} else {
- customizerByType = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizerType);
+ customizerByType = Reflections.invokeConstructorFromArgs(catalogClassLoader, JcloudsLocationCustomizer.class, customizerType);
if (customizerByType.isPresent()) {
result.add(customizerByType.get());
} else {
@@ -438,11 +435,11 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
}
}
if (Strings.isNonBlank(customizersSupplierType)) {
- Optional<Supplier<Collection<JcloudsLocationCustomizer>>> supplier = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizersSupplierType, setup);
+ Maybe<Supplier<Collection<JcloudsLocationCustomizer>>> supplier = Reflections.<Supplier<Collection<JcloudsLocationCustomizer>>>invokeConstructorFromArgsUntyped(catalogClassLoader, customizersSupplierType, setup);
if (supplier.isPresent()) {
result.addAll(supplier.get().get());
} else {
- supplier = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizersSupplierType);
+ supplier = Reflections.<Supplier<Collection<JcloudsLocationCustomizer>>>invokeConstructorFromArgsUntyped(catalogClassLoader, customizersSupplierType);
if (supplier.isPresent()) {
result.addAll(supplier.get().get());
} else {
@@ -1566,7 +1563,7 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
Object rawVal = config.getStringKey(JcloudsLocationConfig.IMAGE_CHOOSER.getName());
if (rawVal instanceof String && Strings.isNonBlank((String)rawVal)) {
// Configured with a string: it could be a class that we need to instantiate
- Optional<?> instance = Reflections.invokeConstructorWithArgs(getManagementContext().getCatalogClassLoader(), (String)rawVal);
+ Maybe<?> instance = Reflections.invokeConstructorFromArgs(getManagementContext().getCatalogClassLoader(), (String)rawVal);
if (!instance.isPresent()) {
throw new IllegalStateException("Failed to create ImageChooser "+rawVal+" for location "+this);
} else if (!(instance.get() instanceof Function)) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
index aa74d1b..a544f01 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/test/Asserts.java
@@ -1161,8 +1161,12 @@ public class Asserts {
/** Throws a {@link ShouldHaveFailedPreviouslyAssertionError} exception,
* to more easily distinguish this failure from other fails.
* In particular, use one of the <code>expectedFailure</code> methods
- * in the surrounding <code>catch</code> block and this error will pass through it. */
- public static void shouldHaveFailedPreviously() {
+ * in the surrounding <code>catch</code> block and this error will pass through it.
+ * <p>
+ * This method throws, never returning normally, but declares a return type
+ * so you can pretend to throw the result,
+ * for instance if your calling code otherwise warns about needing to return something. */
+ public static RuntimeException shouldHaveFailedPreviously() {
throw new ShouldHaveFailedPreviouslyAssertionError();
}
/** As {@link #shouldHaveFailedPreviously()} but allowing detail,
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/main/java/org/apache/brooklyn/util/guava/AnyExceptionSupplier.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/guava/AnyExceptionSupplier.java b/utils/common/src/main/java/org/apache/brooklyn/util/guava/AnyExceptionSupplier.java
index 7111c39..a194ac0 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/guava/AnyExceptionSupplier.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/guava/AnyExceptionSupplier.java
@@ -44,10 +44,10 @@ public class AnyExceptionSupplier<T extends Throwable> implements Supplier<T> {
public T get() {
String msg = message==null ? null : message.get();
Maybe<T> result = Maybe.absent();
- if (result.isAbsent() && msg==null && cause==null) result = Reflections.invokeConstructorWithArgs(type);
- if (result.isAbsent() && cause==null) result = Reflections.invokeConstructorWithArgs(type, msg);
- if (result.isAbsent() && msg==null) result = Reflections.invokeConstructorWithArgs(type, cause);
- if (result.isAbsent()) result = Reflections.invokeConstructorWithArgs(type, msg, cause);
+ if (result.isAbsent() && msg==null && cause==null) result = Reflections.invokeConstructorFromArgs(type);
+ if (result.isAbsent() && cause==null) result = Reflections.invokeConstructorFromArgs(type, msg);
+ if (result.isAbsent() && msg==null) result = Reflections.invokeConstructorFromArgs(type, cause);
+ if (result.isAbsent()) result = Reflections.invokeConstructorFromArgs(type, msg, cause);
if (result.isAbsent()) {
throw new IllegalStateException("Cannot create desired "+type+" (missing constructor)",
new IllegalStateException(message==null ? null : message.get(), cause));
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Boxing.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Boxing.java b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Boxing.java
index 79a1830..87529ad 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Boxing.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Boxing.java
@@ -23,7 +23,11 @@ import java.lang.reflect.Array;
import org.apache.brooklyn.util.guava.Maybe;
import com.google.common.collect.ImmutableBiMap;
+import com.google.common.primitives.Primitives;
+/** Conveniences for working with primitives and their boxed (wrapper) types.
+ * NB: there is redundancy with {@link Primitives}
+ */
public class Boxing {
public static boolean unboxSafely(Boolean ref, boolean valueIfNull) {
@@ -56,6 +60,17 @@ public class Boxing {
}
return Maybe.absent("Not a primitive: "+typeName);
}
+
+ /** returns name of primitive corresponding to the given (boxed or unboxed) type */
+ public static Maybe<String> getPrimitiveName(Class<?> type) {
+ if (type!=null) {
+ if (PRIMITIVE_TO_BOXED.containsKey(type)) return Maybe.of(type.getName());
+ if (PRIMITIVE_TO_BOXED.containsValue(type)) {
+ return Maybe.of(PRIMITIVE_TO_BOXED.inverse().get(type).getName());
+ }
+ }
+ return Maybe.absent("Not a primitive or boxed primitive: "+type);
+ }
public static Class<?> boxedType(Class<?> type) {
if (PRIMITIVE_TO_BOXED.containsKey(type))
@@ -63,6 +78,20 @@ public class Boxing {
return type;
}
+ public static boolean isPrimitiveOrBoxedObject(Object o) {
+ if (o==null) return false;
+ return isPrimitiveOrBoxedClass(o.getClass());
+ }
+ public static boolean isPrimitiveOrBoxedClass(Class<?> t) {
+ // TODO maybe better to switch to using Primitives, eg:
+ // return Primitives.allPrimitiveTypes().contains(type) || Primitives.allWrapperTypes().contains(type);
+
+ if (t==null) return false;
+ if (t.isPrimitive()) return true;
+ if (PRIMITIVE_TO_BOXED.containsValue(t)) return true;
+ return false;
+ }
+
/** sets the given element in an array to the indicated value;
* if the type is a primitive type, the appropriate primitive method is used
* <p>
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Enums.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Enums.java b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Enums.java
index d3bfd83..a9305a8 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Enums.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Enums.java
@@ -71,8 +71,10 @@ public class Enums {
return new EnumFromStringFunction<T>(type);
}
+ /** returns array of values in the given enum, or null if it is not an enum */
@SuppressWarnings("unchecked")
- private static <T extends Enum<?>> T[] values(Class<T> type) {
+ public static <T extends Enum<?>> T[] values(Class<T> type) {
+ if (type==null || !type.isEnum()) return null;
try {
return (T[]) type.getMethod("values").invoke(null);
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/main/java/org/apache/brooklyn/util/javalang/FieldOrderings.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/FieldOrderings.java b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/FieldOrderings.java
new file mode 100644
index 0000000..ceb33e8
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/FieldOrderings.java
@@ -0,0 +1,82 @@
+/*
+ * 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.brooklyn.util.javalang;
+
+import java.lang.reflect.Field;
+import java.util.Comparator;
+
+import org.apache.brooklyn.util.collections.MutableList;
+
+import com.google.common.collect.Ordering;
+
+public class FieldOrderings {
+ public static class FieldNameComparator implements Comparator<Field> {
+ private final Comparator<String> nameComparator;
+ public FieldNameComparator(Comparator<String> nameComparator) { this.nameComparator = nameComparator; }
+ @Override
+ public int compare(Field o1, Field o2) {
+ return nameComparator.compare(o1.getName(), o2.getName());
+ }
+ }
+ public static class FieldClassComparator implements Comparator<Field> {
+ private final Comparator<Class<?>> classComparator;
+ public FieldClassComparator(Comparator<Class<?>> classComparator) { this.classComparator = classComparator; }
+ @Override
+ public int compare(Field o1, Field o2) {
+ return classComparator.compare(o1.getDeclaringClass(), o2.getDeclaringClass());
+ }
+ }
+
+ public static Comparator<Class<?>> SUB_BEST_CLASS_COMPARATOR = new SubbestClassComparator();
+ private static class SubbestClassComparator implements Comparator<Class<?>> {
+ @Override
+ public int compare(Class<?> c1, Class<?> c2) {
+ Class<?> cS = Reflections.inferSubbest(c1, c2);
+ return (cS==c1 ? -1 : cS==c2 ? 1 : 0);
+ }
+ }
+
+ /** Puts fields lower in the hierarchy first, and otherwise leaves fields in order */
+ public static Comparator<Field> SUB_BEST_FIELD_FIST_THEN_DEFAULT =
+ new FieldClassComparator(SUB_BEST_CLASS_COMPARATOR);
+ /** Puts fields higher in the hierarchy first, and otherwise leaves fields in order */
+ public static Comparator<Field> SUB_BEST_FIELD_LAST_THEN_DEFAULT =
+ new FieldClassComparator(Ordering.from(SUB_BEST_CLASS_COMPARATOR).reverse());
+ /** Puts fields that are lower down the hierarchy first, and then sorts those alphabetically */
+ @SuppressWarnings("unchecked")
+ public static Comparator<Field> SUB_BEST_FIELD_FIRST_THEN_ALPHABETICAL = Ordering.compound(MutableList.of(
+ new FieldClassComparator(SUB_BEST_CLASS_COMPARATOR),
+ new FieldNameComparator(Ordering.<String>natural())));
+ /** Puts fields that are higher up in the hierarchy first, and then sorts those alphabetically */
+ @SuppressWarnings("unchecked")
+ public static Comparator<Field> SUB_BEST_FIELD_LAST_THEN_ALPHABETICAL = Ordering.compound(MutableList.of(
+ new FieldClassComparator(Ordering.from(SUB_BEST_CLASS_COMPARATOR).reverse()),
+ new FieldNameComparator(Ordering.<String>natural())));
+ /** Puts fields in alpha order, but in cases of duplicate those lower down the hierarchy are first */
+ @SuppressWarnings("unchecked")
+ public static Comparator<Field> ALPHABETICAL_FIELD_THEN_SUB_BEST_FIRST = Ordering.compound(MutableList.of(
+ new FieldNameComparator(Ordering.<String>natural()),
+ new FieldClassComparator(SUB_BEST_CLASS_COMPARATOR)));
+ /** Puts fields in alpha order, but in cases of duplicate those higher up in the hierarchy are first
+ * (potentially confusing, as this will put masked fields first) */
+ @SuppressWarnings("unchecked")
+ public static Comparator<Field> ALPHABETICAL_FIELD_THEN_SUB_BEST_LAST = Ordering.compound(MutableList.of(
+ new FieldNameComparator(Ordering.<String>natural()),
+ new FieldClassComparator(Ordering.from(SUB_BEST_CLASS_COMPARATOR).reverse())));
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/main/java/org/apache/brooklyn/util/javalang/JavaClassNames.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/JavaClassNames.java b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/JavaClassNames.java
index e9918df..fe8dd0c 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/JavaClassNames.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/JavaClassNames.java
@@ -79,15 +79,23 @@ public class JavaClassNames {
String result = ct.getSimpleName();
if (Strings.isBlank(result) || result.length()<=4) {
- if (ct.isPrimitive()) {
- // TODO unbox
- } else {
- result = ct.getName();
- }
+ result = ct.getName();
}
return result+Strings.repeat("[]", arrayCount);
}
+ /** as {@link #simpleClassName(Class)} but if something is an inner class it drops everything before the $ */
+ public static String verySimpleClassName(Class<?> t) {
+ t = componentType(t);
+ String result = t.getSimpleName();
+ result = result.substring(result.lastIndexOf('.')+1);
+ result = result.substring(result.lastIndexOf('$')+1);
+ if (Strings.isBlank(result)) {
+ result = t.getName();
+ }
+ return result;
+ }
+
/** as {@link #simpleClassName(Class)} but taking the type of the object if it is not already a class
* or a type-token; callers should usually do the getClass themselves, unless they aren't sure whether
* it is already a Class-type object */
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/main/java/org/apache/brooklyn/util/javalang/ReflectionPredicates.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/ReflectionPredicates.java b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/ReflectionPredicates.java
new file mode 100644
index 0000000..3395296
--- /dev/null
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/ReflectionPredicates.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.util.javalang;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+
+public class ReflectionPredicates {
+
+ public static Predicate<Integer> MODIFIERS_PRIVATE = new ModifiersPrivate();
+ private static class ModifiersPrivate implements Predicate<Integer> {
+ @Override public boolean apply(Integer modifiers) { return Modifier.isPrivate(modifiers); }
+ }
+ public static Predicate<Integer> MODIFIERS_PUBLIC = new ModifiersPublic();
+ private static class ModifiersPublic implements Predicate<Integer> {
+ @Override public boolean apply(Integer modifiers) { return Modifier.isPublic(modifiers); }
+ }
+ public static Predicate<Integer> MODIFIERS_PROTECTED = new ModifiersProtected();
+ private static class ModifiersProtected implements Predicate<Integer> {
+ @Override public boolean apply(Integer modifiers) { return Modifier.isProtected(modifiers); }
+ }
+
+ public static Predicate<Integer> MODIFIERS_TRANSIENT = new ModifiersTransient();
+ private static class ModifiersTransient implements Predicate<Integer> {
+ @Override public boolean apply(Integer modifiers) { return Modifier.isTransient(modifiers); }
+ }
+ public static Predicate<Integer> MODIFIERS_STATIC = new ModifiersStatic();
+ private static class ModifiersStatic implements Predicate<Integer> {
+ @Override public boolean apply(Integer modifiers) { return Modifier.isStatic(modifiers); }
+ }
+
+ public static Predicate<Field> fieldModifiers(Predicate<Integer> modifiersCheck) { return new FieldModifiers(modifiersCheck); }
+ private static class FieldModifiers implements Predicate<Field> {
+ private Predicate<Integer> modifiersCheck;
+ private FieldModifiers(Predicate<Integer> modifiersCheck) { this.modifiersCheck = modifiersCheck; }
+ @Override public boolean apply(Field f) { return modifiersCheck.apply(f.getModifiers()); }
+ }
+ public static Predicate<Field> IS_FIELD_PUBLIC = fieldModifiers(MODIFIERS_PUBLIC);
+ public static Predicate<Field> IS_FIELD_TRANSIENT = fieldModifiers(MODIFIERS_TRANSIENT);
+ public static Predicate<Field> IS_FIELD_NON_TRANSIENT = Predicates.not(IS_FIELD_TRANSIENT);
+ public static Predicate<Field> IS_FIELD_STATIC = fieldModifiers(MODIFIERS_STATIC);
+ public static Predicate<Field> IS_FIELD_NON_STATIC = Predicates.not(IS_FIELD_STATIC);
+
+ public static Predicate<Method> methodModifiers(Predicate<Integer> modifiersCheck) { return new MethodModifiers(modifiersCheck); }
+ private static class MethodModifiers implements Predicate<Method> {
+ private Predicate<Integer> modifiersCheck;
+ private MethodModifiers(Predicate<Integer> modifiersCheck) { this.modifiersCheck = modifiersCheck; }
+ @Override public boolean apply(Method m) { return modifiersCheck.apply(m.getModifiers()); }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Reflections.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Reflections.java b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Reflections.java
index 0f31882..7b2cba4 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Reflections.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Reflections.java
@@ -47,18 +47,20 @@ import javax.annotation.Nullable;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
- * Reflection utilities ("borrowed" from cloudsoft monterey).
+ * Reflection utilities
*
* @author aled
*/
@@ -88,7 +90,7 @@ public class Reflections {
private final Map<String, String> classRenameMap = MutableMap.of();
public Reflections(ClassLoader classLoader) {
- this.classLoader = checkNotNull(classLoader);
+ this.classLoader = classLoader!=null ? classLoader : getClass().getClassLoader();
}
/** supply a map of known renames, of the form "old-class -> new-class" */
@@ -99,9 +101,9 @@ public class Reflections {
public Object loadInstance(String classname, Object...argValues) throws ReflectionNotFoundException, ReflectionAccessException {
Class<?> clazz = loadClass(classname);
- Optional<?> v = null;
+ Maybe<?> v = null;
try {
- v = invokeConstructorWithArgs(clazz, argValues);
+ v = invokeConstructorFromArgs(clazz, argValues);
if (v.isPresent()) return v.get();
} catch (Exception e) {
throw new IllegalStateException("Error invoking constructor for "+clazz+Arrays.toString(argValues) + ": " + Exceptions.collapseText(e));
@@ -221,41 +223,80 @@ public class Reflections {
}
}
- /** Invokes a suitable constructor, supporting varargs and primitives */
+ /** @deprecated since 0.10.0 use {@link #invokeConstructorFromArgs(Class, Object...)} or one of the variants;
+ * this allows null field values */ @Deprecated
public static <T> Optional<T> invokeConstructorWithArgs(ClassLoader classLoader, String className, Object...argsArray) {
+ return Reflections.<T>invokeConstructorFromArgsUntyped(classLoader, className, argsArray).toOptional();
+ }
+ /** @deprecated since 0.10.0 use {@link #invokeConstructorFromArgs(Class, Object...)} or one of the variants */ @Deprecated
+ public static <T> Optional<T> invokeConstructorWithArgs(ClassLoader classLoader, Class<T> clazz, Object[] argsArray, boolean setAccessible) {
+ return invokeConstructorFromArgs(classLoader, clazz, argsArray, setAccessible).toOptional();
+ }
+ /** @deprecated since 0.10.0 use {@link #invokeConstructorFromArgs(Class, Object...)} or one of the variants */ @Deprecated
+ public static <T> Optional<T> invokeConstructorWithArgs(Class<? extends T> clazz, Object...argsArray) {
+ return invokeConstructorFromArgs(clazz, argsArray).toOptional();
+ }
+ /** @deprecated since 0.10.0 use {@link #invokeConstructorFromArgs(Class, Object...)} or one of the variants */ @Deprecated
+ public static <T> Optional<T> invokeConstructorWithArgs(Class<? extends T> clazz, Object[] argsArray, boolean setAccessible) {
+ return invokeConstructorFromArgs(clazz, argsArray, setAccessible).toOptional();
+ }
+ /** @deprecated since 0.10.0 use {@link #invokeConstructorFromArgs(Class, Object...)} or one of the variants */ @Deprecated
+ public static <T> Optional<T> invokeConstructorWithArgs(Reflections reflections, Class<? extends T> clazz, Object[] argsArray, boolean setAccessible) {
+ return invokeConstructorFromArgs(reflections, clazz, argsArray, setAccessible).toOptional();
+ }
+
+ /** Finds and invokes a suitable constructor, supporting varargs and primitives, boxing and looking at compatible supertypes in the constructor's signature */
+ public static <T> Maybe<T> invokeConstructorFromArgs(Class<? extends T> clazz, Object...argsArray) {
+ return invokeConstructorFromArgs(clazz, argsArray, false);
+ }
+
+ /** As {@link #invokeConstructorFromArgs(Class, Object...)} but allowing more configurable input */
+ public static Maybe<Object> invokeConstructorFromArgs(ClassLoader classLoader, String className, Object...argsArray) {
+ return invokeConstructorFromArgs(classLoader, null, className, argsArray);
+ }
+
+ /** As {@link #invokeConstructorFromArgs(Class, Object...)} but allowing more configurable input */
+ @SuppressWarnings("unchecked")
+ public static <T> Maybe<T> invokeConstructorFromArgs(ClassLoader classLoader, Class<T> optionalSupertype, String className, Object...argsArray) {
Reflections reflections = new Reflections(classLoader);
- @SuppressWarnings("unchecked")
- Class<T> clazz = (Class<T>) reflections.loadClass(className);
- return invokeConstructorWithArgs(reflections, clazz, argsArray, false);
+ Class<?> clazz = reflections.loadClass(className);
+ if (optionalSupertype!=null && !optionalSupertype.isAssignableFrom(clazz)) {
+ return Maybe.absent("The type requested '"+className+"' is not assignable to "+optionalSupertype);
+ }
+ return invokeConstructorFromArgs(reflections, (Class<T>)clazz, argsArray, false);
}
- /** Invokes a suitable constructor, supporting varargs and primitives */
- public static <T> Optional<T> invokeConstructorWithArgs(ClassLoader classLoader, Class<T> clazz, Object[] argsArray, boolean setAccessible) {
+ /** As {@link #invokeConstructorFromArgs(Class, Object...)} but allowing more configurable input */
+ public static <T> Maybe<T> invokeConstructorFromArgsUntyped(ClassLoader classLoader, String className, Object...argsArray) {
Reflections reflections = new Reflections(classLoader);
- return invokeConstructorWithArgs(reflections, clazz, argsArray, setAccessible);
+ @SuppressWarnings("unchecked")
+ Class<T> clazz = (Class<T>)reflections.loadClass(className);
+ return invokeConstructorFromArgs(reflections, clazz, argsArray, false);
}
- /** Invokes a suitable constructor, supporting varargs and primitives */
- public static <T> Optional<T> invokeConstructorWithArgs(Class<T> clazz, Object...argsArray) {
- return invokeConstructorWithArgs(clazz, argsArray, false);
+ /** As {@link #invokeConstructorFromArgs(Class, Object...)} but allowing more configurable input;
+ * in particular setAccessible allows private constructors to be used (not the default) */
+ public static <T> Maybe<T> invokeConstructorFromArgs(ClassLoader classLoader, Class<T> clazz, Object[] argsArray, boolean setAccessible) {
+ Reflections reflections = new Reflections(classLoader);
+ return invokeConstructorFromArgs(reflections, clazz, argsArray, setAccessible);
}
- /** Invokes a suitable constructor, supporting varargs and primitives */
- public static <T> Optional<T> invokeConstructorWithArgs(Class<T> clazz, Object[] argsArray, boolean setAccessible) {
- ClassLoader cl = clazz.getClassLoader();
- // if bootstrap class loader
- if (cl == null) {
- // The classloader isn't actually used so anything non-null will work
- cl = ClassLoader.getSystemClassLoader();
- }
- Reflections reflections = new Reflections(cl);
- return invokeConstructorWithArgs(reflections, clazz, argsArray, setAccessible);
+ /** As {@link #invokeConstructorFromArgs(Class, Object...)} but allowing more configurable input;
+ * in particular setAccessible allows private constructors to be used (not the default) */
+ public static <T> Maybe<T> invokeConstructorFromArgs(Class<? extends T> clazz, Object[] argsArray, boolean setAccessible) {
+ Reflections reflections = new Reflections(clazz.getClassLoader());
+ return invokeConstructorFromArgs(reflections, clazz, argsArray, setAccessible);
}
- /** Invokes a suitable constructor, supporting varargs and primitives, additionally supporting setAccessible */
+ /** As {@link #invokeConstructorFromArgs(Class, Object...)} but will use private constructors (with setAccessible = true) */
+ public static <T> Maybe<T> invokeConstructorFromArgsIncludingPrivate(Class<? extends T> clazz, Object ...argsArray) {
+ return Reflections.invokeConstructorFromArgs(new Reflections(clazz.getClassLoader()), clazz, argsArray, true);
+ }
+ /** As {@link #invokeConstructorFromArgs(Class, Object...)} but allowing more configurable input;
+ * in particular setAccessible allows private constructors to be used (not the default) */
@SuppressWarnings("unchecked")
- public static <T> Optional<T> invokeConstructorWithArgs(Reflections reflections, Class<T> clazz, Object[] argsArray, boolean setAccessible) {
- for (Constructor<?> constructor : clazz.getConstructors()) {
+ public static <T> Maybe<T> invokeConstructorFromArgs(Reflections reflections, Class<? extends T> clazz, Object[] argsArray, boolean setAccessible) {
+ for (Constructor<?> constructor : MutableList.<Constructor<?>>of().appendAll(Arrays.asList(clazz.getConstructors())).appendAll(Arrays.asList(clazz.getDeclaredConstructors()))) {
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (constructor.isVarArgs()) {
if (typesMatchUpTo(argsArray, parameterTypes, parameterTypes.length-1)) {
@@ -277,16 +318,16 @@ public class Reflections {
System.arraycopy(argsArray, 0, newArgsArray, 0, parameterTypes.length-1);
newArgsArray[parameterTypes.length-1] = varargs;
if (setAccessible) constructor.setAccessible(true);
- return (Optional<T>) Optional.of(reflections.loadInstance(constructor, newArgsArray));
+ return Maybe.of((T)reflections.loadInstance(constructor, newArgsArray));
}
}
}
if (typesMatch(argsArray, parameterTypes)) {
if (setAccessible) constructor.setAccessible(true);
- return (Optional<T>) Optional.of(reflections.loadInstance(constructor, argsArray));
+ return Maybe.of((T) reflections.loadInstance(constructor, argsArray));
}
}
- return Optional.absent();
+ return Maybe.absent("Constructor not found");
}
@@ -560,25 +601,86 @@ public class Reflections {
throw toThrowIfFails;
}
+ /** Finds the field with the given name declared on the given class or any superclass,
+ * using {@link Class#getDeclaredField(String)}.
+ * <p>
+ * If the field name contains a '.' the field is interpreted as having
+ * <code>DeclaringClassCanonicalName.FieldName</code> format,
+ * allowing a way to set a field unambiguously if some are masked.
+ * <p>
+ * @throws NoSuchFieldException if not found
+ */
public static Field findField(Class<?> clazz, String name) throws NoSuchFieldException {
+ return findFieldMaybe(clazz, name).orThrowUnwrapped();
+ }
+ public static Maybe<Field> findFieldMaybe(Class<?> clazz, String originalName) {
+ String name = originalName;
if (clazz == null || name == null) {
throw new NullPointerException("Must not be null: clazz="+clazz+"; name="+name);
}
Class<?> clazzToInspect = clazz;
NoSuchFieldException toThrowIfFails = null;
+
+ String clazzRequired = null;
+ if (name.indexOf('.')>=0) {
+ int lastDotIndex = name.lastIndexOf('.');
+ clazzRequired = name.substring(0, lastDotIndex);
+ name = name.substring(lastDotIndex+1);
+ }
while (clazzToInspect != null) {
try {
- return clazzToInspect.getDeclaredField(name);
+ if (clazzRequired==null || clazzRequired.equals(clazzToInspect.getCanonicalName())) {
+ return Maybe.of(clazzToInspect.getDeclaredField(name));
+ }
} catch (NoSuchFieldException e) {
if (toThrowIfFails == null) toThrowIfFails = e;
- clazzToInspect = clazzToInspect.getSuperclass();
}
+ clazzToInspect = clazzToInspect.getSuperclass();
}
- throw toThrowIfFails;
+ if (toThrowIfFails==null) return Maybe.absent("Field '"+originalName+"' not found");
+ return Maybe.absent(toThrowIfFails);
}
+ public static Maybe<Object> getFieldValueMaybe(Object instance, String fieldName) {
+ try {
+ if (instance==null) return null;
+ Field f = findField(instance.getClass(), fieldName);
+ return getFieldValueMaybe(instance, f);
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ return Maybe.absent(e);
+ }
+ }
+
+ public static Maybe<Object> getFieldValueMaybe(Object instance, Field field) {
+ try {
+ if (instance==null) return null;
+ if (field==null) return null;
+ field.setAccessible(true);
+ return Maybe.of(field.get(instance));
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ return Maybe.absent(e);
+ }
+ }
+
+ /** Lists all public fields declared on the class or any ancestor, with those HIGHEST in the hierarchy first */
public static List<Field> findPublicFieldsOrderedBySuper(Class<?> clazz) {
+ return findFields(clazz, new Predicate<Field>() {
+ @Override public boolean apply(Field input) {
+ return Modifier.isPublic(input.getModifiers());
+ }}, FieldOrderings.SUB_BEST_FIELD_LAST_THEN_DEFAULT);
+ }
+
+ /** Lists all fields declared on the class, with those lowest in the hierarchy first,
+ * filtered and ordered as requested.
+ * <p>
+ * See {@link ReflectionPredicates} and {@link FieldOrderings} for conveniences.
+ * <p>
+ * Default is no filter and {@link FieldOrderings#SUB_BEST_FIELD_LAST_THEN_ALPHABETICAL}
+ * */
+ public static List<Field> findFields(final Class<?> clazz, Predicate<Field> filter, Comparator<Field> fieldOrdering) {
checkNotNull(clazz, "clazz");
MutableList.Builder<Field> result = MutableList.<Field>builder();
Stack<Class<?>> tovisit = new Stack<Class<?>>();
@@ -593,19 +695,12 @@ public class Reflections {
if (nextclazz.getSuperclass() != null) tovisit.add(nextclazz.getSuperclass());
tovisit.addAll(Arrays.asList(nextclazz.getInterfaces()));
- result.addAll(Iterables.filter(Arrays.asList(nextclazz.getDeclaredFields()), new Predicate<Field>() {
- @Override public boolean apply(Field input) {
- return Modifier.isPublic(input.getModifiers());
- }}));
-
+ result.addAll(Iterables.filter(Arrays.asList(nextclazz.getDeclaredFields()),
+ filter!=null ? filter : Predicates.<Field>alwaysTrue()));
}
List<Field> resultList = result.build();
- Collections.sort(resultList, new Comparator<Field>() {
- @Override public int compare(Field f1, Field f2) {
- Field fsubbest = inferSubbestField(f1, f2);
- return (fsubbest == null) ? 0 : (fsubbest == f1 ? 1 : -1);
- }});
+ Collections.sort(resultList, fieldOrdering != null ? fieldOrdering : FieldOrderings.SUB_BEST_FIELD_LAST_THEN_ALPHABETICAL);
return resultList;
}
@@ -645,18 +740,25 @@ public class Reflections {
}
/**
- * Gets the field that is in the sub-class; or null if one field does not come from a sub-class of the other field's class
+ * If the classes of the fields satisfy {@link #inferSubbest(Class, Class)}
+ * return the field in the lower (sub-best) class, otherwise null.
*/
public static Field inferSubbestField(Field f1, Field f2) {
Class<?> c1 = f1.getDeclaringClass();
Class<?> c2 = f2.getDeclaringClass();
boolean isSuper1 = c1.isAssignableFrom(c2);
boolean isSuper2 = c2.isAssignableFrom(c1);
- return (isSuper1) ? (isSuper2 ? null : f2) : (isSuper2 ? f1 : null);
+ return (isSuper1) ? (isSuper2 ?
+ /* same field */ null :
+ /* f1 from super */ f2) :
+ (isSuper2 ?
+ /* f2 from super of f1 */ f1 :
+ /* fields are from different hierarchies */ null);
}
/**
- * Gets the method that is in the sub-class; or null if one method does not come from a sub-class of the other method's class
+ * If the classes of the methods satisfy {@link #inferSubbest(Class, Class)}
+ * return the field in the lower (sub-best) class, otherwise null.
*/
public static Method inferSubbestMethod(Method m1, Method m2) {
Class<?> c1 = m1.getDeclaringClass();
@@ -667,7 +769,8 @@ public class Reflections {
}
/**
- * Gets the class that is in the sub-class; or null if neither is a sub-class of the other.
+ * If one class is a subclass of the other, return that (the lower in the type hierarchy);
+ * otherwise return null (if they are the same or neither is a subclass of the other).
*/
public static Class<?> inferSubbest(Class<?> c1, Class<?> c2) {
boolean isSuper1 = c1.isAssignableFrom(c2);
@@ -684,14 +787,25 @@ public class Reflections {
return (T)candidate;
}
+ /** @deprecated since 0.10.0 use {@link #invokeMethodFromArgs(Object, String, List)};
+ * this allows null return values */ @Deprecated
+ public static Optional<Object> invokeMethodWithArgs(Object clazzOrInstance, String method, List<Object> args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ return invokeMethodWithArgs(clazzOrInstance, method, args, false);
+ }
+ /** @deprecated since 0.10.0 use {@link #invokeMethodFromArgs(Object, String, List)} */ @Deprecated
+ public static Optional<Object> invokeMethodWithArgs(Object clazzOrInstance, String method, List<Object> args, boolean setAccessible) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ return invokeMethodFromArgs(clazzOrInstance, method, args, setAccessible).toOptional();
+ }
+
/** invokes the given method on the given clazz or instance, doing reasonably good matching on args etc
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException */
- public static Optional<Object> invokeMethodWithArgs(Object clazzOrInstance, String method, List<Object> args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
- return invokeMethodWithArgs(clazzOrInstance, method, args, false);
+ public static Maybe<Object> invokeMethodFromArgs(Object clazzOrInstance, String method, List<Object> args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ return invokeMethodFromArgs(clazzOrInstance, method, args, false);
}
- public static Optional<Object> invokeMethodWithArgs(Object clazzOrInstance, String method, List<Object> args, boolean setAccessible) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ /** as {@link #invokeMethodFromArgs(Object, String, List)} but giving control over whether to set it accessible */
+ public static Maybe<Object> invokeMethodFromArgs(Object clazzOrInstance, String method, List<Object> args, boolean setAccessible) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Preconditions.checkNotNull(clazzOrInstance, "clazz or instance");
Preconditions.checkNotNull(method, "method");
Preconditions.checkNotNull(args, "args to "+method);
@@ -731,18 +845,18 @@ public class Reflections {
System.arraycopy(argsArray, 0, newArgsArray, 0, parameterTypes.length-1);
newArgsArray[parameterTypes.length-1] = varargs;
if (setAccessible) m.setAccessible(true);
- return Optional.of(m.invoke(instance, newArgsArray));
+ return Maybe.of(m.invoke(instance, newArgsArray));
}
}
}
if (typesMatch(argsArray, parameterTypes)) {
if (setAccessible) m.setAccessible(true);
- return Optional.of(m.invoke(instance, argsArray));
+ return Maybe.of(m.invoke(instance, argsArray));
}
}
}
- return Optional.absent();
+ return Maybe.absent("Method not found matching given args");
}
/** true iff all args match the corresponding types */
@@ -802,13 +916,18 @@ public class Reflections {
return hasNoNonObjectFields(clazz.getSuperclass());
}
- /** Takes a map of old-class-names to renames classes, and returns the mapped name if matched, or absent */
+ /** @deprecated since 0.10.0 use {@link #findMappedNameMaybe(Map, String)} */ @Deprecated
public static Optional<String> tryFindMappedName(Map<String, String> renames, String name) {
- if (renames==null) return Optional.absent();
+ return findMappedNameMaybe(renames, name).toOptional();
+ }
+
+ /** Takes a map of old-class-names to renames classes, and returns the mapped name if matched, or absent */
+ public static Maybe<String> findMappedNameMaybe(Map<String, String> renames, String name) {
+ if (renames==null) return Maybe.absent("no renames supplied");
String mappedName = renames.get(name);
if (mappedName != null) {
- return Optional.of(mappedName);
+ return Maybe.of(mappedName);
}
// look for inner classes by mapping outer class
@@ -816,20 +935,20 @@ public class Reflections {
String outerClassName = name.substring(0, name.indexOf('$'));
mappedName = renames.get(outerClassName);
if (mappedName != null) {
- return Optional.of(mappedName + name.substring(name.indexOf('$')));
+ return Maybe.of(mappedName + name.substring(name.indexOf('$')));
}
}
- return Optional.absent();
+ return Maybe.absent("mapped name not present");
}
public static String findMappedNameAndLog(Map<String, String> renames, String name) {
- Optional<String> rename = Reflections.tryFindMappedName(renames, name);
+ Maybe<String> rename = Reflections.findMappedNameMaybe(renames, name);
if (rename.isPresent()) {
LOG.debug("Mapping class '"+name+"' to '"+rename.get()+"'");
return rename.get();
}
return name;
}
-
+
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Threads.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Threads.java b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Threads.java
index 8e1b3d2..9d4625a 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Threads.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/Threads.java
@@ -23,7 +23,6 @@ import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.exceptions.RuntimeInterruptedException;
import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/test/java/org/apache/brooklyn/util/javalang/BoxingTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/javalang/BoxingTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/javalang/BoxingTest.java
index 8b5a362..802fb22 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/javalang/BoxingTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/javalang/BoxingTest.java
@@ -35,4 +35,9 @@ public class BoxingTest {
Assert.assertEquals(bt, Integer.class);
}
+ @Test
+ public static void getPrimitive() {
+ Assert.assertEquals(Boxing.getPrimitiveName(Integer.class).get(), "int");
+ }
+
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/23ab1c50/utils/common/src/test/java/org/apache/brooklyn/util/javalang/ReflectionsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/javalang/ReflectionsTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/javalang/ReflectionsTest.java
index 2f0537c..b6bb63c 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/javalang/ReflectionsTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/javalang/ReflectionsTest.java
@@ -58,7 +58,8 @@ public class ReflectionsTest {
@Test
public void testConstructLangObject() {
- Reflections.invokeConstructorWithArgs(java.util.Date.class);
+ // special test for this because the lang object might have classloader null
+ Assert.assertTrue(Reflections.invokeConstructorFromArgs(java.util.Date.class).get() instanceof java.util.Date);
}
public static interface MyInterface {
@@ -123,15 +124,15 @@ public class ReflectionsTest {
Method m = CI1.class.getMethod("m1", String.class, int.class, int.class, int[].class);
Assert.assertEquals(m.invoke(null, "hello", 1, 2, new int[] { 3, 4}), "hello10");
- Assert.assertEquals(Reflections.invokeMethodWithArgs(CI1.class, "m1", Arrays.<Object>asList("hello", 3)).get(), "hello3");
- Assert.assertEquals(Reflections.invokeMethodWithArgs(CI1.class, "m1", Arrays.<Object>asList("hello", 3, 4, 5)).get(), "hello12");
+ Assert.assertEquals(Reflections.invokeMethodFromArgs(CI1.class, "m1", Arrays.<Object>asList("hello", 3)).get(), "hello3");
+ Assert.assertEquals(Reflections.invokeMethodFromArgs(CI1.class, "m1", Arrays.<Object>asList("hello", 3, 4, 5)).get(), "hello12");
}
@Test
public void testConstruction() throws Exception {
- Assert.assertEquals(Reflections.invokeConstructorWithArgs(CI1.class, new Object[] {"hello", 3}).get().constructorArgs, ImmutableList.of("hello", 3));
- Assert.assertEquals(Reflections.invokeConstructorWithArgs(CI1.class, new Object[] {"hello", 3, 4, 5}).get().constructorArgs, ImmutableList.of("hello", 3, 4, 5));
- Assert.assertFalse(Reflections.invokeConstructorWithArgs(CI1.class, new Object[] {"wrong", "args"}).isPresent());
+ Assert.assertEquals(Reflections.invokeConstructorFromArgs(CI1.class, new Object[] {"hello", 3}).get().constructorArgs, ImmutableList.of("hello", 3));
+ Assert.assertEquals(Reflections.invokeConstructorFromArgs(CI1.class, new Object[] {"hello", 3, 4, 5}).get().constructorArgs, ImmutableList.of("hello", 3, 4, 5));
+ Assert.assertFalse(Reflections.invokeConstructorFromArgs(CI1.class, new Object[] {"wrong", "args"}).isPresent());
}
interface I { };