1 package eu.fbk.dkm.pikes.raid;
2
3 import com.google.common.base.Objects;
4 import com.google.common.collect.ImmutableSet;
5 import com.google.common.collect.Iterables;
6 import com.google.common.collect.Lists;
7 import eu.fbk.dkm.pikes.resources.NAFUtils;
8 import ixa.kaflib.KAFDocument;
9 import ixa.kaflib.Opinion;
10 import ixa.kaflib.Opinion.OpinionExpression;
11 import ixa.kaflib.Opinion.OpinionHolder;
12 import ixa.kaflib.Opinion.OpinionTarget;
13 import ixa.kaflib.Opinion.Polarity;
14 import ixa.kaflib.Span;
15 import ixa.kaflib.Term;
16
17 import javax.annotation.Nullable;
18 import java.util.List;
19 import java.util.Set;
20
21 public final class Opinions {
22
23 public static Set<Term> heads(final KAFDocument document, final Span<Term> span,
24 final Component component) {
25
26 if (span == null || span.isEmpty()) {
27 return ImmutableSet.of();
28 }
29 return NAFUtils.extractHeads(document, null, span.getTargets(),
30 NAFUtils.matchExtendedPos(document, component.getHeadPos()));
31 }
32
33 public static boolean deduplicate(final KAFDocument document, final Iterable<Opinion> opinions) {
34 boolean modified = false;
35 final List<Opinion> seen = Lists.newArrayList();
36 outer: for (final Opinion o : opinions) {
37 for (final Opinion s : seen) {
38 if (Objects.equal(o.getLabel(), s.getLabel())
39 && Objects.equal(o.getPolarity(), s.getPolarity())
40 && sameSpan(o.getExpressionSpan(), s.getExpressionSpan())
41 && sameSpan(o.getHolderSpan(), s.getHolderSpan())
42 && sameSpan(o.getTargetSpan(), s.getTargetSpan())) {
43 document.removeAnnotation(o);
44 modified = true;
45 continue outer;
46 }
47 }
48 seen.add(o);
49 }
50 return modified;
51 }
52
53 private static boolean sameSpan(final Span<Term> span1, final Span<Term> span2) {
54 return span1 == null
55 && span2 == null
56 || span1 != null
57 && span2 != null
58 && ImmutableSet.copyOf(span1.getTargets()).equals(
59 ImmutableSet.copyOf(span2.getTargets()));
60 }
61
62 public static List<Opinion> merge(final KAFDocument document,
63 final Iterable<Opinion> opinions, final Iterable<Component> components) {
64
65 return null;
66 }
67
68 public static List<Opinion> split(final KAFDocument document,
69 final Iterable<Opinion> opinions, final Iterable<Component> components) {
70
71 return null;
72 }
73
74 @Deprecated
75 public static List<Opinion> split(final KAFDocument document,
76 final Iterable<Opinion> inOpinions, @Nullable final String outLabel) {
77
78 final List<Span<Term>> emptySpanList = Lists.newArrayList();
79 emptySpanList.add(null);
80
81 final List<Opinion> outOpinions = Lists.newArrayList();
82 for (final Opinion inOpinion : inOpinions) {
83
84 final OpinionExpression inExp = inOpinion.getOpinionExpression();
85 final OpinionHolder inHolder = inOpinion.getOpinionHolder();
86 final OpinionTarget inTarget = inOpinion.getOpinionTarget();
87
88 final Set<Term> expHeads = heads(document, inOpinion.getExpressionSpan(),
89 Component.EXPRESSION);
90
91 if (!expHeads.isEmpty()) {
92 final List<Span<Term>> expSpans = NAFUtils.splitSpan(document, inExp.getSpan(),
93 expHeads);
94
95 final Set<Term> holderHeads = heads(document, inOpinion.getHolderSpan(),
96 Component.HOLDER);
97 final List<Span<Term>> holderSpans = holderHeads.isEmpty() ? emptySpanList
98 : NAFUtils.splitSpan(document, inHolder.getSpan(), holderHeads);
99
100 final Set<Term> targetHeads = heads(document, inOpinion.getTargetSpan(),
101 Component.TARGET);
102 final List<Span<Term>> targetSpans = targetHeads.isEmpty() ? emptySpanList
103 : NAFUtils.splitSpan(document, inTarget.getSpan(), targetHeads);
104
105 for (final Span<Term> expSpan : expSpans) {
106 for (final Span<Term> holderSpan : holderSpans) {
107 for (final Span<Term> targetSpan : targetSpans) {
108 final Opinion outOpinion = document.newOpinion();
109 outOpinion.setLabel(outLabel);
110 final OpinionExpression outExp = outOpinion
111 .createOpinionExpression(expSpan);
112 outExp.setPolarity(inExp.getPolarity());
113 outExp.setSentimentProductFeature(inExp.getSentimentProductFeature());
114 outExp.setSentimentSemanticType(inExp.getSentimentSemanticType());
115 outExp.setStrength(inExp.getStrength());
116 outExp.setSubjectivity(inExp.getSubjectivity());
117 if (holderSpan != null) {
118 outOpinion.createOpinionHolder(holderSpan).setType(
119 inOpinion.getOpinionHolder().getType());
120 }
121 if (targetSpan != null) {
122 outOpinion.createOpinionTarget(targetSpan).setType(
123 inOpinion.getOpinionTarget().getType());
124 }
125 outOpinions.add(outOpinion);
126 }
127 }
128 }
129 }
130 }
131 return outOpinions;
132 }
133
134 public static void retain(final Iterable<Opinion> opinions,
135 @Nullable final Opinion refOpinion, final Iterable<Component> components) {
136
137 for (final Opinion opinion : opinions) {
138 final OpinionExpression expr = opinion.getOpinionExpression();
139 if (!Iterables.contains(components, Component.POLARITY)) {
140 if (refOpinion == null || refOpinion.getOpinionExpression() == null) {
141 expr.setPolarity(null);
142 expr.setStrength(null);
143 expr.setSentimentProductFeature(null);
144 expr.setSentimentSemanticType(null);
145 expr.setSubjectivity(null);
146 } else {
147 final OpinionExpression refExpr = refOpinion.getOpinionExpression();
148 expr.setPolarity(refExpr.getPolarity());
149 expr.setStrength(refExpr.getStrength());
150 expr.setSentimentProductFeature(refExpr.getSentimentProductFeature());
151 expr.setSentimentSemanticType(refExpr.getSentimentSemanticType());
152 expr.setSubjectivity(refExpr.getSubjectivity());
153 }
154 }
155 if (!Iterables.contains(components, Component.EXPRESSION)) {
156 if (refOpinion == null || refOpinion.getOpinionExpression() == null) {
157 expr.setSpan(KAFDocument.newTermSpan());
158 } else {
159 expr.setSpan(refOpinion.getOpinionExpression().getSpan());
160 }
161 }
162 if (!Iterables.contains(components, Component.HOLDER)) {
163 if (refOpinion == null || refOpinion.getOpinionHolder() == null) {
164 opinion.removeOpinionHolder();
165 } else {
166 opinion.createOpinionHolder(refOpinion.getOpinionHolder().getSpan()).setType(
167 refOpinion.getOpinionHolder().getType());
168 }
169 }
170 if (!Iterables.contains(components, Component.TARGET)) {
171 if (refOpinion == null || refOpinion.getOpinionTarget() == null) {
172 opinion.removeOpinionTarget();
173 } else {
174 opinion.createOpinionTarget(refOpinion.getOpinionTarget().getSpan()).setType(
175 refOpinion.getOpinionTarget().getType());
176 }
177 }
178 }
179 }
180
181 public static List<Opinion> create(final KAFDocument document, final Span<Term> expression,
182 final Iterable<Span<Term>> holders, final Iterable<Span<Term>> targets,
183 final Polarity polarity) {
184
185 final int numHolders = Iterables.size(holders);
186 final int numTargets = Iterables.size(targets);
187
188 final List<Opinion> opinions = Lists.newArrayList();
189 for (final Span<Term> holder : holders) {
190 for (final Span<Term> target : targets) {
191
192
193 if (holder == null && numHolders > 1 || target == null && numTargets > 1) {
194 continue;
195 }
196
197
198 final Opinion opinion = document.createOpinion();
199 final OpinionExpression expr = opinion.createOpinionExpression(expression);
200
201
202 if (polarity == Polarity.NEUTRAL) {
203 expr.setPolarity("neutral");
204 } else if (polarity == Polarity.NEGATIVE) {
205 expr.setPolarity("negative");
206 } else if (polarity == Polarity.POSITIVE) {
207 expr.setPolarity("positive");
208 }
209
210
211 if (holder != null) {
212 opinion.createOpinionHolder(holder);
213 }
214
215
216 if (target != null) {
217 opinion.createOpinionTarget(target);
218 }
219
220
221 opinions.add(opinion);
222 }
223 }
224 return opinions;
225 }
226
227 }