package fr.devoxx.sentimental.domain; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import fr.devoxx.sentimental.annotation.DomainService; /** * Sentiment Analysis is about extracting the sentiment (mood) from a given * sentence. */ @DomainService public class SentimentAnalysis { private final Lexicon lexicon; private final Trend audit; public SentimentAnalysis(Lexicon lexicon, Trend audit) { this.lexicon = lexicon; this.audit = audit; } public SentimentAnalysis(Map<String, Sentiment> dictionary, Trend audit) { this(new InMemoryLexicon(dictionary), audit); } public SentimentAnalysis(Map<String, Sentiment> dictionary) { this(new InMemoryLexicon(dictionary), null); } public Sentiment sentimentOf(String sentence) { final Sentiment sentiment = analyze(sentence); if (audit != null) { audit.record(sentence, sentiment); } return sentiment; } private Sentiment analyze(String sentence) { final String[] words = sentence.toLowerCase().split(" "); int negationCount = 0; final List<Sentiment> sentiments = new ArrayList<Sentiment>(); for (String word : words) { if (word.equals("no") || word.equals("not")) { negationCount++; } final Sentiment sentiment = lexicon.get(word); if (sentiment != null) { sentiments.add(sentiment); } } if (sentiments.isEmpty()) { return Sentiment.NEUTRAL; } Collections.sort(sentiments); final Sentiment sentiment = mostOptimistic(sentiments); return isNegation(negationCount) ? sentiment.opposite() : sentiment; } protected boolean isNegation(int negationCount) { return negationCount % 2 != 0; } private Sentiment mostOptimistic(final List<Sentiment> sentiments) { return sentiments.get(sentiments.size() - 1); } }