Skip to content

Commit 6d81605

Browse files
committed
ENH: Add ability to edit built-in plugins (Issue #149) - see TestPlugins.pluginsEdit() for an example.
1 parent f4badd8 commit 6d81605

File tree

5 files changed

+74
-46
lines changed

5 files changed

+74
-46
lines changed

ChangeLog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11

22
## Changes ##
33

4+
### 17.1.7
5+
- ENH: Add ability to edit built-in plugins (Issue #149) - see TestPlugins.pluginsEdit() for an example.
6+
47
### 17.1.6
58
- ENH: Add support for registering Custom Plugins either higher than or lower than built-in plugins (Issue #148)
69
- INT: Bump logback-classic to 1.5.20, SpotBugs to 6.4.4

settings.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ includeBuild 'examples/core/speed'
4040
dependencyResolutionManagement {
4141
versionCatalogs {
4242
libs {
43-
version('fta', '17.1.6')
43+
version('fta', '17.1.7')
4444
version('jacoco', '0.8.12')
4545

4646
// https://mvnrepository.com/artifact/de.siegmar/fastcsv

types/src/main/java/com/cobber/fta/PluginDefinition.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import com.cobber.fta.core.FTAType;
3131
import com.cobber.fta.core.HeaderEntry;
3232
import com.cobber.fta.core.InternalErrorException;
33-
3433
import com.fasterxml.jackson.core.type.TypeReference;
3534
import com.fasterxml.jackson.databind.ObjectMapper;
3635

@@ -192,6 +191,9 @@ public PluginDefinition(final PluginDefinition other) {
192191
/**
193192
* Retrieve the Plugin Definition associated with this Semantic Type name.
194193
*
194+
* Note: Unlike the similar function in TextAnalyzer this one accesses the definition file and any edits
195+
* will not impact the current Analyzer.
196+
*
195197
* @param semanticTypeName The name for this Semantic Type
196198
* @return The Plugin Definition associated with the supplied name.
197199
*/

types/src/main/java/com/cobber/fta/TextAnalyzer.java

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@
5353
import org.apache.commons.text.similarity.LevenshteinDistance;
5454
import org.slf4j.LoggerFactory;
5555

56-
import com.cobber.fta.TextAnalyzer.Escalation;
57-
import com.cobber.fta.TextAnalyzer.Observation;
58-
import com.cobber.fta.TextAnalyzer.OutlierAnalysis;
59-
import com.cobber.fta.TextAnalyzer.SignStatus;
6056
import com.cobber.fta.core.FTAMergeException;
6157
import com.cobber.fta.core.FTAPluginException;
6258
import com.cobber.fta.core.FTAType;
@@ -1257,29 +1253,52 @@ public Plugins getPlugins() {
12571253
return plugins;
12581254
}
12591255

1256+
private void loadPlugins() {
1257+
synchronized (pluginDefinitions) {
1258+
if (pluginDefinitions.isEmpty())
1259+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(TextAnalyzer.class.getResourceAsStream("/reference/plugins.json"), StandardCharsets.UTF_8))) {
1260+
pluginDefinitions = mapper.readValue(reader, new TypeReference<List<PluginDefinition>>(){});
1261+
} catch (Exception e) {
1262+
throw new IllegalArgumentException("Internal error: Issues with plugins file: " + e.getMessage(), e);
1263+
}
1264+
}
1265+
}
1266+
12601267
/**
12611268
* Register the default set of plugins for Semantic Type detection.
12621269
*
12631270
* @param analysisConfig The Analysis configuration used for this analysis.
12641271
* Note: The Locale (on the configuration) will impact both the set of plugins registered as well as the behavior of the individual plugins
12651272
*/
12661273
public void registerDefaultPlugins(final AnalysisConfig analysisConfig) {
1267-
synchronized (pluginDefinitions) {
1268-
if (pluginDefinitions.isEmpty()) {
1269-
try (BufferedReader reader = new BufferedReader(new InputStreamReader(TextAnalyzer.class.getResourceAsStream("/reference/plugins.json"), StandardCharsets.UTF_8))) {
1270-
pluginDefinitions = mapper.readValue(reader, new TypeReference<List<PluginDefinition>>(){});
1271-
} catch (Exception e) {
1272-
throw new IllegalArgumentException("Internal error: Issues with plugins file: " + e.getMessage(), e);
1273-
}
1274-
}
1275-
try {
1276-
plugins.registerPluginsInternal(pluginDefinitions, context.getStreamName(), analysisConfig);
1277-
} catch (Exception e) {
1278-
throw new IllegalArgumentException("Internal error: Issues with plugins file: " + e.getMessage(), e);
1279-
}
1274+
loadPlugins();
1275+
1276+
try {
1277+
plugins.registerPluginsInternal(pluginDefinitions, context.getStreamName(), analysisConfig);
1278+
} catch (Exception e) {
1279+
throw new IllegalArgumentException("Internal error: Issues with plugins file: " + e.getMessage(), e);
12801280
}
12811281
}
12821282

1283+
/**
1284+
* Retrieve the Plugin Definition associated with this Semantic Type name.
1285+
*
1286+
* Note: Unlike the similar function in PluginDefinition this one accesses the current instance and any edits
1287+
* will impact the current Analyzer.
1288+
*
1289+
* @param semanticTypeName The name for this Semantic Type
1290+
* @return The Plugin Definition associated with the supplied name.
1291+
*/
1292+
public PluginDefinition findByName(final String semanticTypeName) {
1293+
loadPlugins();
1294+
1295+
for (final PluginDefinition pluginDefinition : pluginDefinitions)
1296+
if (pluginDefinition.semanticType.equalsIgnoreCase(semanticTypeName))
1297+
return pluginDefinition;
1298+
1299+
return null;
1300+
}
1301+
12831302
private void initialize() throws FTAPluginException, FTAUnsupportedLocaleException {
12841303
memoryDebug("initialize.entry");
12851304

types/src/test/java/com/cobber/fta/TestPlugins.java

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.cobber.fta.core.FTAPluginException;
4949
import com.cobber.fta.core.FTAType;
5050
import com.cobber.fta.core.FTAUnsupportedLocaleException;
51+
import com.cobber.fta.core.HeaderEntry;
5152
import com.cobber.fta.dates.DateTimeParser.DateResolutionMode;
5253
import com.cobber.fta.plugins.CheckDigitEAN13;
5354
import com.cobber.fta.plugins.CheckDigitISBN;
@@ -1962,34 +1963,37 @@ public void pluginsPost() throws FTAException {
19621963

19631964
@Test(groups = { TestGroups.ALL, TestGroups.DATETIME })
19641965
public void pluginsEdit() throws FTAException {
1965-
PluginDefinition defn = PluginDefinition.findByName("NAME.FIRST");
1966-
for (PluginLocaleEntry localeEntry : defn.validLocales) {
1967-
System.err.printf("Found - '%s'\n", localeEntry.localeTag);
1968-
if ("en".equals(localeEntry.localeTag))
1969-
System.err.printf("Found - '%s'\n", localeEntry.headerRegExps[0]);
1970-
}
1971-
PluginDefinition newDefn = new PluginDefinition(defn);
1972-
System.err.printf("New - '%s'\n", newDefn.semanticType);
1973-
for (PluginLocaleEntry localeEntry : newDefn.validLocales) {
1974-
System.err.printf("Found - '%s'\n", localeEntry.localeTag);
1975-
if ("en".equals(localeEntry.localeTag)) {
1976-
System.err.printf("Found - '%s'\n", localeEntry.headerRegExps[0].regExp);
1977-
localeEntry.headerRegExps[0].regExp = localeEntry.headerRegExps[0].regExp.replace("fname", "fname|fn");
1978-
System.err.printf("Found - '%s'\n", localeEntry.headerRegExps[0].regExp);
1979-
}
1980-
}
1981-
// for (PluginDefinition defn : pluginDefinitions) {
1982-
// if ("NAME.FIRST".equals(defn.semanticType)) {
1983-
// System.err.printf("Found - '%s'\n", defn.semanticType);
1984-
// for (PluginLocaleEntry localeEntry : defn.validLocales) {
1985-
// System.err.printf("Found - '%s'\n", localeEntry.localeTag);
1986-
// if ("en".equals(localeEntry.localeTag))
1987-
// System.err.printf("Found - '%s'\n", localeEntry.headerRegExps[0]);
1988-
// }
1989-
// }
1990-
// }
1991-
}
1966+
final String inputs[] = {
1967+
"Anna", "Buffalo", "Peter", "David", "Janet", "Mary", "Joe", "Tim", "Jeremy", "Reginald",
1968+
"Roger", "Lois", "Janet", "Polaris", "Sean", "Shawn", "Shaun", "Regina", "Gail", "Max"
1969+
};
1970+
final TextAnalyzer analysisPre = new TextAnalyzer("fn");
1971+
analysisPre.setLocale(Locale.US);
1972+
for (final String input : inputs)
1973+
analysisPre.train(input);
1974+
final TextAnalysisResult resultPre = analysisPre.getResult();
1975+
assertNull(resultPre.getSemanticType());
1976+
1977+
// Edit the FIRST NAME plugin to add our header "fn"
1978+
PluginDefinition defn = analysisPre.findByName("NAME.FIRST");
1979+
for (PluginLocaleEntry localeEntry : defn.validLocales)
1980+
if ("en".equals(localeEntry.localeTag)) {
1981+
final int entries = localeEntry.headerRegExps.length;
1982+
HeaderEntry[] newHeaders = new HeaderEntry[entries + 1];
1983+
for (int i = 0; i < entries; i++)
1984+
newHeaders[i] = new HeaderEntry(localeEntry.headerRegExps[i]);
1985+
newHeaders[entries] = new HeaderEntry("(?i)fn", 100);
1986+
localeEntry.headerRegExps = newHeaders;
1987+
}
1988+
1989+
final TextAnalyzer analysisPost = new TextAnalyzer("fn");
1990+
analysisPost.setLocale(Locale.US);
1991+
for (final String input : inputs)
1992+
analysisPost.train(input);
1993+
final TextAnalysisResult resultPost = analysisPost.getResult();
1994+
assertEquals(resultPost.getSemanticType(), "NAME.FIRST");
19921995

1996+
}
19931997

19941998
@Test(groups = { TestGroups.ALL, TestGroups.PLUGINS })
19951999
public void basicISIN() throws IOException, FTAException {

0 commit comments

Comments
 (0)