SentimentAnalysisServiceImpl.java
package com.kapil.verbametrics.services.impl;
import com.kapil.verbametrics.domain.SentimentScore;
import com.kapil.verbametrics.services.SentimentAnalysisService;
import com.kapil.verbametrics.services.classifiers.SentimentLabelClassifier;
import com.kapil.verbametrics.services.engines.SentimentCalculationEngine;
import com.kapil.verbametrics.util.VerbaMetricsConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Implementation of SentimentAnalysisService using calculation engine and label classifier.
* Provides functionality to analyze text and return sentiment scores.
*
* @author Kapil Garg
*/
@Service
public class SentimentAnalysisServiceImpl implements SentimentAnalysisService {
private static final Logger LOGGER = LoggerFactory.getLogger(SentimentAnalysisServiceImpl.class);
private final SentimentCalculationEngine calculationEngine;
private final SentimentLabelClassifier labelClassifier;
@Autowired
public SentimentAnalysisServiceImpl(SentimentCalculationEngine calculationEngine,
SentimentLabelClassifier labelClassifier) {
this.calculationEngine = calculationEngine;
this.labelClassifier = labelClassifier;
}
/**
* Analyzes the sentiment of the given text and returns a SentimentScore with confidence.
*
* @param text the text to analyze
* @return the sentiment score with label and confidence
*/
@Override
public SentimentScore analyzeSentiment(String text) {
return analyzeSentiment(text, true);
}
/**
* Analyzes the sentiment of the given text and returns a SentimentScore.
*
* @param text the text to analyze
* @param includeConfidence whether to include confidence score
* @return the sentiment score with label and confidence
*/
@Override
public SentimentScore analyzeSentiment(String text, boolean includeConfidence) {
if (text == null || text.isBlank()) {
return new SentimentScore(VerbaMetricsConstants.NEUTRAL, includeConfidence ? 1.0 : 0.0, 0.0);
}
LOGGER.debug("Starting sentiment analysis for text of length: {}", text.length());
try {
double score = calculationEngine.calculateSentimentScore(text);
String label = labelClassifier.determineSentimentLabel(score);
double confidence = includeConfidence ? calculateConfidence(text, score) : 1.0;
SentimentScore result = new SentimentScore(label, confidence, score);
LOGGER.debug("Sentiment analysis completed: {}", result);
return result;
} catch (Exception e) {
LOGGER.error("Failed to analyze sentiment", e);
throw new RuntimeException("Failed to analyze sentiment: " + e.getMessage(), e);
}
}
/**
* Calculates confidence score based on sentiment score magnitude and text length.
*
* @param text the input text
* @param score the calculated sentiment score
* @return confidence score between 0.1 and 1.0
*/
private double calculateConfidence(String text, double score) {
int totalWords = Math.max(1, text.split("\\s+").length);
double scoreMagnitude = Math.abs(score);
double sentimentConfidence = Math.min(0.9, 0.1 + (scoreMagnitude * 0.8));
double lengthFactor = Math.min(0.8, 0.3 + (totalWords / 15.0));
double finalConfidence = sentimentConfidence * lengthFactor;
return Math.max(0.1, Math.min(0.95, finalConfidence));
}
}