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 package org.apache.hc.core5.http.config;
29
30 import org.apache.hc.core5.util.Args;
31
32
33
34
35
36
37
38
39 public class NamedElementChain<E> {
40
41 private final Node master;
42 private int size;
43
44 public NamedElementChain() {
45 this.master = new Node("master", null);
46 this.master.previous = this.master;
47 this.master.next = this.master;
48 this.size = 0;
49 }
50
51 public Node getFirst() {
52 return master.next != master ? master.next : null;
53 }
54
55 public Node getLast() {
56 return master.previous != master ? master.previous : null;
57 }
58
59 public Node addFirst(final E value, final String name) {
60 Args.notBlank(name, "Name");
61 Args.notNull(value, "Value");
62 final Node newNode = new Node(name, value);
63 final Node oldNode = master.next;
64 master.next = newNode;
65 newNode.previous = master;
66 newNode.next = oldNode;
67 oldNode.previous = newNode;
68 size++;
69 return newNode;
70 }
71
72 public Node addLast(final E value, final String name) {
73 Args.notBlank(name, "Name");
74 Args.notNull(value, "Value");
75 final Node newNode = new Node(name, value);
76 final Node oldNode = master.previous;
77 master.previous = newNode;
78 newNode.previous = oldNode;
79 newNode.next = master;
80 oldNode.next = newNode;
81 size++;
82 return newNode;
83 }
84
85 public Node find(final String name) {
86 Args.notBlank(name, "Name");
87 return doFind(name);
88 }
89
90 private Node doFind(final String name) {
91 Node current = master.next;
92 while (current != master) {
93 if (name.equals(current.name)) {
94 return current;
95 }
96 current = current.next;
97 }
98 return null;
99 }
100
101 public Node addBefore(final String existing, final E value, final String name) {
102 Args.notBlank(name, "Name");
103 Args.notNull(value, "Value");
104 final Node current = doFind(existing);
105 if (current == null) {
106 return null;
107 }
108 final Node newNode = new Node(name, value);
109 final Node previousNode = current.previous;
110 previousNode.next = newNode;
111 newNode.previous = previousNode;
112 newNode.next = current;
113 current.previous = newNode;
114 size++;
115 return newNode;
116 }
117
118 public Node addAfter(final String existing, final E value, final String name) {
119 Args.notBlank(name, "Name");
120 Args.notNull(value, "Value");
121 final Node current = doFind(existing);
122 if (current == null) {
123 return null;
124 }
125 final Node newNode = new Node(name, value);
126 final Node nextNode = current.next;
127 current.next = newNode;
128 newNode.previous = current;
129 newNode.next = nextNode;
130 nextNode.previous = newNode;
131 size++;
132 return newNode;
133 }
134
135 public boolean remove(final String name) {
136 final Node node = doFind(name);
137 if (node == null) {
138 return false;
139 }
140 node.previous.next = node.next;
141 node.next.previous = node.previous;
142 node.previous = null;
143 node.next = null;
144 size--;
145 return true;
146 }
147
148 public boolean replace(final String existing, final E value) {
149 final Node node = doFind(existing);
150 if (node == null) {
151 return false;
152 }
153 node.value = value;
154 return true;
155 }
156
157 public int getSize() {
158 return size;
159 }
160
161 public class Node {
162
163 private final String name;
164 private E value;
165 private Node previous;
166 private Node next;
167
168 Node(final String name, final E value) {
169 this.name = name;
170 this.value = value;
171 }
172
173 public String getName() {
174 return name;
175 }
176
177 public E getValue() {
178 return value;
179 }
180
181 public Node getPrevious() {
182 return previous != master ? previous : null;
183 }
184
185 public Node getNext() {
186 return next != master ? next: null;
187 }
188
189 @Override
190 public String toString() {
191 return name + ": " + value;
192 }
193
194 }
195
196 }