Beispiel #1
0
 public static void main(String[] args) {
   Map<String, String> map1 = Generics.newHashMap();
   map1.put("a", "1");
   map1.put("b", "2");
   map1.put("c", "2");
   map1.put("d", "4");
   Map<String, String> map2 = Generics.newHashMap();
   map2.put("1", "x");
   map2.put("2", "y");
   map2.put("3", "z");
   System.out.println("map1: " + map1);
   System.out.println("invert(map1): " + Maps.invert(map1));
   System.out.println("invertSet(map1): " + Maps.invertSet(map1));
   System.out.println("map2: " + map2);
   System.out.println("compose(map1,map2): " + Maps.compose(map1, map2));
   Map<String, Set<String>> setValues = Generics.newHashMap();
   Map<String, List<String>> listValues = Generics.newHashMap();
   Maps.putIntoValueArrayList(listValues, "a", "1");
   Maps.putIntoValueArrayList(listValues, "a", "1");
   Maps.putIntoValueArrayList(listValues, "a", "2");
   Maps.putIntoValueHashSet(setValues, "a", "1");
   Maps.putIntoValueHashSet(setValues, "a", "1");
   Maps.putIntoValueHashSet(setValues, "a", "2");
   System.out.println("listValues: " + listValues);
   System.out.println("setValues: " + setValues);
 }
 @Test
 public void should_format_Map() {
   Map<String, Class<?>> map = new LinkedHashMap<String, Class<?>>();
   map.put("One", String.class);
   map.put("Two", File.class);
   assertEquals("{'One'=java.lang.String, 'Two'=java.io.File}", Maps.format(map));
 }
Beispiel #3
0
 @NonNull
 public IAndroidTarget[] getMissingTargets() {
   synchronized (mLocalPackages) {
     if (mCachedMissingTargets == null) {
       Map<MissingTarget, MissingTarget> result = Maps.newHashMap();
       Set<ISystemImage> seen = Sets.newHashSet();
       for (IAndroidTarget target : getTargets()) {
         Collections.addAll(seen, target.getSystemImages());
       }
       for (LocalPkgInfo local : getPkgsInfos(PkgType.PKG_ADDON_SYS_IMAGE)) {
         LocalAddonSysImgPkgInfo info = (LocalAddonSysImgPkgInfo) local;
         ISystemImage image = info.getSystemImage();
         if (!seen.contains(image)) {
           addOrphanedSystemImage(image, info.getDesc(), result);
         }
       }
       for (LocalPkgInfo local : getPkgsInfos(PkgType.PKG_SYS_IMAGE)) {
         LocalSysImgPkgInfo info = (LocalSysImgPkgInfo) local;
         ISystemImage image = info.getSystemImage();
         if (!seen.contains(image)) {
           addOrphanedSystemImage(image, info.getDesc(), result);
         }
       }
       mCachedMissingTargets = result.keySet();
     }
     return mCachedMissingTargets.toArray(new IAndroidTarget[mCachedMissingTargets.size()]);
   }
 }
Beispiel #4
0
 public NBTStorage(final File file, final String name) {
   this.root = (Map<String, Tag>) Maps.newHashMap();
   this.file = file;
   if (!this.file.exists()) {
     this.create();
   }
   this.name = name;
 }
Beispiel #5
0
  private int repeatInternal(
      @NotNull PseudocodeImpl originalPseudocode,
      @Nullable Label startLabel,
      @Nullable Label finishLabel,
      int labelCount) {
    Integer startIndex =
        startLabel != null
            ? ((PseudocodeLabel) startLabel).getTargetInstructionIndex()
            : Integer.valueOf(0);
    assert startIndex != null;
    Integer finishIndex =
        finishLabel != null
            ? ((PseudocodeLabel) finishLabel).getTargetInstructionIndex()
            : Integer.valueOf(originalPseudocode.mutableInstructionList.size());
    assert finishIndex != null;

    Map<Label, Label> originalToCopy = Maps.newLinkedHashMap();
    Multimap<Instruction, Label> originalLabelsForInstruction = HashMultimap.create();
    for (PseudocodeLabel label : originalPseudocode.labels) {
      Integer index = label.getTargetInstructionIndex();
      if (index == null) continue; // label is not bounded yet
      if (label == startLabel || label == finishLabel) continue;

      if (startIndex <= index && index <= finishIndex) {
        originalToCopy.put(label, label.copy(labelCount++));
        originalLabelsForInstruction.put(getJumpTarget(label), label);
      }
    }
    for (Label label : originalToCopy.values()) {
      labels.add((PseudocodeLabel) label);
    }
    for (int index = startIndex; index < finishIndex; index++) {
      Instruction originalInstruction = originalPseudocode.mutableInstructionList.get(index);
      repeatLabelsBindingForInstruction(
          originalInstruction, originalToCopy, originalLabelsForInstruction);
      Instruction copy = copyInstruction(originalInstruction, originalToCopy);
      addInstruction(copy);
      if (originalInstruction == originalPseudocode.errorInstruction
          && copy instanceof SubroutineExitInstruction) {
        errorInstruction = (SubroutineExitInstruction) copy;
      }
      if (originalInstruction == originalPseudocode.exitInstruction
          && copy instanceof SubroutineExitInstruction) {
        exitInstruction = (SubroutineExitInstruction) copy;
      }
      if (originalInstruction == originalPseudocode.sinkInstruction
          && copy instanceof SubroutineSinkInstruction) {
        sinkInstruction = (SubroutineSinkInstruction) copy;
      }
    }
    if (finishIndex < mutableInstructionList.size()) {
      repeatLabelsBindingForInstruction(
          originalPseudocode.mutableInstructionList.get(finishIndex),
          originalToCopy,
          originalLabelsForInstruction);
    }
    return labelCount;
  }
  private void writeDelegateMethods(
      final ClassVisitor visitor,
      final Type generatedType,
      StructSchema<?> delegateSchema,
      Set<Class<?>> typesToDelegate) {
    Class<?> delegateClass = delegateSchema.getType().getConcreteClass();
    Type delegateType = Type.getType(delegateClass);
    Map<Equivalence.Wrapper<Method>, Map<Class<?>, Method>> methodsToDelegate = Maps.newHashMap();
    for (Class<?> typeToDelegate : typesToDelegate) {
      for (Method methodToDelegate : typeToDelegate.getMethods()) {
        if (ModelSchemaUtils.isIgnoredMethod(methodToDelegate)) {
          continue;
        }
        Equivalence.Wrapper<Method> methodKey = METHOD_EQUIVALENCE.wrap(methodToDelegate);
        Map<Class<?>, Method> methodsByReturnType = methodsToDelegate.get(methodKey);
        if (methodsByReturnType == null) {
          methodsByReturnType = Maps.newHashMap();
          methodsToDelegate.put(methodKey, methodsByReturnType);
        }
        methodsByReturnType.put(methodToDelegate.getReturnType(), methodToDelegate);
      }
    }
    Set<Equivalence.Wrapper<Method>> delegateMethodKeys =
        ImmutableSet.copyOf(
            Iterables.transform(
                Arrays.asList(delegateClass.getMethods()),
                new Function<Method, Equivalence.Wrapper<Method>>() {
                  @Override
                  public Equivalence.Wrapper<Method> apply(Method method) {
                    return METHOD_EQUIVALENCE.wrap(method);
                  }
                }));
    for (Map.Entry<Equivalence.Wrapper<Method>, Map<Class<?>, Method>> entry :
        methodsToDelegate.entrySet()) {
      Equivalence.Wrapper<Method> methodKey = entry.getKey();
      if (!delegateMethodKeys.contains(methodKey)) {
        continue;
      }

      Map<Class<?>, Method> methodsByReturnType = entry.getValue();
      for (Method methodToDelegate : methodsByReturnType.values()) {
        writeDelegatedMethod(visitor, generatedType, delegateType, methodToDelegate);
      }
    }
  }
 private static Map<ClassDescriptor, JetType> getSuperclassToSupertypeMap(
     ClassDescriptor containingClass) {
   Map<ClassDescriptor, JetType> superclassToSupertype = Maps.newHashMap();
   for (JetType supertype : TypeUtils.getAllSupertypes(containingClass.getDefaultType())) {
     ClassifierDescriptor superclass = supertype.getConstructor().getDeclarationDescriptor();
     assert superclass instanceof ClassDescriptor;
     superclassToSupertype.put((ClassDescriptor) superclass, supertype);
   }
   return superclassToSupertype;
 }
 /** Returns document counts for each partition. */
 Map<Object, Integer> getDocumentCountByPartition(List<Document> documents) {
   return ImmutableMap.copyOf(
       Maps.transformValues(
           getDocumentsByPartition(documents).asMap(),
           new Function<Collection<Document>, Integer>() {
             public Integer apply(Collection<Document> documents) {
               return documents.size();
             }
           }));
 }
    public List<Vertex> getProductAssociations(Vertex v) {
      Map<Vertex, Edge> adjacent = Maps.newHashMap(graph.row(v));
      adjacent.putAll(graph.column(v));

      return adjacent
          .entrySet()
          .stream()
          .sorted((e1, e2) -> e2.getValue().weight - e1.getValue().weight)
          .map(Map.Entry::getKey)
          .collect(Collectors.toList());
    }
Beispiel #10
0
/**
 * Rest配置中心
 *
 * @author Peter Zhang
 */
public class RestConfigurations {

  private static Map<String, RestServiceConfiguration> CONFIG_FOR_NAME = Maps.newHashMap();

  private static Map<String, RestServiceConfiguration> CONFIG_FOR_SERVICE_NAME = Maps.newHashMap();

  private static Map<String, RestServiceConfiguration> CONFIG_FOR_ENV = Maps.newHashMap();

  private static RestServiceConfiguration DEFAULT_CONFIG;

  /**
   * 注册配置
   *
   * @param configuration Rest服务基础配置
   */
  public static void register(RestServiceConfiguration configuration) {

    CONFIG_FOR_NAME.put(configuration.getConfigurationName(), configuration);
    CONFIG_FOR_SERVICE_NAME.put(configuration.getCgiServiceName(), configuration);
    CONFIG_FOR_ENV.put(configuration.getEnvironment(), configuration);
    DEFAULT_CONFIG = configuration;
  }

  /** 获取默认配置对象 */
  public static RestServiceConfiguration getDefaultConfiguration() {

    return DEFAULT_CONFIG;
  }

  /**
   * 根据环境获取配置
   *
   * @param environment 环境
   */
  public static RestServiceConfiguration getConfigByEnvironment(String environment) {

    return CONFIG_FOR_ENV.get(environment);
  }
}
Beispiel #11
0
 /** Stringifies a Map in a stable fashion. */
 public static <K extends Comparable<K>, V> void toStringSorted(
     Map<K, V> map, StringBuilder builder) {
   builder.append('{');
   List<Entry<K, V>> sortedProperties = Maps.sortedEntries(map);
   int index = 0;
   for (Entry<K, V> entry : sortedProperties) {
     if (index > 0) {
       builder.append(", ");
     }
     builder.append(entry.getKey()).append('=').append(entry.getValue());
     index++;
   }
   builder.append('}');
 }
 /**
  * 按照对应关系对 aitID:threadInfo-> 1:n 对N从大到小排序 处理MulitMap中的数据,key:value->1:n 取出<key, n>
  * 对n降序排序后,取得序列后的List<Map.Entry<key, n>>
  *
  * @return
  */
 public List<Map.Entry<String, Integer>> getOrderList(Multimap<String, ThreadInfo> w_IdMap) {
   Set<String> keys = w_IdMap.keySet();
   Map<String, Integer> w_IdMappingThread = Maps.newHashMap();
   for (String key : keys) {
     Collection<ThreadInfo> values = w_IdMap.get(key);
     w_IdMappingThread.put(key, values.size());
   }
   List<Map.Entry<String, Integer>> orderList =
       new ArrayList<Map.Entry<String, Integer>>(w_IdMappingThread.entrySet());
   Collections.sort(
       orderList,
       new Comparator<Map.Entry<String, Integer>>() {
         @Override
         public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
           return o2.getValue().compareTo(o1.getValue());
         }
       });
   return orderList;
 }
Beispiel #13
0
  /**
   * Prepares a temporary attributes map for serialization purposes. Includes only the requested
   * elements in the map.
   */
  private Map<String, Object> prepareAttributesForSerialization(
      boolean saveDocuments, boolean saveClusters, boolean saveOtherAttributes) {
    final Map<String, Object> tempAttributes = Maps.newHashMap();

    if (saveOtherAttributes) {
      tempAttributes.putAll(attributes);
      tempAttributes.remove(AttributeNames.DOCUMENTS);
      tempAttributes.remove(AttributeNames.CLUSTERS);
    } else {
      tempAttributes.put(AttributeNames.QUERY, attributes.get(AttributeNames.QUERY));
    }

    if (saveDocuments) {
      tempAttributes.put(AttributeNames.DOCUMENTS, getDocuments());
    }

    if (saveClusters) {
      tempAttributes.put(AttributeNames.CLUSTERS, getClusters());
    }

    return tempAttributes;
  }
