2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.so.client.graphinventory.entities;
 
  23 import java.lang.reflect.Field;
 
  24 import java.util.ArrayList;
 
  25 import java.util.Arrays;
 
  26 import java.util.List;
 
  27 import java.util.stream.Collectors;
 
  28 import org.onap.so.client.aai.entities.QueryStep;
 
  29 import org.onap.so.client.graphinventory.GraphInventoryObjectName;
 
  30 import com.google.common.base.Joiner;
 
  32 public class DSLQueryBuilder<S, E> {
 
  34     private List<QueryStep> steps = new ArrayList<>();
 
  35     private String suffix = "";
 
  37     protected DSLQueryBuilder() {
 
  41     protected DSLQueryBuilder(QueryStep node) {
 
  45     public <T> DSLQueryBuilder<S, DSLNodeBase<?>> node(DSLNodeBase<?> node) {
 
  48         return (DSLQueryBuilder<S, DSLNodeBase<?>>) this;
 
  51     public DSLQueryBuilder<S, Node> output() {
 
  52         Object obj = steps.get(steps.size() - 1);
 
  53         if (obj instanceof DSLNodeBase) {
 
  54             ((DSLNodeBase) steps.get(steps.size() - 1)).output();
 
  55         } else if (obj.getClass().getName().contains("$$Lambda$")) {
 
  56             // process lambda expressions
 
  57             for (Field f : obj.getClass().getDeclaredFields()) {
 
  58                 f.setAccessible(true);
 
  62                     if (o instanceof DSLQueryBuilder && ((DSLQueryBuilder) o).steps.get(0) instanceof DSLNodeBase) {
 
  63                         ((DSLNodeBase) ((DSLQueryBuilder) o).steps.get(0)).output();
 
  65                 } catch (IllegalArgumentException | IllegalAccessException e) {
 
  67                 f.setAccessible(false);
 
  71         return (DSLQueryBuilder<S, Node>) this;
 
  75     public final <E2> DSLQueryBuilder<S, E2> union(final DSLQueryBuilder<?, E2>... union) {
 
  77         List<DSLQueryBuilder<?, ?>> unions = Arrays.asList(union);
 
  79             StringBuilder query = new StringBuilder();
 
  82                     .append(Joiner.on(", ")
 
  83                             .join(unions.stream().map(item -> item.compile()).collect(Collectors.toList())))
 
  85             return query.toString();
 
  88         return (DSLQueryBuilder<S, E2>) this;
 
  91     public DSLQueryBuilder<S, E> where(DSLQueryBuilder<?, ?> where) {
 
  94             StringBuilder query = new StringBuilder();
 
  95             query.append(where.compile()).append(")");
 
  96             String result = query.toString();
 
  97             if (!result.startsWith(">")) {
 
  98                 result = "> " + result;
 
 105     public <E2> DSLQueryBuilder<S, E2> to(DSLQueryBuilder<?, E2> to) {
 
 107             StringBuilder query = new StringBuilder();
 
 109             query.append("> ").append(to.compile());
 
 110             return query.toString();
 
 112         return (DSLQueryBuilder<S, E2>) this;
 
 115     public DSLQueryBuilder<S, E> to(GraphInventoryObjectName name) {
 
 116         return (DSLQueryBuilder<S, E>) to(__.node(name));
 
 119     public DSLQueryBuilder<S, E> to(GraphInventoryObjectName name, DSLNodeKey... key) {
 
 120         return (DSLQueryBuilder<S, E>) to(__.node(name, key));
 
 123     public DSLQueryBuilder<S, E> limit(int limit) {
 
 124         suffix = " LIMIT " + limit;
 
 128     public DSLTraversal<E> build() {
 
 129         return new DSLTraversal<>(compile());
 
 133     public String toString() {
 
 134         return build().get();
 
 138     public boolean equals(Object o) {
 
 140             return o.toString().equals(toString());
 
 146     public int hashCode() {
 
 148         return compile().hashCode();
 
 151     private String compile() {
 
 152         return String.join(" ", steps.stream().map(item -> item.build()).collect(Collectors.toList())) + suffix;
 
 155     protected QueryStep getFirst() {