1   package ixa.kaflib;
2   
3   import java.io.Serializable;
4   import java.util.ArrayList;
5   import java.util.HashMap;
6   import java.util.List;
7   
8   
9   /** Class for representing features. There are two types of features: properties and categories. */
10  public class Feature implements Relational, Serializable {
11  
12      /* Feature's ID (required) */
13      private String id;
14  
15      /* Lemma (required) */
16      private String lemma;
17  
18      private List<Span<Term>> references;
19  
20      private List<ExternalRef> externalReferences;
21  
22      Feature(String id, String lemma, List<Span<Term>> references) {
23  	if (references.size() < 1) {
24  	    throw new IllegalStateException("Features must contain at least one reference span");
25  	}
26  	if (references.get(0).size() < 1) {
27  	    throw new IllegalStateException("Features' reference's spans must contain at least one target");
28  	}
29  	this.id = id;
30  	this.lemma = lemma;
31  	this.references = references;
32  	this.externalReferences = new ArrayList<ExternalRef>();
33      }
34  
35      Feature(Feature feature, HashMap<String, Term> terms) {
36  	this.id = feature.id;
37  	this.lemma = feature.lemma;
38  	/* Copy references */
39  	String id = feature.getId();
40  	this.references = new ArrayList<Span<Term>>();
41  	for (Span<Term> span : feature.getSpans()) {
42  	    /* Copy span */
43  	    List<Term> targets = span.getTargets();
44  	    List<Term> copiedTargets = new ArrayList<Term>();
45  	    for (Term term : targets) {
46  		Term copiedTerm = terms.get(term.getId());
47  		if (copiedTerm == null) {
48  		    throw new IllegalStateException("Term not found when copying " + id);
49  		}
50  		copiedTargets.add(copiedTerm);
51  	    }
52  	    if (span.hasHead()) {
53  		Term copiedHead = terms.get(span.getHead().getId());
54  		this.references.add(new Span<Term>(copiedTargets, copiedHead));
55  	    }
56  	    else {
57  		this.references.add(new Span<Term>(copiedTargets));
58  	    }
59  	}
60  	/* Copy external references */
61  	this.externalReferences = new ArrayList<ExternalRef>();
62  	for (ExternalRef externalRef : feature.getExternalRefs()) {
63  	    this.externalReferences.add(new ExternalRef(externalRef));
64  	}
65      }
66  
67      public boolean isAProperty() {
68  	return this.id.matches("p.*");
69      }
70  
71      public boolean isACategory() {
72  	return this.id.matches("c.*");
73      }
74  
75      public String getId() {
76  	return this.id;
77      }
78  
79      void setId(String id) {
80  	this.id = id;
81      }
82  
83      public String getLemma() {
84  	return this.lemma;
85      }
86  
87      public void setLemma(String lemma) {
88  	this.lemma = lemma;
89      }
90  
91      /** Returns the term targets of the first span. When targets of other spans are needed getReferences() method should be used. */ 
92      public List<Term> getTerms() {
93  	return this.references.get(0).getTargets();
94      }
95  
96      /** Adds a term to the first span. */
97      public void addTerm(Term term) {
98  	this.references.get(0).addTarget(term);
99      }
100 
101     /** Adds a term to the first span. */
102     public void addTerm(Term term, boolean isHead) {
103 	this.references.get(0).addTarget(term, isHead);
104     }
105 
106     public List<Span<Term>> getSpans() {
107 	return this.references;
108     }
109 
110     public void addSpan(Span<Term> span) {
111 	references.add(span);
112     }
113 
114     public List<ExternalRef> getExternalRefs() {
115 	return externalReferences;
116     }
117 
118     public void addExternalRef(ExternalRef externalRef) {
119 	externalReferences.add(externalRef);
120     }
121 
122     public void addExternalRefs(List<ExternalRef> externalRefs) {
123 	externalReferences.addAll(externalRefs);
124     }
125 
126     public String getSpanStr(Span<Term> span) {
127 	String str = "";
128 	for (Term term : span.getTargets()) {
129 	    if (!str.isEmpty()) {
130 		str += " ";
131 	    }
132 	    str += term.getStr();
133 	}
134 	return str;
135     }
136 
137     public String getStr() {
138 	return getSpanStr(this.getSpans().get(0));
139     }
140 
141 
142     /** Deprecated */
143     public List<List<Term>> getReferences() {
144 	List<List<Term>> list = new ArrayList<List<Term>>();
145 	for (Span<Term> span : this.references) {
146 	    list.add(span.getTargets());
147 	}
148 	return list;
149     }
150 
151     /** Deprecated */
152     public void addReference(List<Term> span) {
153 	this.references.add(KAFDocument.<Term>list2Span(span));
154     }
155 }