Beispiel #1
0
  private static Object[] prepareArgsForEffectorFromMap(Effector<?> eff, Map m) {
    m = Maps.newLinkedHashMap(m); // make editable copy
    List newArgs = Lists.newArrayList();
    int newArgsNeeded = eff.getParameters().size();
    boolean mapUsed = false;

    for (int index = 0; index < eff.getParameters().size(); index++) {
      ParameterType<?> it = eff.getParameters().get(index);
      Object v;
      if (truth(it.getName()) && m.containsKey(it.getName())) {
        // argument is in the map
        v = m.remove(it.getName());
      } else if (it instanceof BasicParameterType && ((BasicParameterType) it).hasDefaultValue()) {
        // finally, default values are used to make up for missing parameters
        v = ((BasicParameterType) it).getDefaultValue();
      } else {
        throw new IllegalArgumentException(
            "Invalid arguments (missing argument " + it + ") for effector " + eff + ": " + m);
      }

      newArgs.add(TypeCoercions.coerce(v, it.getParameterClass()));
      newArgsNeeded--;
    }
    if (newArgsNeeded > 0)
      throw new IllegalArgumentException(
          "Invalid arguments (missing " + newArgsNeeded + ") for effector " + eff + ": " + m);
    return newArgs.toArray(new Object[newArgs.size()]);
  }
 @SuppressWarnings("unchecked")
 private Object coerce(Object v) {
   if (v != PollConfig.UNSET) {
     return TypeCoercions.coerce(v, sensor.getType());
   } else {
     return v;
   }
 }
 public AbstractLocation(Map properties) {
   configure(properties);
   boolean deferConstructionChecks =
       (properties.containsKey("deferConstructionChecks")
           && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
   if (!deferConstructionChecks) {
     FlagUtils.checkRequiredFields(this);
   }
 }
 @Override
 public <T> T getConfig(ConfigKey<T> key, T defaultValue) {
   if (!containsKey(key.getName())) {
     if (defaultValue != null) return defaultValue;
     return key.getDefaultValue();
   }
   Object value = get(key.getName());
   if (value == null) return null;
   // no evaluation / key extraction here
   return TypeCoercions.coerce(value, key.getType());
 }
 @SuppressWarnings("unchecked")
 protected void setSensor(Object v) {
   if (v == FeedConfig.UNCHANGED) {
     // nothing
   } else if (v == FeedConfig.REMOVE) {
     ((EntityInternal) entity).removeAttribute(sensor);
   } else if (sensor == FeedConfig.NO_SENSOR) {
     // nothing
   } else {
     entity.setAttribute(sensor, TypeCoercions.coerce(v, sensor.getType()));
   }
 }
  public Object getObjectValueForDisplay(Object value) {
    if (value == null) return null;
    // currently everything converted to string, expanded if it is a "done" future
    if (value instanceof Future) {
      if (((Future<?>) value).isDone()) {
        try {
          value = ((Future<?>) value).get();
        } catch (Exception e) {
          value = "" + value + " (error evaluating: " + e + ")";
        }
      }
    }

    if (TypeCoercions.isPrimitiveOrBoxer(value.getClass())) return value;
    return value.toString();
  }
  /**
   * Will set fields from flags. The unused configuration can be found via the {@linkplain
   * ConfigBag#getUnusedConfig()}. This can be overridden for custom initialization but note the
   * following.
   *
   * <p>For new-style locations (i.e. not calling constructor directly, this will be invoked
   * automatically by brooklyn-core post-construction).
   *
   * <p>For legacy location use, this will be invoked by the constructor in this class. Therefore if
   * over-riding you must *not* rely on field initializers because they may not run until *after*
   * this method (this method is invoked by the constructor in this class, so initializers in
   * subclasses will not have run when this overridden method is invoked.) If you require fields to
   * be initialized you must do that in this method with a guard (as in
   * FixedListMachineProvisioningLocation).
   */
  public void configure(Map properties) {
    assertNotYetManaged();

    boolean firstTime = !configured.getAndSet(true);

    configBag.putAll(properties);

    if (properties.containsKey(PARENT_LOCATION.getName())) {
      // need to ensure parent's list of children is also updated
      setParent(configBag.get(PARENT_LOCATION));

      // don't include parentLocation in configBag, as breaks rebind
      configBag.remove(PARENT_LOCATION);
    }

    // NB: flag-setting done here must also be done in BasicLocationRebindSupport
    FlagUtils.setFieldsFromFlagsWithBag(this, properties, configBag, firstTime);
    FlagUtils.setAllConfigKeys(this, configBag, false);

    if (properties.containsKey("displayName")) {
      name.set((String) removeIfPossible(properties, "displayName"));
      displayNameAutoGenerated = false;
    } else if (properties.containsKey("name")) {
      name.set((String) removeIfPossible(properties, "name"));
      displayNameAutoGenerated = false;
    } else if (isLegacyConstruction()) {
      name.set(getClass().getSimpleName() + ":" + id.substring(0, Math.min(id.length(), 4)));
      displayNameAutoGenerated = true;
    }

    // TODO Explicitly dealing with iso3166 here because want custom splitter rule comma-separated
    // string.
    // Is there a better way to do it (e.g. more similar to latitude, where configKey+TypeCoercion
    // is enough)?
    if (groovyTruth(properties.get("iso3166"))) {
      Object rawCodes = removeIfPossible(properties, "iso3166");
      Set<String> codes;
      if (rawCodes instanceof CharSequence) {
        codes = ImmutableSet.copyOf(Splitter.on(",").trimResults().split((CharSequence) rawCodes));
      } else {
        codes = TypeCoercions.coerce(rawCodes, Set.class);
      }
      configBag.put(LocationConfigKeys.ISO_3166, codes);
    }
  }
 protected void unmarshalStringKey(
     HierarchicalStreamReader reader, UnmarshallingContext context, Map map, String key) {
   String type = reader.getAttribute("type");
   Object value;
   if (type == null && reader.hasMoreChildren()) {
     reader.moveDown();
     value = readItem(reader, context, map);
     reader.moveUp();
   } else {
     Class typeC = type != null ? mapper().realClass(type) : String.class;
     try {
       value = TypeCoercions.coerce(reader.getValue(), typeC);
     } catch (Exception e) {
       log.warn("FAILED to coerce " + reader.getValue() + " to " + typeC + ": " + e);
       throw Exceptions.propagate(e);
     }
   }
   map.put(key, value);
 }
  /**
   * Construct a new instance of an AbstractLocation.
   *
   * <p>The properties map recognizes the following keys:
   *
   * <ul>
   *   <li>name - a name for the location
   *   <li>parentLocation - the parent {@link Location}
   * </ul>
   *
   * Other common properties (retrieved via get/findLocationProperty) include:
   *
   * <ul>
   *   <li>latitude
   *   <li>longitude
   *   <li>displayName
   *   <li>iso3166 - list of iso3166-2 code strings
   *   <li>timeZone
   *   <li>abbreviatedName
   * </ul>
   */
  public AbstractLocation(Map properties) {
    inConstruction = true;
    _legacyConstruction = !InternalLocationFactory.FactoryConstructionTracker.isConstructing();
    if (!_legacyConstruction && properties != null && !properties.isEmpty()) {
      LOG.warn(
          "Forcing use of deprecated old-style location construction for "
              + getClass().getName()
              + " because properties were specified ("
              + properties
              + ")");
      _legacyConstruction = true;
    }

    // When one calls getConfig(key), we want to use the default value specified on *this* location
    // if it overrides the default config. The easiest way to look up all our config keys is to
    // reuse the code for Entity (and this will become identical when locations become first-class
    // entities). See {@link #getConfig(ConfigKey)}
    entityType = new EntityDynamicType((Class) getClass());

    if (_legacyConstruction) {
      LOG.warn(
          "Deprecated use of old-style location construction for "
              + getClass().getName()
              + "; instead use LocationManager().createLocation(spec)");
      if (LOG.isDebugEnabled())
        LOG.debug(
            "Source of use of old-style location construction",
            new Throwable("Source of use of old-style location construction"));

      configure(properties);

      boolean deferConstructionChecks =
          (properties.containsKey("deferConstructionChecks")
              && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
      if (!deferConstructionChecks) {
        FlagUtils.checkRequiredFields(this);
      }
    }

    inConstruction = false;
  }
 protected boolean isInlineableType(Class<?> type) {
   return TypeCoercions.isPrimitiveOrBoxer(type) || String.class.equals(type) || type.isEnum();
 }
Beispiel #11
0
  /**
   * attempt to resolve the given value as the given type, waiting on futures, submitting if
   * necessary, and coercing as allowed by TypeCoercions; contextMessage (optional) will be
   * displayed in status reports while it waits (e.g. the name of the config key being looked up)
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  public static <T> T resolveValue(
      Object v, Class<T> type, ExecutionContext exec, String contextMessage)
      throws ExecutionException, InterruptedException {
    // if the expected type is a closure or map and that's what we have, we're done (or if it's
    // null);
    // but not allowed to return a future or DeferredSupplier as the resolved value
    if (v == null
        || (type.isInstance(v)
            && !Future.class.isInstance(v)
            && !DeferredSupplier.class.isInstance(v))) return (T) v;
    try {
      // if it's a task or a future, we wait for the task to complete
      if (v instanceof Task) {
        // if it's a task, we make sure it is submitted
        // (perhaps could run it here? ... tbd)
        if (!((Task) v).isSubmitted()) {
          exec.submit((Task) v);
        }
      }

      if (v instanceof Future) {
        final Future<?> vfuture = (Future<?>) v;

        // including tasks, above
        if (!vfuture.isDone()) {
          final AtomicReference<Object> vref = new AtomicReference<Object>(v);

          withBlockingDetails(
              "Waiting for " + (contextMessage != null ? contextMessage + ", " : "") + v,
              new Callable<Void>() {
                public Void call() throws Exception {
                  vref.set(vfuture.get());
                  return null;
                }
              });

          v = vref.get();

        } else {
          v = vfuture.get();
        }

      } else if (v instanceof DeferredSupplier<?>) {
        v = ((DeferredSupplier<?>) v).get();

      } else if (v instanceof Map) {
        // and if a map or list we look inside
        Map result = Maps.newLinkedHashMap();
        for (Map.Entry<?, ?> entry : ((Map<?, ?>) v).entrySet()) {
          result.put(
              entry.getKey(),
              resolveValue(
                  entry.getValue(),
                  type,
                  exec,
                  (contextMessage != null ? contextMessage + ", " : "")
                      + "map entry "
                      + entry.getKey()));
        }
        return (T) result;

      } else if (v instanceof List) {
        List result = Lists.newArrayList();
        int count = 0;
        for (Object it : (List) v) {
          result.add(
              resolveValue(
                  it,
                  type,
                  exec,
                  (contextMessage != null ? contextMessage + ", " : "") + "list entry " + count));
          count++;
        }
        return (T) result;

      } else {
        return TypeCoercions.coerce(v, type);
      }

    } catch (Exception e) {
      throw new IllegalArgumentException(
          "Error resolving "
              + (contextMessage != null ? contextMessage + ", " : "")
              + v
              + ", in "
              + exec
              + ": "
              + e,
          e);
    }
    return resolveValue(v, type, exec, contextMessage);
  }