/******************************************************************************* * Copyright (c) 2011,2013 IBM Corporation. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. * * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * * Masaki Wakao * Yoshio Horiuchi * Kohji Ohsawa *******************************************************************************/ package org.eclipse.lyo.samples.excel.adapter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.eclipse.lyo.core.query.NestedProperty; import org.eclipse.lyo.core.query.PName; import org.eclipse.lyo.core.query.ParseException; import org.eclipse.lyo.core.query.Property; import org.eclipse.lyo.core.query.QueryUtils; import org.eclipse.lyo.core.query.SelectClause; import org.eclipse.lyo.rio.query.OslcWhereHelper.OslcWhereParseException; import org.eclipse.lyo.rio.query.SimpleQueryBuilder; import org.eclipse.lyo.samples.excel.adapter.common.ResourceSet; import org.eclipse.lyo.samples.excel.common.ConfigSingleton; import org.eclipse.lyo.samples.excel.services.common.ServiceProviderService; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.RDFWriter; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.vocabulary.RDFS; public class ModelQuery { class ResourceSetImpl implements ResourceSet { private Model model; public ResourceSetImpl(Model model) { this.model = model; } public void outputAsXML(OutputStream out) { RDFWriter w = model.getWriter("RDF/XML-ABBREV"); w.setProperty("showXMLDeclaration", "true"); w.write(model, out, ""); } } class QueryResultResourceSet implements ResourceSet { private String requestUri; private List<Model> list = new ArrayList<Model>(); public void addRequestUri(String requestUri) { this.requestUri = requestUri; } public void addModel(Model model) { list.add(model); } private byte[] getModelByteArray(Model model) { ByteArrayOutputStream os = new ByteArrayOutputStream(); RDFWriter w = model.getWriter("RDF/XML-ABBREV"); w.setProperty("showXMLDeclaration", "true"); w.write(model, os, ""); return os.toByteArray(); } private int[] findResourcePos(byte[] b) { int start = 0; boolean openTag = false; for (int i = 0; i < b.length; i++) { if (openTag && b[i] == '>') { start = i + 1; break; } if (b[i] == 'R' && (i + 1 < b.length && b[i + 1] == 'D') && (i + 2 < b.length && b[i + 2] == 'F')) { openTag = true; } } int end = b.length - 1; boolean closeTag = false; for (int i = b.length - 1; i >= 0; i--) { if (closeTag && b[i] == '<') { end = i - 1; break; } if (b[i] == 'F' && (i - 1 >= 0 && b[i - 1] == 'D') && (i - 2 >= 0 && b[i - 2] == 'R')) { closeTag = true; } } if (start < end) { return new int[] { start, end }; } else { return new int[] { 0, b.length - 1 }; } } public void outputAsXML(OutputStream out) { byte[] close = new byte[0]; for (int i = 0; i < list.size(); i++) { Model model = list.get(i); try { byte[] b = getModelByteArray(model); // one model, one resource int[] pos = findResourcePos(b); int start; int end; // write open tag if (i == 0) { start = 0; end = pos[0] - 1; out.write(b, start, end - start + 1); out.write("\n".getBytes()); out.write(new String("<rdf:Description rdf:about=\"" + requestUri + "\">\n").getBytes()); } // write resource contents out.write(new String("<!-- " + i + " -->").getBytes()); start = pos[0]; end = pos[1]; out.write(new String("<rdfs:member>").getBytes()); out.write(b, start, end - start + 1); out.write(new String("</rdfs:member>").getBytes()); // store close tag to a buffer, and append it later if (i == 0) { start = pos[1] + 1; end = b.length - 1; ByteArrayOutputStream os = new ByteArrayOutputStream(); os.write(b, start, end - start + 1); close = os.toByteArray(); } } catch (IOException e) { e.printStackTrace(); } } try { // write close tag if(list.isEmpty()){ out.write(new String("<rdf:Description xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>\n").getBytes()); } out.write(new String("</rdf:Description>\n").getBytes()); out.write(close); } catch (IOException e) { e.printStackTrace(); } } } public ResourceSet query(String requestUri, String uri, ModelManager modelManager, String prefix, String select, String where, String orderBy, String searchTerms) { ModelGroup modelGroup = modelManager.getModelGroup(uri); Model model = modelGroup.getModel(); System.out.println("original model :"); printModel(model); SimpleQueryBuilder queryBuilder = new SimpleQueryBuilder(); try { queryBuilder.parsePrefix(prefix); for (Entry<String, String> e : ConfigSingleton.getInstance().getNsPrefixes().entrySet()) { queryBuilder.addPrefix(e.getValue(), e.getKey()); } queryBuilder.parseSelect(select); if (where != null && !where.isEmpty()) { queryBuilder.parseWhere("uri", where); //$NON-NLS-1$ } String targetResourceType = getQueryResourceType(requestUri); if (targetResourceType != null) { queryBuilder.appendWhere("?uri a <" + targetResourceType + "> ."); } else { queryBuilder.appendWhere("?uri a ?type ."); } queryBuilder.parseSelect(orderBy); queryBuilder.parseSearchTerms(searchTerms); } catch (OslcWhereParseException e) { e.printStackTrace(); } Map<String, String> prefixMap = null; SelectClause selectClause = null; try { if (select != null) { prefixMap = QueryUtils.parsePrefixes(prefix); prefixMap.putAll(ConfigSingleton.getInstance().getNsPrefixes()); selectClause = QueryUtils.parseSelect(select, prefixMap); } } catch (ParseException e) { } String sparql = queryBuilder.getQueryString(null); System.out.println("query:"); System.out.println(sparql); Query query = QueryFactory.create(sparql); QueryExecution qexec = QueryExecutionFactory.create(query, model); ResultSet result = qexec.execSelect(); QueryResultResourceSet rs = new QueryResultResourceSet(); rs.addRequestUri(requestUri); try { while (result.hasNext()) { Model retModel = ModelFactory.createDefaultModel(); retModel.setNsPrefixes(ConfigSingleton.getInstance().getNsPrefixes()); retModel.setNsPrefix("rdfs", RDFS.getURI()); QuerySolution qs = result.next(); Resource r = (Resource) qs.get("uri"); System.out.println(r); Resource o = model.getResource(r.getURI()); StmtIterator si = o.listProperties(); while (si.hasNext()) { Statement s = si.nextStatement(); System.out.println("stmt: " + s); retModel.add(s); // if (selectClause != null) { ArrayList<String> nameList = new ArrayList<String>(); nameList.add(s.getPredicate().getURI()); if (isNested(nameList, selectClause, prefixMap)) { setStatements(retModel, s.getObject().asResource(), nameList, selectClause, prefixMap); } } } rs.addModel(retModel); } } finally { qexec.close(); } return rs; } private void setStatements(Model model, Resource resource, List<String> nameList, SelectClause selectClause, Map<String, String> prefixMap) { System.out.println(nameList + " is nested property..."); StmtIterator si = resource.listProperties(); while (si.hasNext()) { Statement s = si.nextStatement(); System.out.println("stmt: " + s); model.add(s); // ArrayList<String> nextNameList = new ArrayList<String>(nameList); nextNameList.add(s.getPredicate().getURI()); if (isNested(nextNameList, selectClause, prefixMap)) { setStatements(model, s.getObject().asResource(), nextNameList, selectClause, prefixMap); } } } private boolean isNested(List<String> nameList, SelectClause sel, Map<String, String> prefixMap) { List<Property> children = sel.children(); for (int i = 0; i < children.size(); i++) { Property child = children.get(i); if (isNested(nameList, child, prefixMap)) { return true; } } return false; } private boolean isNested(List<String> nameList, Property p, Map<String, String> prefixMap) { if (nameList.isEmpty()) { return false; } if (p instanceof NestedProperty) { String name = nameList.get(0); if (p.isWildcard() || equalPName(p.identifier(), name, prefixMap)) { if (nameList.size() == 1) { return true; } ArrayList<String> nextNameList = new ArrayList<String>(); for (int i = 1; i < nameList.size(); i++) { nextNameList.add(nameList.get(i)); } List<Property> children = ((NestedProperty)p).children(); for (int i = 0; i < children.size(); i++) { Property child = children.get(i); if (isNested(nextNameList, child, prefixMap)) { return true; } } } } return false; } private String getNameUri(String name, Map<String, String> prefixMap) { Set<String> keys = prefixMap.keySet(); Iterator<String> ite = keys.iterator(); String prefix = null; while (ite.hasNext()) { String key = ite.next(); if (name.startsWith(key + ":")) { prefix = key; } } if (prefix != null) { String uri = prefixMap.get(prefix); return name.replaceFirst(prefix + ":", uri); } return name; } private boolean equalPName(PName pname, String uri, Map<String, String> prefixMap) { String pnameUri = getNameUri(pname.toString(), prefixMap); return pnameUri.equals(uri); } /** * should be sync with {@link ServiceProviderService#buildServicesResource(String, String)} */ private String getQueryResourceType(String uri){ Map<String, String> queryCapabilities = ConfigSingleton.getInstance().getQueryCapabilities(); for(String uriLastSegment: queryCapabilities.keySet()){ if(uri.endsWith(uriLastSegment)){ return queryCapabilities.get(uriLastSegment); } } return null; } public ResourceSet getResource(ModelManager modelManager, String resourceUri) { Iterator<ModelGroup> iterator = modelManager.getModelGroups().iterator(); while (iterator.hasNext()) { ModelGroup modelGroup = iterator.next(); Model model = modelGroup.getModel(); Resource r = model.getResource(resourceUri); if (r != null) { Model retModel = ModelFactory.createDefaultModel(); retModel.setNsPrefixes(ConfigSingleton.getInstance().getNsPrefixes()); Resource o = retModel.createResource(r.getURI()); System.out.println(o); StmtIterator si = r.listProperties(); while (si.hasNext()) { Statement s = si.nextStatement(); System.out.println("stmt: " + s); retModel.add(s); } return new ResourceSetImpl(retModel); } } return null; } private void printModel(Model model) { try { RDFWriter w = model.getWriter("RDF/XML-ABBREV"); w.setProperty("showXMLDeclaration", "true"); w.write(model, System.out, ""); } catch (Exception e){ e.printStackTrace(); } } public ResultSet executeSparql(String uri, ModelManager modelManager, String queryExp) { ModelGroup modelGroup = modelManager.getModelGroup(uri); Model model = modelGroup.getModel(); Query query = QueryFactory.create(queryExp); QueryExecution qexec = QueryExecutionFactory.create(query, model); return qexec.execSelect(); } }