├── .gitignore ├── .script ├── deploy_artifacts.sh └── deploy_javadocs.sh ├── .travis.yml ├── README.md ├── TODO ├── apex ├── build.gradle ├── gradle.properties └── src │ ├── main │ └── java │ │ └── com │ │ └── sixthsolution │ │ └── apex │ │ ├── Apex.java │ │ ├── model │ │ ├── Event.java │ │ ├── Frequency.java │ │ ├── Recurrence.java │ │ └── WeekDay.java │ │ └── nlp │ │ ├── dict │ │ ├── Dictionary.java │ │ ├── DictionaryBuilder.java │ │ ├── Tag.java │ │ ├── TagValue.java │ │ └── Tags.java │ │ ├── event │ │ ├── EventBuilder.java │ │ ├── EventDetector.java │ │ ├── Extractor.java │ │ ├── SeekBy.java │ │ ├── StandardDateExtractor.java │ │ ├── StandardEventDetector.java │ │ ├── StandardLocationExtractor.java │ │ └── StandardTimeExtractor.java │ │ ├── ner │ │ ├── ChunkedPart.java │ │ ├── Chunker.java │ │ ├── Entity.java │ │ ├── Label.java │ │ └── regex │ │ │ ├── ChunkDetectionFilter.java │ │ │ ├── ChunkDetector.java │ │ │ └── RegExChunker.java │ │ ├── parser │ │ ├── Parser.java │ │ └── StandardParserBase.java │ │ ├── tagger │ │ ├── StandardTagger.java │ │ ├── TaggedWord.java │ │ ├── TaggedWords.java │ │ └── Tagger.java │ │ ├── tokenization │ │ ├── StandardTokenizer.java │ │ └── Tokenizer.java │ │ └── util │ │ ├── NumericUtils.java │ │ ├── Pair.java │ │ └── Triple.java │ └── test │ └── java │ └── com │ └── sixthsolution │ └── apex │ └── nlp │ └── test │ ├── ChunkAssertion.java │ ├── ChunkDetectorAssertion.java │ ├── ChunkerAssertion.java │ ├── ParserAssertion.java │ ├── TagAssertion.java │ ├── TaggerAssertion.java │ └── TokenizerAssertion.java ├── build.gradle ├── dfalex ├── README.md ├── build.gradle ├── gradle.properties └── src │ ├── main │ └── java │ │ ├── backport │ │ └── java │ │ │ └── util │ │ │ └── function │ │ │ ├── BackportFuncs.java │ │ │ ├── BiConsumer.java │ │ │ ├── Consumer.java │ │ │ ├── Function.java │ │ │ ├── IntConsumer.java │ │ │ ├── ObjIntConsumer.java │ │ │ └── Objects.java │ │ └── com │ │ └── nobigsoftware │ │ ├── dfalex │ │ ├── BitUtils.java │ │ ├── CharRange.java │ │ ├── CompactIntSubset.java │ │ ├── DfaAmbiguityException.java │ │ ├── DfaAmbiguityResolver.java │ │ ├── DfaAuxiliaryInformation.java │ │ ├── DfaBuilder.java │ │ ├── DfaFromNfa.java │ │ ├── DfaMinimizer.java │ │ ├── DfaState.java │ │ ├── DfaStateImpl.java │ │ ├── DfaStateInfo.java │ │ ├── DfaStatePlaceholder.java │ │ ├── DfaStateSignatureCodec.java │ │ ├── DfaTransitionConsumer.java │ │ ├── IntListKey.java │ │ ├── IntRangeClosureQueue.java │ │ ├── Matchable.java │ │ ├── Nfa.java │ │ ├── NfaTransition.java │ │ ├── PackedTreeDfaPlaceholder.java │ │ ├── Pattern.java │ │ ├── PrimeSizeFinder.java │ │ ├── RawDfa.java │ │ ├── RegexParser.java │ │ ├── ReplacementSelector.java │ │ ├── SafeAppendable.java │ │ ├── SearchAndReplaceBuilder.java │ │ ├── SerializableDfa.java │ │ ├── StringMatchIterator.java │ │ ├── StringMatcher.java │ │ ├── StringReplaceAppendable.java │ │ ├── StringReplacement.java │ │ ├── StringReplacements.java │ │ └── StringSearcher.java │ │ └── util │ │ ├── BuilderCache.java │ │ └── SHAOutputStream.java │ └── test │ ├── java │ └── com │ │ └── nobigsoftware │ │ └── dfalex │ │ ├── BitUtilTest.java │ │ ├── BuilderCacheTest.java │ │ ├── By3Test.java │ │ ├── IntTest.java │ │ ├── JavaTest.java │ │ ├── JavaToken.java │ │ ├── PrettyPrinter.java │ │ ├── RegexSpeedTest.java │ │ ├── RegexTest.java │ │ ├── ReverseFinderTest.java │ │ ├── StringMatcherTest.java │ │ ├── StringSearcherTest.java │ │ ├── TarjanTest.java │ │ └── TestBase.java │ └── resources │ ├── By3Test.out.txt │ ├── JavaTest.out.txt │ ├── SearcherTestInput.txt │ └── SearcherTestOutput.txt ├── english-nlp ├── build.gradle ├── gradle.properties └── src │ ├── main │ └── java │ │ └── com │ │ └── sixthsolution │ │ └── apex │ │ └── nlp │ │ └── english │ │ ├── DateDetector.java │ │ ├── EnglishParser.java │ │ ├── EnglishTokenizer.java │ │ ├── EnglishVocabulary.java │ │ ├── LocationDetector.java │ │ ├── StandardExtractor.java │ │ ├── TimeDetector.java │ │ └── filter │ │ ├── DateDetectionFilter.java │ │ ├── LocationDetectionFilter.java │ │ └── TimeDetectionFilter.java │ └── test │ └── java │ └── com │ └── sixthsolution │ └── apex │ └── nlp │ └── english │ └── test │ └── tokenization │ ├── DateDetectorTest.java │ ├── EnglishChunkerTest.java │ ├── EnglishDetectorTest.java │ ├── EnglishTaggerTest.java │ ├── EnglishTokenizationTest.java │ ├── EventTest.java │ ├── LocationDetectorTest.java │ └── TimeDetectorTest.java ├── gradle.properties ├── gradle ├── jacoco.gradle ├── jfrog-uploader.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── logo.png ├── persian-nlp ├── build.gradle ├── gradle.properties └── src │ ├── main │ └── java │ │ └── com │ │ └── sixthsolution │ │ └── apex │ │ └── nlp │ │ └── persian │ │ ├── PersianDateDetector.java │ │ ├── PersianLocationDetector.java │ │ ├── PersianParser.java │ │ ├── PersianTagger.java │ │ ├── PersianTimeDetector.java │ │ ├── PersianTokenizer.java │ │ ├── PersianVocabulary.java │ │ ├── calendar │ │ └── tools │ │ │ ├── CalendarTool.java │ │ │ └── JalaliCalendar.java │ │ ├── event │ │ ├── PersianEventBuilder.java │ │ ├── PersianRecurrence.java │ │ └── StandardPersianExtractor.java │ │ ├── filter │ │ ├── DateDetectionFilter.java │ │ ├── LocationDetectionFilter.java │ │ └── TimeDetectionFilter.java │ │ └── model │ │ ├── PersianEvent.java │ │ └── PersianExtractor.java │ └── test │ └── java │ └── com │ └── sixthsolution │ └── apex │ └── nlp │ └── persian │ └── test │ ├── EventTest.java │ ├── PersianDDTest.java │ ├── PersianDLTest.java │ ├── PersianDTTest.java │ ├── PersianDetectorTest.java │ └── PersianTokenizationTest.java ├── pipeline-arch.png ├── sample-android ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── sixthsolution │ │ └── apex │ │ └── sample │ │ └── android │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── sixthsolution │ │ │ └── apex │ │ │ └── sample │ │ │ └── android │ │ │ ├── ApexApplication.java │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── sixthsolution │ └── apex │ └── sample │ └── android │ └── ExampleUnitTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .gradle 3 | /build 4 | */build 5 | *.iml 6 | local.properties -------------------------------------------------------------------------------- /.script/deploy_artifacts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Deploy a jar, source jar, and javadoc jar to bintray repo. 4 | # 5 | # Adapted from https://coderwall.com/p/9b_lfq and 6 | # http://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/ 7 | 8 | SLUG="6thsolution/ApexNLP" 9 | BRANCH="master" 10 | JDK="oraclejdk8" 11 | 12 | set -e 13 | 14 | if [ "$TRAVIS_REPO_SLUG" != "$SLUG" ]; then 15 | echo "Skipping deployment: wrong repository. Expected '$SLUG' but was '$TRAVIS_REPO_SLUG'." 16 | elif [ "$TRAVIS_JDK_VERSION" != "$JDK" ]; then 17 | echo "Skipping deployment: wrong JDK. Expected '$JDK' but was '$TRAVIS_JDK_VERSION'." 18 | elif [ "$TRAVIS_PULL_REQUEST" != "false" ]; then 19 | echo "Skipping deployment: was pull request." 20 | elif [ "$TRAVIS_BRANCH" != "$BRANCH" ]; then 21 | echo "Skipping deployment: wrong branch. Expected '$BRANCH' but was '$TRAVIS_BRANCH'." 22 | else 23 | echo "Deploying artifacts..." 24 | ./gradlew publishFromCI --info 25 | echo "Artifacts deployed!" 26 | fi -------------------------------------------------------------------------------- /.script/deploy_javadocs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | REPO="git@github.com:6thsolution/ApexNLP.git" 6 | 7 | DIR=temp-clone 8 | 9 | # Delete any existing temporary website clone 10 | rm -rf $DIR 11 | 12 | # Clone the current repo into temp folder 13 | git clone $REPO $DIR 14 | 15 | # Move working directory into temp folder 16 | cd $DIR 17 | # Checkout and track the gh-pages branch 18 | git checkout -t origin/gh-pages 19 | 20 | # Artifactory location 21 | server=https://oss.jfrog.org 22 | repo=oss-snapshot-local 23 | 24 | # jfrog artifacts location 25 | for name in apex dfalex english-nlp persian-nlp 26 | do 27 | artifact=com/sixthsolution/easymvp/$name 28 | path=$server/$repo/$artifact 29 | version=`curl -s $path/maven-metadata.xml | grep latest | sed "s/.*\([^<]*\)<\/latest>.*/\1/"` 30 | build=`curl -s $path/$version/maven-metadata.xml | grep '' | head -1 | sed "s/.*\([^<]*\)<\/value>.*/\1/"` 31 | jar=$name-$build-javadoc.jar 32 | url=$path/$version/$jar 33 | 34 | # Download 35 | echo $url 36 | curl -L $url > "$name".zip 37 | javadoc="${name:8}-javadoc" 38 | mkdir -p "$javadoc" 39 | unzip "$name".zip -d "$javadoc" 40 | rm "$name".zip 41 | done 42 | 43 | # Stage all files in git and create a commit 44 | git add . 45 | git add -u 46 | git commit -m "java docs updated at $(date)" 47 | 48 | # Push the new files up to GitHub 49 | git push origin gh-pages 50 | 51 | cd .. 52 | rm -rf $DIR -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk8 5 | 6 | cache: 7 | directories: 8 | - $HOME/.m2 9 | - $HOME/.gradle 10 | 11 | before_script: 12 | - chmod +x gradlew 13 | - chmod +x .script/deploy_artifacts.sh 14 | 15 | script: 16 | - ./gradlew clean build --info 17 | 18 | after_success: 19 | - bash <(curl -s https://codecov.io/bash) 20 | - .script/deploy_artifacts.sh 21 | 22 | notifications: 23 | email: false -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | # English NLP 2 | 1. Support Go to [place name] 3 | 2. Support time like( half past ten, next hour) 4 | 3. Support 930am 5 | 6 | http://www.nltk.org/book/ch07.html 7 | http://www.slideshare.net/gagan1667/opennlp-demo 8 | https://github.com/stanfordnlp/CoreNLP/blob/master/src/edu/stanford/nlp/time/SUTime.java 9 | https://helpspot.readdle.com/calendars/index.php?pg=kb.page&id=429 10 | https://github.com/dstl/baleen/blob/master/baleen/baleen-annotators/src/main/java/uk/gov/dstl/baleen/annotators/regex/Date.java 11 | https://github.com/ahmetaa/zemberek-nlp -------------------------------------------------------------------------------- /apex/build.gradle: -------------------------------------------------------------------------------- 1 | apply from: rootProject.file('gradle/jfrog-uploader.gradle') 2 | apply from: rootProject.file('gradle/jacoco.gradle') 3 | 4 | configurations { 5 | testOutput 6 | } 7 | 8 | dependencies { 9 | testOutput sourceSets.test.output 10 | } 11 | 12 | dependencies { 13 | compile project(':dfalex') 14 | compileOnly group: 'org.threeten', name: 'threetenbp', version: '1.3.3' 15 | 16 | testCompile group: 'junit', name: 'junit', version: '4.11' 17 | testCompile group: 'org.threeten', name: 'threetenbp', version: '1.3.3' 18 | } 19 | -------------------------------------------------------------------------------- /apex/gradle.properties: -------------------------------------------------------------------------------- 1 | DESC=Apex NLP 2 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/Apex.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex; 2 | 3 | import com.sixthsolution.apex.model.Event; 4 | import com.sixthsolution.apex.nlp.parser.Parser; 5 | 6 | import org.threeten.bp.LocalDateTime; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author Saeed Masoumi (s-masoumi@live.com) 13 | * @author Rozhin Bayati 14 | */ 15 | 16 | public class Apex { 17 | 18 | private static Apex inst = null; 19 | private Map parsers = new HashMap<>(); 20 | 21 | private Apex(ApexConfig config) { 22 | this.parsers = config.parsers; 23 | } 24 | 25 | public static void init(ApexConfig config) { 26 | for (Parser parser : config.parsers.values()) { 27 | parser.initialize(); 28 | } 29 | inst = new Apex(config); 30 | } 31 | 32 | public static Event nlp(String name, String sentence) { 33 | return inst.parsers.get(name).parse(LocalDateTime.now(), sentence); 34 | } 35 | 36 | public static class ApexBuilder { 37 | 38 | private Map parsers = new HashMap<>(); 39 | 40 | public ApexBuilder addParser(String name, Parser parser) { 41 | parsers.put(name, parser); 42 | return this; 43 | } 44 | 45 | public ApexConfig build() { 46 | return new ApexConfig(parsers); 47 | } 48 | } 49 | 50 | private static class ApexConfig { 51 | Map parsers = new HashMap<>(); 52 | 53 | ApexConfig(Map parsers) { 54 | this.parsers = parsers; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/model/Event.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 6thSolution 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.sixthsolution.apex.model; 18 | 19 | import org.threeten.bp.LocalDateTime; 20 | 21 | /** 22 | * Represents a single calendar event. 23 | * 24 | * @author Saeed Masoumi (saeed@6thsolution.com) 25 | * @author Rozhin Bayati 26 | */ 27 | public class Event { 28 | 29 | private String title = ""; 30 | private String location = ""; 31 | private LocalDateTime startDateTime = null; 32 | private LocalDateTime endDateTime = null; 33 | private boolean isAllDay = false; 34 | private Recurrence recurrence = null; 35 | 36 | public Event() { 37 | 38 | } 39 | 40 | public Event(String title, String location, LocalDateTime startDateTime, 41 | LocalDateTime endDateTime, 42 | boolean isAllDay, Recurrence recurrence) { 43 | this.title = title; 44 | this.location = location; 45 | this.startDateTime = startDateTime; 46 | this.endDateTime = endDateTime; 47 | this.isAllDay = isAllDay; 48 | this.recurrence = recurrence; 49 | } 50 | 51 | 52 | public void setTitle(String title) { 53 | this.title = title; 54 | } 55 | 56 | public void setStartDateTime(LocalDateTime startDateTime) { 57 | this.startDateTime = startDateTime; 58 | } 59 | 60 | public void setEndDateTime(LocalDateTime endDateTime) { 61 | this.endDateTime = endDateTime; 62 | } 63 | 64 | public String title() { 65 | return title; 66 | } 67 | 68 | public String location() { 69 | return location; 70 | } 71 | 72 | public LocalDateTime start() { 73 | return startDateTime; 74 | } 75 | 76 | public LocalDateTime end() { 77 | return endDateTime; 78 | } 79 | 80 | public boolean isAllDay() { 81 | return isAllDay; 82 | } 83 | 84 | public void setAllDay(boolean allDay) { 85 | isAllDay = allDay; 86 | } 87 | 88 | public boolean isRecurrence() { 89 | return recurrence != null; 90 | } 91 | 92 | public void setRecurrence(Recurrence recurrence) { 93 | this.recurrence = recurrence; 94 | } 95 | 96 | public Recurrence recurrence() { 97 | return recurrence; 98 | } 99 | 100 | 101 | @Override 102 | public String toString() { 103 | return "Event{" + 104 | "title='" + title + '\'' + 105 | ", startDateTime=" + startDateTime + 106 | ", endDateTime=" + endDateTime + 107 | ", isAllDay=" + isAllDay + 108 | ", recurrence=" + recurrence + 109 | '}'; 110 | } 111 | 112 | } 113 | 114 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/model/Frequency.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 6thSolution 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.sixthsolution.apex.model; 18 | 19 | /** 20 | * The frequency that the {@link Event} should be repeated (such as "DAILY"). 21 | * 22 | * @author Saeed Masoumi (saeed@6thsolution.com) 23 | */ 24 | public enum Frequency { 25 | DAILY, WEEKLY, MONTHLY, YEARLY 26 | } 27 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/model/Recurrence.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 6thSolution 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.sixthsolution.apex.model; 18 | 19 | import org.threeten.bp.LocalDateTime; 20 | 21 | import java.util.List; 22 | 23 | /** 24 | * Represents a recurring event. 25 | * 26 | * @author Saeed Masoumi (saeed@6thsolution.com) 27 | * @author Rozhin Bayati 28 | */ 29 | public class Recurrence { 30 | 31 | private Frequency frequency = Frequency.DAILY; 32 | 33 | /** 34 | * Specifies how often the event should be repeated. 35 | */ 36 | private int interval = 1; 37 | 38 | /** 39 | * The date or date-time until which the event should be repeated. 40 | */ 41 | private LocalDateTime until = null; 42 | 43 | private boolean forever = false; 44 | /** 45 | * Days of the week on which the event should be repeated 46 | */ 47 | private List byDays; 48 | 49 | public Recurrence(Frequency frequency, int interval, LocalDateTime until, boolean forever, 50 | List byDays) { 51 | this.frequency = frequency; 52 | this.interval = interval; 53 | this.until = until; 54 | this.forever = forever; 55 | this.byDays = byDays; 56 | } 57 | 58 | public Frequency frequency() { 59 | return frequency; 60 | } 61 | 62 | public int interval() { 63 | return interval; 64 | } 65 | 66 | //TODO @nullable 67 | public LocalDateTime until() { 68 | return until; 69 | } 70 | 71 | public boolean isForever() { 72 | return forever; 73 | } 74 | 75 | public List byDays() { 76 | return byDays; 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return "Recurrence{" + 82 | "frequency=" + frequency + 83 | ", interval=" + interval + 84 | ", until=" + until + 85 | ", forever=" + forever + 86 | ", byDays=" + byDays + 87 | '}'; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/model/WeekDay.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 6thSolution 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.sixthsolution.apex.model; 18 | 19 | /** 20 | * @author Saeed Masoumi (saeed@6thsolution.com) 21 | */ 22 | public enum WeekDay { 23 | MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(7); 24 | 25 | private final int dayofWeek; 26 | 27 | WeekDay(int dayOfWeek) { 28 | this.dayofWeek = dayOfWeek; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/dict/Dictionary.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.dict; 2 | 3 | import com.sixthsolution.apex.nlp.ner.Entity; 4 | 5 | import java.util.HashMap; 6 | 7 | /** 8 | * @author Saeed Masoumi (s-masoumi@live.com) 9 | */ 10 | public class Dictionary extends HashMap { 11 | private static final Tags NONE_TAG; 12 | 13 | static { 14 | NONE_TAG = new Tags(); 15 | NONE_TAG.add(new TagValue(Tag.NONE, "", Entity.NONE)); 16 | } 17 | 18 | public void addAll(String[] words, Tag tag, Object value, Entity entity) { 19 | TagValue tagValue = new TagValue(tag, value, entity); 20 | for (String word : words) { 21 | update(word, tagValue); 22 | } 23 | } 24 | 25 | public void update(String word, TagValue tagValue) { 26 | Tags posting = getOrEmpty(word); 27 | posting.add(tagValue); 28 | put(word, posting); 29 | } 30 | 31 | public Tags getOrEmpty(String word) { 32 | if (!containsKey(word)) { 33 | return new Tags(); 34 | } 35 | return get(word); 36 | } 37 | 38 | public Tags getRelatedTags(String word, boolean caseInsensitive) { 39 | if (caseInsensitive) { 40 | return getTags(word.toLowerCase()); 41 | } 42 | return getTags(word); 43 | } 44 | 45 | private Tags getTags(String word) { 46 | Tags tags = getOrEmpty(word); 47 | if (!tags.isEmpty()) { 48 | return tags; 49 | } 50 | return NONE_TAG; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/dict/DictionaryBuilder.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.dict; 2 | 3 | import com.sixthsolution.apex.nlp.ner.Entity; 4 | 5 | /** 6 | * @author Saeed Masoumi (s-masoumi@live.com) 7 | */ 8 | public class DictionaryBuilder { 9 | 10 | private Dictionary dictionary = new Dictionary(); 11 | 12 | public Dictionary build() { 13 | return dictionary; 14 | } 15 | 16 | public TagEntryBuilder tag(Tag tag, Entity entity) { 17 | return new TagEntryBuilder(dictionary, tag, entity); 18 | } 19 | 20 | public static class TagEntryBuilder { 21 | private final Dictionary dictionary; 22 | private final Tag tag; 23 | private final Entity entity; 24 | 25 | TagEntryBuilder(Dictionary dictionary, Tag tag, Entity entity) { 26 | this.dictionary = dictionary; 27 | this.tag = tag; 28 | this.entity = entity; 29 | } 30 | 31 | public TagEntryBuilder e(Object value, String... words) { 32 | dictionary.addAll(words, tag, value, entity); 33 | return this; 34 | } 35 | 36 | public TagEntryBuilder e(String... words) { 37 | dictionary.addAll(words, tag, "", entity); 38 | return this; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/dict/Tag.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.dict; 2 | 3 | /** 4 | * @author Saeed Masoumi (s-masoumi@live.com) 5 | * @author Rozhin Bayati 6 | */ 7 | public enum Tag { 8 | NONE(97), 9 | NUMBER(98), 10 | PREPOSITION(99), 11 | RELATIVE_PREPOSITION(100), 12 | RELATIVE_SUFFIX(101), 13 | //LOCATION 14 | LOCATION_PREFIX(102), 15 | LOCATION_SUFFIX(103), 16 | LOCATION_NAME(137), 17 | //TIME 18 | TIME_PREFIX(104), //e.g. at, in ,the 19 | TIME_START_RANGE(105), //e.g. from 20 | TIME_RANGE(106), 21 | TIME_RELATIVE_PREFIX(107), //e.g. for 22 | TIME_RELATIVE(108), //e.g. morning 23 | TIME_RELATIVE_INDICATOR(109), //e.g. before,after 24 | TIME_HOUR(110), //e.g. hour 25 | TIME_MIN(111), //e.g. minutes 26 | TIME_SEC(112), //e.g. seconds 27 | TIME_MERIDIEM(113), //e.g am, pm 28 | TIME_SEPARATOR(114), //e.g :, . 29 | //DATE 30 | DATE_PREPOSITION(115), 31 | DATE_SEEKBY(116), 32 | DATE_START_RANGE(117), 33 | DATE_SUFFIX(118), 34 | DATE_DURATION_SUFFIX(119), 35 | DATE_SEPARATOR(120), 36 | WEEK_DAY(121), 37 | MONTH_NAME(122), 38 | SEASON(123), 39 | DATE_PREFIX(124), 40 | //RECURRENCE 41 | REC_WEEK_DAYS(125), 42 | NAMED_DATE(126), 43 | GLOBAL_PREPOSITION(127), 44 | DATE_RECURRENCE(128), 45 | DATE_RANGE(129), 46 | DATE_FOREVER_KEY(130), 47 | THE_PREFIX(131), 48 | DATE_BAND(132), 49 | YEAR_SEEK(133), 50 | MONTH_SEEK(134), 51 | WEEK_SEEK(135), 52 | DAY_SEEK(136), 53 | CURRENT(138); 54 | 55 | public int id; 56 | 57 | Tag(int id) { 58 | this.id = id; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return String.valueOf((char) id); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/dict/TagValue.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.dict; 2 | 3 | import com.sixthsolution.apex.nlp.ner.Entity; 4 | import com.sixthsolution.apex.nlp.util.Triple; 5 | 6 | /** 7 | * @author Saeed Masoumi (s-masoumi@live.com) 8 | */ 9 | 10 | public class TagValue extends Triple { 11 | 12 | public Tag tag; 13 | public Object value; 14 | public Entity entity; 15 | 16 | private volatile String toStringResult; 17 | 18 | public TagValue(Tag tag, Object value, Entity entity) { 19 | super(tag, value, entity); 20 | this.tag = tag; 21 | this.value = value; 22 | this.entity = entity; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | if (toStringResult == null) { 28 | toStringResult = "Triple{" + 29 | "tag=" + tag.name() + 30 | ", value=" + value + 31 | ", entity=" + entity + 32 | '}'; 33 | } 34 | 35 | return toStringResult; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/dict/Tags.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.dict; 2 | 3 | import com.sixthsolution.apex.nlp.ner.Entity; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Collection; 8 | import java.util.Iterator; 9 | 10 | /** 11 | * @author Saeed Masoumi (s-masoumi@live.com) 12 | * @author Rozhin Bayati 13 | */ 14 | 15 | public class Tags extends ArrayList { 16 | 17 | public boolean containsTag(Tag tag) { 18 | Iterator iterator = iterator(); 19 | while (iterator.hasNext()) { 20 | TagValue next = iterator.next(); 21 | if (next.tag.equals(tag)) { 22 | return true; 23 | } 24 | } 25 | return false; 26 | } 27 | 28 | public TagValue containsTagByValue(Tag tag) { 29 | Iterator iterator = iterator(); 30 | while (iterator.hasNext()) { 31 | TagValue next = iterator.next(); 32 | if (next.tag.equals(tag)) { 33 | return next; 34 | } 35 | } 36 | return null; 37 | } 38 | 39 | public boolean containsTag(Tag... tags) { 40 | return containsTag(Arrays.asList(tags)); 41 | } 42 | 43 | public boolean containsTag(Collection tags) { 44 | Iterator iterator = iterator(); 45 | while (iterator.hasNext()) { 46 | TagValue next = iterator.next(); 47 | for (Tag tag : tags) 48 | if (next.tag.equals(tag)) { 49 | return true; 50 | } 51 | } 52 | return false; 53 | } 54 | 55 | public boolean containsTagName(int tag) { 56 | for (TagValue tagValue : this) { 57 | if (tagValue.tag.id == tag) { 58 | return true; 59 | } 60 | } 61 | return false; 62 | } 63 | 64 | public TagValue getTagByEntity(Entity entity) { 65 | Iterator iterator = iterator(); 66 | while (iterator.hasNext()) { 67 | TagValue next = iterator.next(); 68 | if (next.entity == entity) { 69 | return next; 70 | } 71 | } 72 | return null; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/event/EventBuilder.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.event; 2 | 3 | import com.sixthsolution.apex.model.Event; 4 | 5 | import com.sixthsolution.apex.model.Recurrence; 6 | import org.threeten.bp.LocalDate; 7 | import org.threeten.bp.LocalDateTime; 8 | import org.threeten.bp.LocalTime; 9 | 10 | 11 | /** 12 | * @author Saeed Masoumi (s-masoumi@live.com) 13 | * @author Rozhin Bayati 14 | */ 15 | 16 | public class EventBuilder { 17 | 18 | private LocalTime startTime = null; 19 | private LocalTime endTime = null; 20 | private LocalDate startDate; 21 | private LocalDate endDate; 22 | private String location = ""; 23 | private Recurrence recurrence =null; 24 | 25 | public void setStartTime(LocalTime startTime) { 26 | this.startTime = startTime; 27 | } 28 | 29 | public void setEndTime(LocalTime endTime) { 30 | this.endTime = endTime; 31 | } 32 | 33 | public void setStartDate(LocalDate startDate) { 34 | this.startDate = startDate; 35 | } 36 | 37 | public void setEndDate(LocalDate endDate) { 38 | this.endDate = endDate; 39 | } 40 | 41 | public void setLocation(String location) { 42 | this.location = location; 43 | } 44 | 45 | public void setReccurence(Recurrence reccurence ){this.recurrence=reccurence;} 46 | 47 | public Event build(LocalDateTime source) { 48 | if (startTime == null) { 49 | startTime = source.toLocalTime(); 50 | } 51 | if (endTime == null) { 52 | endTime = startTime.plusHours(1); 53 | } 54 | if (startDate == null) { 55 | startDate = source.toLocalDate(); 56 | } 57 | if (endDate == null) { 58 | endDate = startDate; 59 | } 60 | 61 | 62 | LocalDateTime startDateTime = LocalDateTime.of(startDate, startTime); 63 | LocalDateTime endDateTime = LocalDateTime.of(endDate, endTime); 64 | 65 | return new Event("", location, startDateTime, endDateTime, false, recurrence); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/event/EventDetector.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.event; 2 | 3 | import com.sixthsolution.apex.model.Event; 4 | import com.sixthsolution.apex.nlp.ner.ChunkedPart; 5 | 6 | import org.threeten.bp.LocalDateTime; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author Saeed Masoumi (s-masoumi@live.com) 12 | */ 13 | 14 | public interface EventDetector { 15 | 16 | Event detect(LocalDateTime source, List chunkedParts); 17 | } 18 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/event/Extractor.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.event; 2 | 3 | import com.sixthsolution.apex.nlp.ner.ChunkedPart; 4 | 5 | import org.threeten.bp.LocalDateTime; 6 | 7 | /** 8 | * @author Saeed Masoumi (s-masoumi@live.com) 9 | */ 10 | 11 | public interface Extractor { 12 | void extract(EventBuilder builder, LocalDateTime source, ChunkedPart chunkedPart); 13 | } 14 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/event/SeekBy.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.event; 2 | 3 | /** 4 | * @author Saeed Masoumi (s-masoumi@live.com) 5 | */ 6 | 7 | public enum SeekBy { 8 | MIN, HOUR 9 | } 10 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/event/StandardEventDetector.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.event; 2 | 3 | import com.sixthsolution.apex.model.Event; 4 | import com.sixthsolution.apex.nlp.ner.ChunkedPart; 5 | 6 | import org.threeten.bp.LocalDateTime; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author Saeed Masoumi (s-masoumi@live.com) 12 | * @author Rozhin Bayati 13 | */ 14 | 15 | public class StandardEventDetector implements EventDetector { 16 | 17 | protected Extractor timeExtractor; 18 | protected Extractor dateExtractor; 19 | protected Extractor locationExtractor; 20 | 21 | public StandardEventDetector() { 22 | timeExtractor = provideTimeExtractor(); 23 | dateExtractor = provideDateExtractor(); 24 | locationExtractor = provideLocationExtractor(); 25 | } 26 | 27 | @Override 28 | public Event detect(LocalDateTime source, List chunkedParts) { 29 | EventBuilder builder = new EventBuilder(); 30 | for (ChunkedPart part : chunkedParts) { 31 | switch (part.getEntity()) { 32 | case TIME: 33 | timeExtractor.extract(builder, source, part); 34 | break; 35 | case DATE: 36 | dateExtractor.extract(builder, source, part); 37 | break; 38 | case LOCATION: 39 | locationExtractor.extract(builder, source, part); 40 | break; 41 | } 42 | } 43 | return builder.build(source); 44 | } 45 | 46 | public StandardEventDetector(Extractor DateExtractor) { 47 | timeExtractor = provideTimeExtractor(); 48 | dateExtractor = DateExtractor; 49 | locationExtractor = provideLocationExtractor(); 50 | } 51 | 52 | protected Extractor provideTimeExtractor() { 53 | return new StandardTimeExtractor(); 54 | } 55 | 56 | protected Extractor provideDateExtractor() { 57 | return new StandardDateExtractor(); 58 | } 59 | 60 | protected Extractor provideLocationExtractor() { 61 | return new StandardLocationExtractor(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/event/StandardLocationExtractor.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.event; 2 | 3 | import com.sixthsolution.apex.nlp.dict.Tag; 4 | import com.sixthsolution.apex.nlp.ner.ChunkedPart; 5 | import com.sixthsolution.apex.nlp.tagger.TaggedWord; 6 | 7 | import org.threeten.bp.LocalDateTime; 8 | 9 | import java.util.Iterator; 10 | 11 | /** 12 | * @author Saeed Masoumi (s-masoumi@live.com) 13 | * 14 | */ 15 | 16 | public class StandardLocationExtractor implements Extractor { 17 | 18 | @Override 19 | public void extract(EventBuilder builder, LocalDateTime source, ChunkedPart chunkedPart) { 20 | switch (chunkedPart.getLabel()) { 21 | case LOCATION: 22 | String location = getLocation(chunkedPart); 23 | builder.setLocation(location); 24 | break; 25 | } 26 | } 27 | 28 | private String getLocation(ChunkedPart chunkedPart) { 29 | StringBuilder sb = new StringBuilder(); 30 | Iterator itr = chunkedPart.getTaggedWords().iterator(); 31 | while (itr.hasNext()) { 32 | TaggedWord next = itr.next(); 33 | if (!next.hasTag(Tag.LOCATION_PREFIX)) { 34 | sb.append(next.getWord()); 35 | if (itr.hasNext()) { 36 | sb.append(" "); 37 | } 38 | } 39 | 40 | } 41 | return sb.toString(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/ner/ChunkedPart.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.ner; 2 | 3 | import com.sixthsolution.apex.nlp.tagger.TaggedWord; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author Saeed Masoumi (s-masoumi@live.com) 9 | */ 10 | 11 | public class ChunkedPart { 12 | 13 | private final Entity entity; 14 | private final Label label; 15 | private final List taggedWords; 16 | 17 | public ChunkedPart(Entity entity,Label label, 18 | List taggedWords) { 19 | this.entity =entity; 20 | this.label = label; 21 | this.taggedWords = taggedWords; 22 | } 23 | 24 | public Label getLabel() { 25 | return label; 26 | } 27 | 28 | public Entity getEntity() { 29 | return entity; 30 | } 31 | 32 | public List getTaggedWords(int start,int end) { 33 | return taggedWords.subList(start,end); 34 | } 35 | public List getTaggedWords() { 36 | return taggedWords; 37 | } 38 | public String toStringTaggedWords() { 39 | StringBuilder sb = new StringBuilder(); 40 | for (TaggedWord taggedWord : taggedWords) { 41 | sb.append(taggedWord.getWord()).append(" "); 42 | } 43 | return sb.toString().trim(); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return label.name() + " -> " + toStringTaggedWords() ; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/ner/Chunker.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.ner; 2 | 3 | import com.sixthsolution.apex.nlp.tagger.TaggedWords; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author Saeed Masoumi (s-masoumi@live.com) 9 | */ 10 | 11 | public interface Chunker { 12 | 13 | List chunk(TaggedWords taggedWords); 14 | } 15 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/ner/Entity.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.ner; 2 | 3 | /** 4 | * @author Saeed Masoumi (s-masoumi@live.com) 5 | */ 6 | 7 | public enum Entity { 8 | TIME, DATE, LOCATION, NONE 9 | } 10 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/ner/Label.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.ner; 2 | 3 | /** 4 | * @author Saeed Masoumi (s-masoumi@live.com) 5 | * @author Rozhin Bayati 6 | */ 7 | 8 | public enum Label { 9 | NONE, DATE, TIME, LOCATION, TITLE, 10 | FIXED_TIME, 11 | RELATIVE_TIME, 12 | RANGE_TIME, 13 | /** 14 | * Formal dates are those in which the month, day, and year are represented as integers 15 | * separated by a common separator character. The year is optional and may proceed the month or 16 | * succeed the day of month. If a two-digit year is given, it must succeed the day of month. 17 | */ 18 | FORMAL_DATE, 19 | RELAX_DATE, 20 | RELATIVE_DATE, 21 | EXPLICIT_RELATIVE_DATE, 22 | GLOBAL_DATE, 23 | FOREVER_DATE, 24 | LIMITED_DATE, 25 | DATE_RULES, 26 | RECURRENCE, 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/ner/regex/ChunkDetectionFilter.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.ner.regex; 2 | 3 | import com.sixthsolution.apex.nlp.ner.Label; 4 | import com.sixthsolution.apex.nlp.tagger.TaggedWords; 5 | 6 | /** 7 | * @author Saeed Masoumi (s-masoumi@live.com) 8 | */ 9 | 10 | public abstract class ChunkDetectionFilter { 11 | 12 | public abstract boolean accept(Label label, TaggedWords taggedWords, int startIndex, int endIndex); 13 | } 14 | -------------------------------------------------------------------------------- /apex/src/main/java/com/sixthsolution/apex/nlp/ner/regex/ChunkDetector.java: -------------------------------------------------------------------------------- 1 | package com.sixthsolution.apex.nlp.ner.regex; 2 | 3 | import com.nobigsoftware.dfalex.DfaBuilder; 4 | import com.nobigsoftware.dfalex.DfaState; 5 | import com.nobigsoftware.dfalex.Pattern; 6 | import com.nobigsoftware.dfalex.StringMatcher; 7 | import com.sixthsolution.apex.nlp.dict.Tag; 8 | import com.sixthsolution.apex.nlp.dict.TagValue; 9 | import com.sixthsolution.apex.nlp.dict.Tags; 10 | import com.sixthsolution.apex.nlp.ner.ChunkedPart; 11 | import com.sixthsolution.apex.nlp.ner.Entity; 12 | import com.sixthsolution.apex.nlp.ner.Label; 13 | import com.sixthsolution.apex.nlp.tagger.TaggedWord; 14 | import com.sixthsolution.apex.nlp.tagger.TaggedWords; 15 | import com.sixthsolution.apex.nlp.util.Pair; 16 | 17 | import java.util.List; 18 | 19 | import static com.sixthsolution.apex.nlp.dict.Tag.NONE; 20 | import static com.sixthsolution.apex.nlp.dict.Tag.NUMBER; 21 | 22 | /** 23 | * @author Saeed Masoumi (s-masoumi@live.com) 24 | * @author Rozhin Bayati 25 | */ 26 | 27 | public abstract class ChunkDetector { 28 | 29 | protected final DfaState