Beispiel #14
0
 @Override
 public Map<String, Object> getValuesDeep() {
   final Tag tag = this.findLastTag(this.path, false);
   if (!(tag instanceof CompoundTag)) {
     return Collections.emptyMap();
   }
   final Queue<Node> node =
       new ArrayDeque<Node>(
           (Collection<? extends Node>) ImmutableList.of((Object) new Node(tag)));
   final Map<String, Object> values = (Map<String, Object>) Maps.newHashMap();
   while (!node.isEmpty()) {
     final Node root = node.poll();
     for (final Map.Entry<String, Tag> entry : root.values.entrySet()) {
       final String key = this.createRelativeKey(root.parent, entry.getKey());
       if (entry.getValue() instanceof CompoundTag) {
         node.add(new Node(key, entry.getValue()));
       } else {
         values.put(key, entry.getValue().getValue());
       }
     }
   }
   return values;
 }
Beispiel #15
0
  /** Transfers document and cluster lists to the attributes map after deserialization. */
  @Commit
  private void afterDeserialization() throws Exception {
    if (otherAttributesForSerialization != null) {
      attributes = SimpleXmlWrappers.unwrap(otherAttributesForSerialization);
    }

    attributesView = Collections.unmodifiableMap(attributes);

    attributes.put(AttributeNames.QUERY, query != null ? query.trim() : null);
    attributes.put(AttributeNames.DOCUMENTS, documents);
    attributes.put(AttributeNames.CLUSTERS, clusters);

    // Convert document ids to the actual references
    if (clusters != null && documents != null) {
      final Map<String, Document> documentsById = Maps.newHashMap();
      for (Document document : documents) {
        documentsById.put(document.getStringId(), document);
      }

      for (Cluster cluster : clusters) {
        documentIdToReference(cluster, documentsById);
      }
    }
  }
Beispiel #16
0
/**
 * Represents one network of nodes, where each nodes is somehow connected to another within the
 * network.
 *
 * <p>Network contains following node types: - networking nodes - nodes that are a back-bone of a
 * network. These allow to connect multiple nodes in the network. A networking node "conducts" the
 * "signal" of the network to nodes defined in the "connectingOnSides" nodes in its vicinity. - leaf
 * nodes - nodes that are only receiving or producing a signal, and do not themselves "conduct" it
 * to other nodes.
 *
 * <p>A couple of non-obvious facts: 1. The same node (defined as location) cannot be both a
 * networking node and a leaf node in the same network. 2. The same leaf node can be a member of
 * multiple disjunctive networks (different network on each side). 3. A valid network can have no
 * networking nodes at all, and exactly two leaf nodes (neighbouring leaf nodes).
 *
 * @author Marcin Sciesinski <*****@*****.**>
 */
public class SimpleNetwork implements Network {
  private static final boolean SANITY_CHECK = false;
  private SetMultimap<ImmutableBlockLocation, NetworkNode> networkingNodes = HashMultimap.create();
  private SetMultimap<ImmutableBlockLocation, NetworkNode> leafNodes = HashMultimap.create();

  // Distance cache
  private Map<TwoNetworkNodes, Integer> distanceCache = Maps.newHashMap();

  public static SimpleNetwork createDegenerateNetwork(
      NetworkNode networkNode1, NetworkNode networkNode2) {
    if (!areNodesConnecting(networkNode1, networkNode2))
      throw new IllegalArgumentException("These two nodes are not connected");

    SimpleNetwork network = new SimpleNetwork();
    network.leafNodes.put(networkNode1.location, networkNode1);
    network.leafNodes.put(networkNode2.location, networkNode2);
    return network;
  }

  /**
   * Adds a networking node to the network.
   *
   * @param networkNode Definition of the networking node position and connecting sides.
   */
  public void addNetworkingNode(NetworkNode networkNode) {
    if (SANITY_CHECK && !canAddNetworkingNode(networkNode))
      throw new IllegalStateException("Unable to add this node to network");
    networkingNodes.put(networkNode.location, networkNode);
    distanceCache.clear();
  }

  /**
   * Adds a leaf node to the network.
   *
   * @param networkNode Definition of the leaf node position and connecting sides.
   */
  public void addLeafNode(NetworkNode networkNode) {
    if (SANITY_CHECK && (!canAddLeafNode(networkNode) || isEmptyNetwork()))
      throw new IllegalStateException("Unable to add this node to network");
    leafNodes.put(networkNode.location, networkNode);
    distanceCache.clear();
  }

  /**
   * Returns the network size - a number of nodes it spans. If the same node is added twice with
   * different connecting sides, it is counted twice.
   *
   * @return The sum of networking nodes and leaf nodes (count).
   */
  @Override
  public int getNetworkSize() {
    return networkingNodes.size() + leafNodes.size();
  }

  /**
   * Removes a leaf node from the network. If this removal made the network degenerate, it will
   * return <code>true</code>.
   *
   * @param networkingNode Definition of the leaf node position and connecting sides.
   * @return <code>true</code> if the network after the removal is degenerated or empty (no longer
   *     valid).
   */
  public boolean removeLeafNode(NetworkNode networkingNode) {
    // Removal of a leaf node cannot split the network, so it's just safe to remove it
    // We just need to check, if after removal of the node, network becomes degenerated, if so - we
    // need
    // to signal that the network is no longer valid and should be removed.
    final boolean changed = leafNodes.remove(networkingNode.location, networkingNode);
    if (!changed)
      throw new IllegalStateException("Tried to remove a node that is not in the network");

    distanceCache.clear();

    return isDegeneratedNetwork() || isEmptyNetwork();
  }

  public void removeAllLeafNodes() {
    leafNodes.clear();
    distanceCache.clear();
  }

  public void removeAllNetworkingNodes() {
    networkingNodes.clear();
    distanceCache.clear();
  }

  public void removeNetworkingNode(NetworkNode networkNode) {
    if (!networkingNodes.remove(networkNode.location, networkNode))
      throw new IllegalStateException("Tried to remove a node that is not in the network");
    distanceCache.clear();
  }

  public Collection<NetworkNode> getNetworkingNodes() {
    return Collections.unmodifiableCollection(networkingNodes.values());
  }

  public Collection<NetworkNode> getLeafNodes() {
    return Collections.unmodifiableCollection(leafNodes.values());
  }

  public static boolean areNodesConnecting(NetworkNode node1, NetworkNode node2) {
    for (Side side : SideBitFlag.getSides(node1.connectionSides)) {
      final ImmutableBlockLocation possibleConnectedLocation = node1.location.move(side);
      if (node2.location.equals(possibleConnectedLocation)
          && SideBitFlag.hasSide(node2.connectionSides, side.reverse())) return true;
    }
    return false;
  }

  /**
   * If this network can connect to node at the location specified with the specified connecting
   * sides.
   *
   * @param networkNode Definition of the networking node position and connecting sides.
   * @return If the networking node can be added to the network (connects to it).
   */
  public boolean canAddNetworkingNode(NetworkNode networkNode) {
    if (isEmptyNetwork()) return true;
    if (networkingNodes.containsValue(networkNode) || leafNodes.containsValue(networkNode))
      return false;
    return canConnectToNetworkingNode(networkNode);
  }

  public boolean canAddLeafNode(NetworkNode networkNode) {
    if (isEmptyNetwork()) return false;
    if (networkingNodes.containsValue(networkNode) || leafNodes.containsValue(networkNode))
      return false;

    return canConnectToNetworkingNode(networkNode);
  }

  private boolean canConnectToNetworkingNode(NetworkNode networkNode) {
    for (Side connectingOnSide : SideBitFlag.getSides(networkNode.connectionSides)) {
      final ImmutableBlockLocation possibleConnectionLocation =
          networkNode.location.move(connectingOnSide);
      for (NetworkNode possibleConnectedNode : networkingNodes.get(possibleConnectionLocation)) {
        if (SideBitFlag.hasSide(possibleConnectedNode.connectionSides, connectingOnSide.reverse()))
          return true;
      }
    }
    return false;
  }

  @Override
  public boolean hasNetworkingNode(NetworkNode networkNode) {
    return networkingNodes.containsValue(networkNode);
  }

  @Override
  public boolean hasLeafNode(NetworkNode networkNode) {
    return leafNodes.containsValue(networkNode);
  }

  @Override
  public int getDistance(NetworkNode from, NetworkNode to) {
    TwoNetworkNodes nodePair = new TwoNetworkNodes(from, to);
    final Integer cachedDistance = distanceCache.get(nodePair);
    if (cachedDistance != null) return cachedDistance;

    if ((!hasNetworkingNode(from) && !hasLeafNode(from))
        || (!hasNetworkingNode(to) && !hasLeafNode(to)))
      throw new IllegalArgumentException("Cannot test nodes not in network");

    if (from.equals(to)) return 0;

    if (SimpleNetwork.areNodesConnecting(from, to)) return 1;

    // Breadth-first search of the network
    Set<NetworkNode> visitedNodes = Sets.newHashSet();
    visitedNodes.add(from);

    Set<NetworkNode> networkingNodesToTest = Sets.newHashSet();
    listConnectedNotVisitedNetworkingNodes(visitedNodes, from, networkingNodesToTest);
    int distanceSearched = 1;
    while (networkingNodesToTest.size() > 0) {
      distanceSearched++;

      for (NetworkNode nodeToTest : networkingNodesToTest) {
        if (SimpleNetwork.areNodesConnecting(nodeToTest, to)) {
          distanceCache.put(new TwoNetworkNodes(from, to), distanceSearched);
          return distanceSearched;
        }
        visitedNodes.add(nodeToTest);
      }

      Set<NetworkNode> nextNetworkingNodesToTest = Sets.newHashSet();
      for (NetworkNode nodeToTest : networkingNodesToTest)
        listConnectedNotVisitedNetworkingNodes(visitedNodes, nodeToTest, nextNetworkingNodesToTest);

      networkingNodesToTest = nextNetworkingNodesToTest;
    }
    return -1;
  }

  @Override
  public boolean isInDistance(int distance, NetworkNode from, NetworkNode to) {
    if (distance < 0) throw new IllegalArgumentException("distance must be >= 0");

    TwoNetworkNodes nodePair = new TwoNetworkNodes(from, to);
    final Integer cachedDistance = distanceCache.get(nodePair);
    if (cachedDistance != null) return cachedDistance <= distance;

    if ((!hasNetworkingNode(from) && !hasLeafNode(from))
        || (!hasNetworkingNode(to) && !hasLeafNode(to)))
      throw new IllegalArgumentException("Cannot test nodes not in network");

    return isInDistanceInternal(distance, from, to, nodePair);
  }

  private boolean isInDistanceInternal(
      int distance, NetworkNode from, NetworkNode to, TwoNetworkNodes cachePairKey) {
    if (from.equals(to)) return true;

    if (distance == 0) return false;

    if (SimpleNetwork.areNodesConnecting(from, to)) return true;

    // Breadth-first search of the network
    Set<NetworkNode> visitedNodes = Sets.newHashSet();
    visitedNodes.add(from);

    Set<NetworkNode> networkingNodesToTest = Sets.newHashSet();
    listConnectedNotVisitedNetworkingNodes(visitedNodes, from, networkingNodesToTest);
    int distanceSearched = 1;
    while (distanceSearched < distance) {
      distanceSearched++;

      for (NetworkNode nodeToTest : networkingNodesToTest) {
        if (SimpleNetwork.areNodesConnecting(nodeToTest, to)) {
          distanceCache.put(cachePairKey, distanceSearched);
          return true;
        }
        visitedNodes.add(nodeToTest);
      }

      Set<NetworkNode> nextNetworkingNodesToTest = Sets.newHashSet();
      for (NetworkNode nodeToTest : networkingNodesToTest)
        listConnectedNotVisitedNetworkingNodes(visitedNodes, nodeToTest, nextNetworkingNodesToTest);

      networkingNodesToTest = nextNetworkingNodesToTest;
    }

    return false;
  }

  @Override
  public boolean isInDistanceWithSide(int distance, NetworkNode from, NetworkNode to, Side toSide) {
    to = new NetworkNode(to.location.toVector3i(), toSide);
    TwoNetworkNodes nodePair = new TwoNetworkNodes(from, to);
    return isInDistanceInternal(distance, from, to, nodePair);
  }

