aboutsummaryrefslogtreecommitdiffstats
path: root/documentapi/src/main/java/com/yahoo/documentapi/messagebus/systemstate/rule/Location.java
blob: 4ca6fb038215e5146abdd2b5b7cb8fa2b4b9beb7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.documentapi.messagebus.systemstate.rule;

import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;

/**
 * @author Simon Thoresen Hult
 */
public class Location {

    private List<String> items = new ArrayList<String>();

    /**
     * Constructs a new location with no items.
     */
    public Location() {
        // empty
    }

    /**
     * Constructs a new location based on a location string.
     *
     * @param loc The location string to parse.
     */
    public Location(String loc) {
        items.addAll(Arrays.asList(loc.split("/")));
        normalize();
    }

    /**
     * Constructs a new location based on a list of items.
     *
     * @param items The components that make up this location.
     */
    public Location(List<String> items) {
        this.items.addAll(items);
        normalize();
    }

    /**
     * Constructs a new location as a copy of another.
     *
     * @param loc The location to copy.
     */
    public Location(Location loc) {
        items.addAll(loc.items);
    }

    /**
     * Constructs a new location based on a working directory and a list of items.
     *
     * @param pwd The path of the working directory.
     * @param items The components that make up this location.
     */
    public Location(Location pwd, List<String> items) {
        this.items.addAll(pwd.getItems());
        this.items.addAll(items);
        normalize();
    }

    /**
     * Returns a location object that represents the "next" step along this location path. This means removing the first
     * elements of this location's items and returning a new location for this sublist.
     *
     * @return The next location along this path.
     */
    public Location getNext() {
        List<String> next = new ArrayList<String>(items);
        next.remove(0);
        return new Location(next);
    }

    /**
     * Returns the components of this location.
     *
     * @return The component array.
     */
    public List<String> getItems() {
        return items;
    }

    /**
     * Normalizes the items list of this location so that all PREV or THIS locations are replaced by their actual
     * meaning. This carries some overhead since it is not done in place.
     *
     * @return This, to allow chaining.
     */
    private Location normalize() {
        List<String> norm = new ArrayList<String>();
        for (String item : items) {
            if (item.equals(NodeState.NODE_PARENT)) {
                if (norm.size() == 0) {
                    // ignore
                }
                else {
                    norm.remove(norm.size() - 1);
                }
            }
            else if (!item.equals(NodeState.NODE_CURRENT)) {
                norm.add(item);
            }
        }
        items = norm;
        return this;
    }

    @Override
    public String toString() {
        StringBuffer ret = new StringBuffer();
        for (int i = 0; i < items.size(); ++i) {
            ret.append(items.get(i));
            if (i < items.size() - 1) {
                ret.append("/");
            }
        }
        return ret.toString();
    }
}