Skip to content

Commit dae6911

Browse files
committed
Streamline text & sentiment analysis architecture
Includes the following: - Created Service Layer Separation to eliminate fat services and improve maintainability - Added Engines for core logic - Added Classifiers/Calculators as small, focused components - Implemented Managers for IO/caching - Externalized configuration using @ConfigurationProperties to remove hardcoded values - Introduced classpath-based word list resources and added loader support for classpath - Removed explicit H2 dialect (auto-detected by Spring Boot) - Centralized constants used throughout the application
1 parent 00005aa commit dae6911

32 files changed

Lines changed: 1773 additions & 494 deletions
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.kapil.verbametrics.config;
2+
3+
import lombok.Data;
4+
import org.springframework.boot.context.properties.ConfigurationProperties;
5+
import org.springframework.context.annotation.Configuration;
6+
7+
/**
8+
* Configuration properties for readability analysis.
9+
* Contains coefficients for Flesch-Kincaid and Flesch Reading Ease for reading and complexity levels.
10+
*
11+
* @author Kapil Garg
12+
*/
13+
@Data
14+
@Configuration
15+
@ConfigurationProperties(prefix = "readability.analysis")
16+
public class ReadabilityAnalysisProperties {
17+
18+
/**
19+
* Reading level thresholds
20+
*/
21+
private ReadingLevels readingLevels = new ReadingLevels();
22+
23+
/**
24+
* Flesch-Kincaid formula coefficients
25+
*/
26+
private FleschKincaid fleschKincaid = new FleschKincaid();
27+
28+
/**
29+
* Complexity level thresholds
30+
*/
31+
private ComplexityLevels complexityLevels = new ComplexityLevels();
32+
33+
/**
34+
* Flesch Reading Ease formula coefficients
35+
*/
36+
private FleschReadingEase fleschReadingEase = new FleschReadingEase();
37+
38+
@Data
39+
public static class ReadingLevels {
40+
private double elementary = 6.0;
41+
private double middleSchool = 9.0;
42+
private double highSchool = 12.0;
43+
private double college = 16.0;
44+
}
45+
46+
@Data
47+
public static class FleschKincaid {
48+
private double sentenceLengthMultiplier = 0.39;
49+
private double syllablesPerWordMultiplier = 11.8;
50+
private double constant = -15.59;
51+
}
52+
53+
@Data
54+
public static class ComplexityLevels {
55+
private double veryEasy = 80.0;
56+
private double easy = 60.0;
57+
private double moderate = 40.0;
58+
private double difficult = 20.0;
59+
}
60+
61+
@Data
62+
public static class FleschReadingEase {
63+
private double constant = 206.835;
64+
private double sentenceLengthMultiplier = 1.015;
65+
private double syllablesPerWordMultiplier = 84.6;
66+
}
67+
68+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.kapil.verbametrics.config;
2+
3+
import lombok.Data;
4+
import org.springframework.boot.context.properties.ConfigurationProperties;
5+
import org.springframework.context.annotation.Configuration;
6+
7+
import java.util.List;
8+
9+
/**
10+
* Configuration properties for sentiment analysis.
11+
* Contains thresholds for sentiment classification, confidence levels, text processing options, and word lists.
12+
*
13+
* @author Kapil Garg
14+
*/
15+
@Data
16+
@Configuration
17+
@ConfigurationProperties(prefix = "sentiment.analysis")
18+
public class SentimentAnalysisProperties {
19+
20+
/**
21+
* Word list configuration
22+
*/
23+
private WordLists wordLists = new WordLists();
24+
25+
/**
26+
* Sentiment thresholds for classification
27+
*/
28+
private Thresholds thresholds = new Thresholds();
29+
30+
/**
31+
* Text processing configuration
32+
*/
33+
private TextProcessing textProcessing = new TextProcessing();
34+
35+
/**
36+
* Confidence level thresholds
37+
*/
38+
private ConfidenceLevels confidenceLevels = new ConfidenceLevels();
39+
40+
@Data
41+
public static class WordLists {
42+
private String positiveWordsPath;
43+
private String negativeWordsPath;
44+
private List<String> positiveWords = List.of();
45+
private List<String> negativeWords = List.of();
46+
}
47+
48+
@Data
49+
public static class Thresholds {
50+
private double positive = 0.1;
51+
private double negative = -0.1;
52+
}
53+
54+
@Data
55+
public static class TextProcessing {
56+
private String wordSeparator = "\\W+";
57+
private boolean caseSensitive = false;
58+
private boolean removePunctuation = true;
59+
}
60+
61+
@Data
62+
public static class ConfidenceLevels {
63+
private double high = 0.8;
64+
private double medium = 0.6;
65+
}
66+
67+
}

src/main/java/com/kapil/verbametrics/config/SentimentWordProperties.java

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/main/java/com/kapil/verbametrics/constants/SentimentConstants.java

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/main/java/com/kapil/verbametrics/constants/TextAnalysisConstants.java

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/main/java/com/kapil/verbametrics/domain/BasicTextStatistics.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,24 @@ public record BasicTextStatistics(
2929
*/
3030
private static void validateInputs(int wordCount, int sentenceCount, int characterCount,
3131
int characterCountNoSpaces, int paragraphCount) {
32-
if (wordCount < 0) throw new IllegalArgumentException("Word count cannot be negative");
33-
if (sentenceCount < 0) throw new IllegalArgumentException("Sentence count cannot be negative");
34-
if (characterCount < 0) throw new IllegalArgumentException("Character count cannot be negative");
35-
if (characterCountNoSpaces < 0)
32+
if (wordCount < 0) {
33+
throw new IllegalArgumentException("Word count cannot be negative");
34+
}
35+
if (sentenceCount < 0) {
36+
throw new IllegalArgumentException("Sentence count cannot be negative");
37+
}
38+
if (characterCount < 0) {
39+
throw new IllegalArgumentException("Character count cannot be negative");
40+
}
41+
if (characterCountNoSpaces < 0) {
3642
throw new IllegalArgumentException("Character count without spaces cannot be negative");
37-
if (paragraphCount < 0) throw new IllegalArgumentException("Paragraph count cannot be negative");
38-
if (characterCountNoSpaces > characterCount)
43+
}
44+
if (paragraphCount < 0) {
45+
throw new IllegalArgumentException("Paragraph count cannot be negative");
46+
}
47+
if (characterCountNoSpaces > characterCount) {
3948
throw new IllegalArgumentException("Character count without spaces cannot exceed total character count");
49+
}
4050
}
4151

4252
@Override

src/main/java/com/kapil/verbametrics/domain/ReadabilityMetrics.java

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -43,62 +43,6 @@ private static void validateInputs(double fleschKincaidScore, double fleschReadi
4343
}
4444
}
4545

46-
/**
47-
* Determines the reading level description based on Flesch-Kincaid score.
48-
*
49-
* @return the reading level description
50-
*/
51-
public String getReadingLevelDescription() {
52-
if (fleschKincaidScore <= 6) {
53-
return "Elementary";
54-
} else if (fleschKincaidScore <= 9) {
55-
return "Middle School";
56-
} else if (fleschKincaidScore <= 12) {
57-
return "High School";
58-
} else if (fleschKincaidScore <= 16) {
59-
return "College";
60-
} else {
61-
return "Graduate";
62-
}
63-
}
64-
65-
/**
66-
* Determines the complexity level based on Flesch Reading Ease score.
67-
*
68-
* @return the complexity level
69-
*/
70-
public String getComplexityLevel() {
71-
if (fleschReadingEase >= 80) {
72-
return "Very Easy";
73-
} else if (fleschReadingEase >= 60) {
74-
return "Easy";
75-
} else if (fleschReadingEase >= 40) {
76-
return "Moderate";
77-
} else if (fleschReadingEase >= 20) {
78-
return "Difficult";
79-
} else {
80-
return "Very Difficult";
81-
}
82-
}
83-
84-
/**
85-
* Checks if the text is easy to read.
86-
*
87-
* @return true if the text is easy to read
88-
*/
89-
public boolean isEasyToRead() {
90-
return fleschReadingEase >= 60;
91-
}
92-
93-
/**
94-
* Checks if the text is difficult to read.
95-
*
96-
* @return true if the text is difficult to read
97-
*/
98-
public boolean isDifficultToRead() {
99-
return fleschReadingEase < 40;
100-
}
101-
10246
@Override
10347
public String toString() {
10448
return """
Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.kapil.verbametrics.domain;
22

3-
import com.kapil.verbametrics.constants.SentimentConstants;
3+
import com.kapil.verbametrics.util.VerbaMetricsConstants;
44

55
/**
66
* Domain record representing sentiment analysis results.
@@ -12,11 +12,11 @@ public record SentimentScore(
1212
double confidence,
1313
double score
1414
) {
15-
15+
1616
public SentimentScore {
1717
validateInputs(label, confidence, score);
1818
}
19-
19+
2020
/**
2121
* Validates the input parameters to ensure they are valid.
2222
*
@@ -36,49 +36,40 @@ private static void validateInputs(String label, double confidence, double score
3636
throw new IllegalArgumentException("Score must be between -1.0 and 1.0");
3737
}
3838
}
39-
39+
4040
/**
4141
* Determines the confidence level based on the confidence value.
4242
*
4343
* @return the confidence level as a string
4444
*/
4545
public String getConfidenceLevel() {
46-
if (confidence >= SentimentConstants.HIGH_CONFIDENCE) {
47-
return "HIGH";
48-
} else if (confidence >= SentimentConstants.MEDIUM_CONFIDENCE) {
49-
return "MEDIUM";
46+
if (confidence >= VerbaMetricsConstants.HIGH_CONFIDENCE) {
47+
return VerbaMetricsConstants.K_HIGH;
48+
} else if (confidence >= VerbaMetricsConstants.MEDIUM_CONFIDENCE) {
49+
return VerbaMetricsConstants.K_MEDIUM;
5050
} else {
51-
return "LOW";
51+
return VerbaMetricsConstants.K_LOW;
5252
}
5353
}
54-
54+
5555
/**
5656
* Checks if the sentiment is positive.
5757
*
5858
* @return true if the sentiment is positive
5959
*/
6060
public boolean isPositive() {
61-
return SentimentConstants.POSITIVE.equals(label);
61+
return VerbaMetricsConstants.POSITIVE.equals(label);
6262
}
63-
63+
6464
/**
6565
* Checks if the sentiment is negative.
6666
*
6767
* @return true if the sentiment is negative
6868
*/
6969
public boolean isNegative() {
70-
return SentimentConstants.NEGATIVE.equals(label);
70+
return VerbaMetricsConstants.NEGATIVE.equals(label);
7171
}
72-
73-
/**
74-
* Checks if the sentiment is neutral.
75-
*
76-
* @return true if the sentiment is neutral
77-
*/
78-
public boolean isNeutral() {
79-
return SentimentConstants.NEUTRAL.equals(label);
80-
}
81-
72+
8273
@Override
8374
public String toString() {
8475
return """
@@ -89,5 +80,5 @@ public String toString() {
8980
label, confidence, score, getConfidenceLevel()
9081
);
9182
}
92-
83+
9384
}

0 commit comments

Comments
 (0)