  @Override
  public byte getLeafSidesInNetwork(NetworkNode networkNode) {
    if (!hasLeafNode(networkNode))
      throw new IllegalArgumentException("Cannot test nodes not in network");

    if (networkingNodes.size() == 0) {
      // Degenerated network
      for (Side connectingOnSide : SideBitFlag.getSides(networkNode.connectionSides)) {
        Vector3i possibleLocation = networkNode.location.toVector3i();
        possibleLocation.add(connectingOnSide.getVector3i());
        for (NetworkNode node : leafNodes.get(new ImmutableBlockLocation(possibleLocation))) {
          if (SideBitFlag.hasSide(node.connectionSides, connectingOnSide.reverse())) {
            return SideBitFlag.getSide(connectingOnSide);
          }
        }
      }

      return 0;
    } else {
      byte result = 0;
      for (Side connectingOnSide : SideBitFlag.getSides(networkNode.connectionSides)) {
        Vector3i possibleLocation = networkNode.location.toVector3i();
        possibleLocation.add(connectingOnSide.getVector3i());
        for (NetworkNode node : networkingNodes.get(new ImmutableBlockLocation(possibleLocation))) {
          if (SideBitFlag.hasSide(node.connectionSides, connectingOnSide.reverse())) {
            result += SideBitFlag.getSide(connectingOnSide);
          }
        }
      }

      return result;
    }
  }

  //    public Map<Vector3i, Byte> getConnectedNodes(Vector3i location, byte connectionSides) {
  //        Map<Vector3i, Byte> result = Maps.newHashMap();
  //        for (Direction connectingOnSide : DirectionsUtil.getDirections(connectionSides)) {
  //            final Vector3i possibleNodeLocation = new Vector3i(location);
  //            possibleNodeLocation.add(connectingOnSide.getVector3i());
  //
  //            final Byte directionsForNodeOnThatSide = networkingNodes.get(possibleNodeLocation);
  //            if (directionsForNodeOnThatSide != null &&
  // DirectionsUtil.hasDirection(directionsForNodeOnThatSide, connectingOnSide.reverse()))
  //                result.put(possibleNodeLocation, directionsForNodeOnThatSide);
  //
  //            for (byte directionsForLeafNodeOnThatSide : leafNodes.get(possibleNodeLocation)) {
  //                if (DirectionsUtil.hasDirection(directionsForLeafNodeOnThatSide,
  // connectingOnSide.reverse()))
  //                    result.put(possibleNodeLocation, directionsForLeafNodeOnThatSide);
  //            }
  //        }
  //        return result;
  //    }

  private void listConnectedNotVisitedNetworkingNodes(
      Set<NetworkNode> visitedNodes, NetworkNode location, Collection<NetworkNode> result) {
    for (Side connectingOnSide : SideBitFlag.getSides(location.connectionSides)) {
      final ImmutableBlockLocation possibleConnectionLocation =
          location.location.move(connectingOnSide);
      for (NetworkNode possibleConnection : networkingNodes.get(possibleConnectionLocation)) {
        if (!visitedNodes.contains(possibleConnection)
            && SideBitFlag.hasSide(possibleConnection.connectionSides, connectingOnSide.reverse()))
          result.add(possibleConnection);
      }
    }
  }

  private boolean isDegeneratedNetwork() {
    return networkingNodes.isEmpty() && leafNodes.size() == 1;
  }

  private boolean isEmptyNetwork() {
    return networkingNodes.isEmpty() && leafNodes.isEmpty();
  }
}
Beispiel #17
0
public class PseudocodeImpl implements Pseudocode {

  public class PseudocodeLabel implements Label {
    private final String name;
    private final String comment;
    private Integer targetInstructionIndex;

    private PseudocodeLabel(@NotNull String name, @Nullable String comment) {
      this.name = name;
      this.comment = comment;
    }

    @NotNull
    @Override
    public String getName() {
      return name;
    }

    @Override
    public String toString() {
      return comment == null ? name : (name + " [" + comment + "]");
    }

    public Integer getTargetInstructionIndex() {
      return targetInstructionIndex;
    }

    public void setTargetInstructionIndex(int targetInstructionIndex) {
      this.targetInstructionIndex = targetInstructionIndex;
    }

    @Nullable
    private List<Instruction> resolve() {
      assert targetInstructionIndex != null;
      return mutableInstructionList.subList(
          getTargetInstructionIndex(), mutableInstructionList.size());
    }

    public Instruction resolveToInstruction() {
      assert targetInstructionIndex != null;
      return mutableInstructionList.get(targetInstructionIndex);
    }

    public PseudocodeLabel copy(int newLabelIndex) {
      return new PseudocodeLabel("L" + newLabelIndex, "copy of " + name + ", " + comment);
    }

    public PseudocodeImpl getPseudocode() {
      return PseudocodeImpl.this;
    }
  }

  private final List<Instruction> mutableInstructionList = new ArrayList<Instruction>();
  private final List<Instruction> instructions = new ArrayList<Instruction>();

  private final BidirectionalMap<KtElement, PseudoValue> elementsToValues =
      new BidirectionalMap<KtElement, PseudoValue>();

  private final Map<PseudoValue, List<Instruction>> valueUsages = Maps.newHashMap();
  private final Map<PseudoValue, Set<PseudoValue>> mergedValues = Maps.newHashMap();
  private final Set<Instruction> sideEffectFree = Sets.newHashSet();

  private Pseudocode parent = null;
  private Set<LocalFunctionDeclarationInstruction> localDeclarations = null;
  // todo getters
  private final Map<KtElement, Instruction> representativeInstructions =
      new HashMap<KtElement, Instruction>();

  private final List<PseudocodeLabel> labels = new ArrayList<PseudocodeLabel>();

  private final KtElement correspondingElement;
  private SubroutineExitInstruction exitInstruction;
  private SubroutineSinkInstruction sinkInstruction;
  private SubroutineExitInstruction errorInstruction;
  private boolean postPrecessed = false;

  public PseudocodeImpl(KtElement correspondingElement) {
    this.correspondingElement = correspondingElement;
  }

  @NotNull
  @Override
  public KtElement getCorrespondingElement() {
    return correspondingElement;
  }

  @NotNull
  @Override
  public Set<LocalFunctionDeclarationInstruction> getLocalDeclarations() {
    if (localDeclarations == null) {
      localDeclarations = getLocalDeclarations(this);
    }
    return localDeclarations;
  }

  @NotNull
  private static Set<LocalFunctionDeclarationInstruction> getLocalDeclarations(
      @NotNull Pseudocode pseudocode) {
    Set<LocalFunctionDeclarationInstruction> localDeclarations = Sets.newLinkedHashSet();
    for (Instruction instruction : ((PseudocodeImpl) pseudocode).mutableInstructionList) {
      if (instruction instanceof LocalFunctionDeclarationInstruction) {
        localDeclarations.add((LocalFunctionDeclarationInstruction) instruction);
        localDeclarations.addAll(
            getLocalDeclarations(((LocalFunctionDeclarationInstruction) instruction).getBody()));
      }
    }
    return localDeclarations;
  }

  @Override
  @Nullable
  public Pseudocode getParent() {
    return parent;
  }

  private void setParent(Pseudocode parent) {
    this.parent = parent;
  }

  @NotNull
  public Pseudocode getRootPseudocode() {
    Pseudocode parent = getParent();
    while (parent != null) {
      if (parent.getParent() == null) return parent;
      parent = parent.getParent();
    }
    return this;
  }

  /*package*/ PseudocodeLabel createLabel(@NotNull String name, @Nullable String comment) {
    PseudocodeLabel label = new PseudocodeLabel(name, comment);
    labels.add(label);
    return label;
  }

  @Override
  @NotNull
  public List<Instruction> getInstructions() {
    return instructions;
  }

  @NotNull
  @Override
  public List<Instruction> getReversedInstructions() {
    LinkedHashSet<Instruction> traversedInstructions = Sets.newLinkedHashSet();
    PseudocodeTraverserKt.traverseFollowingInstructions(
        sinkInstruction, traversedInstructions, BACKWARD, null);
    if (traversedInstructions.size() < instructions.size()) {
      List<Instruction> simplyReversedInstructions = Lists.newArrayList(instructions);
      Collections.reverse(simplyReversedInstructions);
      for (Instruction instruction : simplyReversedInstructions) {
        if (!traversedInstructions.contains(instruction)) {
          PseudocodeTraverserKt.traverseFollowingInstructions(
              instruction, traversedInstructions, BACKWARD, null);
        }
      }
    }
    return Lists.newArrayList(traversedInstructions);
  }

  @Override
  @NotNull
  public List<Instruction> getInstructionsIncludingDeadCode() {
    return mutableInstructionList;
  }

  // for tests only
  @NotNull
  public List<PseudocodeLabel> getLabels() {
    return labels;
  }

  /*package*/ void addExitInstruction(SubroutineExitInstruction exitInstruction) {
    addInstruction(exitInstruction);
    assert this.exitInstruction == null;
    this.exitInstruction = exitInstruction;
  }

  /*package*/ void addSinkInstruction(SubroutineSinkInstruction sinkInstruction) {
    addInstruction(sinkInstruction);
    assert this.sinkInstruction == null;
    this.sinkInstruction = sinkInstruction;
  }

  /*package*/ void addErrorInstruction(SubroutineExitInstruction errorInstruction) {
    addInstruction(errorInstruction);
    assert this.errorInstruction == null;
    this.errorInstruction = errorInstruction;
  }

  /*package*/ void addInstruction(Instruction instruction) {
    mutableInstructionList.add(instruction);
    instruction.setOwner(this);

    if (instruction instanceof KtElementInstruction) {
      KtElementInstruction elementInstruction = (KtElementInstruction) instruction;
      representativeInstructions.put(elementInstruction.getElement(), instruction);
    }

    if (instruction instanceof MergeInstruction) {
      addMergedValues((MergeInstruction) instruction);
    }

    for (PseudoValue inputValue : instruction.getInputValues()) {
      addValueUsage(inputValue, instruction);
      for (PseudoValue mergedValue : getMergedValues(inputValue)) {
        addValueUsage(mergedValue, instruction);
      }
    }
    if (PseudocodeUtilsKt.calcSideEffectFree(instruction)) {
      sideEffectFree.add(instruction);
    }
  }

  @Override
  @NotNull
  public SubroutineExitInstruction getExitInstruction() {
    return exitInstruction;
  }

  @Override
  @NotNull
  public SubroutineSinkInstruction getSinkInstruction() {
    return sinkInstruction;
  }

  @Override
  @NotNull
  public SubroutineEnterInstruction getEnterInstruction() {
    return (SubroutineEnterInstruction) mutableInstructionList.get(0);
  }

  @Nullable
  @Override
  public PseudoValue getElementValue(@Nullable KtElement element) {
    return elementsToValues.get(element);
  }

  @NotNull
  @Override
  public List<? extends KtElement> getValueElements(@Nullable PseudoValue value) {
    List<? extends KtElement> result = elementsToValues.getKeysByValue(value);
    return result != null ? result : Collections.<KtElement>emptyList();
  }

  @NotNull
  @Override
  public List<? extends Instruction> getUsages(@Nullable PseudoValue value) {
    List<? extends Instruction> result = valueUsages.get(value);
    return result != null ? result : Collections.<Instruction>emptyList();
  }

  @Override
  public boolean isSideEffectFree(@NotNull Instruction instruction) {
    return sideEffectFree.contains(instruction);
  }

  /*package*/ void bindElementToValue(@NotNull KtElement element, @NotNull PseudoValue value) {
    elementsToValues.put(element, value);
  }

  /*package*/ void bindLabel(Label label) {
    ((PseudocodeLabel) label).setTargetInstructionIndex(mutableInstructionList.size());
  }

  private Set<PseudoValue> getMergedValues(@NotNull PseudoValue value) {
    Set<PseudoValue> result = mergedValues.get(value);
    return result != null ? result : Collections.<PseudoValue>emptySet();
  }

  private void addMergedValues(@NotNull MergeInstruction instruction) {
    Set<PseudoValue> result = new LinkedHashSet<PseudoValue>();
    for (PseudoValue value : instruction.getInputValues()) {
      result.addAll(getMergedValues(value));
      result.add(value);
    }
    mergedValues.put(instruction.getOutputValue(), result);
  }

  private void addValueUsage(PseudoValue value, Instruction usage) {
    if (usage instanceof MergeInstruction) return;
    MapsKt.getOrPut(
            valueUsages,
            value,
            new Function0<List<Instruction>>() {
              @Override
              public List<Instruction> invoke() {
                return Lists.newArrayList();
              }
            })
        .add(usage);
  }

