Skip to content

Commit c721ad6

Browse files
authored
Merge pull request #1522 from GRIDAPPSD/releases/2021.04.0
Release of version 2021.04.0
2 parents a2064a2 + 9d440b7 commit c721ad6

File tree

5 files changed

+503
-186
lines changed

5 files changed

+503
-186
lines changed

gov.pnnl.goss.gridappsd/src/gov/pnnl/goss/gridappsd/data/BGPowergridModelDataManagerImpl.java

Lines changed: 274 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
package gov.pnnl.goss.gridappsd.data;
22

33
import java.io.ByteArrayOutputStream;
4+
import java.io.File;
5+
import java.io.FileOutputStream;
46
import java.io.StringWriter;
7+
import java.net.URL;
58
import java.util.ArrayList;
9+
import java.util.Date;
610
import java.util.HashMap;
11+
import java.util.HashSet;
712
import java.util.List;
13+
import java.util.PriorityQueue;
14+
import java.util.Queue;
815

916
import javax.xml.parsers.DocumentBuilder;
1017
import javax.xml.parsers.DocumentBuilderFactory;
@@ -125,17 +132,30 @@ public static void main(String[] args){
125132
// " ?tank c:TransformerTank.PowerTransformer ?pxf."+
126133
// " ?pxf c:IdentifiedObject.name ?key"+
127134
// "} GROUP BY ?key ORDER BY ?key";
128-
//BGPowergridModelDataManagerImpl bg = new BGPowergridModelDataManagerImpl("http://localhost:9999/blazegraph/namespace/kb/sparql");
129-
BGPowergridModelDataManagerImpl bg = new BGPowergridModelDataManagerImpl("http://192.168.99.100:8889/bigdata/namespace/kb/sparql");
130-
bg.endpointNSURL = "http://localhost:8889/bigdata/sparql";
135+
// BGPowergridModelDataManagerImpl bg = new BGPowergridModelDataManagerImpl("http://localhost:9999/blazegraph/namespace/kb/sparql");
136+
// BGPowergridModelDataManagerImpl bg = new BGPowergridModelDataManagerImpl("http://192.168.99.100:8889/bigdata/namespace/kb/sparql");
137+
BGPowergridModelDataManagerImpl bg = new BGPowergridModelDataManagerImpl("http://localhost:8889/bigdata/namespace/kb/sparql");
138+
139+
bg.endpointNSURL = "http://localhost:8889/bigdata/namespace/kb/sparql";
131140
try {
132141
// String query = "select ?s ?p ?o where {?s r:type c:ConnectivityNode. ?s ?p ?o}";
133142
// System.out.println(bg.query("ieee13", query, "JSON"));
134143

135144
// bg.queryObject("ieee13", "_211AEE43-D357-463C-95B9-184942ABE3E5", "JSON");
136145
// System.out.println(bg.queryObjectTypes("_4F76A5F9-271D-9EB8-5E31-AA362D86F2C3", "JSON", "12345", "user"));
137-
// System.out.println(bg.queryModelNameList("12345", "user"));
138-
// System.out.println(bg.queryModel("_4F76A5F9-271D-9EB8-5E31-AA362D86F2C3", "http://iec.ch/TC57/2012/CIM-schema-cim17#PowerTransformer", "?s c:IdentifiedObject.name 't5138260a'", "JSON", "12345", "user"));
146+
System.out.println(bg.queryModelNameList("12345", "user"));
147+
long start = new Date().getTime();
148+
String model = bg.queryModel("_4F76A5F9-271D-9EB8-5E31-AA362D86F2C3", "", "", "XML", "12345", "user");
149+
// String model = bg.queryModel("_503D6E20-F499-4CC7-8051-971E23D0BF79", "", "", "XML", "12345", "user");
150+
151+
152+
FileOutputStream fout = new FileOutputStream(new File("xml_new_full.xml"));
153+
fout.write(model.getBytes());
154+
fout.flush();
155+
fout.close();
156+
long end = new Date().getTime();
157+
System.out.println("Took "+((end-start)/1000));
158+
// System.out.println(bg.queryModel("_4F76A5F9-271D-9EB8-5E31-AA362D86F2C3", "", "", "XML", "12345", "user"));
139159
// System.out.println(bg.queryModelNames("XML"));
140160
// System.out.println(bg.queryModelNamesAndIds("XML", "12345", "user"));
141161

@@ -154,8 +174,8 @@ public static void main(String[] args){
154174
// // TODO: handle exception
155175
// }
156176
// System.out.println(bg.queryObjectDictByType("JSON", "_4F76A5F9-271D-9EB8-5E31-AA362D86F2C3", "LinearShuntCompensator", null, "12345", "user")); //ieee8500
157-
System.out.println(bg.queryMeasurementDictByObject("JSON", "_4F76A5F9-271D-9EB8-5E31-AA362D86F2C3", null, "_7A02B3B0-2746-EB24-45A5-C3FBA8ACB88E", "12345", "user"));
158-
System.out.println(bg.queryMeasurementDictByObject("JSON", "_4F76A5F9-271D-9EB8-5E31-AA362D86F2C3", "LinearShuntCompensator", null, "12345", "user"));
177+
// System.out.println(bg.queryMeasurementDictByObject("JSON", "_4F76A5F9-271D-9EB8-5E31-AA362D86F2C3", null, "_7A02B3B0-2746-EB24-45A5-C3FBA8ACB88E", "12345", "user"));
178+
// System.out.println(bg.queryMeasurementDictByObject("JSON", "_4F76A5F9-271D-9EB8-5E31-AA362D86F2C3", "LinearShuntCompensator", null, "12345", "user"));
159179

160180
// System.out.println
161181
} catch (Exception e) {
@@ -267,42 +287,124 @@ public List<String> queryObjectTypeList(String modelId, String processId, String
267287
@Override
268288
public String queryModel(String modelId, String objectType, String filter, String resultFormat, String processId, String username) throws Exception {
269289
String result = null;
270-
ResultSet rs = queryModelResultSet(modelId, objectType, filter, processId, username);
290+
ResultSet rs = queryModelResultSet(modelId, objectType, filter, processId, username, true);
291+
HashSet<String> alreadySeen = new HashSet<String>();
292+
Queue<String> newIds = new PriorityQueue<String>();
293+
List<BGResult> results = new ArrayList<BGResult>();
294+
295+
//Tracks which subjects have been seen already and follows links to pull information on those that haven't been included yet
296+
while(rs.hasNext() || newIds.size()>0){
297+
while(rs.hasNext()){
298+
QuerySolution qs = rs.nextSolution();
299+
String subject = qs.getResource(SUBJECT).getLocalName();
300+
String subjectUri = qs.getResource(SUBJECT).getURI();
301+
String propertyName = qs.getResource(PREDICATE).getURI();
302+
303+
String value = "";
304+
if(qs.get(OBJECT).isLiteral()){
305+
Literal literal = qs.getLiteral(OBJECT);
306+
value = literal.toString();
307+
} else {
308+
Resource resource = qs.getResource(OBJECT);
309+
value = resource.toString();
310+
if(!alreadySeen.contains(value) && !newIds.contains(value)){
311+
newIds.add(value);
312+
}
313+
}
314+
if(!alreadySeen.contains(subjectUri)){
315+
alreadySeen.add(subjectUri);
316+
if(newIds.contains(subjectUri)){
317+
newIds.remove(subjectUri);
318+
}
319+
}
320+
BGResult r = new BGResult(subject, propertyName, value);
321+
results.add(r);
322+
}
323+
if(newIds.size()>0){
324+
//build query with new ids
325+
String newIdQuery = "CONSTRUCT {?s ?p ?o} WHERE { ";
326+
327+
for(int i=0;i<100 && newIds.size()>0; i++){
328+
String id = newIds.poll();
329+
newIdQuery = newIdQuery+"{ ?s ?p ?o . VALUES ?s { <"+id+"> }} UNION";
330+
if(!alreadySeen.contains(id)) {
331+
alreadySeen.add(id);
332+
}
333+
334+
}
335+
newIdQuery = newIdQuery.substring(0,newIdQuery.length()-6);
336+
newIdQuery = newIdQuery+" }";
337+
338+
BlazegraphQueryHandler queryHandler = new BlazegraphQueryHandler(getEndpointURL(modelId), logManager, processId, username);
339+
rs = queryHandler.construct(newIdQuery);
340+
341+
342+
343+
}
344+
345+
}
346+
271347
if(resultFormat.equals(ResultFormat.JSON.toString())){
272-
result = resultSetToJson(rs);
348+
result = resultSetToJson(results);
273349
} else if(resultFormat.equals(ResultFormat.XML.toString())){
274-
result = resultSetToXML(rs);
275-
// ResultSetFormatter.outputAsXML(resultString, rs);
350+
result = resultSetToXML(results);
276351
} else {
277-
//TODO throw error
352+
//TODO throw error??
278353
//logManager.log(new LogMessage(processId, timestamp, logMessage, logLevel, processStatus, storeToDb), username);
354+
355+
//OR JUST DEFAULT TO JSON
356+
result = resultSetToJson(results);
279357
}
280358

281359
//TODO
282-
logStatus("COMPLETE");
360+
logStatus("Generation of queryModel in "+resultFormat+" is complete");
283361

284362
return result;
285363

286364
}
287365
@Override
288366
public ResultSet queryModelResultSet(String modelId, String objectType, String filter, String processId, String username) {
367+
return queryModelResultSet(modelId, objectType, filter, processId, username, false);
368+
}
369+
370+
371+
protected ResultSet queryModelResultSet(String modelId, String objectType, String filter, String processId, String username, boolean multiLevel) {
289372
if(modelId==null){
290373
throw new RuntimeException("queryModel: model id missing");
291374
}
292375

293-
String query = "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o ";
294-
query = query+". ?s ?p2 <"+getEndpointNS(modelId)+"> ";
295-
if(objectType!=null && objectType.trim().length()>0){
296-
query = query+". ?s rdf:type <"+objectType+"> ";
297-
}
298-
if(filter!=null && filter.trim().length()>0){
299-
if(filter.startsWith(".")){
300-
filter = filter.substring(1);
376+
String query;
377+
if(multiLevel){
378+
query = "CONSTRUCT { ?s ?p ?o . ?o ?p3 ?o3 } WHERE { ?s ?p ?o ";
379+
query = query+". ?s ?p2 <"+getEndpointNS(modelId)+"> OPTIONAL {?o ?p3 ?o3 } ";
380+
if(objectType!=null && objectType.trim().length()>0){
381+
query = query+". ?s rdf:type <"+objectType+"> ";
382+
}
383+
if(filter!=null && filter.trim().length()>0){
384+
if(filter.startsWith(".")){
385+
filter = filter.substring(1);
386+
}
387+
query = query+". "+filter;
388+
}
389+
query = query+"}";
390+
} else {
391+
query = "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o ";
392+
query = query+". ?s ?p2 <"+getEndpointNS(modelId)+"> ";
393+
if(objectType!=null && objectType.trim().length()>0){
394+
query = query+". ?s rdf:type <"+objectType+"> ";
301395
}
302-
query = query+". "+filter;
396+
if(filter!=null && filter.trim().length()>0){
397+
if(filter.startsWith(".")){
398+
filter = filter.substring(1);
399+
}
400+
query = query+". "+filter;
401+
}
402+
query = query+"}";
303403
}
304-
query = query+"}";
305-
// System.out.println(query);
404+
405+
406+
407+
System.out.println(query);
306408

307409
BlazegraphQueryHandler queryHandler = new BlazegraphQueryHandler(getEndpointURL(modelId), logManager, processId, username);
308410
ResultSet rs = queryHandler.construct(query);
@@ -529,6 +631,8 @@ protected Element getXMLElementWithPrefix(Document rootDoc, String namespace, St
529631

530632
}
531633

634+
635+
532636
// protected void sendResult(String result, String resultTopic) throws Exception{
533637
// Credentials credentials = new UsernamePasswordCredentials(
534638
// GridAppsDConstants.username, GridAppsDConstants.password);
@@ -539,6 +643,50 @@ protected Element getXMLElementWithPrefix(Document rootDoc, String namespace, St
539643
// }
540644

541645

646+
647+
protected String resultSetToJson(List<BGResult> results){
648+
JsonArray resultArr = new JsonArray();
649+
String baseUrl = getEndpointNS(null);
650+
HashMap<String, JsonObject> resultObjects = new HashMap<String, JsonObject>();
651+
for(BGResult result: results) {
652+
String subject = result.getSubject();
653+
JsonObject obj = new JsonObject();
654+
if(resultObjects.containsKey(subject)){
655+
obj = resultObjects.get(subject);
656+
} else {
657+
obj.add("id", new JsonPrimitive(subject));
658+
resultObjects.put(subject, obj);
659+
}
660+
661+
String propertyName = result.getProperty();
662+
if(propertyName.startsWith(nsCIM)){
663+
propertyName = propertyName.substring(nsCIM.length());
664+
} else if(propertyName.startsWith(nsRDF)){
665+
propertyName = propertyName.substring(nsRDF.length());
666+
}
667+
668+
String value = result.getObject();
669+
670+
if(value.startsWith(baseUrl+"#")){
671+
value = value.substring(baseUrl.length()+1);
672+
} else if(value.startsWith(nsCIM)){
673+
value = value.substring(nsCIM.length());
674+
} else if(value.startsWith(nsRDF)){
675+
value = value.substring(nsRDF.length());
676+
}
677+
// }
678+
obj.add(propertyName, new JsonPrimitive(value));
679+
680+
}
681+
682+
for(JsonObject obj: resultObjects.values()){
683+
resultArr.add(obj);
684+
}
685+
686+
return resultArr.toString();
687+
}
688+
689+
542690
protected String resultSetToJson(ResultSet rs){
543691
JsonArray resultArr = new JsonArray();
544692
String baseUrl = getEndpointNS(null);
@@ -587,8 +735,110 @@ protected String resultSetToJson(ResultSet rs){
587735

588736
return resultArr.toString();
589737
}
738+
739+
740+
protected String resultSetToXML(List<BGResult> results) throws Exception {
741+
DocumentBuilderFactory factory =
742+
DocumentBuilderFactory.newInstance();
743+
factory.setNamespaceAware(true);
744+
745+
746+
DocumentBuilder builder =
747+
factory.newDocumentBuilder();
748+
Document rootDoc = builder.newDocument();
749+
Element rootElement = getXMLElementWithPrefix(rootDoc, nsRDF, "RDF");
750+
rootElement.setAttribute("xmlns:cim", nsCIM);
751+
rootElement.setAttribute("xmlns:rdf", nsRDF);
752+
rootDoc.appendChild(rootElement);
753+
754+
755+
String baseUrl = getEndpointNS(null);
756+
HashMap<String, List<Element>> resultObjects = new HashMap<String, List<Element>>();
757+
HashMap<String, String> resultTypes = new HashMap<String, String>();
758+
759+
for(BGResult result: results) {
760+
String subject = result.getSubject();
761+
List<Element> objs = null;
762+
if(resultObjects.containsKey(subject)){
763+
objs = resultObjects.get(subject);
764+
} else {
765+
objs = new ArrayList<Element>();
766+
resultObjects.put(subject, objs);
767+
}
768+
769+
String propertyName = result.getProperty();
770+
String value = result.getObject();
771+
772+
if(propertyName.equals(RDF_TYPE)){
773+
resultTypes.put(subject, value);
774+
} else {
775+
String ns = "";
776+
String localName = propertyName;
777+
if(propertyName.contains("#")){
778+
ns = propertyName.substring(0, propertyName.indexOf("#")+1);
779+
localName = propertyName.substring(propertyName.indexOf("#")+1);
780+
// System.out.println("GOT property NS "+ns+" LOCAL "+localName);
781+
}
782+
Element tmp = getXMLElementWithPrefix(rootDoc, ns, localName);
783+
if(!isValidURI(value)){
784+
tmp.setTextContent(value);
785+
} else {
786+
if(value.startsWith(baseUrl+"#")){
787+
value = value.substring(baseUrl.length());
788+
}
789+
tmp.setAttributeNS(nsRDF, RDF_RESOURCE, value);
790+
}
791+
objs.add(tmp);
792+
}
793+
794+
}
795+
796+
//Build result elements based on types and properties
797+
for(String subject: resultTypes.keySet()){
798+
// Resource subjectRes = resultTypes.get(subject);
799+
String subjectType = resultTypes.get(subject);
800+
String ns = "";
801+
String localName = subjectType;
802+
if(subjectType.contains("#")){
803+
ns = subjectType.substring(0, subjectType.indexOf("#")+1);
804+
localName = subjectType.substring(subjectType.indexOf("#")+1);
805+
}
806+
807+
808+
List<Element> elements = resultObjects.get(subject);
809+
Element element = getXMLElementWithPrefix(rootDoc, ns, localName);
810+
element.setAttributeNS(nsRDF, RDF_ID, subject);
811+
for(Element child: elements){
812+
element.appendChild(child);
813+
}
814+
rootElement.appendChild(element);
815+
}
816+
817+
818+
TransformerFactory tranFactory = TransformerFactory.newInstance();
819+
Transformer transformer = tranFactory.newTransformer();
820+
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
821+
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
822+
823+
StringWriter resultWriter = new StringWriter();
824+
transformer.transform(new DOMSource(rootDoc), new StreamResult(resultWriter));
825+
return resultWriter.toString();
826+
}
590827

591828

829+
protected boolean isValidURI(String url){
830+
/* Try creating a valid URL */
831+
try {
832+
new URL(url).toURI();
833+
return true;
834+
}
835+
836+
// If there was an Exception
837+
// while creating URL object
838+
catch (Exception e) {
839+
return false;
840+
}
841+
}
592842
protected String resultSetToXML(ResultSet rs) throws Exception {
593843
DocumentBuilderFactory factory =
594844
DocumentBuilderFactory.newInstance();

0 commit comments

Comments
 (0)