diff --git a/ida-chatbot/src/app/app.component.ts b/ida-chatbot/src/app/app.component.ts index d18a97581..b233ceda0 100644 --- a/ida-chatbot/src/app/app.component.ts +++ b/ida-chatbot/src/app/app.component.ts @@ -1,16 +1,16 @@ -import {Component, ElementRef, QueryList, ViewChild, ViewChildren} from '@angular/core'; -import {Message} from './models/message'; -import {ResponseBean} from './models/response-bean'; -import {SidebarComponent} from './components/sidebar/sidebar.component'; -import {MainviewElement} from './models/mainview-element'; -import {SidebarElement} from './models/sidebar-element'; -import {ChatboxComponent} from './components/chatbox/chatbox.component'; -import {RestService} from './service/rest/rest.service'; -import {DataViewContainerComponent} from './components/data-view-container/data-view-container.component'; -import {TabElement} from './models/tab-element'; -import {UniqueIdProviderService} from './service/misc/unique-id-provider.service'; -import {TabType} from './enums/tab-type.enum'; -import {IdaEventService} from './service/event/ida-event.service'; +import { Component, ElementRef, QueryList, ViewChild, ViewChildren } from '@angular/core' +import { Message } from './models/message' +import { ResponseBean } from './models/response-bean' +import { SidebarComponent } from './components/sidebar/sidebar.component' +import { MainviewElement } from './models/mainview-element' +import { SidebarElement } from './models/sidebar-element' +import { ChatboxComponent } from './components/chatbox/chatbox.component' +import { RestService } from './service/rest/rest.service' +import { DataViewContainerComponent } from './components/data-view-container/data-view-container.component' +import { TabElement } from './models/tab-element' +import { UniqueIdProviderService } from './service/misc/unique-id-provider.service' +import { TabType } from './enums/tab-type.enum' +import { IdaEventService } from './service/event/ida-event.service' @Component({ selector: 'app-root', @@ -78,6 +78,9 @@ export class AppComponent { // Open new tab with DataTable const newTab = new TabElement(this.uis.getUniqueId(), resp.payload.actvTbl, TabType.SSB, resp.payload.ssbDiagramData, true, true); this.addNewTab(newTab, resp); + } else if (resp.actnCode === 10) { + const newTab = new TabElement(this.uis.getUniqueId(),'Soldier Career Timeline', TabType.SCTL, resp.payload.soldierTimeLineData, true, true) + this.addNewTab(newTab, resp) } } diff --git a/ida-chatbot/src/app/app.module.ts b/ida-chatbot/src/app/app.module.ts index 7849a8234..28607f5ab 100644 --- a/ida-chatbot/src/app/app.module.ts +++ b/ida-chatbot/src/app/app.module.ts @@ -62,6 +62,7 @@ import { VennViewComponent } from './components/venn-view/venn-view.component'; import { DeckglHexViewComponent } from './components/deckgl-hex-view/deckgl-hex-view.component'; import { SpeechInputComponent } from './components/speech-input/speech-input.component'; import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; +import { SoldierTimelineComponent } from './components/soldier-timeline/soldier-timeline.component' @NgModule({ declarations: [ AppComponent, @@ -81,12 +82,14 @@ import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; SsbViewComponent, VennViewComponent, DeckglHexViewComponent, - SpeechInputComponent + SpeechInputComponent, + SoldierTimelineComponent ], imports: [ BrowserModule, BrowserAnimationsModule, FormsModule, + ReactiveFormsModule, HttpModule, HttpClientModule, CdkTableModule, diff --git a/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.css b/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.css new file mode 100644 index 000000000..aed4ad43b --- /dev/null +++ b/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.css @@ -0,0 +1,13 @@ +.soldierInfoDiv { + position: relative; + bottom: 34px; + left: 265px; + font-size: 18px; + width:275px; + } + + .fieldLabelClass { + font-size: 20px; + } + + \ No newline at end of file diff --git a/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.html b/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.html new file mode 100644 index 000000000..f95e8cfb0 --- /dev/null +++ b/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.html @@ -0,0 +1,253 @@ + + +
+

Soldier Career Timeline

+
+
+
+ + + + + + {{dateCorectValue.get(i)}} DOB + {{dateCorectValue.get(i)}} Rank + {{dateCorectValue.get(i)}} Regiment + {{dateCorectValue.get(i)}} Decoration + {{dateCorectValue.get(i)}} DOD + + + +
+ Date of Birth +
+ +
+
+ Date : +
{{dateCorectValue.get(i)}}
+
+ + +
+
+ + +
+ Rank Information +
+ +
+
+ Date: +
{{soldierDatesVsFileds.get(i).get("applicableFrom_inXSDDate")}}
+
+ + + +
+ Rank Name : +
{{soldierDatesVsFileds.get(i).get("hasRank_name")}}
+
+ +
+ Rank Sortation : +
{{soldierDatesVsFileds.get(i).get("hasRank_sortation")}}
+
+ + +
+ Label : +
{{soldierDatesVsFileds.get(i).get("label")}}
+
+ +
+ Rank Id : +
{{soldierDatesVsFileds.get(i).get("hasRank_id")}}
+
+ + + +
+
+ + +
+ Regiment Information +
+ +
+
+ Date : +
{{soldierDatesVsFileds.get(i).get("applicableFrom_inXSDDate")}}
+
+ +
+ ID : +
{{soldierDatesVsFileds.get(i).get("id")}}
+
+ +
+ Regiment Info Name : +
{{soldierDatesVsFileds.get(i).get("regimentInfo_name")}}
+
+ +
+ Regiment Info Id : +
{{soldierDatesVsFileds.get(i).get("regimentInfo_id")}}
+
+ +
+ Label : +
{{soldierDatesVsFileds.get(i).get("label")}}
+
+ +
+ Regiment Info Abbreviation : +
{{soldierDatesVsFileds.get(i).get("regimentInfo_abbreviation")}}
+
+ + + + + + +
+ + +
+ + +
+ Decoration Information +
+ +
+
+ Date : +
{{soldierDatesVsFileds.get(i).get("applicableFrom_inXSDDate")}}
+
+ + + +
+ Decoration Name : +
{{soldierDatesVsFileds.get(i).get("hasDecoration_name")}}
+
+ +
+ Decoration Id : +
{{soldierDatesVsFileds.get(i).get("hasDecoration_id")}}
+
+ +
+ Label : +
{{soldierDatesVsFileds.get(i).get("label")}}
+
+ +
+ Decoration Abbreviation : +
{{soldierDatesVsFileds.get(i).get("hasDecoration_abbreviation")}}
+
+ + + + + + +
+ +
+ + +
+ Date of Death +
+ +
+
+ Date : +
{{dateCorectValue.get(i)}}
+
+ + +
+
+ +
+ +
+ + +
+
+ + +
+ + +
+ Soldier Information +
+ +
+ +
+ Full Name : +
{{soldierData.basicInfo__0.label}}
+
+ + + +
+ ID : +
{{soldierData.basicInfo__0.id}}
+
+ +
+ DALVerified : +
{{soldierData.basicInfo__0.DALVerified}}
+
+ +
+ NSDAPNumber : +
{{soldierData.basicInfo__0.NSDAPNumber}}
+
+ +
+ Membership Number : +
{{soldierData.basicInfo__0.membershipNumber}}
+
+ +
+ +
diff --git a/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.spec.ts b/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.spec.ts new file mode 100644 index 000000000..3b7ac3c05 --- /dev/null +++ b/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing' + +import { SoldierTimelineComponent } from './soldier-timeline.component' + +describe('SoldierTimelineComponent', () => { + let component: SoldierTimelineComponent + let fixture: ComponentFixture + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SoldierTimelineComponent ] + }) + .compileComponents() + })) + + beforeEach(() => { + fixture = TestBed.createComponent(SoldierTimelineComponent) + component = fixture.componentInstance + fixture.detectChanges() + }) + + it('should create', () => { + expect(component).toBeTruthy() + }) +}) diff --git a/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.ts b/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.ts new file mode 100644 index 000000000..1bfdc5de1 --- /dev/null +++ b/ida-chatbot/src/app/components/soldier-timeline/soldier-timeline.component.ts @@ -0,0 +1,62 @@ +import { Component, OnInit, Input } from '@angular/core' + +@Component({ + selector: 'app-soldier-timeline', + templateUrl: './soldier-timeline.component.html', + styleUrls: ['./soldier-timeline.component.css'] +}) +export class SoldierTimelineComponent implements OnInit { + + @Input('data') soldierData: any; + allDates = [] + allDOB = [] + allDOD = [] + allDatesOfRank = [] + allDatesOfRegiment = [] + allDatesOfDecoration = [] + temp ='' + + public dateCorectValue: Map = new Map() + public soldierDatesVsFileds: Map> = new Map>() + + constructor() { } + + ngOnInit() { + + for (const key in this.soldierData.dates) { + this.allDates.push(key) + } + + for (const key in this.soldierData.correctDates) { + this.dateCorectValue.set(key,this.soldierData.correctDates[key]) + } + + for (const key in this.soldierData.allDOB) { + this.allDOB.push(key) + } + + for (const key in this.soldierData.allRegiment) { + this.allDatesOfRegiment.push(key) + } + + for (const key in this.soldierData.allRanks) { + this.allDatesOfRank.push(key) + } + + for (const key in this.soldierData.allDecoration) { + this.allDatesOfDecoration.push(key) + } + + for (const key in this.soldierData.dates) { + + this.soldierDatesVsFileds.set(key,new Map()) + this.temp = this.soldierData.dates[key] + + for(const key123 in this.soldierData[this.temp]) + { + this.soldierDatesVsFileds.get(key).set(key123,this.soldierData[this.temp][key123]) + } + } + } + +} diff --git a/ida-chatbot/src/app/components/tab-view/tab-view.component.html b/ida-chatbot/src/app/components/tab-view/tab-view.component.html index 9cb1c9345..a97a16a50 100644 --- a/ida-chatbot/src/app/components/tab-view/tab-view.component.html +++ b/ida-chatbot/src/app/components/tab-view/tab-view.component.html @@ -9,4 +9,5 @@ + diff --git a/ida-chatbot/src/app/enums/tab-type.enum.ts b/ida-chatbot/src/app/enums/tab-type.enum.ts index c9ea794b9..9e8368729 100644 --- a/ida-chatbot/src/app/enums/tab-type.enum.ts +++ b/ida-chatbot/src/app/enums/tab-type.enum.ts @@ -1,3 +1,3 @@ export enum TabType { - BG, FDG, DTTBL, GEN, DSDET, VENND, GSD, SSB + BG, FDG, DTTBL, GEN, DSDET, VENND, GSD, SSB, SCTL } diff --git a/ida-vs/fdg_service/pom.xml b/ida-vs/fdg_service/pom.xml index 4ae7cd5ef..ccf2938ae 100644 --- a/ida-vs/fdg_service/pom.xml +++ b/ida-vs/fdg_service/pom.xml @@ -27,7 +27,7 @@ - + org.springframework.boot spring-boot-starter-test @@ -37,7 +37,7 @@ org.springframework.boot spring-boot-starter-web - + org.springframework.boot spring-boot-devtools @@ -74,8 +74,13 @@ opencsv 4.0 - - + + + org.aksw.jena-sparql-api + jena-sparql-api-core + 3.9.0-1 + + diff --git a/ida-ws/pom.xml b/ida-ws/pom.xml index 56672e47f..5ebfcf31f 100644 --- a/ida-ws/pom.xml +++ b/ida-ws/pom.xml @@ -237,6 +237,12 @@ 3.9.0-1 + + org.aksw.jena-sparql-api + jena-sparql-api-core + 3.9.0-1 + + ida-ws diff --git a/ida-ws/src/main/java/upb/ida/dao/SoldierTimeLine.java b/ida-ws/src/main/java/upb/ida/dao/SoldierTimeLine.java new file mode 100644 index 000000000..052a81f7b --- /dev/null +++ b/ida-ws/src/main/java/upb/ida/dao/SoldierTimeLine.java @@ -0,0 +1,360 @@ +package upb.ida.dao; + +import org.apache.jena.graph.Triple; +import org.apache.jena.query.ResultSet; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.ResultSetFactory; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdfconnection.RDFConnectionFuseki; +import org.apache.jena.rdfconnection.RDFConnectionRemoteBuilder; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +public class SoldierTimeLine { + private final String PREFIXES = "PREFIX datagraph: \n" + + "PREFIX data: \n" + + "PREFIX rdf: \n" + + "PREFIX dbo: \n" + + "PREFIX rdfs: \n" + + "PREFIX soldierData: "; + private static String dbhost = System.getenv("FUSEKI_URL"); + private Model model = null; + private RDFConnectionFuseki conn = null; + private Map> soldierDataMap = new HashMap>(); + private Map soldierDatesMap = new TreeMap(); + private Map soldierCorrectDatesMap = new HashMap(); + private Map soldierAllDOBMap = new HashMap(); + private Map soldierAllRanksMap = new HashMap(); + private Map soldierAllRegimentsMap = new HashMap(); + private Map soldierAllDecorationsMap = new HashMap(); + private int datesFlag = 0; + + + /** + * @param queryString the SPARQL query to be executed on the RDF dataset + * @return It takes query string as its parameter and returns the result set after executing the query. + */ + public ResultSet getResultFromQuery(String queryString, String dataset) { + QueryExecution queryExecution; + ResultSet resultSet; + Query query = QueryFactory.create(queryString); + + + /* + * No need to create a model from file or make database connection if the query is being run on already existing model. ( multiple queries are run on same model from getData function.) + */ + if (model == null) { + /* + * Create a fuseki model from the file and run the query on that model for test cases. + */ + if ("test-data".equals(dataset)) { + try { + model = ModelFactory.createDefaultModel(); + String path = Objects.requireNonNull(getClass().getClassLoader().getResource("dataset/test-soldier.ttl")).getFile(); + model.read(path); + queryExecution = QueryExecutionFactory.create(query, model); + } catch (NullPointerException ex) { + return null; + } + } else { + try { + RDFConnectionRemoteBuilder builder = RDFConnectionFuseki.create().destination(dbhost + dataset); + conn = (RDFConnectionFuseki) builder.build(); + queryExecution = conn.query(query); + } catch (Exception ex) { + return null; + } finally { + conn.close(); + } + } + } else { + queryExecution = QueryExecutionFactory.create(query, model); + } + if (queryExecution != null) { + try { + resultSet = ResultSetFactory.copyResults(queryExecution.execSelect()); + queryExecution.close(); + return resultSet; + } catch (Exception e) { + return null; + } + } + return null; + } + + public Map> getData(String soldierId, String datasetName) { + datesFlag = 0; + soldierDataMap = new HashMap>(); + soldierDatesMap = new TreeMap(); + soldierCorrectDatesMap = new HashMap(); + soldierAllDOBMap = new HashMap(); + soldierAllRanksMap = new HashMap(); + soldierAllRegimentsMap = new HashMap(); + soldierAllDecorationsMap = new HashMap(); + model = null; + String dataset = datasetName + "-data"; + String qString = "SELECT ?subject ?predicate ?object \n WHERE { ?subject ?predicate ?object }"; + + ResultSet resultSet = getResultFromQuery(qString, dataset); + model = ModelFactory.createDefaultModel(); + QuerySolution s; + Triple t; + + while (resultSet.hasNext()) { + s = resultSet.nextSolution(); + t = Triple.create(s.get("subject").asNode(), s.get("predicate").asNode(), s.get("object").asNode()); + model.add(model.asStatement(t)); + } + + String queryString = PREFIXES + "SELECT ?s ?p ?o\n" + "WHERE {\n" + " ?s ?p ?o\n" + " FILTER( ?s = soldierData:" + soldierId + " && ?p != rdf:type)\n" + "}"; + + JSONArray rows = queryData(queryString, dataset); + return preProcessSoldierData(rows); + } + + public JSONArray queryData(String queryString, String dataset) { + ResultSet resultSet = getResultFromQuery(queryString, dataset); + QuerySolution resource; + JSONArray rows = new JSONArray(); + Map rowsMap = new HashMap<>(); + Map foreignRef; + JSONObject rowObject; + String id = ""; + String key = ""; + String value = ""; + Set duplicateColumnLst = new TreeSet<>(); + Set nestedColLst = new TreeSet<>(); + JSONObject childObj = new JSONObject(); + JSONArray childLst = new JSONArray(); + + while (resultSet.hasNext()) { + resource = resultSet.next(); + id = resource.get("s").asNode().getURI(); + id = id.substring(id.lastIndexOf("/") + 1); + key = resource.get("p").asNode().getURI(); + + if (key.contains("#")) { + key = key.substring(key.lastIndexOf("#") + 1); + } else { + key = key.substring(key.lastIndexOf("/") + 1); + } + + if (rowsMap.get(id) == null) { + rowObject = new JSONObject(); + } else { + rowObject = rowsMap.get(id); + } + + if (resource.get("o").isLiteral()) { + value = resource.get("o").asLiteral().getString(); + if (rowObject.get(key) == null) { + rowObject.put(key, value); + } else { + rowObject.put(key, ""); + duplicateColumnLst.add(key); + } + } else { + value = resource.get("o").asNode().getURI(); + if (nestedColLst.contains(key)) { + if (rowObject.get(key) == null) { + rowObject.put(key, value); + } else { + rowObject.put(key, ""); + duplicateColumnLst.add(key); + } + } else { + foreignRef = getResource(value, dataset); + + for (String k : foreignRef.keySet()) { + childObj.put(k, foreignRef.get(k)); + } + + if (rowObject.get(key) != null) { + childLst = (JSONArray) rowObject.get(key); + } + childLst.add(childObj); + rowObject.put(key, childLst); + + childObj = new JSONObject(); + childLst = new JSONArray(); + } + } + rowsMap.put(id, rowObject); + } + + for (String rowId : rowsMap.keySet()) { + for (String col : duplicateColumnLst) { + rowsMap.get(rowId).remove(col); + } + rows.add(rowsMap.get(rowId)); + } + return rows; + } + + public Map> preProcessSoldierData(JSONArray rows) { + Map tempStringVsStringMap; + JSONObject eachSoldierData; + + for (int i = 0; i < rows.size(); i++) { + eachSoldierData = (JSONObject) rows.get(i); + + tempStringVsStringMap = new HashMap<>(); + + for (Object key : eachSoldierData.keySet()) { + if(eachSoldierData.get(key) instanceof String){ + tempStringVsStringMap.put(key.toString(), eachSoldierData.get(key).toString()); + } + } + + if (eachSoldierData.get("birthDate") != null) { + soldierAllDOBMap.put(eachSoldierData.get("birthDate").toString() + "__" + datesFlag, " "); + soldierDatesMap.put(eachSoldierData.get("birthDate").toString() + "__" + datesFlag, "basicInfo__" + String.valueOf(i)); + soldierCorrectDatesMap.put(eachSoldierData.get("birthDate").toString() + "__" + datesFlag, eachSoldierData.get("birthDate").toString()); + datesFlag++; + } + soldierDataMap.put("basicInfo__" + i, tempStringVsStringMap); + + extractDecorationData(eachSoldierData); + extractRegimentData(eachSoldierData); + extractRankData(eachSoldierData); + } + + soldierDataMap.put("dates", soldierDatesMap); + soldierDataMap.put("correctDates", soldierCorrectDatesMap); + soldierDataMap.put("allDOB", soldierAllDOBMap); + soldierDataMap.put("allRanks", soldierAllRanksMap); + soldierDataMap.put("allDecoration", soldierAllDecorationsMap); + soldierDataMap.put("allRegiment", soldierAllRegimentsMap); + + return soldierDataMap; + } + + + public void extractDecorationData(JSONObject eachSoldierData) { + JSONObject decorationInfoObject; + JSONArray decorationInformation; + Map tempStringVsStringMap; + + decorationInformation = (JSONArray) eachSoldierData.get("decorationInfo"); + + for (int j = 0; j < decorationInformation.size(); j++) { + decorationInfoObject = (JSONObject) decorationInformation.get(j); + tempStringVsStringMap = new HashMap<>(); + for (Object key : decorationInfoObject.keySet()) { + if(decorationInfoObject.get(key) instanceof String){ + tempStringVsStringMap.put(key.toString(), decorationInfoObject.get(key).toString()); + } + } + if (decorationInfoObject.get("applicableFrom_inXSDDate") != null) { + soldierAllDecorationsMap.put(decorationInfoObject.get("applicableFrom_inXSDDate").toString() + "__" + datesFlag, " "); + soldierDatesMap.put(decorationInfoObject.get("applicableFrom_inXSDDate").toString() + "__" + datesFlag, "decorationInfo__" + j); + soldierCorrectDatesMap.put(decorationInfoObject.get("applicableFrom_inXSDDate").toString() + "__" + datesFlag, decorationInfoObject.get("applicableFrom_inXSDDate").toString()); + datesFlag++; + } + soldierDataMap.put("decorationInfo__" + j, tempStringVsStringMap); + } + } + + public void extractRegimentData(JSONObject eachSoldierData) { + JSONObject regimentInfoObject; + JSONArray regimentInformation; + Map tempStringVsStringMap; + + regimentInformation = (JSONArray) eachSoldierData.get("hasRegiment"); + for (int j = 0; j < regimentInformation.size(); j++) { + regimentInfoObject = (JSONObject) regimentInformation.get(j); + + tempStringVsStringMap = new HashMap<>(); + for (Object key : regimentInfoObject.keySet()) { + if(regimentInfoObject.get(key) instanceof String){ + tempStringVsStringMap.put(key.toString(), regimentInfoObject.get(key).toString()); + } + } + if (regimentInfoObject.get("applicableFrom_inXSDDate") != null) { + soldierAllRegimentsMap.put(regimentInfoObject.get("applicableFrom_inXSDDate").toString() + "__" + datesFlag, " "); + soldierDatesMap.put(regimentInfoObject.get("applicableFrom_inXSDDate").toString() + "__" + datesFlag, "regimentInfo__" + j); + soldierCorrectDatesMap.put(regimentInfoObject.get("applicableFrom_inXSDDate").toString() + "__" + datesFlag, regimentInfoObject.get("applicableFrom_inXSDDate").toString()); + datesFlag++; + } + soldierDataMap.put("regimentInfo__" + j, tempStringVsStringMap); + } + } + + public void extractRankData(JSONObject eachSoldierData) { + JSONObject rankInfoObject; + JSONArray rankInformation; + Map tempStringVsStringMap; + + rankInformation = (JSONArray) eachSoldierData.get("rankInfo"); + for (int j = 0; j < rankInformation.size(); j++) { + rankInfoObject = (JSONObject) rankInformation.get(j); + tempStringVsStringMap = new HashMap<>(); + + for (Object key : rankInfoObject.keySet()) { + if(rankInfoObject.get(key) instanceof String){ + tempStringVsStringMap.put(key.toString(), rankInfoObject.get(key).toString()); + } + } + if (rankInfoObject.get("applicableFrom_inXSDDate") != null) { + soldierAllRanksMap.put(rankInfoObject.get("applicableFrom_inXSDDate").toString() + "__" + datesFlag, " "); + soldierDatesMap.put(rankInfoObject.get("applicableFrom_inXSDDate").toString() + "__" + datesFlag, "rankInfo__" + j); + soldierCorrectDatesMap.put(rankInfoObject.get("applicableFrom_inXSDDate").toString() + "__" + datesFlag, rankInfoObject.get("applicableFrom_inXSDDate").toString()); + datesFlag++; + } + soldierDataMap.put("rankInfo__" + j, tempStringVsStringMap); + } + } + + public Map getResource(String sub, String dataset) { + Map map = new HashMap<>(); + Map childRef = new HashMap<>(); + String key = ""; + String value = ""; + QuerySolution resource; + String queryString = PREFIXES + + "SELECT *\n" + + "WHERE {\n" + + " <" + sub + "> ?p ?o;\n" + + " FILTER ( ?p != rdf:type)\n" + + "}"; + ResultSet resultSet = getResultFromQuery(queryString, dataset); + while (resultSet.hasNext()) { + resource = resultSet.next(); + key = resource.get("p").asNode().getURI(); + + if (key.contains("#")) { + key = key.substring(key.lastIndexOf("#") + 1); + } else { + key = key.substring(key.lastIndexOf("/") + 1); + } + + if (resource.get("o").isLiteral()) { + value = resource.get("o").asLiteral().getString(); + map.put(key, value); + } else { + value = resource.get("o").asNode().getURI(); + childRef = getResource(value, dataset); + for (String k : childRef.keySet()) { + map.put(key + "_" + k, childRef.get(k)); + } + /*JSONObject childObj = new JSONObject(); + JSONArray childLst = new JSONArray(); + for (String k : childRef.keySet()) { + childObj.put(k, childRef.get(k)); + } + childLst.add(childObj); + map.put(key, childLst.toString());*/ + } + } + return map; + } +} diff --git a/ida-ws/src/main/java/upb/ida/provider/RiveScriptBeanProvider.java b/ida-ws/src/main/java/upb/ida/provider/RiveScriptBeanProvider.java index 46904ec5a..d44a8d447 100644 --- a/ida-ws/src/main/java/upb/ida/provider/RiveScriptBeanProvider.java +++ b/ida-ws/src/main/java/upb/ida/provider/RiveScriptBeanProvider.java @@ -1,90 +1,93 @@ -package upb.ida.provider; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.stereotype.Component; - -import com.rivescript.Config; -import com.rivescript.RiveScript; - -import upb.ida.constant.IDALiteral; -import upb.ida.temp.ExampleMacro; -import upb.ida.util.FileUtil; - - -/** - * Beans provider for the rivescript bot instance - * - */ - -@Component -public class RiveScriptBeanProvider { - - @Autowired - private LoadDataContent loadDataContent; - @Autowired - private FdgHandler fdgHandler; - @Autowired - private BgdHandler bgdHandler; - @Autowired - private ClusterConHandler clusterConHandler; - @Autowired - private ParamsHandler paramsHandler; - @Autowired - private UserParamEntry userParamEntry; - @Autowired - private UserParamValueCollector userParamValueCollector; - @Autowired - private ClusterDataGetter clusterDataGetter; - @Autowired - private CheckParamCollected checkParamCollected; - @Autowired - private FileUtil demoMain; - @Autowired - private LoadDsMetadata dsmdLoader; - @Autowired - private VennDiagramHandler VennDiagramHandler; - @Autowired - private GeoDiagramHandler GeoDiagramHandler; - @Autowired - private SSBDiagramHandler SSBDiagramHandler; - - /** - * Method to provide a session scoped bean for the RiveScript bot - * @return - RiveScript Instance - */ - @Bean - @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) - @Qualifier("sessionBotInstance") - public RiveScript initBotInstance() { - - RiveScript bot = new RiveScript(Config.utf8()); - - // Load the Rivescript directory. - bot.loadDirectory(demoMain.fetchSysFilePath(IDALiteral.RS_DIRPATH)); - - // Sort the replies and set Subroutine calls for designated functionality - bot.sortReplies(); - bot.setSubroutine("sayname", new ExampleMacro()); - bot.setSubroutine("loadDataset", loadDataContent); - bot.setSubroutine("FdgHandler", fdgHandler); - bot.setSubroutine("BgdHandler", bgdHandler); - bot.setSubroutine("ClusterConHandler", clusterConHandler); - bot.setSubroutine("ParamsHandler", paramsHandler); - bot.setSubroutine("UserParamEntry", userParamEntry); - bot.setSubroutine("UserParamValueCollector", userParamValueCollector); - bot.setSubroutine("ClusterDataGetter", clusterDataGetter); - bot.setSubroutine("CheckParamCollected", checkParamCollected); - bot.setSubroutine("LoadDsMetadata", dsmdLoader); - bot.setSubroutine("VennDiagramHandler", VennDiagramHandler); - bot.setSubroutine("GeoDiagramHandler", GeoDiagramHandler); - bot.setSubroutine("SSBDiagramHandler", SSBDiagramHandler); - return bot; - } - - - -} +package upb.ida.provider; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.stereotype.Component; + +import com.rivescript.Config; +import com.rivescript.RiveScript; + +import upb.ida.constant.IDALiteral; +import upb.ida.temp.ExampleMacro; +import upb.ida.util.FileUtil; + + +/** + * Beans provider for the rivescript bot instance + * + */ + +@Component +public class RiveScriptBeanProvider { + + @Autowired + private LoadDataContent loadDataContent; + @Autowired + private FdgHandler fdgHandler; + @Autowired + private BgdHandler bgdHandler; + @Autowired + private ClusterConHandler clusterConHandler; + @Autowired + private ParamsHandler paramsHandler; + @Autowired + private UserParamEntry userParamEntry; + @Autowired + private UserParamValueCollector userParamValueCollector; + @Autowired + private ClusterDataGetter clusterDataGetter; + @Autowired + private CheckParamCollected checkParamCollected; + @Autowired + private FileUtil demoMain; + @Autowired + private LoadDsMetadata dsmdLoader; + @Autowired + private VennDiagramHandler VennDiagramHandler; + @Autowired + private GeoDiagramHandler GeoDiagramHandler; + @Autowired + private SSBDiagramHandler SSBDiagramHandler; + @Autowired + private SoldierTimeLineHandler soldierTimeLineHandler; + + /** + * Method to provide a session scoped bean for the RiveScript bot + * @return - RiveScript Instance + */ + @Bean + @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) + @Qualifier("sessionBotInstance") + public RiveScript initBotInstance() { + + RiveScript bot = new RiveScript(Config.utf8()); + + // Load the Rivescript directory. + bot.loadDirectory(demoMain.fetchSysFilePath(IDALiteral.RS_DIRPATH)); + + // Sort the replies and set Subroutine calls for designated functionality + bot.sortReplies(); + bot.setSubroutine("sayname", new ExampleMacro()); + bot.setSubroutine("loadDataset", loadDataContent); + bot.setSubroutine("FdgHandler", fdgHandler); + bot.setSubroutine("BgdHandler", bgdHandler); + bot.setSubroutine("ClusterConHandler", clusterConHandler); + bot.setSubroutine("ParamsHandler", paramsHandler); + bot.setSubroutine("UserParamEntry", userParamEntry); + bot.setSubroutine("UserParamValueCollector", userParamValueCollector); + bot.setSubroutine("ClusterDataGetter", clusterDataGetter); + bot.setSubroutine("CheckParamCollected", checkParamCollected); + bot.setSubroutine("LoadDsMetadata", dsmdLoader); + bot.setSubroutine("VennDiagramHandler", VennDiagramHandler); + bot.setSubroutine("GeoDiagramHandler", GeoDiagramHandler); + bot.setSubroutine("SSBDiagramHandler", SSBDiagramHandler); + bot.setSubroutine("SoldierTimeLineHandler", soldierTimeLineHandler); + return bot; + } + + + +} diff --git a/ida-ws/src/main/java/upb/ida/provider/SoldierTimeLineHandler.java b/ida-ws/src/main/java/upb/ida/provider/SoldierTimeLineHandler.java new file mode 100644 index 000000000..5547e935b --- /dev/null +++ b/ida-ws/src/main/java/upb/ida/provider/SoldierTimeLineHandler.java @@ -0,0 +1,31 @@ +package upb.ida.provider; + +import com.rivescript.macro.Subroutine; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import upb.ida.bean.ResponseBean; +import upb.ida.constant.IDALiteral; +import upb.ida.dao.SoldierTimeLine; + +import java.util.Map; + +@Component +public class SoldierTimeLineHandler implements Subroutine { + @Autowired + private ResponseBean responseBean; + + @Autowired + private SoldierTimeLine soldierTimeLine; + + public String call (com.rivescript.RiveScript rs, String[] args) { + Map dataMap = responseBean.getPayload(); + responseBean.setActnCode(10); + try { + dataMap.put("soldierTimeLineData", soldierTimeLine.getData(args[0], "ssfuehrer")); + return IDALiteral.RESP_PASS_ROUTINE; + } catch (Exception ex){ + System.out.println(ex.getMessage()); + } + return IDALiteral.RESP_FAIL_ROUTINE; + } +} diff --git a/ida-ws/src/main/java/upb/ida/rest/MessageRestController.java b/ida-ws/src/main/java/upb/ida/rest/MessageRestController.java index 7efc536a5..0787fe74f 100644 --- a/ida-ws/src/main/java/upb/ida/rest/MessageRestController.java +++ b/ida-ws/src/main/java/upb/ida/rest/MessageRestController.java @@ -1,74 +1,74 @@ -package upb.ida.rest; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import upb.ida.bean.ResponseBean; -import upb.ida.service.DataService; -import upb.ida.service.RiveScriptService; - -/** - * Exposes RESTful RPCs for the IDA Chatbot - * - * @author Nikit - * - */ -@RestController -@CrossOrigin(origins = "*", allowCredentials = "true") -@RequestMapping("/message") -public class MessageRestController { - @Autowired - private ResponseBean response; - @Autowired - private RiveScriptService rsService; - @Autowired - private DataService dataService; - @RequestMapping("/sayhello") - public String greeting(@RequestParam(value = "name", defaultValue = "World") String name) { - return "Hello " + name + "!"; - } - /** - * Method to accept queries for the chatbot - * @param msg - query in natural language - * @param actvScrId - id of the active screen - * @param actvTbl - name of the active data table on screen - * @param actvDs - name of the active dataset on screen - * @return - instance of {@link ResponseBean} - * @throws Exception - */ - @RequestMapping("/sendmessage") - public ResponseBean sendmessage(@RequestParam(value = "msg") String msg, - @RequestParam(value = "actvScrId") String actvScrId, @RequestParam(value = "actvTbl") String actvTbl, - @RequestParam(value = "actvDs") String actvDs) throws Exception { - - Map dataMap = new HashMap<>(); - dataMap.put("actvScrId", actvScrId); - dataMap.put("actvTbl", actvTbl); - dataMap.put("actvDs", actvDs); - response.setPayload(dataMap); - String reply = rsService.getRSResponse(msg); - - response.setChatmsg(reply); - return response; - } - - @RequestMapping("/getdatatable") - public ResponseBean getDataTable(@RequestParam(value = "actvScrId") String actvScrId, @RequestParam(value = "actvTbl") String actvTbl, - @RequestParam(value = "actvDs") String actvDs) throws Exception { - - Map dataMap = new HashMap<>(); - dataMap.put("actvScrId", actvScrId); - dataMap.put("actvTbl", actvTbl); - dataMap.put("actvDs", actvDs); - response.setPayload(dataMap); - dataService.getDataTable(actvDs, actvTbl); - return response; - } - -} \ No newline at end of file +package upb.ida.rest; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import upb.ida.bean.ResponseBean; +import upb.ida.service.DataService; +import upb.ida.service.RiveScriptService; + +/** + * Exposes RESTful RPCs for the IDA Chatbot + * + * @author Nikit + * + */ +@RestController +@CrossOrigin(origins = "*", allowCredentials = "true") +@RequestMapping("/message") +public class MessageRestController { + @Autowired + private ResponseBean response; + @Autowired + private RiveScriptService rsService; + @Autowired + private DataService dataService; + @RequestMapping("/sayhello") + public String greeting(@RequestParam(value = "name", defaultValue = "World") String name) { + return "Hello " + name + "!"; + } + /** + * Method to accept queries for the chatbot + * @param msg - query in natural language + * @param actvScrId - id of the active screen + * @param actvTbl - name of the active data table on screen + * @param actvDs - name of the active dataset on screen + * @return - instance of {@link ResponseBean} + * @throws Exception + */ + @RequestMapping("/sendmessage") + public ResponseBean sendmessage(@RequestParam(value = "msg") String msg, + @RequestParam(value = "actvScrId") String actvScrId, @RequestParam(value = "actvTbl") String actvTbl, + @RequestParam(value = "actvDs") String actvDs) throws Exception { + + Map dataMap = new HashMap<>(); + dataMap.put("actvScrId", actvScrId); + dataMap.put("actvTbl", actvTbl); + dataMap.put("actvDs", actvDs); + response.setPayload(dataMap); + String reply = rsService.getRSResponse(msg); + + response.setChatmsg(reply); + return response; + } + + @RequestMapping("/getdatatable") + public ResponseBean getDataTable(@RequestParam(value = "actvScrId") String actvScrId, @RequestParam(value = "actvTbl") String actvTbl, + @RequestParam(value = "actvDs") String actvDs) throws Exception { + + Map dataMap = new HashMap<>(); + dataMap.put("actvScrId", actvScrId); + dataMap.put("actvTbl", actvTbl); + dataMap.put("actvDs", actvDs); + response.setPayload(dataMap); + dataService.getDataTable(actvDs, actvTbl); + return response; + } + +} diff --git a/ida-ws/src/main/resources/dataset/test-soldier.ttl b/ida-ws/src/main/resources/dataset/test-soldier.ttl new file mode 100644 index 000000000..eb77fdae8 --- /dev/null +++ b/ida-ws/src/main/resources/dataset/test-soldier.ttl @@ -0,0 +1,120 @@ +@prefix owl: . +@prefix rdf: . +@prefix xml: . +@prefix foaf: . +@prefix xsd: . +@prefix dbo: . +@prefix time: . +@prefix rdfs: . +@prefix dc: . +@prefix dbr: . +@prefix regiment: . +@prefix rank: . +@prefix decoration: . +@prefix literature: . +@prefix soldier: . +@prefix soldier_decoration: . +@prefix soldier_regiment: . +@prefix soldier_rank: . +@prefix soldier_literature: . +@prefix : . +@base . + + +#######Soldier Information######## +soldier:47540 + rdf:type owl:NamedIndividual, :Soldier ; + :id 47540 ; + :membershipNumber 12345 ; + dbo:firstName "John"^^xsd:string ; + dbo:lastName "Doe"^^xsd:string ; + dbo:birthDate "1854-01-01"^^xsd:date ; + :NSDAPNumber 443322 ; + :DALVerified true ; + rdfs:label "Doe, John" . + + +######Decoration########## +soldier_decoration:35189 + rdf:type owl:NamedIndividual, :DecorationEvent ; + :id 35189 ; + :hasDecoration decoration:420 ; + :applicableFrom soldier_decoration:soldier_decoration_from_35189 ; + rdfs:label "Soldier Decoration: 35189" . + +soldier_decoration:soldier_decoration_from_35189 + rdf:type owl:NamedIndividual, time:Instant ; + time:inXSDDate "1875-11-01"^^xsd:date . + +soldier:47540 :decorationInfo soldier_decoration:35189 . + + +###########Regiment######## +soldier_regiment:7253 + rdf:type owl:NamedIndividual, :SoldierRegimentInfo ; + :id 7253 ; + :regimentInfo regiment:271 ; + :applicableFrom soldier_regiment:soldier_regiment_from_7253 ; + rdfs:label "Soldier Regiment: 7253" . + +soldier_regiment:soldier_regiment_from_7253 + rdf:type owl:NamedIndividual, time:Instant ; + time:inXSDDate "1887-11-25"^^xsd:date . + +soldier:47540 :hasRegiment soldier_regiment:7253 . +## + + +## +soldier_rank:24680 + rdf:type owl:NamedIndividual, :SoldierRankInfo ; + :id 24680 ; + :hasRank rank:23 ; + :applicableFrom soldier_rank:soldier_rank_from_24680 ; + rdfs:label "Soldier Rank: 24680" . + +soldier_rank:soldier_rank_from_24680 + rdf:type owl:NamedIndividual, time:Instant ; + time:inXSDDate "1885-05-01"^^xsd:date . + +soldier:47540 :rankInfo soldier_rank:24680 . +## + + +## +regiment:271 + rdf:type owl:NamedIndividual, :Regiment ; + :id 271 ; + :name "North West"^^xsd:string ; + :abbreviation "NW"^^xsd:string ; + rdfs:label "North West" . +## + +## +decoration:420 + rdf:type owl:NamedIndividual, :Decoration ; + :id 420 ; + :name "Officer"^^xsd:string ; + :abbreviation "OFR"^^xsd:string ; + time:hasBeginning decoration:decoration_start_420 ; + time:hasEnd decoration:decoration_end_420 ; + rdfs:label "Officer" . + +decoration:decoration_end_420 + rdf:type owl:NamedIndividual, time:Instant ; + time:inXSDDate "1875-11-20"^^xsd:date . + +decoration:decoration_start_420 + rdf:type owl:NamedIndividual, time:Instant ; + time:inXSDDate "1880-06-05"^^xsd:date . + +## + +## +rank:23 + rdf:type owl:NamedIndividual, :Rank ; + :id 23 ; + :name "Colonel"^^xsd:string ; + :sortation 23 ; + rdfs:label "Colonel" . +## diff --git a/ida-ws/src/main/resources/rivescript/ida-soldier-Timeline.rive b/ida-ws/src/main/resources/rivescript/ida-soldier-Timeline.rive new file mode 100644 index 000000000..19cd02463 --- /dev/null +++ b/ida-ws/src/main/resources/rivescript/ida-soldier-Timeline.rive @@ -0,0 +1,13 @@ +! version = 2.0 + +//User queries for soldier career timeline + ++ i want a soldier career timeline for * +* SoldierTimeLineHandler "" == pass => Your requested +^ \sSoldier Timeline is now added to the main view + ++ i want career timeline for * +@ i want a soldier career timeline for + ++ i want timeline for * +@ i want a soldier career timeline for diff --git a/ida-ws/src/test/java/upb/ida/test/SoldierTimelineTest.java b/ida-ws/src/test/java/upb/ida/test/SoldierTimelineTest.java new file mode 100644 index 000000000..101baf1c8 --- /dev/null +++ b/ida-ws/src/test/java/upb/ida/test/SoldierTimelineTest.java @@ -0,0 +1,53 @@ +package upb.ida.test; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import upb.ida.Application; +import upb.ida.dao.SoldierTimeLine; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +@RunWith(SpringRunner.class) +@WebAppConfiguration +@ContextConfiguration(classes = { Application.class }) +public class SoldierTimelineTest { + @Autowired + private SoldierTimeLine soldierTimeLine; + + @Test + public void soldierDataTestPos(){ + Map expected = new HashMap<>(); + expected.put("membershipNumber", "12345"); + expected.put("firstName", "John"); + expected.put("lastName", "Doe"); + expected.put("DALVerified", "true"); + expected.put("id", "47540"); + expected.put("label", "Doe, John"); + expected.put("birthDate", "1854-01-01"); + expected.put("NSDAPNumber", "443322"); + Map actual = soldierTimeLine.getData("47540", "test").get("basicInfo__0"); + assertEquals(expected, actual); + } + + @Test + public void soldierDataTestNeg(){ + Map expected = new HashMap<>(); + expected.put("membershipNumber", "23466y"); + expected.put("firstName", "Jane"); + expected.put("DALVerified", "true"); + expected.put("id", "47540"); + expected.put("label", "Doe, John"); + expected.put("birthDate", "1855-01-01"); + expected.put("NSDAPNumber", "23456"); + Map actual = soldierTimeLine.getData("47540", "test").get("basicInfo__0"); + assertNotEquals(expected, actual); + } +}