  public void postProcess() {
    if (postPrecessed) return;
    postPrecessed = true;
    errorInstruction.setSink(getSinkInstruction());
    exitInstruction.setSink(getSinkInstruction());
    int index = 0;
    for (Instruction instruction : mutableInstructionList) {
      // recursively invokes 'postProcess' for local declarations
      processInstruction(instruction, index);
      index++;
    }
    if (getParent() != null) return;

    // Collecting reachable instructions should be done after processing all instructions
    // (including instructions in local declarations) to avoid being in incomplete state.
    collectAndCacheReachableInstructions();
    for (LocalFunctionDeclarationInstruction localFunctionDeclarationInstruction :
        getLocalDeclarations()) {
      ((PseudocodeImpl) localFunctionDeclarationInstruction.getBody())
          .collectAndCacheReachableInstructions();
    }
  }

  private void collectAndCacheReachableInstructions() {
    Set<Instruction> reachableInstructions = collectReachableInstructions();
    for (Instruction instruction : mutableInstructionList) {
      if (reachableInstructions.contains(instruction)) {
        instructions.add(instruction);
      }
    }
    markDeadInstructions();
  }

  private void processInstruction(Instruction instruction, final int currentPosition) {
    instruction.accept(
        new InstructionVisitor() {
          @Override
          public void visitInstructionWithNext(@NotNull InstructionWithNext instruction) {
            instruction.setNext(getNextPosition(currentPosition));
          }

          @Override
          public void visitJump(@NotNull AbstractJumpInstruction instruction) {
            instruction.setResolvedTarget(getJumpTarget(instruction.getTargetLabel()));
          }

          @Override
          public void visitNondeterministicJump(
              @NotNull NondeterministicJumpInstruction instruction) {
            instruction.setNext(getNextPosition(currentPosition));
            List<Label> targetLabels = instruction.getTargetLabels();
            for (Label targetLabel : targetLabels) {
              instruction.setResolvedTarget(targetLabel, getJumpTarget(targetLabel));
            }
          }

          @Override
          public void visitConditionalJump(@NotNull ConditionalJumpInstruction instruction) {
            Instruction nextInstruction = getNextPosition(currentPosition);
            Instruction jumpTarget = getJumpTarget(instruction.getTargetLabel());
            if (instruction.getOnTrue()) {
              instruction.setNextOnFalse(nextInstruction);
              instruction.setNextOnTrue(jumpTarget);
            } else {
              instruction.setNextOnFalse(jumpTarget);
              instruction.setNextOnTrue(nextInstruction);
            }
            visitJump(instruction);
          }

          @Override
          public void visitLocalFunctionDeclarationInstruction(
              @NotNull LocalFunctionDeclarationInstruction instruction) {
            PseudocodeImpl body = (PseudocodeImpl) instruction.getBody();
            body.setParent(PseudocodeImpl.this);
            body.postProcess();
            instruction.setNext(getSinkInstruction());
          }

          @Override
          public void visitSubroutineExit(@NotNull SubroutineExitInstruction instruction) {
            // Nothing
          }

          @Override
          public void visitSubroutineSink(@NotNull SubroutineSinkInstruction instruction) {
            // Nothing
          }

          @Override
          public void visitInstruction(@NotNull Instruction instruction) {
            throw new UnsupportedOperationException(instruction.toString());
          }
        });
  }

  private Set<Instruction> collectReachableInstructions() {
    Set<Instruction> visited = Sets.newHashSet();
    PseudocodeTraverserKt.traverseFollowingInstructions(
        getEnterInstruction(), visited, FORWARD, null);
    if (!visited.contains(getExitInstruction())) {
      visited.add(getExitInstruction());
    }
    if (!visited.contains(errorInstruction)) {
      visited.add(errorInstruction);
    }
    if (!visited.contains(getSinkInstruction())) {
      visited.add(getSinkInstruction());
    }
    return visited;
  }

  private void markDeadInstructions() {
    Set<Instruction> instructionSet = Sets.newHashSet(instructions);
    for (Instruction instruction : mutableInstructionList) {
      if (!instructionSet.contains(instruction)) {
        ((InstructionImpl) instruction).setMarkedAsDead(true);
        for (Instruction nextInstruction : instruction.getNextInstructions()) {
          nextInstruction.getPreviousInstructions().remove(instruction);
        }
      }
    }
  }

  @NotNull
  private Instruction getJumpTarget(@NotNull Label targetLabel) {
    return ((PseudocodeLabel) targetLabel).resolveToInstruction();
  }

  @NotNull
  private Instruction getNextPosition(int currentPosition) {
    int targetPosition = currentPosition + 1;
    assert targetPosition < mutableInstructionList.size() : currentPosition;
    return mutableInstructionList.get(targetPosition);
  }

  @Override
  public PseudocodeImpl copy() {
    PseudocodeImpl result = new PseudocodeImpl(correspondingElement);
    result.repeatWhole(this);
    return result;
  }

  private void repeatWhole(@NotNull PseudocodeImpl originalPseudocode) {
    repeatInternal(originalPseudocode, null, null, 0);
    parent = originalPseudocode.parent;
  }

  public int repeatPart(@NotNull Label startLabel, @NotNull Label finishLabel, int labelCount) {
    return repeatInternal(
        ((PseudocodeLabel) startLabel).getPseudocode(), startLabel, finishLabel, labelCount);
  }

  private int repeatInternal(
      @NotNull PseudocodeImpl originalPseudocode,
      @Nullable Label startLabel,
      @Nullable Label finishLabel,
      int labelCount) {
    Integer startIndex =
        startLabel != null
            ? ((PseudocodeLabel) startLabel).getTargetInstructionIndex()
            : Integer.valueOf(0);
    assert startIndex != null;
    Integer finishIndex =
        finishLabel != null
            ? ((PseudocodeLabel) finishLabel).getTargetInstructionIndex()
            : Integer.valueOf(originalPseudocode.mutableInstructionList.size());
    assert finishIndex != null;

    Map<Label, Label> originalToCopy = Maps.newLinkedHashMap();
    Multimap<Instruction, Label> originalLabelsForInstruction = HashMultimap.create();
    for (PseudocodeLabel label : originalPseudocode.labels) {
      Integer index = label.getTargetInstructionIndex();
      if (index == null) continue; // label is not bounded yet
      if (label == startLabel || label == finishLabel) continue;

      if (startIndex <= index && index <= finishIndex) {
        originalToCopy.put(label, label.copy(labelCount++));
        originalLabelsForInstruction.put(getJumpTarget(label), label);
      }
    }
    for (Label label : originalToCopy.values()) {
      labels.add((PseudocodeLabel) label);
    }
    for (int index = startIndex; index < finishIndex; index++) {
      Instruction originalInstruction = originalPseudocode.mutableInstructionList.get(index);
      repeatLabelsBindingForInstruction(
          originalInstruction, originalToCopy, originalLabelsForInstruction);
      Instruction copy = copyInstruction(originalInstruction, originalToCopy);
      addInstruction(copy);
      if (originalInstruction == originalPseudocode.errorInstruction
          && copy instanceof SubroutineExitInstruction) {
        errorInstruction = (SubroutineExitInstruction) copy;
      }
      if (originalInstruction == originalPseudocode.exitInstruction
          && copy instanceof SubroutineExitInstruction) {
        exitInstruction = (SubroutineExitInstruction) copy;
      }
      if (originalInstruction == originalPseudocode.sinkInstruction
          && copy instanceof SubroutineSinkInstruction) {
        sinkInstruction = (SubroutineSinkInstruction) copy;
      }
    }
    if (finishIndex < mutableInstructionList.size()) {
      repeatLabelsBindingForInstruction(
          originalPseudocode.mutableInstructionList.get(finishIndex),
          originalToCopy,
          originalLabelsForInstruction);
    }
    return labelCount;
  }

  private void repeatLabelsBindingForInstruction(
      @NotNull Instruction originalInstruction,
      @NotNull Map<Label, Label> originalToCopy,
      @NotNull Multimap<Instruction, Label> originalLabelsForInstruction) {
    for (Label originalLabel : originalLabelsForInstruction.get(originalInstruction)) {
      bindLabel(originalToCopy.get(originalLabel));
    }
  }

  private static Instruction copyInstruction(
      @NotNull Instruction instruction, @NotNull Map<Label, Label> originalToCopy) {
    if (instruction instanceof AbstractJumpInstruction) {
      Label originalTarget = ((AbstractJumpInstruction) instruction).getTargetLabel();
      if (originalToCopy.containsKey(originalTarget)) {
        return ((AbstractJumpInstruction) instruction).copy(originalToCopy.get(originalTarget));
      }
    }
    if (instruction instanceof NondeterministicJumpInstruction) {
      List<Label> originalTargets =
          ((NondeterministicJumpInstruction) instruction).getTargetLabels();
      List<Label> copyTargets = copyLabels(originalTargets, originalToCopy);
      return ((NondeterministicJumpInstruction) instruction).copy(copyTargets);
    }
    return ((InstructionImpl) instruction).copy();
  }

  @NotNull
  private static List<Label> copyLabels(
      Collection<Label> labels, Map<Label, Label> originalToCopy) {
    List<Label> newLabels = Lists.newArrayList();
    for (Label label : labels) {
      Label newLabel = originalToCopy.get(label);
      newLabels.add(newLabel != null ? newLabel : label);
    }
    return newLabels;
  }
}
Beispiel #18
0
/**
 * Encapsulates the results of processing. Provides access to the values of attributes collected
 * after processing and utility methods for obtaining processed documents ( {@link
 * #getDocuments()})) and the created clusters ({@link #getClusters()}).
 */
@Root(name = "searchresult", strict = false)
public final class ProcessingResult {
  /** Attributes collected after processing */
  private Map<String, Object> attributes = Maps.newHashMap();

  /** Read-only view of attributes exposed in {@link #getAttributes()} */
  private Map<String, Object> attributesView;

  /**
   * Query field used during serialization/ deserialization, see {@link #afterDeserialization()} and
   * {@link #beforeSerialization()}
   */
  @Element(required = false)
  private String query;

  /**
   * Documents field used during serialization/ deserialization, see {@link #afterDeserialization()}
   * and {@link #beforeSerialization()}
   */
  @ElementList(inline = true, required = false)
  private List<Document> documents;

  /**
   * Clusters field used during serialization/ deserialization, see {@link #afterDeserialization()}
   * and {@link #beforeSerialization()}
   */
  @ElementList(inline = true, required = false)
  private List<Cluster> clusters;

  /** Attributes of this result for serialization/ deserialization purposes. */
  @ElementMap(entry = "attribute", key = "key", attribute = true, inline = true, required = false)
  private HashMap<String, SimpleXmlWrapperValue> otherAttributesForSerialization;

  /** Parameterless constructor required for XML serialization/ deserialization. */
  ProcessingResult() {
    this(new HashMap<String, Object>());
  }

  /**
   * Creates a {@link ProcessingResult} with the provided <code>attributes</code>. Assigns unique
   * document identifiers if documents are present in the <code>attributes</code> map (under the key
   * {@link AttributeNames#DOCUMENTS}).
   */
  @SuppressWarnings("unchecked")
  ProcessingResult(Map<String, Object> attributes) {
    this.attributes = attributes;

    // Replace a modifiable collection of documents with an unmodifiable one
    final List<Document> documents = (List<Document>) attributes.get(AttributeNames.DOCUMENTS);
    if (documents != null) {
      Document.assignDocumentIds(documents);
      attributes.put(AttributeNames.DOCUMENTS, Collections.unmodifiableList(documents));
    }

    // Replace a modifiable collection of clusters with an unmodifiable one
    final List<Cluster> clusters = (List<Cluster>) attributes.get(AttributeNames.CLUSTERS);
    if (clusters != null) {
      Cluster.assignClusterIds(clusters);
      attributes.put(AttributeNames.CLUSTERS, Collections.unmodifiableList(clusters));
    }

    // Store a reference to attributes as an unmodifiable map
    this.attributesView = Collections.unmodifiableMap(attributes);
  }

  /**
   * Returns attributes fed-in and collected during processing. The returned map is unmodifiable.
   *
   * @return attributes fed-in and collected during processing
   */
  public Map<String, Object> getAttributes() {
    return attributesView;
  }

  /**
   * Returns a specific attribute of this result set. This method is equivalent to calling {@link
   * #getAttributes()} and then getting the required attribute from the map.
   *
   * @param key key of the attribute to return
   * @return value of the attribute
   */
  @SuppressWarnings("unchecked")
  public <T> T getAttribute(String key) {
    return (T) attributesView.get(key);
  }

  /**
   * Returns the documents that have been processed. The returned collection is unmodifiable.
   *
   * @return documents that have been processed or <code>null</code> if no documents are present in
   *     the result.
   */
  @SuppressWarnings("unchecked")
  public List<Document> getDocuments() {
    return (List<Document>) attributes.get(AttributeNames.DOCUMENTS);
  }

