1 package ixa.kaflib;
2
3 import java.io.Serializable;
4 import java.util.*;
5
6
7
8 public class Dep implements Serializable {
9
10
11 private Term from;
12
13
14 private Term to;
15
16
17 private String rfunc;
18
19
20 private String depcase;
21
22 Dep(Term from, Term to, String rfunc) {
23 this.from = from;
24 this.to = to;
25 this.rfunc = rfunc;
26 }
27
28 Dep(Dep dep, HashMap<String, Term> terms) {
29 this.from = terms.get(dep.from.getId());
30 if (this.from == null) {
31 throw new IllegalStateException("Couldn't find the term when loading dep (" + dep.getFrom().getId()+", "+dep.getTo().getId()+")");
32 }
33 this.to = terms.get(dep.to.getId());
34 if (this.to == null) {
35 throw new IllegalStateException("Couldn't find the term when loading dep (" + dep.getFrom().getId()+", "+dep.getTo().getId()+")");
36 }
37 this.rfunc = dep.rfunc;
38 this.depcase = dep.depcase;
39 }
40
41 public Term getFrom() {
42 return this.from;
43 }
44
45 public void setFrom(Term term) {
46 this.from = term;
47 }
48
49 public Term getTo() {
50 return to;
51 }
52
53 public void setTo(Term term) {
54 this.to = term;
55 }
56
57 public String getRfunc() {
58 return rfunc;
59 }
60
61 public void setRfunc(String rfunc) {
62 this.rfunc = rfunc;
63 }
64
65 public boolean hasCase() {
66 return depcase != null;
67 }
68
69 public String getCase() {
70 return depcase;
71 }
72
73 public void setCase(String depcase) {
74 this.depcase = depcase;
75 }
76
77 public String getStr() {
78 String idFrom = this.getFrom().getId().replaceAll("[^0-9]", "");
79 String idTo = this.getTo().getId().replaceAll("[^0-9]", "");
80 return String.format("%s(%s-%s, %s-%s)", rfunc, this.getFrom().getStr(), idFrom, this.getTo().getStr(), idTo);
81 }
82
83 @Override
84 public String toString() {
85 return getStr();
86 }
87
88 public static final class Path {
89
90 private final List<Dep> deps;
91
92 private final List<Term> terms;
93
94 private String label;
95
96 private Path(final List<Dep> deps, final List<Term> terms) {
97 this.deps = deps;
98 this.terms = terms;
99 }
100
101 public static Path create(final Term from, final Term to, final Iterable<Dep> deps) {
102
103 Term term = from;
104 List<Dep> depList = new ArrayList<>();
105 final List<Term> termList = new ArrayList<>();
106 termList.add(term);
107 for (final Dep dep : deps) {
108 depList.add(dep);
109 term = dep.getTo() == term ? dep.getFrom() : dep.getTo();
110 if (!termList.add(term)) {
111 throw new IllegalArgumentException("Path contains loop");
112 }
113 }
114 if (!term.equals(to)) {
115 throw new IllegalArgumentException("Invalid path");
116 }
117
118 return new Path(depList, termList);
119 }
120
121 public static Path create(final Term from, final Term to, final KAFDocument document) {
122
123
124 if (from == to) {
125 return create(from, to, Collections.<Dep>emptyList());
126 }
127
128
129 final List<Dep> toPath = new ArrayList<Dep>();
130 for (Dep dep = document.getDepToTerm(to); dep != null; dep = document.getDepToTerm(dep
131 .getFrom())) {
132 toPath.add(dep);
133 if (dep.getFrom() == from) {
134 Collections.reverse(toPath);
135 return create(from, to, toPath);
136 }
137 }
138
139
140 final List<Dep> fromPath = new ArrayList<Dep>();
141 for (Dep dep = document.getDepToTerm(from); dep != null; dep = document
142 .getDepToTerm(dep.getFrom())) {
143 fromPath.add(dep);
144 if (dep.getFrom() == to) {
145 return create(from, to, fromPath);
146 }
147 for (int i = 0; i < toPath.size(); ++i) {
148 if (dep.getFrom() == toPath.get(i).getFrom()) {
149 for (int j = i; j >= 0; --j) {
150 fromPath.add(toPath.get(j));
151 }
152 return create(from, to, fromPath);
153 }
154 }
155 }
156
157
158 return null;
159 }
160
161 public Term getFrom() {
162 return this.terms.get(0);
163 }
164
165 public Term getTo() {
166 return this.terms.get(this.terms.size() - 1);
167 }
168
169 public List<Dep> getDeps() {
170 return this.deps;
171 }
172
173 public List<Term> getTerms() {
174 return this.terms;
175 }
176
177 public String getLabel() {
178 if (this.label == null) {
179 final StringBuilder builder = new StringBuilder();
180 Term term = this.terms.get(0);
181 for (final Dep dep : this.deps) {
182 builder.append(dep.getRfunc().toLowerCase());
183 if (term.equals(dep.getFrom())) {
184 builder.append('D');
185 term = dep.getTo();
186 } else {
187 builder.append('U');
188 term = dep.getFrom();
189 }
190 }
191 this.label = builder.toString();
192 }
193 return this.label;
194 }
195
196 public int length() {
197 return this.deps.size();
198 }
199
200 public Path concat(final Path path) {
201 if (!path.getFrom().equals(getTo())) {
202 throw new IllegalArgumentException();
203 }
204 if (this.deps.isEmpty()) {
205 return path;
206 } else if (path.deps.isEmpty()) {
207 return this;
208 } else {
209 List<Dep> deps = new ArrayList<Dep>();
210 deps.addAll(this.deps);
211 deps.addAll(path.deps);
212 return create(this.terms.get(0), path.terms.get(this.terms.size() - 1), deps);
213 }
214 }
215
216 @Override
217 public boolean equals(final Object object) {
218 if (object == this) {
219 return true;
220 }
221 if (!(object instanceof Path)) {
222 return false;
223 }
224 final Path other = (Path) object;
225 return this.deps.equals(other.deps);
226 }
227
228 @Override
229 public int hashCode() {
230 return Objects.hash(this.deps);
231 }
232
233 @Override
234 public String toString() {
235 return getLabel();
236 }
237
238 }
239
240 }