Package com.getperka.flatpack.ext

Source Code of com.getperka.flatpack.ext.PropertyPath$Receiver

/*
* #%L
* FlatPack serialization code
* %%
* Copyright (C) 2012 Perka Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package com.getperka.flatpack.ext;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import com.getperka.flatpack.BaseHasUuid;
import com.getperka.flatpack.util.UuidDigest;

/**
* Represents a sequence of simple property evaluations.
*/
public class PropertyPath extends BaseHasUuid {

  public interface Receiver {
    /**
     * Returns {@code true} if additional values should be received.
     */
    boolean receive(Object value);
  }

  private List<Property> path;

  /**
   * Constructor that creates a copy of {@code path}.
   */
  public PropertyPath(Collection<Property> path) {
    this.path = Collections.unmodifiableList(new ArrayList<Property>(path));
  };

  /**
   * Flatpack.
   */
  PropertyPath() {}

  /**
   * Evaluate each possible property value in the path, passing the value to {@code receiver}.
   */
  public void evaluate(Object target, Receiver receiver) {
    evaluate(target, path, receiver);
  }

  /**
   * Return an unmodifiable view of the properties that comprise the path.
   */
  public List<Property> getPath() {
    return path;
  }

  /**
   * For debugging use only.
   */
  @Override
  public String toString() {
    if (path.isEmpty()) {
      return "<this>";
    }

    StringBuilder sb = new StringBuilder();
    boolean needsDot = false;
    for (Property p : path) {
      if (needsDot) {
        sb.append(".");
      } else {
        needsDot = true;
      }
      sb.append(p.getName());
    }
    return sb.toString();
  }

  @Override
  protected UUID defaultUuid() {
    return new UuidDigest(getClass()).addEntities(path).digest();
  }

  void setPath(List<Property> path) {
    this.path = path;
  }

  private boolean evaluate(Object target, List<Property> properties, Receiver receiver) {
    if (properties.isEmpty()) {
      return receiver.receive(target);
    }
    Throwable ex;
    try {
      Property prop = properties.get(0);
      if (prop.getGetter() == null) {
        return false;
      }
      Object currentValue = prop.getGetter().invoke(target);
      if (currentValue == null) {
        return false;
      }
      switch (prop.getType().getJsonKind()) {
        case STRING:
          return evaluate(currentValue, properties.subList(1, properties.size()), receiver);
        case LIST:
          for (Object element : (Iterable<?>) currentValue) {
            if (!evaluate(element, properties.subList(1, properties.size()), receiver)) {
              return false;
            }
          }
          break;
        case MAP:
          for (Object element : ((Map<?, ?>) currentValue).values()) {
            if (!evaluate(element, properties.subList(1, properties.size()), receiver)) {
              return false;
            }
          }
          break;
        default:
          throw new RuntimeException("Cannot descend into property " + prop);
      }
      return true;
    } catch (IllegalArgumentException e) {
      ex = e;
    } catch (IllegalAccessException e) {
      ex = e;
    } catch (InvocationTargetException e) {
      ex = e.getCause();
    }
    throw new RuntimeException(ex);
  }
}
TOP

Related Classes of com.getperka.flatpack.ext.PropertyPath$Receiver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.