11package gov .pnnl .goss .gridappsd .data ;
22
33import java .io .ByteArrayOutputStream ;
4+ import java .io .File ;
5+ import java .io .FileOutputStream ;
46import java .io .StringWriter ;
7+ import java .net .URL ;
58import java .util .ArrayList ;
9+ import java .util .Date ;
610import java .util .HashMap ;
11+ import java .util .HashSet ;
712import java .util .List ;
13+ import java .util .PriorityQueue ;
14+ import java .util .Queue ;
815
916import javax .xml .parsers .DocumentBuilder ;
1017import 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