  /*
   * TODO: Returning a list of clusters instead of a (possibly artificial) cluster with
   * subclusters adds a little complexity to recursive methods operating on clusters (a
   * natural entry point is a method taking one cluster and acting on subclusters
   * recursively). If we have to start with a list of clusters, we have to handle this
   * special case separately...
   */

  /**
   * Returns the clusters that have been created during processing. The returned list is
   * unmodifiable.
   *
   * @return clusters created during processing or <code>null</code> if no clusters were present in
   *     the result.
   */
  @SuppressWarnings("unchecked")
  public List<Cluster> getClusters() {
    return (List<Cluster>) attributes.get(AttributeNames.CLUSTERS);
  }

  /** Extracts document and cluster lists before serialization. */
  @Persist
  private void beforeSerialization() {
    /*
     * See http://issues.carrot2.org/browse/CARROT-693; this monitor does not save us
     * in multi-threaded environment anyway. A better solution would be to prepare
     * this eagerly in the constructor, but we try to balance overhead and full
     * correctness here.
     */
    synchronized (this) {
      query = (String) attributes.get(AttributeNames.QUERY);

      if (getDocuments() != null) {
        documents = Lists.newArrayList(getDocuments());
      } else {
        documents = null;
      }

      if (getClusters() != null) {
        clusters = Lists.newArrayList(getClusters());
      } else {
        clusters = null;
      }

      otherAttributesForSerialization = MapUtils.asHashMap(SimpleXmlWrappers.wrap(attributes));
      otherAttributesForSerialization.remove(AttributeNames.QUERY);
      otherAttributesForSerialization.remove(AttributeNames.CLUSTERS);
      otherAttributesForSerialization.remove(AttributeNames.DOCUMENTS);
      if (otherAttributesForSerialization.isEmpty()) {
        otherAttributesForSerialization = null;
      }
    }
  }

  /** Transfers document and cluster lists to the attributes map after deserialization. */
  @Commit
  private void afterDeserialization() throws Exception {
    if (otherAttributesForSerialization != null) {
      attributes = SimpleXmlWrappers.unwrap(otherAttributesForSerialization);
    }

    attributesView = Collections.unmodifiableMap(attributes);

    attributes.put(AttributeNames.QUERY, query != null ? query.trim() : null);
    attributes.put(AttributeNames.DOCUMENTS, documents);
    attributes.put(AttributeNames.CLUSTERS, clusters);

    // Convert document ids to the actual references
    if (clusters != null && documents != null) {
      final Map<String, Document> documentsById = Maps.newHashMap();
      for (Document document : documents) {
        documentsById.put(document.getStringId(), document);
      }

      for (Cluster cluster : clusters) {
        documentIdToReference(cluster, documentsById);
      }
    }
  }

  /** Replace document refids with the actual references upon deserialization. */
  private void documentIdToReference(Cluster cluster, Map<String, Document> documents) {
    if (cluster.documentIds != null) {
      for (Cluster.DocumentRefid documentRefid : cluster.documentIds) {
        cluster.addDocuments(documents.get(documentRefid.refid));
      }
    }

    for (Cluster subcluster : cluster.getSubclusters()) {
      documentIdToReference(subcluster, documents);
    }
  }

