/******************************************************************************* * Copyright (c) 2012 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: * * Keith Wells - initial API and implementation * Sam Padgett - initial API and Implementation * Jim Conallen - initial API and implementation * *******************************************************************************/ package org.eclipse.lyo.samples.sharepoint.store; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.wink.json4j.JSONArray; import org.apache.wink.json4j.JSONException; import org.apache.wink.json4j.JSONObject; import org.eclipse.lyo.samples.sharepoint.core.IConstants; import org.eclipse.lyo.samples.sharepoint.store.ShareValue.ShareValueType; public class JsonFormatter { private Map<String, String> namespacePrefixes = new HashMap<String, String>(); private Map<String, JSONObject> blankNodes = new HashMap<String, JSONObject>(); // private Map<String,Element> otherStatementIds = new HashMap<String,Element>(); // private Map<String,Element> idElm = new HashMap<String,Element>(); static private List<String> reifiedStatementProperties = null; static { reifiedStatementProperties = new ArrayList<String>(); reifiedStatementProperties.add(IConstants.RDF_STATEMENT); reifiedStatementProperties.add(IConstants.RDF_SUBJECT); reifiedStatementProperties.add(IConstants.RDF_PREDICATE); reifiedStatementProperties.add(IConstants.RDF_OBJECT); reifiedStatementProperties.add(IConstants.RDF_TYPE); } public JsonFormatter() { } /* * Resource */ static public String formatResource(ShareResource resource) throws ShareServerException { JsonFormatter formatter = new JsonFormatter(); return formatter.format(resource); } public void addNamespacePrefix(String ns, String prefix) { this.namespacePrefixes.put(ns, prefix); } public String format(ShareResource resource) throws ShareServerException { initPrefixes(); try { JSONObject jresource = new JSONObject(); jresource.put("rdf:about", resource.getUri()); List<ShareStatement> statements = resource.getStatements(); // find all reified statements, by looking for statement with type rdf:statement Iterator<ShareStatement> i = statements.iterator(); while (i.hasNext()) { ShareStatement statement = i.next(); String predicate = statement.getPredicate(); ShareValue object = statement.getObject(); // String IConstants.RDF_STATEMENT IConstants.RDF_TYPE if (IConstants.RDF_STATEMENT.equals(object.stringValue()) && IConstants.RDF_TYPE.equals(predicate)) { //createOtherDescription(statement, resource, jresource); } } //now get the rest of the statements for (ShareStatement statement : statements) { String subject = statement.getSubject(); String predicate = statement.getPredicate(); if (subject.equals(resource.getUri())) { ShareValue value = statement.getObject(); setValue(jresource, predicate, value, resource); String predObj = extractPredObj(statement); } else if (statement.isBNode()) { if (false) { ShareValue value = statement.getObject(); } } else { if (!isReifiedStatementProperty(predicate)) { // now put it in the right description String strSubj = subject.toString(); String id = extractUrlFragment(strSubj); if (false) { String[] nsLocal = extractNsLocal(predicate); String ns = nsLocal[0]; String local = nsLocal[1]; String prefix = nsLocal[2]; ShareValue value = statement.getObject(); } } } } // set namespaces and prefixes setNamespaces(jresource); return jresource.toString(4); } catch (Exception e) { throw new ShareServerException(e); } } /** * @param predicate * @return */ private String[] extractNsLocal(String uri) { int pos = uri.lastIndexOf('#'); if (pos < 0) { pos = uri.lastIndexOf('/'); } String namespace = uri.substring(0, pos + 1); String local = uri.substring(pos + 1); String prefix = this.getPrefix(namespace); return new String[]{namespace, local, prefix}; } private String extractUrlFragment(String uri) { int pos = uri.lastIndexOf('#'); if (pos > 0) { return uri.substring(pos + 1); } return null; } private String concatPredObj(String p, String o) { return '[' + p + ',' + o + ']'; } private String extractPredObj(ShareStatement statement) { String p = statement.getPredicate(); String o = statement.getObject().stringValue(); return concatPredObj(p, o); } private void setValue(JSONObject jresource, String predicate, ShareValue value, ShareResource resource) throws JSONException, IncompatibleValueException { String nsLocal[] = extractNsLocal(predicate); String ns = nsLocal[0]; String local = nsLocal[1]; String prefix = nsLocal[2]; String propertyName = prefix + ":" + local; if (getPrefix(ns) == null) { namespacePrefixes.put(ns, prefix); } JSONObject targetObject = null; JSONArray targetArray = null; if (jresource.containsKey(propertyName)) { // we have multiple values of this property if (jresource.get(propertyName) instanceof JSONArray) { // have an array, so fetch it targetArray = jresource.getJSONArray(propertyName); } else { // don't have an array yet, so create one Object firstValue = jresource.get(propertyName); targetArray = new JSONArray(); targetArray.add(firstValue); jresource.put(propertyName, targetArray); } } else { targetObject = jresource; } if (value.getType() == ShareValueType.BLANK_NODE) { List<ShareStatement> statements = resource.getStatements(value.stringValue(), IConstants.RDF_TYPE, null); if (statements.size() > 0) { ShareStatement bNodeTypeStatement = statements.get(0); ShareValue bNodeType = bNodeTypeStatement.getObject(); if (bNodeType.getType() == ShareValueType.URI) { String typeUri = bNodeType.stringValue(); if (IConstants.RDF_SEQ.equals(typeUri) || IConstants.RDF_BAG.equals(typeUri)) { JSONObject bnode = new JSONObject(); bnode.put(local, value); this.blankNodes.put(bNodeTypeStatement.getSubject(), bnode); } } } } else if (value.getType() == ShareValueType.URI) { JSONObject resourceValue = new JSONObject(); resourceValue.put("rdf:resource", value.stringValue()); if (targetObject != null) { targetObject.put(propertyName, resourceValue); } else { targetArray.add(resourceValue); } } else { if (targetObject != null) { targetObject.put(propertyName, value.stringValue()); } else { targetArray.add(value.stringValue()); } } } private void initPrefixes() { namespacePrefixes.put(IConstants.RDF_NAMESPACE, IConstants.RDF_PREFIX); namespacePrefixes.put(IConstants.OSLC_NAMESPACE, IConstants.OSLC_PREFIX); namespacePrefixes.put(IConstants.DCTERMS_NAMESPACE, IConstants.DCTERMS_PREFIX); namespacePrefixes.put(IConstants.SHARE_NAMESPACE, IConstants.SHARE_PREFIX); } private String getPrefix(String namespace) { String prefix = namespacePrefixes.get(namespace); if (prefix == null) { // then find the next available prefix int i = 0; String pre = "pr" + i; //$NON-NLS-1$ Collection<String> prefixes = namespacePrefixes.values(); while (prefixes.contains(pre)) { i++; pre = "pr" + i; //$NON-NLS-1$ } namespacePrefixes.put(namespace, pre); prefix = pre; } return prefix; } private void setNamespaces(JSONObject jresource) throws JSONException { Set<String> namespaces = namespacePrefixes.keySet(); JSONObject prefixes = new JSONObject(); for (String namespace : namespaces) { prefixes.put(namespacePrefixes.get(namespace), namespace); } jresource.put("prefixes", prefixes); } static public boolean isReifiedStatementProperty(String uri) { return reifiedStatementProperties.contains(uri); } }