  /** Serializes this {@link ProcessingResult} to an XML string. */
  public String serialize() {
    try {
      StringWriter sw = new StringWriter();
      new Persister().write(this, sw);
      return sw.toString();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Serializes this {@link ProcessingResult} to an XML stream. The output includes all documents,
   * clusters and other attributes.
   *
   * <p>This method is not thread-safe, external synchronization must be applied if needed.
   *
   * @param stream the stream to serialize this {@link ProcessingResult} to. The stream will
   *     <strong>not</strong> be closed.
   * @throws Exception in case of any problems with serialization
   */
  public void serialize(OutputStream stream) throws Exception {
    serialize(stream, true, true);
  }

  /**
   * Serializes this {@link ProcessingResult} to a byte stream. Documents and clusters can be
   * included or skipped in the output as requested. Other attributes are always included.
   *
   * <p>This method is not thread-safe, external synchronization must be applied if needed.
   *
   * @param stream the stream to serialize this {@link ProcessingResult} to. The stream will
   *     <strong>not</strong> be closed.
   * @param saveDocuments if <code>false</code>, documents will not be serialized. Notice that when
   *     deserializing XML containing clusters but not documents, document references in {@link
   *     Cluster#getDocuments()} will not be restored.
   * @param saveClusters if <code>false</code>, clusters will not be serialized
   * @throws Exception in case of any problems with serialization
   */
  public void serialize(OutputStream stream, boolean saveDocuments, boolean saveClusters)
      throws Exception {
    serialize(stream, saveDocuments, saveClusters, true);
  }

  /**
   * Serializes this {@link ProcessingResult} to a byte stream. Documents, clusters and other
   * attributes can be included or skipped in the output as requested.
   *
   * <p>This method is not thread-safe, external synchronization must be applied if needed.
   *
   * @param stream the stream to serialize this {@link ProcessingResult} to. The stream will
   *     <strong>not</strong> be closed.
   * @param saveDocuments if <code>false</code>, documents will not be serialized. Notice that when
   *     deserializing XML containing clusters but not documents, document references in {@link
   *     Cluster#getDocuments()} will not be restored.
   * @param saveClusters if <code>false</code>, clusters will not be serialized
   * @param saveOtherAttributes if <code>false</code>, other attributes will not be serialized
   * @throws Exception in case of any problems with serialization
   */
  public void serialize(
      OutputStream stream, boolean saveDocuments, boolean saveClusters, boolean saveOtherAttributes)
      throws Exception {
    final Map<String, Object> backupAttributes = attributes;

    attributes =
        prepareAttributesForSerialization(saveDocuments, saveClusters, saveOtherAttributes);

    new Persister().write(this, stream);

    attributes = backupAttributes;
  }

  /** Deserialize from an input stream of characters. */
  public static ProcessingResult deserialize(CharSequence input) throws Exception {
    return new Persister().read(ProcessingResult.class, input.toString());
  }

  /**
   * Deserializes a {@link ProcessingResult} from an XML stream.
   *
   * @param input the input XML stream to deserialize a {@link ProcessingResult} from. The stream
   *     will <strong>not</strong> be closed.
   * @return deserialized {@link ProcessingResult}
   * @throws Exception is case of any problems with deserialization
   */
  public static ProcessingResult deserialize(InputStream input) throws Exception {
    return new Persister().read(ProcessingResult.class, input);
  }

  /**
   * Serializes this processing result as JSON to the provided <code>writer</code>. The output
   * includes all documents, clusters and other attributes.
   *
   * <p>This method is not thread-safe, external synchronization must be applied if needed.
   *
   * @param writer the writer to serialize this processing result to. The writer will
   *     <strong>not</strong> be closed.
   * @throws IOException in case of any problems with serialization
   */
  public void serializeJson(Writer writer) throws IOException {
    serializeJson(writer, null);
  }

  /**
   * Serializes this processing result as JSON to the provided <code>writer</code>. The output
   * includes all documents, clusters and other attributes.
   *
   * <p>This method is not thread-safe, external synchronization must be applied if needed.
   *
   * @param writer the writer to serialize this processing result to. The writer will
   *     <strong>not</strong> be closed.
   * @param callback JavaScript function name in which to wrap the JSON response or <code>null
   *     </code>.
   * @throws IOException in case of any problems with serialization
   */
  public void serializeJson(Writer writer, String callback) throws IOException {
    serializeJson(writer, callback, true, true);
  }

  /**
   * Serializes this processing result as JSON to the provided <code>writer</code>. Documents and
   * clusters can be included or skipped in the output as requested. Other attributes are always
   * included.
   *
   * <p>This method is not thread-safe, external synchronization must be applied if needed.
   *
   * @param writer the writer to serialize this processing result to. The writer will
   *     <strong>not</strong> be closed.
   * @param callback JavaScript function name in which to wrap the JSON response or <code>null
   *     </code>.
   * @param saveDocuments if <code>false</code>, documents will not be serialized.
   * @param saveClusters if <code>false</code>, clusters will not be serialized
   * @throws IOException in case of any problems with serialization
   */
  public void serializeJson(
      Writer writer, String callback, boolean saveDocuments, boolean saveClusters)
      throws IOException {
    serializeJson(writer, callback, false, saveDocuments, saveClusters);
  }

  /**
   * Serializes this processing result as JSON to the provided <code>writer</code>.
   *
   * <p>This method is not thread-safe, external synchronization must be applied if needed.
   *
   * @param writer the writer to serialize this processing result to. The writer will
   *     <strong>not</strong> be closed.
   * @param callback JavaScript function name in which to wrap the JSON response or <code>null
   *     </code>.
   * @param indent if <code>true</code>, the output JSON will be pretty-printed
   * @param saveDocuments if <code>false</code>, documents will not be serialized.
   * @param saveClusters if <code>false</code>, clusters will not be serialized
   * @throws IOException in case of any problems with serialization
   */
  public void serializeJson(
      Writer writer, String callback, boolean indent, boolean saveDocuments, boolean saveClusters)
      throws IOException {
    serializeJson(writer, callback, indent, saveDocuments, saveClusters, true);
  }

  /**
   * Serializes this processing result as JSON to the provided <code>writer</code>. Documents,
   * clusters and other attributes can be included or skipped in the output as requested.
   *
   * @param writer the writer to serialize this processing result to. The writer will
   *     <strong>not</strong> be closed.
   * @param callback JavaScript function name in which to wrap the JSON response or <code>null
   *     </code>.
   * @param indent if <code>true</code>, the output JSON will be pretty-printed
   * @param saveDocuments if <code>false</code>, documents will not be serialized.
   * @param saveClusters if <code>false</code>, clusters will not be serialized
   * @param saveOtherAttributes if <code>false</code>, other attributes will not be serialized
   * @throws IOException in case of any problems with serialization
   */
  public void serializeJson(
      Writer writer,
      String callback,
      boolean indent,
      boolean saveDocuments,
      boolean saveClusters,
      boolean saveOtherAttributes)
      throws IOException {
    final ObjectMapper mapper = new ObjectMapper();
    mapper.getFactory().disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
    mapper.enable(SerializationFeature.INDENT_OUTPUT);

    if (StringUtils.isNotBlank(callback)) {
      writer.write(callback + "(");
    }
    final Map<String, Object> attrs =
        prepareAttributesForSerialization(saveDocuments, saveClusters, saveOtherAttributes);

    mapper.writeValue(writer, attrs);
    if (StringUtils.isNotBlank(callback)) {
      writer.write(");");
    }
  }

  /**
   * Prepares a temporary attributes map for serialization purposes. Includes only the requested
   * elements in the map.
   */
  private Map<String, Object> prepareAttributesForSerialization(
      boolean saveDocuments, boolean saveClusters, boolean saveOtherAttributes) {
    final Map<String, Object> tempAttributes = Maps.newHashMap();

    if (saveOtherAttributes) {
      tempAttributes.putAll(attributes);
      tempAttributes.remove(AttributeNames.DOCUMENTS);
      tempAttributes.remove(AttributeNames.CLUSTERS);
    } else {
      tempAttributes.put(AttributeNames.QUERY, attributes.get(AttributeNames.QUERY));
    }

    if (saveDocuments) {
      tempAttributes.put(AttributeNames.DOCUMENTS, getDocuments());
    }

    if (saveClusters) {
      tempAttributes.put(AttributeNames.CLUSTERS, getClusters());
    }

    return tempAttributes;
  }
}
Beispiel #19
0
  public MutationState createTable(CreateTableStatement statement, byte[][] splits)
      throws SQLException {
    PTableType tableType = statement.getTableType();
    boolean isView = tableType == PTableType.VIEW;
    if (isView && !statement.getProps().isEmpty()) {
      throw new SQLExceptionInfo.Builder(SQLExceptionCode.VIEW_WITH_TABLE_CONFIG)
          .build()
          .buildException();
    }
    connection.rollback();
    boolean wasAutoCommit = connection.getAutoCommit();
    try {
      connection.setAutoCommit(false);
      TableName tableNameNode = statement.getTableName();
      String schemaName = tableNameNode.getSchemaName();
      String tableName = tableNameNode.getTableName();

      PrimaryKeyConstraint pkConstraint = statement.getPrimaryKeyConstraint();
      String pkName = null;
      Set<String> pkColumns = Collections.<String>emptySet();
      Iterator<String> pkColumnsIterator = Iterators.emptyIterator();
      if (pkConstraint != null) {
        pkColumns = pkConstraint.getColumnNames();
        pkColumnsIterator = pkColumns.iterator();
        pkName = pkConstraint.getName();
      }

      List<ColumnDef> colDefs = statement.getColumnDefs();
      List<PColumn> columns = Lists.newArrayListWithExpectedSize(colDefs.size());
      PreparedStatement colUpsert = connection.prepareStatement(INSERT_COLUMN);
      int columnOrdinal = 0;
      Map<String, PName> familyNames = Maps.newLinkedHashMap();
      boolean isPK = false;
      for (ColumnDef colDef : colDefs) {
        if (colDef.isPK()) {
          if (isPK) {
            throw new SQLExceptionInfo.Builder(SQLExceptionCode.PRIMARY_KEY_ALREADY_EXISTS)
                .setColumnName(colDef.getColumnDefName().getColumnName().getName())
                .build()
                .buildException();
          }
          isPK = true;
        }
        PColumn column = newColumn(columnOrdinal++, colDef, pkConstraint);
        if (SchemaUtil.isPKColumn(column)) {
          // TODO: remove this constraint?
          if (!pkColumns.isEmpty()
              && !column.getName().getString().equals(pkColumnsIterator.next())) {
            throw new SQLExceptionInfo.Builder(SQLExceptionCode.PRIMARY_KEY_OUT_OF_ORDER)
                .setSchemaName(schemaName)
                .setTableName(tableName)
                .setColumnName(column.getName().getString())
                .build()
                .buildException();
          }
        }
        columns.add(column);
        if (colDef.getDataType() == PDataType.BINARY && colDefs.size() > 1) {
          throw new SQLExceptionInfo.Builder(SQLExceptionCode.BINARY_IN_ROW_KEY)
              .setSchemaName(schemaName)
              .setTableName(tableName)
              .setColumnName(column.getName().getString())
              .build()
              .buildException();
        }
        if (column.getFamilyName() != null) {
          familyNames.put(column.getFamilyName().getString(), column.getFamilyName());
        }
      }
      if (!isPK && pkColumns.isEmpty()) {
        throw new SQLExceptionInfo.Builder(SQLExceptionCode.PRIMARY_KEY_MISSING)
            .setSchemaName(schemaName)
            .setTableName(tableName)
            .build()
            .buildException();
      }

      List<Pair<byte[], Map<String, Object>>> familyPropList =
          Lists.newArrayListWithExpectedSize(familyNames.size());
      Map<String, Object> commonFamilyProps = Collections.emptyMap();
      Map<String, Object> tableProps = Collections.emptyMap();
      if (!statement.getProps().isEmpty()) {
        if (statement.isView()) {
          throw new SQLExceptionInfo.Builder(SQLExceptionCode.VIEW_WITH_PROPERTIES)
              .build()
              .buildException();
        }
        for (String familyName : statement.getProps().keySet()) {
          if (!familyName.equals(QueryConstants.ALL_FAMILY_PROPERTIES_KEY)) {
            if (familyNames.get(familyName) == null) {
              throw new SQLExceptionInfo.Builder(SQLExceptionCode.PROPERTIES_FOR_FAMILY)
                  .setFamilyName(familyName)
                  .build()
                  .buildException();
            }
          }
        }
        commonFamilyProps = Maps.newHashMapWithExpectedSize(statement.getProps().size());
        tableProps = Maps.newHashMapWithExpectedSize(statement.getProps().size());

        Collection<Pair<String, Object>> props =
            statement.getProps().get(QueryConstants.ALL_FAMILY_PROPERTIES_KEY);
        // Somewhat hacky way of determining if property is for HColumnDescriptor or
        // HTableDescriptor
        HColumnDescriptor defaultDescriptor =
            new HColumnDescriptor(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES);
        for (Pair<String, Object> prop : props) {
          if (defaultDescriptor.getValue(prop.getFirst()) != null) {
            commonFamilyProps.put(prop.getFirst(), prop.getSecond());
          } else {
            tableProps.put(prop.getFirst(), prop.getSecond());
          }
        }
      }

      for (PName familyName : familyNames.values()) {
        Collection<Pair<String, Object>> props = statement.getProps().get(familyName.getString());
        if (props.isEmpty()) {
          familyPropList.add(
              new Pair<byte[], Map<String, Object>>(familyName.getBytes(), commonFamilyProps));
        } else {
          Map<String, Object> combinedFamilyProps =
              Maps.newHashMapWithExpectedSize(props.size() + commonFamilyProps.size());
          combinedFamilyProps.putAll(commonFamilyProps);
          for (Pair<String, Object> prop : props) {
            combinedFamilyProps.put(prop.getFirst(), prop.getSecond());
          }
          familyPropList.add(
              new Pair<byte[], Map<String, Object>>(familyName.getBytes(), combinedFamilyProps));
        }
      }

      // Bootstrapping for our SYSTEM.TABLE that creates itself before it exists
      if (tableType == PTableType.SYSTEM) {
        PTable table =
            new PTableImpl(
                new PNameImpl(tableName),
                tableType,
                MetaDataProtocol.MIN_TABLE_TIMESTAMP,
                0,
                QueryConstants.SYSTEM_TABLE_PK_NAME,
                null,
                columns);
        connection.addTable(schemaName, table);
      }

      for (PColumn column : columns) {
        addColumnMutation(schemaName, tableName, column, colUpsert);
      }

      Integer saltBucketNum = (Integer) tableProps.remove(PhoenixDatabaseMetaData.SALT_BUCKETS);
      if (saltBucketNum != null
          && (saltBucketNum <= 0 || saltBucketNum > SaltingUtil.MAX_BUCKET_NUM)) {
        throw new SQLExceptionInfo.Builder(SQLExceptionCode.INVALID_BUCKET_NUM)
            .build()
            .buildException();
      }

      PreparedStatement tableUpsert = connection.prepareStatement(CREATE_TABLE);
      tableUpsert.setString(1, schemaName);
      tableUpsert.setString(2, tableName);
      tableUpsert.setString(3, tableType.getSerializedValue());
      tableUpsert.setInt(4, 0);
      tableUpsert.setInt(5, columnOrdinal);
      if (saltBucketNum != null) {
        tableUpsert.setInt(6, saltBucketNum);
      } else {
        tableUpsert.setNull(6, Types.INTEGER);
      }
      tableUpsert.setString(7, pkName);
      tableUpsert.execute();

      final List<Mutation> tableMetaData = connection.getMutationState().toMutations();
      connection.rollback();

      MetaDataMutationResult result =
          connection
              .getQueryServices()
              .createTable(tableMetaData, isView, tableProps, familyPropList, splits);
      MutationCode code = result.getMutationCode();
      switch (code) {
        case TABLE_ALREADY_EXISTS:
          connection.addTable(schemaName, result.getTable());
          if (!statement.ifNotExists()) {
            throw new TableAlreadyExistsException(schemaName, tableName);
          }
          break;
        case NEWER_TABLE_FOUND:
          // TODO: add table if in result?
          throw new NewerTableAlreadyExistsException(schemaName, tableName);
        case UNALLOWED_TABLE_MUTATION:
          throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_MUTATE_TABLE)
              .setSchemaName(schemaName)
              .setTableName(tableName)
              .build()
              .buildException();
        default:
          PTable table =
              new PTableImpl(
                  new PNameImpl(tableName),
                  tableType,
                  result.getMutationTime(),
                  0,
                  pkName,
                  saltBucketNum,
                  columns);
          connection.addTable(schemaName, table);
          if (tableType == PTableType.USER) {
            connection.setAutoCommit(true);
            // Delete everything in the column. You'll still be able to do queries at earlier
            // timestamps
            Long scn = connection.getSCN();
            long ts = (scn == null ? result.getMutationTime() : scn);
            PSchema schema =
                new PSchemaImpl(
                    schemaName,
                    ImmutableMap.<String, PTable>of(table.getName().getString(), table));
            TableRef tableRef = new TableRef(null, table, schema, ts);
            byte[] emptyCF = SchemaUtil.getEmptyColumnFamily(table.getColumnFamilies());
            MutationPlan plan =
                new PostDDLCompiler(connection).compile(tableRef, emptyCF, null, ts);
            return connection.getQueryServices().updateData(plan);
          }
          break;
      }
      return new MutationState(0, connection);
    } finally {
      connection.setAutoCommit(wasAutoCommit);
    }
  }
 @Test
 public void should_return_null_if_Map_is_null() {
   assertNull(Maps.format(null));
 }
 @Test
 public void should_return_empty_braces_if_Map_is_empty() {
   assertEquals(Maps.format(new HashMap<String, String>()), "{}");
 }
Beispiel #22
0
 public OptiqSchema(OptiqSchema parent, final Schema schema, String name) {
   this.parent = parent;
   this.schema = schema;
   this.name = name;
   assert (parent == null) == (this instanceof OptiqRootSchema);
   //noinspection unchecked
   this.compositeTableMap =
       CompositeMap.of(
           Maps.transformValues(
               tableMap,
               new com.google.common.base.Function<TableEntry, Table>() {
                 public Table apply(TableEntry input) {
                   return input.getTable();
                 }
               }),
           Maps.transformValues(
               Multimaps.filterEntries(
                       functionMap,
                       new Predicate<Map.Entry<String, FunctionEntry>>() {
                         public boolean apply(Map.Entry<String, FunctionEntry> entry) {
                           final Function function = entry.getValue().getFunction();
                           return function instanceof TableMacro
                               && function.getParameters().isEmpty();
                         }
                       })
                   .asMap(),
               new com.google.common.base.Function<Collection<FunctionEntry>, Table>() {
                 public Table apply(Collection<FunctionEntry> input) {
                   // At most one function with zero parameters.
                   final TableMacro tableMacro =
                       (TableMacro) input.iterator().next().getFunction();
                   return tableMacro.apply(ImmutableList.of());
                 }
               }),
           Compatible.INSTANCE.asMap(
               schema.getTableNames(),
               new com.google.common.base.Function<String, Table>() {
                 public Table apply(String input) {
                   return schema.getTable(input);
                 }
               }));
   // TODO: include schema's functions in this map.
   this.compositeFunctionMap =
       Multimaps.transformValues(
           functionMap,
           new com.google.common.base.Function<FunctionEntry, Function>() {
             public Function apply(FunctionEntry input) {
               return input.getFunction();
             }
           });
   //noinspection unchecked
   this.compositeSubSchemaMap =
       CompositeMap.of(
           subSchemaMap,
           Compatible.INSTANCE.asMap(
               schema.getSubSchemaNames(),
               new com.google.common.base.Function<String, OptiqSchema>() {
                 public OptiqSchema apply(String name) {
                   return add(name, schema.getSubSchema(name));
                 }
               }));
 }
Beispiel #23
0
  /**
   * Parse the given array of arguments.
   *
   * <p>Empty arguments are removed from the list of arguments.
   *
   * @param args an array with arguments
   * @param expectedValueFlags a set containing all value flags (pass null to disable value flag
   *     parsing)
   * @param allowHangingFlag true if hanging flags are allowed
   * @param namespace the locals, null to create empty one
   * @throws CommandException thrown on a parsing error
   */
  public CommandContext(
      String[] args,
      Set<Character> expectedValueFlags,
      boolean allowHangingFlag,
      Namespace namespace)
      throws CommandException {
    if (expectedValueFlags == null) {
      expectedValueFlags = Collections.emptySet();
    }

    originalArgs = args;
    command = args[0];
    this.namespace = namespace != null ? namespace : new Namespace();
    boolean isHanging = false;
    SuggestionContext suggestionContext = SuggestionContext.hangingValue();

    // Eliminate empty args and combine multiword args first
    List<Integer> argIndexList = new ArrayList<Integer>(args.length);
    List<String> argList = new ArrayList<String>(args.length);
    for (int i = 1; i < args.length; ++i) {
      isHanging = false;

      String arg = args[i];
      if (arg.isEmpty()) {
        isHanging = true;
        continue;
      }

      argIndexList.add(i);

      switch (arg.charAt(0)) {
        case '\'':
        case '"':
          final StringBuilder build = new StringBuilder();
          final char quotedChar = arg.charAt(0);

          int endIndex;
          for (endIndex = i; endIndex < args.length; ++endIndex) {
            final String arg2 = args[endIndex];
            if (arg2.charAt(arg2.length() - 1) == quotedChar && arg2.length() > 1) {
              if (endIndex != i) build.append(' ');
              build.append(arg2.substring(endIndex == i ? 1 : 0, arg2.length() - 1));
              break;
            } else if (endIndex == i) {
              build.append(arg2.substring(1));
            } else {
              build.append(' ').append(arg2);
            }
          }

          if (endIndex < args.length) {
            arg = build.toString();
            i = endIndex;
          }

          // In case there is an empty quoted string
          if (arg.isEmpty()) {
            continue;
          }
          // else raise exception about hanging quotes?
      }
      argList.add(arg);
    }

    // Then flags

    List<Integer> originalArgIndices = Lists.newArrayListWithCapacity(argIndexList.size());
    List<String> parsedArgs = Lists.newArrayListWithCapacity(argList.size());
    Map<Character, String> valueFlags = Maps.newHashMap();
    List<Character> booleanFlags = Lists.newArrayList();

    for (int nextArg = 0; nextArg < argList.size(); ) {
      // Fetch argument
      String arg = argList.get(nextArg++);
      suggestionContext = SuggestionContext.hangingValue();

      // Not a flag?
      if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z\\?]+$")) {
        if (!isHanging) {
          suggestionContext = SuggestionContext.lastValue();
        }

        originalArgIndices.add(argIndexList.get(nextArg - 1));
        parsedArgs.add(arg);
        continue;
      }

      // Handle flag parsing terminator --
      if (arg.equals("--")) {
        while (nextArg < argList.size()) {
          originalArgIndices.add(argIndexList.get(nextArg));
          parsedArgs.add(argList.get(nextArg++));
        }
        break;
      }

      // Go through the flag characters
      for (int i = 1; i < arg.length(); ++i) {
        char flagName = arg.charAt(i);

        if (expectedValueFlags.contains(flagName)) {
          if (valueFlags.containsKey(flagName)) {
            throw new CommandException("Value flag '" + flagName + "' already given");
          }

          if (nextArg >= argList.size()) {
            if (allowHangingFlag) {
              suggestionContext = SuggestionContext.flag(flagName);
              break;
            } else {
              throw new CommandException("No value specified for the '-" + flagName + "' flag.");
            }
          }

          // If it is a value flag, read another argument and add it
          valueFlags.put(flagName, argList.get(nextArg++));
          if (!isHanging) {
            suggestionContext = SuggestionContext.flag(flagName);
          }
        } else {
          booleanFlags.add(flagName);
        }
      }
    }

    ImmutableMap.Builder<Character, String> allFlagsBuilder =
        new ImmutableMap.Builder<Character, String>().putAll(valueFlags);
    for (Character flag : booleanFlags) {
      allFlagsBuilder.put(flag, "true");
    }

    this.parsedArgs = ImmutableList.copyOf(parsedArgs);
    this.originalArgIndices = ImmutableList.copyOf(originalArgIndices);
    this.booleanFlags = ImmutableSet.copyOf(booleanFlags);
    this.valueFlags = ImmutableMap.copyOf(valueFlags);
    this.allFlags = allFlagsBuilder.build();
    this.suggestionContext = suggestionContext;
  }
Beispiel #24
0
  private void init(
      PName name,
      PTableType type,
      long timeStamp,
      long sequenceNumber,
      String pkName,
      List<PColumn> columns,
      PTableStats stats) {
    this.name = name;
    this.type = type;
    this.timeStamp = timeStamp;
    this.sequenceNumber = sequenceNumber;
    this.columnsByName = ArrayListMultimap.create(columns.size(), 1);
    this.pkName = pkName;
    List<PColumn> pkColumns = Lists.newArrayListWithExpectedSize(columns.size() - 1);
    PColumn[] allColumns = new PColumn[columns.size()];
    RowKeySchemaBuilder builder = new RowKeySchemaBuilder();
    for (int i = 0; i < allColumns.length; i++) {
      PColumn column = columns.get(i);
      allColumns[column.getPosition()] = column;
      PName familyName = column.getFamilyName();
      if (familyName == null) {
        pkColumns.add(column);
        builder.addField(column);
      }
      columnsByName.put(column.getName().getString(), column);
    }
    this.pkColumns = ImmutableList.copyOf(pkColumns);
    this.rowKeySchema = builder.setMinNullable(pkColumns.size()).build();
    this.allColumns = ImmutableList.copyOf(allColumns);

    // Two pass so that column order in column families matches overall column order
    // and to ensure that column family order is constant
    int maxExpectedSize = allColumns.length - pkColumns.size();
    // Maintain iteration order so that column families are ordered as they are listed
    Map<PName, List<PColumn>> familyMap = Maps.newLinkedHashMap();
    for (PColumn column : allColumns) {
      PName familyName = column.getFamilyName();
      if (familyName != null) {
        List<PColumn> columnsInFamily = familyMap.get(familyName);
        if (columnsInFamily == null) {
          columnsInFamily = Lists.newArrayListWithExpectedSize(maxExpectedSize);
          familyMap.put(familyName, columnsInFamily);
        }
        columnsInFamily.add(column);
      }
    }

    Iterator<Map.Entry<PName, List<PColumn>>> iterator = familyMap.entrySet().iterator();
    PColumnFamily[] families = new PColumnFamily[familyMap.size()];
    ImmutableMap.Builder<String, PColumnFamily> familyByString = ImmutableMap.builder();
    ImmutableSortedMap.Builder<byte[], PColumnFamily> familyByBytes =
        ImmutableSortedMap.orderedBy(Bytes.BYTES_COMPARATOR);
    for (int i = 0; i < families.length; i++) {
      Map.Entry<PName, List<PColumn>> entry = iterator.next();
      PColumnFamily family = new PColumnFamilyImpl(entry.getKey(), entry.getValue());
      families[i] = family;
      familyByString.put(family.getName().getString(), family);
      familyByBytes.put(family.getName().getBytes(), family);
    }
    this.families = ImmutableList.copyOf(families);
    this.familyByBytes = familyByBytes.build();
    this.familyByString = familyByString.build();
    this.stats = stats;
  }
Beispiel #25
0
public class FunctionUtil {

  private FunctionUtil() {}

  public static FieldValue evaluate(
      Apply apply, List<FieldValue> values, EvaluationContext context) {
    String name = apply.getFunction();

    Function function = getFunction(name);
    if (function == null) {
      DefineFunction defineFunction = context.resolveFunction(name);
      if (defineFunction == null) {
        throw new UnsupportedFeatureException(apply);
      }

      return evaluate(defineFunction, values, context);
    }

    return function.evaluate(values);
  }

  public static FieldValue evaluate(
      DefineFunction defineFunction, List<FieldValue> values, EvaluationContext context) {
    List<ParameterField> parameterFields = defineFunction.getParameterFields();

    if (parameterFields.size() < 1) {
      throw new InvalidFeatureException(defineFunction);
    } // End if

    if (parameterFields.size() != values.size()) {
      throw new EvaluationException();
    }

    FunctionEvaluationContext functionContext = new FunctionEvaluationContext(context);

    for (int i = 0; i < parameterFields.size(); i++) {
      ParameterField parameterField = parameterFields.get(i);

      FieldValue value = FieldValueUtil.refine(parameterField, values.get(i));

      functionContext.declare(parameterField.getName(), value);
    }

    Expression expression = defineFunction.getExpression();
    if (expression == null) {
      throw new InvalidFeatureException(defineFunction);
    }

    FieldValue result = ExpressionUtil.evaluate(expression, functionContext);

    return FieldValueUtil.refine(defineFunction.getDataType(), defineFunction.getOptype(), result);
  }

  public static Function getFunction(String name) {
    return FunctionUtil.functions.get(name);
  }

  public static void putFunction(String name, Function function) {
    FunctionUtil.functions.put(name, function);
  }

  private static void checkArguments(List<FieldValue> values, int size) {
    checkArguments(values, size, false);
  }

  private static void checkArguments(List<FieldValue> values, int size, boolean allowNulls) {
    boolean success = (values.size() == size) && (allowNulls ? true : !values.contains(null));
    if (!success) {
      throw new EvaluationException();
    }
  }

  private static void checkVariableArguments(List<FieldValue> values, int size) {
    checkVariableArguments(values, size, false);
  }

  private static void checkVariableArguments(
      List<FieldValue> values, int size, boolean allowNulls) {
    boolean success = (values.size() >= size) && (allowNulls ? true : !values.contains(null));
    if (!success) {
      throw new EvaluationException();
    }
  }

  private static Number cast(DataType dataType, Number number) {

    switch (dataType) {
      case INTEGER:
        if (number instanceof Integer) {
          return number;
        }
        return Integer.valueOf(number.intValue());
      case FLOAT:
        if (number instanceof Float) {
          return number;
        }
        return Float.valueOf(number.floatValue());
      case DOUBLE:
        if (number instanceof Double) {
          return number;
        }
        return Double.valueOf(number.doubleValue());
      default:
        break;
    }

    throw new EvaluationException();
  }

  private static DataType integerToDouble(DataType dataType) {

    switch (dataType) {
      case INTEGER:
        return DataType.DOUBLE;
      default:
        break;
    }

    return dataType;
  }

  private static final Map<String, Function> functions = Maps.newLinkedHashMap();

  public interface Function {

    FieldValue evaluate(List<FieldValue> values);
  }

  public abstract static class ArithmeticFunction implements Function {

    public abstract Number evaluate(Number left, Number right);

    @Override
    public FieldValue evaluate(List<FieldValue> values) {

      if (values.size() != 2) {
        throw new EvaluationException();
      }

      FieldValue left = values.get(0);
      FieldValue right = values.get(1);

      // "If one of the input fields of a simple arithmetic function is a missing value, the result
      // evaluates to missing value"
      if (left == null || right == null) {
        return null;
      }

      DataType dataType = TypeUtil.getResultDataType(left.getDataType(), right.getDataType());

      Number result;

      try {
        result = evaluate(left.asNumber(), right.asNumber());
      } catch (ArithmeticException ae) {
        throw new InvalidResultException(null);
      }

      return FieldValueUtil.create(cast(dataType, result));
    }
  }

  static {
    putFunction(
        "+",
        new ArithmeticFunction() {

          @Override
          public Double evaluate(Number left, Number right) {
            return Double.valueOf(left.doubleValue() + right.doubleValue());
          }
        });

    putFunction(
        "-",
        new ArithmeticFunction() {

          @Override
          public Double evaluate(Number left, Number right) {
            return Double.valueOf(left.doubleValue() - right.doubleValue());
          }
        });

    putFunction(
        "*",
        new ArithmeticFunction() {

          @Override
          public Double evaluate(Number left, Number right) {
            return Double.valueOf(left.doubleValue() * right.doubleValue());
          }
        });

    putFunction(
        "/",
        new ArithmeticFunction() {

          @Override
          public Number evaluate(Number left, Number right) {

            if (left instanceof Integer && right instanceof Integer) {
              return Integer.valueOf(left.intValue() / right.intValue());
            }

            return Double.valueOf(left.doubleValue() / right.doubleValue());
          }
        });
  }

  public abstract static class AggregateFunction implements Function {

    public abstract StorelessUnivariateStatistic createStatistic();

    public DataType getResultType(DataType dataType) {
      return dataType;
    }

    @Override
    public FieldValue evaluate(List<FieldValue> values) {
      StorelessUnivariateStatistic statistic = createStatistic();

      DataType dataType = null;

      for (FieldValue value : values) {

        // "Missing values in the input to an aggregate function are simply ignored"
        if (value == null) {
          continue;
        }

        statistic.increment((value.asNumber()).doubleValue());

        if (dataType != null) {
          dataType = TypeUtil.getResultDataType(dataType, value.getDataType());
        } else {
          dataType = value.getDataType();
        }
      }

      if (statistic.getN() == 0) {
        throw new MissingResultException(null);
      }

      Object result = cast(getResultType(dataType), statistic.getResult());

      return FieldValueUtil.create(result);
    }
  }

  static {
    putFunction(
        "min",
        new AggregateFunction() {

          @Override
          public Min createStatistic() {
            return new Min();
          }
        });

    putFunction(
        "max",
        new AggregateFunction() {

          @Override
          public Max createStatistic() {
            return new Max();
          }
        });

    putFunction(
        "avg",
        new AggregateFunction() {

          @Override
          public Mean createStatistic() {
            return new Mean();
          }

          @Override
          public DataType getResultType(DataType dataType) {
            return integerToDouble(dataType);
          }
        });

    putFunction(
        "sum",
        new AggregateFunction() {

          @Override
          public Sum createStatistic() {
            return new Sum();
          }
        });

    putFunction(
        "product",
        new AggregateFunction() {

          @Override
          public Product createStatistic() {
            return new Product();
          }
        });
  }

  public abstract static class MathFunction implements Function {

    public abstract Double evaluate(Number value);

    public DataType getResultType(DataType dataType) {
      return dataType;
    }

    @Override
    public FieldValue evaluate(List<FieldValue> values) {
      checkArguments(values, 1);

      FieldValue value = values.get(0);

      Number result = cast(getResultType(value.getDataType()), evaluate(value.asNumber()));

      return FieldValueUtil.create(result);
    }
  }

  public abstract static class FpMathFunction extends MathFunction {

    @Override
    public DataType getResultType(DataType dataType) {
      return integerToDouble(dataType);
    }
  }

  static {
    putFunction(
        "log10",
        new FpMathFunction() {

          @Override
          public Double evaluate(Number value) {
            return Math.log10(value.doubleValue());
          }
        });

    putFunction(
        "ln",
        new FpMathFunction() {

          @Override
          public Double evaluate(Number value) {
            return Math.log(value.doubleValue());
          }
        });

    putFunction(
        "exp",
        new FpMathFunction() {

          @Override
          public Double evaluate(Number value) {
            return Math.exp(value.doubleValue());
          }
        });

    putFunction(
        "sqrt",
        new FpMathFunction() {

          @Override
          public Double evaluate(Number value) {
            return Math.sqrt(value.doubleValue());
          }
        });

    putFunction(
        "abs",
        new MathFunction() {

          @Override
          public Double evaluate(Number value) {
            return Math.abs(value.doubleValue());
          }
        });

    putFunction(
        "pow",
        new Function() {

          @Override
          public FieldValue evaluate(List<FieldValue> values) {
            checkArguments(values, 2);

            FieldValue left = values.get(0);
            FieldValue right = values.get(1);

            DataType dataType = TypeUtil.getResultDataType(left.getDataType(), right.getDataType());

            Double result =
                Math.pow((left.asNumber()).doubleValue(), (right.asNumber()).doubleValue());

            return FieldValueUtil.create(cast(dataType, result));
          }
        });

    putFunction(
        "threshold",
        new Function() {

          @Override
          public FieldValue evaluate(List<FieldValue> values) {
            checkArguments(values, 2);

            FieldValue left = values.get(0);
            FieldValue right = values.get(1);

            DataType dataType = TypeUtil.getResultDataType(left.getDataType(), right.getDataType());

            Integer result =
                ((left.asNumber()).doubleValue() > (right.asNumber()).doubleValue()) ? 1 : 0;

            return FieldValueUtil.create(cast(dataType, result));
          }
        });

    putFunction(
        "floor",
        new MathFunction() {

          @Override
          public Double evaluate(Number number) {
            return Math.floor(number.doubleValue());
          }
        });

    putFunction(
        "ceil",
        new MathFunction() {

          @Override
          public Double evaluate(Number number) {
            return Math.ceil(number.doubleValue());
          }
        });

    putFunction(
        "round",
        new MathFunction() {

          @Override
          public Double evaluate(Number number) {
            return (double) Math.round(number.doubleValue());
          }
        });
  }

  public abstract static class ValueFunction implements Function {

    public abstract Boolean evaluate(FieldValue value);

    @Override
    public FieldValue evaluate(List<FieldValue> values) {
      checkArguments(values, 1, true);

      FieldValue value = values.get(0);

      Boolean result = evaluate(value);

      return FieldValueUtil.create(result);
    }
  }

  static {
    putFunction(
        "isMissing",
        new ValueFunction() {

          @Override
          public Boolean evaluate(FieldValue value) {
            return Boolean.valueOf(value == null);
          }
        });

    putFunction(
        "isNotMissing",
        new ValueFunction() {

          @Override
          public Boolean evaluate(FieldValue value) {
            return Boolean.valueOf(value != null);
          }
        });
  }

  public abstract static class EqualityFunction implements Function {

    public abstract Boolean evaluate(boolean equals);

    @Override
    public FieldValue evaluate(List<FieldValue> values) {
      checkArguments(values, 2);

      FieldValue left = values.get(0);
      FieldValue right = values.get(1);

      Boolean result = evaluate((left).equalsValue(right));

      return FieldValueUtil.create(result);
    }
  }

  static {
    putFunction(
        "equal",
        new EqualityFunction() {

          @Override
          public Boolean evaluate(boolean equals) {
            return Boolean.valueOf(equals);
          }
        });

    putFunction(
        "notEqual",
        new EqualityFunction() {

          @Override
          public Boolean evaluate(boolean equals) {
            return Boolean.valueOf(!equals);
          }
        });
  }

  public abstract static class ComparisonFunction implements Function {

    public abstract Boolean evaluate(int order);

    @Override
    public FieldValue evaluate(List<FieldValue> values) {
      checkArguments(values, 2);

      FieldValue left = values.get(0);
      FieldValue right = values.get(1);

      Boolean result = evaluate((left).compareToValue(right));

      return FieldValueUtil.create(result);
    }
  }

  static {
    putFunction(
        "lessThan",
        new ComparisonFunction() {

          @Override
          public Boolean evaluate(int order) {
            return Boolean.valueOf(order < 0);
          }
        });

    putFunction(
        "lessOrEqual",
        new ComparisonFunction() {

          @Override
          public Boolean evaluate(int order) {
            return Boolean.valueOf(order <= 0);
          }
        });

    putFunction(
        "greaterThan",
        new ComparisonFunction() {

          @Override
          public Boolean evaluate(int order) {
            return Boolean.valueOf(order > 0);
          }
        });

    putFunction(
        "greaterOrEqual",
        new ComparisonFunction() {

          @Override
          public Boolean evaluate(int order) {
            return Boolean.valueOf(order >= 0);
          }
        });
  }

  public abstract static class BinaryBooleanFunction implements Function {

    public abstract Boolean evaluate(Boolean left, Boolean right);

    @Override
    public FieldValue evaluate(List<FieldValue> values) {
      checkVariableArguments(values, 2);

      Boolean result = (values.get(0)).asBoolean();

      for (int i = 1; i < values.size(); i++) {
        result = evaluate(result, (values.get(i)).asBoolean());
      }

      return FieldValueUtil.create(result);
    }
  }

  static {
    putFunction(
        "and",
        new BinaryBooleanFunction() {

          @Override
          public Boolean evaluate(Boolean left, Boolean right) {
            return Boolean.valueOf(left.booleanValue() & right.booleanValue());
          }
        });

    putFunction(
        "or",
        new BinaryBooleanFunction() {

          @Override
          public Boolean evaluate(Boolean left, Boolean right) {
            return Boolean.valueOf(left.booleanValue() | right.booleanValue());
          }
        });
  }

  public abstract static class UnaryBooleanFunction implements Function {

    public abstract Boolean evaluate(Boolean value);

    @Override
    public FieldValue evaluate(List<FieldValue> values) {
      checkArguments(values, 1);

      FieldValue value = values.get(0);

      Boolean result = evaluate(value.asBoolean());

      return FieldValueUtil.create(result);
    }
  }

  static {
    putFunction(
        "not",
        new UnaryBooleanFunction() {

          @Override
          public Boolean evaluate(Boolean value) {
            return Boolean.valueOf(!value.booleanValue());
          }
        });
  }

  public abstract static class ValueListFunction implements Function {

    public abstract Boolean evaluate(FieldValue value, List<FieldValue> values);

    @Override
    public FieldValue evaluate(List<FieldValue> values) {
      checkVariableArguments(values, 2);

      Boolean result = evaluate(values.get(0), values.subList(1, values.size()));

      return FieldValueUtil.create(result);
    }
  }

  static {
    putFunction(
        "isIn",
        new ValueListFunction() {

          @Override
          public Boolean evaluate(FieldValue value, List<FieldValue> values) {
            return value.equalsAnyValue(values);
          }
        });

    putFunction(
        "isNotIn",
        new ValueListFunction() {

          @Override
          public Boolean evaluate(FieldValue value, List<FieldValue> values) {
            return !value.equalsAnyValue(values);
          }
        });
  }

  static {
    putFunction(
        "if",
        new Function() {

          @Override
          public FieldValue evaluate(List<FieldValue> values) {

            if ((values.size() < 2 || values.size() > 3)) {
              throw new EvaluationException();
            }

            FieldValue flag = values.get(0);
            if (flag == null) {
              throw new EvaluationException();
            } // End if

            if (flag.asBoolean()) {
              FieldValue trueValue = values.get(1);

              // "The THEN part is required"
              if (trueValue == null) {
                throw new EvaluationException();
              }

              return trueValue;
            } else {
              FieldValue falseValue = (values.size() > 2 ? values.get(2) : null);

              // "The ELSE part is optional. If the ELSE part is absent then a missing value is
              // returned"
              if (falseValue == null) {
                return null;
              }

              return falseValue;
            }
          }
        });
  }

  public abstract static class StringFunction implements Function {

    public abstract String evaluate(String value);

    @Override
    public FieldValue evaluate(List<FieldValue> values) {
      checkArguments(values, 1);

      FieldValue value = values.get(0);

      String result = evaluate(value.asString());

      return FieldValueUtil.create(result);
    }
  }

  static {
    putFunction(
        "uppercase",
        new StringFunction() {

          @Override
          public String evaluate(String value) {
            return value.toUpperCase();
          }
        });

    putFunction(
        "lowercase",
        new StringFunction() {

          @Override
          public String evaluate(String value) {
            return value.toLowerCase();
          }
        });

    putFunction(
        "substring",
        new Function() {

          @Override
          public FieldValue evaluate(List<FieldValue> values) {
            checkArguments(values, 3);

            String string = (values.get(0)).asString();

            int position = (values.get(1)).asInteger();
            int length = (values.get(2)).asInteger();

            // "The first character of a string is located at position 1 (not position 0)"
            if (position <= 0 || length < 0) {
              throw new EvaluationException();
            }

            String result = string.substring(position - 1, (position + length) - 1);

            return FieldValueUtil.create(result);
          }
        });

    putFunction(
        "trimBlanks",
        new StringFunction() {

          @Override
          public String evaluate(String value) {
            return value.trim();
          }
        });
  }

  static {
    putFunction(
        "formatNumber",
        new Function() {

          @Override
          public FieldValue evaluate(List<FieldValue> values) {
            checkArguments(values, 2);

            FieldValue value = values.get(0);
            FieldValue pattern = values.get(1);

            String result;

            // According to the java.util.Formatter javadoc, Java formatting is more strict than C's
            // printf formatting.
            // For example, in Java, if a conversion is incompatible with a flag, an exception will
            // be thrown. In C's printf, inapplicable flags are silently ignored.
            try {
              result = String.format(pattern.asString(), value.asNumber());
            } catch (IllegalFormatException ife) {
              throw ife;
            }

            return FieldValueUtil.create(result);
          }
        });

    putFunction(
        "formatDatetime",
        new Function() {

          @Override
          public FieldValue evaluate(List<FieldValue> values) {
            checkArguments(values, 2);

            FieldValue value = values.get(0);
            FieldValue pattern = values.get(1);

            String result;

            try {
              result =
                  String.format(
                      translatePattern(pattern.asString()), (value.asDateTime()).toDate());
            } catch (IllegalFormatException ife) {
              throw ife;
            }

            return FieldValueUtil.create(result);
          }

          private String translatePattern(String pattern) {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < pattern.length(); i++) {
              char c = pattern.charAt(i);

              sb.append(c);

              if (c == '%') {

                // Every %[conversion] has to become %1$t[conversion]
                // Here, "1$" denotes the first argument, and "t" denotes the prefix for date and
                // time conversion characters
                if (i < (pattern.length() - 1) && pattern.charAt(i + 1) != '%') {
                  sb.append("1$t");
                }
              }
            }

            return sb.toString();
          }
        });
  }

  static {
    putFunction(
        "dateDaysSinceYear",
        new Function() {

          @Override
          public FieldValue evaluate(List<FieldValue> values) {
            checkArguments(values, 2);

            LocalDate instant = (values.get(0)).asLocalDate();

            int year = (values.get(1)).asInteger();

            DaysSinceDate period = new DaysSinceDate(year, instant);

            return FieldValueUtil.create(period.intValue());
          }
        });

    putFunction(
        "dateSecondsSinceMidnight",
        new Function() {

          @Override
          public FieldValue evaluate(List<FieldValue> values) {
            checkArguments(values, 1);

            LocalTime instant = (values.get(0)).asLocalTime();

            Seconds seconds =
                Seconds.seconds(
                    instant.getHourOfDay() * 60 * 60
                        + instant.getMinuteOfHour() * 60
                        + instant.getSecondOfMinute());

            SecondsSinceMidnight period = new SecondsSinceMidnight(seconds);

            return FieldValueUtil.create(period.intValue());
          }
        });

    putFunction(
        "dateSecondsSinceYear",
        new Function() {

          @Override
          public FieldValue evaluate(List<FieldValue> values) {
            checkArguments(values, 2);

            LocalDateTime instant = (values.get(0)).asLocalDateTime();

            int year = (values.get(1)).asInteger();

            SecondsSinceDate period = new SecondsSinceDate(year, instant);

            return FieldValueUtil.create(period.intValue());
          }
        });
  }
}
Beispiel #26
0
 /** For JSON and XML serialization only. */
 @JsonProperty("attributes")
 @SuppressWarnings("unused")
 private Map<String, Object> getOtherAttributes() {
   final Map<String, Object> otherAttributes = Maps.newHashMap(attributesView);
   return otherAttributes.isEmpty() ? null : otherAttributes;
 }