/* * Copyright 2013, TopicQuests * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions * and limitations under the License. */ package org.topicquests.topicmap.json.persist; import java.io.Writer; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.UUID; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import net.minidev.json.*; import net.minidev.json.parser.*; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; //import org.json.simple.JSONObject; //import org.json.simple.parser.JSONParser; import org.nex.util.LRUCache; import org.topicquests.common.ResultPojo; import org.topicquests.common.api.IMergeRuleMethod; import org.topicquests.common.api.IResult; import org.topicquests.common.api.ITopicQuestsOntology; //import org.topicquests.model.Environment; import org.topicquests.model.api.IEnvironment; import org.topicquests.model.api.IMergeImplementation; //import org.topicquests.model.api.node.IAddressableInformationResource; import org.topicquests.model.api.node.INode; import org.topicquests.model.api.node.INodeModel; import org.topicquests.model.api.query.INodeQuery; import org.topicquests.model.api.node.ITuple; import org.topicquests.model.api.query.ITupleQuery; import org.topicquests.model.api.ITicket; import org.topicquests.model.Node; import org.topicquests.model.api.IXMLFields; import org.topicquests.persist.json.JSONDocStoreEnvironment; import org.topicquests.persist.json.api.IJSONDocStoreModel; //import org.topicquests.topicmap.json.merge.DefaultVirtualizer; import org.topicquests.topicmap.json.merge.MergeInterceptor; import org.topicquests.topicmap.json.merge.VirtualizerHandler; import org.topicquests.topicmap.json.model.CitationModel; import org.topicquests.topicmap.json.model.CredentialUtility; import org.topicquests.topicmap.json.model.JSONTopicmapEnvironment; import org.topicquests.topicmap.json.model.NodeQuery; import org.topicquests.topicmap.json.model.TopicMapXMLExporter; import org.topicquests.topicmap.json.model.TupleQuery; import org.topicquests.topicmap.json.model.api.ICitationModel; import org.topicquests.topicmap.json.model.api.IErrorMessages; import org.topicquests.topicmap.json.model.api.IJSONTopicDataProvider; import org.topicquests.topicmap.json.model.api.IJSONTopicMapOntology; import org.topicquests.topicmap.json.model.api.IMergeResultsListener; import org.topicquests.topicmap.json.model.api.ITreeNode; import org.topicquests.topicmap.json.model.api.IVirtualizer; import org.topicquests.topicmap.json.util.TreeNode; import org.topicquests.util.ConcurrentLRUCache; import org.topicquests.topicmap.json.model.NodeModel; /** * @author park * */ public class JSONDocStoreTopicMapProvider implements IJSONTopicDataProvider { private JSONTopicmapEnvironment environment; private JSONDocStoreEnvironment jsonEnvironment; private IJSONDocStoreModel jsonModel; private IMergeImplementation merger = null;//not used here private INodeModel _model; private ITupleQuery tupleQuery; private ICitationModel citationModel; private TopicMapXMLExporter exporter; private MergeInterceptor interceptor; private VirtualizerHandler mergePerformer; private CredentialUtility credentialUtil; /** We only save public nodes in this cache */ private LRUCache nodeCache; //ConcurrentLRUCache nodeCache; private final String //defined in jsonblobstore-props.xml TOPIC_INDEX = IJSONTopicMapOntology.TOPIC_INDEX, CORE_TYPE = IJSONTopicMapOntology.CORE_TYPE; /** * Constructor * @param env * @param cachesize */ public JSONDocStoreTopicMapProvider(JSONTopicmapEnvironment env, int cachesize) throws Exception { environment = env; jsonEnvironment = environment.getJSONEnvironment(); jsonModel = jsonEnvironment.getModel(); citationModel = new CitationModel(environment,_model); nodeCache = new LRUCache(cachesize); //new ConcurrentLRUCache(cachesize); //maybe not sending in a merge engine //The theory being that an external merge engine // will be at work _model = new NodeModel(environment,this, null,cachesize); tupleQuery = new TupleQuery(this, jsonModel); exporter = new TopicMapXMLExporter(this); interceptor = new MergeInterceptor(); credentialUtil = new CredentialUtility(this,jsonModel); //environment.logDebug("JSONDocStoreTopicMapProvider.init "+environment+" "+jsonEnvironment+" "+jsonModel); } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#setMergeBean(org.topicquests.model.api.IMergeImplementation) */ @Override public void setMergeBean(IMergeImplementation merger) { this.merger = merger; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#exportXmlFile(java.io.Writer, java.util.Set) */ @Override public IResult exportXmlFile(Writer out, ITicket credentials) { throw new RuntimeException("Use exportXmlTreeFile instead"); } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#exportXmlTreeFile(java.lang.String, java.io.Writer, java.util.Set) */ @Override public IResult exportXmlTreeFile(String treeRootLocator, Writer out, ITicket credentials) { IResult result = null; try { out.write("<"+IXMLFields.DATABASE+">\n"); result = exporter.exportXmlTreeFile(treeRootLocator, out, credentials, true); out.write("</"+IXMLFields.DATABASE+">\n"); out.flush(); out.close(); } catch (Exception e) { result.addErrorString(e.getMessage()); environment.logError(e.getMessage(),e); } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#getNode(java.lang.String, java.util.Set) */ @Override public IResult getNode(String locator, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.getNode- "+locator); //getDocument(String index, String type, String documentId) Object nx = nodeCache.get(locator); IResult result = null; if (nx != null) { result = new ResultPojo(); result.setResultObject(nx); } else { result = jsonModel.getDocument(TOPIC_INDEX, CORE_TYPE, locator); if (result.getResultObject() != null) { try { JSONObject jo = (JSONObject)new JSONParser(JSONParser.MODE_JSON_SIMPLE).parse((String)result.getResultObject()); if (credentialUtil.checkCredentials(jo, credentials)) { INode n = new Node(jo); result.setResultObject(n); //nodeCache.put(locator, n); nodeCache.add(locator, n); } else { result.setResultObject(null); result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { environment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); result.setResultObject(null); } } } return result; } @Override public IResult getNodeJSON(String locator, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.getNode- "+locator); //getDocument(String index, String type, String documentId) Object nx = nodeCache.get(locator); IResult result = null; JSONObject jo = null; if (nx != null) { result = new ResultPojo(); jo = (JSONObject)((INode)nx).getProperties(); if (credentialUtil.checkCredentials(jo, credentials)) result.setResultObject(jo); else { result.setResultObject(null); result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } else { result = jsonModel.getDocument(TOPIC_INDEX, CORE_TYPE, locator); if (result.getResultObject() != null) { try { jo = (JSONObject)new JSONParser(JSONParser.MODE_JSON_SIMPLE).parse((String)result.getResultObject()); if (credentialUtil.checkCredentials(jo, credentials)) result.setResultObject(jo); else { result.setResultObject(null); result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { environment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); result.setResultObject(null); } } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#getNodeView(java.lang.String, java.util.Set) */ @Override public IResult getNodeView(String locator, ITicket credentials) { IResult result = new ResultPojo(); // TODO Auto-generated method stub return result; } ///////////////////////////////////////////////////////////// //Removing a node is messy. // First, a node as pivots and other relations // Second, a node might have parents or children // Third, a node might be transcluded to some place, in which case, it cannot be removed, // but rather, the transclusion links are removed // Fourth, a node might be transcluded elsewhere, in which case, those transclusions need to be muted // as well. Typical transclusions are in terms of parent-child relations // Fifth, a node might be a member of a merged ensemble; its values must be // excised from the virtual node to which it is merged, and its merge relation removed // Which brings us to another issue: if it is unmerged, we need to leave it alone and // visible, and add an unmerge with reason link. // We should never get here from an unmerge ////////////////////////////////////////////////////////////// // Settled: // We set the given node to isLive = false // STILL MUST DEAL WITH children and relations // If you just set the node to isLive = false, and do nothing else, // Then the node will still appear in relations and parent nodes ////////////////////////////////////////////////////////////// /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#removeNode(...) */ @Override public IResult removeNode(INode node, ITicket credentials) { IResult result = new ResultPojo(); //first, set not live node.setIsLive(false); //save it IResult r = this.putNode(node, false); //now, deal with its network //TODO return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#removeNode(...) */ @Override public IResult removeNode(String locator, ITicket credentials) { IResult result = new ResultPojo(); IResult r = this.getNode(locator, credentials); INode n = (INode)r.getResultObject(); if (r.hasError()) result.addErrorString(r.getErrorString()); r = removeNode(n, credentials); if (r.hasError()) result.addErrorString(r.getErrorString()); return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#putNode(org.topicquests.model.api.INode) */ @Override public IResult putNode(INode node, boolean checkVersion) { //environment.logDebug("JSONDocStoreTopicMapProvider.putNode- "+node); nodeCache.add(node.getLocator(),node); //putDocument(String id, String index, String type, String jsonString); IResult result = jsonModel.putDocument(node.getLocator(), TOPIC_INDEX, CORE_TYPE, (JSONObject)node.getProperties(), true); interceptor.acceptNodeForMerge(node); return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#putNodeNoMerge(org.topicquests.model.api.INode) */ @Override public IResult putNodeNoMerge(INode node, boolean checkVersion) { //environment.logDebug("JSONDocStoreTopicMapProvider.putNodeNoMerge- "+node); nodeCache.remove(node.getLocator()); IResult result = jsonModel.putDocument(node.getLocator(), TOPIC_INDEX, CORE_TYPE, (JSONObject)node.getProperties(), true); return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#getVirtualNodeIfExists(java.lang.String, java.util.Set) */ @Override public IResult getVirtualNodeIfExists(INode node, ITicket credentials) { IResult result = new ResultPojo(); List<String> tups = node.listMergeTupleLocators(); //a merged node should have just one-- that is tups.size() == 1 //a virtualnode could have many if (node.getIsVirtualProxy() ) { result.setResultObject(node); } else if (tups != null) { String tuplox = tups.get(0); IResult r = this.getNode(tuplox, credentials); ITuple tup = (ITuple)r.getResultObject(); if (r.hasError()) result.addErrorString(r.getErrorString()); //this ITuple has this node as object, virtualnode as subject //see BaseVirtualizer.relateNodes tuplox = tup.getSubjectLocator(); r = this.getNode(tuplox, credentials); result.setResultObject(r.getResultObject()); if (r.hasError()) result.addErrorString(r.getErrorString()); } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#existsTupleBySubjectOrObjectAndRelation(java.lang.String, java.lang.String) */ @Override public IResult existsTupleBySubjectOrObjectAndRelation(String theLocator, String relationLocator) { BoolQueryBuilder qb = QueryBuilders.boolQuery(); QueryBuilder qb1 = QueryBuilders.termQuery(ITopicQuestsOntology.TUPLE_SUBJECT_PROPERTY, theLocator); QueryBuilder qb2 = QueryBuilders.termQuery(ITopicQuestsOntology.TUPLE_OBJECT_PROPERTY, theLocator); QueryBuilder qb3 = QueryBuilders.termQuery(ITopicQuestsOntology.INSTANCE_OF_PROPERTY_TYPE, relationLocator); qb.must(qb3); qb.should(qb1); qb.should(qb2); //environment.logDebug("JSONDocStoreTopicMapProvider.existsTupleBySubjectOrObjectAndRelation- "+qb.toString()); IResult result = jsonModel.runQuery(TOPIC_INDEX, qb, 0, -1, CORE_TYPE); if (result.getResultObject() != null) result.setResultObject(new Boolean(true)); else result.setResultObject(new Boolean(false)); return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#nodeIsA(java.lang.String, java.lang.String, java.util.Set) */ @Override public IResult nodeIsA(String nodeLocator, String targetTypeLocator, ITicket credentials) { IResult result = this.getNode(nodeLocator, credentials); INode n = (INode)result.getResultObject(); boolean t = n.isA(targetTypeLocator); result.setResultObject(new Boolean(t)); return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listNodesByPSI(java.lang.String, int, int, java.util.Set) */ @Override public IResult listNodesByPSI(String psi, int start, int count, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.listNodesByPSI- "+psi); //listDocumentsByProperty(String index, String key, String value, int start, int count, String... types) IResult result = jsonModel.listDocumentsByProperty(TOPIC_INDEX, ITopicQuestsOntology.PSI_PROPERTY_TYPE, psi, start, count, CORE_TYPE); if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listNodesByLabelAndType(java.lang.String, java.lang.String, int, int, java.util.Set) */ @Override public IResult listNodesByLabelAndType(String label, String typeLocator,String language, int start, int count, ITicket credentials) { BoolQueryBuilder qb = QueryBuilders.boolQuery(); String labprop = makeField(ITopicQuestsOntology.LABEL_PROPERTY, language); QueryBuilder qb1 = QueryBuilders.termQuery(labprop, label); QueryBuilder qb2 = QueryBuilders.termQuery(ITopicQuestsOntology.INSTANCE_OF_PROPERTY_TYPE, typeLocator); qb.must(qb1); qb.should(qb2); //environment.logDebug("JSONDocStoreTopicMapProvider.listNodesByLabelAndType- "+qb.toString()); IResult result = jsonModel.runQuery(TOPIC_INDEX, qb, 0, -1, CORE_TYPE); if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listNodesByLabel(java.lang.String, int, int, java.util.Set) */ @Override public IResult listNodesByLabel(String label, String language, int start, int count, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.listNodesByLabel- "+label); //listDocumentsByProperty(String index, String key, String value, int start, int count, String... types) String labprop = makeField(ITopicQuestsOntology.LABEL_PROPERTY, language); IResult result = jsonModel.listDocumentsByProperty(TOPIC_INDEX, labprop, label, start, count, CORE_TYPE); if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listNodesByLabelLike(java.lang.String, int, int, java.util.Set) */ @Override public IResult listNodesByLabelLike(String labelFragment, String language, int start, int count, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.listNodesByLabelLike- "+labelFragment); //listDocumentsByProperty(String index, String key, String value, int start, int count, String... types) String labprop = makeField(ITopicQuestsOntology.LABEL_PROPERTY, language); IResult result = jsonModel.listDocumentsByWildcardPropertyValue(TOPIC_INDEX, labprop, labelFragment, start, count, CORE_TYPE); //that required the "label" field to be unanalyzed if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listNodesByDetailsLike(java.lang.String, int, int, java.util.Set) */ @Override public IResult listNodesByDetailsLike(String detailsFragment, String language, int start, int count, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.listNodesByDetailsLike- "+detailsFragment); //listDocumentsByProperty(String index, String key, String value, int start, int count, String... types) String detprop = makeField(ITopicQuestsOntology.DETAILS_PROPERTY, language); IResult result = jsonModel.listDocumentsByWildcardPropertyValue(TOPIC_INDEX, detprop, detailsFragment, start, count, CORE_TYPE); //that required the "label" field to be unanalyzed if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listNodesByQuery(java.lang.String, int, int, java.util.Set) * MUST be a valid ElasticSearch <code>queryString</code> */ @Override public IResult listNodesByQuery(String queryString, int start, int count, ITicket credentials) { return jsonModel.runQuery(TOPIC_INDEX, queryString, start, count, CORE_TYPE); } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listNodesByCreatorId(java.lang.String, int, int, java.util.Set) */ @Override public IResult listNodesByCreatorId(String creatorId, int start, int count, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.listNodesByCreatorId- "+creatorId); //listDocumentsByProperty(String index, String key, String value, int start, int count, String... types) IResult result = jsonModel.listDocumentsByProperty(TOPIC_INDEX, ITopicQuestsOntology.CREATOR_ID_PROPERTY, creatorId, start, count, CORE_TYPE); if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listNodesByType(java.lang.String, int, int, java.util.Set) */ @Override public IResult listNodesByType(String typeLocator, int start, int count, ITicket credentials) { return listInstanceNodes(typeLocator,start,count,credentials); } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listTuplesBySignature(java.lang.String, int, int, java.util.Set) */ @Override public IResult listTuplesBySignature(String signature, int start, int count, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.listTuplesBySignature- "+signature); //listDocumentsByProperty(String index, String key, String value, int start, int count, String... types) IResult result = jsonModel.listDocumentsByProperty(TOPIC_INDEX, ITopicQuestsOntology.TUPLE_SIGNATURE_PROPERTY, signature, start, count, CORE_TYPE); if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listInstanceNodes(java.lang.String, int, int, java.util.Set) */ @Override public IResult listInstanceNodes(String typeLocator, int start, int count, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.listInstanceNodes- "+typeLocator); //listDocumentsByProperty(String index, String key, String value, int start, int count, String... types) IResult result = jsonModel.listDocumentsByProperty(TOPIC_INDEX, ITopicQuestsOntology.INSTANCE_OF_PROPERTY_TYPE, typeLocator, start, count, CORE_TYPE); if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); System.out.println("LISTINSTANCES "+docs.size()); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listTrimmedInstanceNodes(java.lang.String, int, int, java.util.Set) */ @Override public IResult listTrimmedInstanceNodes(String typeLocator, int start, int count, ITicket credentials) { // Can be same type AND virtual proxy // OR Can be same type AND NOT merged // TODO Auto-generated method stub // String query = // "("+ITopicQuestsOntology.INSTANCE_OF_PROPERTY_TYPE+":"+typeLocator+" AND "+ITopicQuestsOntology.IS_VIRTUAL_PROXY+":true) OR "+ // "("+ITopicQuestsOntology.INSTANCE_OF_PROPERTY_TYPE+":"+typeLocator+" AND NOT "+ITopicQuestsOntology.MERGE_TUPLE_PROPERTY+":* )"; BoolQueryBuilder qba = QueryBuilders.boolQuery(); BoolQueryBuilder qbb = QueryBuilders.boolQuery(); QueryBuilder qb1 = QueryBuilders.termQuery(ITopicQuestsOntology.INSTANCE_OF_PROPERTY_TYPE, typeLocator); QueryBuilder qb2 = QueryBuilders.termQuery(ITopicQuestsOntology.IS_VIRTUAL_PROXY, true); qba.must(qb1); qba.must(qb2); QueryBuilder qb3 = QueryBuilders.termQuery(ITopicQuestsOntology.INSTANCE_OF_PROPERTY_TYPE, typeLocator); QueryBuilder qb4 = QueryBuilders.wildcardQuery(ITopicQuestsOntology.MERGE_TUPLE_PROPERTY, "*"); qbb.must(qb3); qbb.mustNot(qb4); BoolQueryBuilder qbc = QueryBuilders.boolQuery(); qbc.should(qba); qbc.should(qbb); //environment.logDebug("JSONDocStoreTopicMapProvider.listTrimmedInstanceNodes- "+qbc.toString()); IResult result = jsonModel.runQuery(TOPIC_INDEX, qbc, 0, -1, CORE_TYPE); if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#listSubclassNodes(java.lang.String, int, int, java.util.Set) */ @Override public IResult listSubclassNodes(String superclassLocator, int start, int count, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.listSubclassNodes- "+superclassLocator); //listDocumentsByProperty(String index, String key, String value, int start, int count, String... types) IResult result = jsonModel.listDocumentsByProperty(TOPIC_INDEX, ITopicQuestsOntology.SUBCLASS_OF_PROPERTY_TYPE, superclassLocator, start, count, CORE_TYPE); //environment.logDebug("JSONDocStoreTopicMapProvider.listSubclassNodes-1 "+result.getResultObject()); if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); System.out.println("LISTSUBS "+docs.size()); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#putTuple(org.topicquests.model.api.ITuple) */ @Override public IResult putTuple(ITuple tuple, boolean checkVersion) { return putNode(tuple, true); } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#getTuple(java.lang.String, java.util.Set) */ @Override public IResult getTuple(String tupleLocator, ITicket credentials) { //environment.logDebug("JSONDocStoreTopicMapProvider.getTuple- "+tupleLocator); IResult result = jsonModel.getDocument(TOPIC_INDEX, CORE_TYPE, tupleLocator); if (result.getResultObject() != null) { try { JSONObject jo = (JSONObject)new JSONParser(JSONParser.MODE_JSON_SIMPLE).parse((String)result.getResultObject()); if (credentialUtil.checkCredentials(jo, credentials)) { ITuple n = new Node(jo); result.setResultObject(n); } else { result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); result.setResultObject(null); } } catch (Exception e) { environment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); result.setResultObject(null); } } return result; } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#updateNode(org.topicquests.model.api.INode) */ @Override public IResult updateNode(INode node, boolean checkVersion) { return putNode(node, true); } /* (non-Javadoc) * @see org.topicquests.model.api.ITopicDataProvider#runQuery(java.lang.String, int, int, java.util.Set) */ @Override public IResult runQuery(String queryString, int start, int count, ITicket credentials) { return this.listNodesByQuery(queryString, start, count, credentials); } /* (non-Javadoc) * @see org.topicquests.model.api.IDataProvider#getNodeModel() */ @Override public INodeModel getNodeModel() { return _model; } /* (non-Javadoc) * @see org.topicquests.model.api.IDataProvider#getTupleQuery() */ @Override public ITupleQuery getTupleQuery() { return tupleQuery; } /* (non-Javadoc) * @see org.topicquests.model.api.IDataProvider#removeFromCache(java.lang.String) */ @Override public void removeFromCache(String nodeLocator) { nodeCache.remove(nodeLocator); //Object o = nodeCache.remove(nodeLocator); //if (o != null) // recycleNode((INode)o); } /* (non-Javadoc) * @see org.topicquests.model.api.IDataProvider#getUUID() */ @Override public String getUUID() { UUID x = UUID.randomUUID(); return x.toString(); } /* (non-Javadoc) * @see org.topicquests.model.api.IDataProvider#getUUID_Pre(java.lang.String) */ public String getUUID_Pre(String prefix) { UUID x = UUID.randomUUID(); return prefix+x.toString(); } /* (non-Javadoc) * @see org.topicquests.model.api.IDataProvider#getUUID_Post(java.lang.String) */ public String getUUID_Post(String suffix) { UUID x = UUID.randomUUID(); return x.toString()+suffix; } /* (non-Javadoc) * @see org.topicquests.model.api.IDataProvider#createMergeRule(org.topicquests.common.api.IMergeRuleMethod) */ @Override public IResult createMergeRule(IMergeRuleMethod theMethod) { IResult result = new ResultPojo(); // TODO Auto-generated method stub return result; } private JSONObject jsonToJSON(String json) throws Exception { return (JSONObject)new JSONParser(JSONParser.MODE_JSON_SIMPLE).parse(json); } @Override public void updateNodeFromXML(String nodeXML) { // TODO Auto-generated method stub } ///////////////////////////////// // Tree Support private List<String>loopStopper = null; @Override public IResult loadTree(String rootNodeLocator, int maxDepth, int start, int count, ITicket credentials) { IResult result = new ResultPojo(); loopStopper = new ArrayList<String>(); //Get the root node IResult r = this.getNode(rootNodeLocator, credentials); if (r.hasError()) result.addErrorString(r.getErrorString()); ITreeNode root = new TreeNode(rootNodeLocator); INode n = (INode)r.getResultObject(); String label = n.getLabel("en"); root.setNodeLabel(label); result.setResultObject(root); //now populate its child nodes recursiveWalkDownTree(result,root,maxDepth,maxDepth,start,count,credentials); //environment.logDebug("JSONDocStoreTopicMapProvider.loadTree "+rootNodeLocator+" "+root.getSubclassCount()+" "+root.getInstanceCount()); return result; } private void recursiveWalkDownTree(IResult result, ITreeNode root, int maxDepth, int curDepth, int start, int count, ITicket credentials) { //stopping rule if (curDepth == 0) return; //Given this root, grab its children, then recurse on them String lox = root.getNodeLocator(); if (loopStopper.contains(lox)) return; loopStopper.add(lox); //Note: the day will come when -1 will bite us in the butt due to huge //collections IResult r = this.listSubclassNodes(lox, start, count, credentials); if (r.hasError()) result.addErrorString(r.getErrorString()); List<INode>kids = null; Iterator<INode>itr; INode snapper; ITreeNode child; if (r.getResultObject() != null) { kids = (List<INode>)r.getResultObject(); itr = kids.iterator(); while (itr.hasNext()) { //get the kid snapper = itr.next(); child = new TreeNode(snapper.getLocator(), snapper.getLabel("en")); root.addSubclassChild(child); //now populate it recursiveWalkDownTree(result,child,maxDepth, --curDepth, start, count, credentials); } } r = this.listInstanceNodes(lox, 0, 200, credentials); if (r.hasError()) result.addErrorString(r.getErrorString()); if (r.getResultObject() != null) { kids = (List<INode>)r.getResultObject(); itr = kids.iterator(); while (itr.hasNext()) { //get the kid snapper = itr.next(); child = new TreeNode(snapper.getLocator(), snapper.getLabel("en")); root.addInstanceChild(child); //now populate it recursiveWalkDownTree(result,child,maxDepth, --curDepth,start,count,credentials); } } } ///////////////////////////////// // AIRs /** @Override public IResult getAIRVersion(String airLocator, int version, ITicket credentials) { String lox = makeAIRLocator(airLocator,Integer.toBinaryString(version)); IResult result = jsonModel.getDocument(IJSONTopicDataProvider.AIR_INDEX, CORE_TYPE, lox); if (result.getResultObject() != null) { try { JSONObject json = this.jsonToJSON((String)result.getResultObject()); IAddressableInformationResource a = new Node(json); result.setResultObject(a); } catch (Exception e) { environment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } @Override public IResult listAIRVersions(String airLocator) { IResult result = jsonModel.listDocumentsByKeywordProperty(IJSONTopicDataProvider.AIR_INDEX, ITopicQuestsOntology.LOCATOR_PROPERTY, airLocator, 0, -1, CORE_TYPE); if (result.getResultObject() != null) { List<String>airs = (List<String>)result.getResultObject(); int len = airs.size()+1; List<String>versions = new ArrayList<String>(); for (int i=1;i<len;i++) versions.add(Integer.toString(i)); result.setResultObject(versions); } return result; } @Override public IResult putAIRVersion(IAddressableInformationResource air, boolean checkVersion) { String lox = makeAIRLocator(air.getLocator(),Integer.toString(air.getAIRVersion())); IResult result = jsonModel.putDocument(lox, IJSONTopicDataProvider.AIR_INDEX, CORE_TYPE, air.toJSON(),true); return result; } private String makeAIRLocator(String locator, String version) { return locator+"_"+version; } **/ ///////////////////////////////// // Merge @Override public void mergeTwoNodes(INode leftNode, INode rightNode, String reason, String userLocator, IMergeResultsListener mergeListener) { Map<String,Double> mergeData = new HashMap<String,Double>(); String rx = reason; if (rx == null || rx.equals("")) rx = "No reason given: user-suggested"; mergeData.put(rx, 1.0); mergePerformer.performMerge(leftNode, rightNode, mergeData, 1.0, userLocator, mergeListener); } ///////////////////////////////// // utility public void shutDown() { this.interceptor.shutDown(); } @Override public INodeQuery getNodeQuery(INode node) { return new NodeQuery(node,this,jsonModel); } /** * <p>The {@link INode} implementation uses this to calculate * which actual label or details field to use depending on language. * We need it for fetching nodes based on label or details</p> * @param fieldBase * @param language * @return */ private String makeField(String fieldBase, String language) { String result = fieldBase; if (!language.equals("en")) result += language; return result; } @Override public void setVirtualizerHandler(VirtualizerHandler h) { mergePerformer = h; } @Override public void recycleNode(INode n) { _model.recycleNode(n); } @Override public IResult init(IEnvironment arg0, int arg1) { // NOT USED return null; } @Override public ICitationModel getCitationModel() { return citationModel; } @Override public IResult existsNode(String locator) { Object nx = nodeCache.get(locator); IResult result = new ResultPojo(); if (nx != null) { result.setResultObject(new Boolean(true)); } else { result = jsonModel.getDocument(TOPIC_INDEX, CORE_TYPE, locator); if (result.getResultObject() != null) result.setResultObject(new Boolean(true)); else result.setResultObject(new Boolean(false)); } return result; } @Override public IResult getNodeByPSI(String psi, ITicket credentials) { BoolQueryBuilder qb = QueryBuilders.boolQuery(); QueryBuilder qb1 = QueryBuilders.termQuery(ITopicQuestsOntology.PSI_PROPERTY_TYPE, psi); //environment.logDebug("JSONDocStoreTopicMapProvider.existsTupleBySubjectOrObjectAndRelation- "+qb.toString()); IResult result = jsonModel.runQuery(TOPIC_INDEX, qb, 0, -1, CORE_TYPE); if (result.getResultObject() != null) { String json = (String)result.getResultObject(); try { JSONObject jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) result.setResultObject(new Node(jo)); else { result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); result.setResultObject(null); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } /** @Override public IResult getNodeByURL(String url, ITicket credentials) { BoolQueryBuilder qb = QueryBuilders.boolQuery(); QueryBuilder qb1 = QueryBuilders.termQuery(ITopicQuestsOntology.RESOURCE_URL_PROPERTY, url); //environment.logDebug("JSONDocStoreTopicMapProvider.existsTupleBySubjectOrObjectAndRelation- "+qb.toString()); IResult result = jsonModel.runQuery(TOPIC_INDEX, qb, 0, -1, CORE_TYPE); if (result.getResultObject() != null) { List<String> l = (List<String>)result.getResultObject(); String json; if (l != null && !l.isEmpty()) { json = l.get(0); try { JSONObject jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) result.setResultObject(new Node(jo)); else { result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); result.setResultObject(null); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } } return result; } */ @Override public IResult listNodesByTypeAndURL(String type, String url, ITicket credentials) { BoolQueryBuilder qb = QueryBuilders.boolQuery(); QueryBuilder qb1 = QueryBuilders.termQuery(ITopicQuestsOntology.SUBCLASS_OF_PROPERTY_TYPE, type); QueryBuilder qb2 = QueryBuilders.termQuery(ITopicQuestsOntology.INSTANCE_OF_PROPERTY_TYPE, type); QueryBuilder qb3 = QueryBuilders.termQuery(ITopicQuestsOntology.RESOURCE_URL_PROPERTY, url); qb.must(qb3); qb.should(qb1); qb.should(qb2); //environment.logDebug("JSONDocStoreTopicMapProvider.existsTupleBySubjectOrObjectAndRelation- "+qb.toString()); IResult result = jsonModel.runQuery(TOPIC_INDEX, qb, 0, -1, CORE_TYPE); if (result.getResultObject() != null) { List<String>docs = (List<String>)result.getResultObject(); String json; Iterator<String>itr = docs.iterator(); List<INode>nl = new ArrayList<INode>(); result.setResultObject(nl); INode n; JSONObject jo; try { while(itr.hasNext()) { json = itr.next(); jo = jsonToJSON(json); if (credentialUtil.checkCredentials(jo,credentials)) nl.add(new Node(jo)); else result.addErrorString(IErrorMessages.CREDENTIAL_EXCEPTION); } } catch (Exception e) { jsonEnvironment.logError(e.getMessage(), e); result.addErrorString(e.getMessage()); } } return result; } @Override public IResult updateNodeLabel(INode node, String oldLabel, String newLabel, ITicket credentials) { IResult result = new ResultPojo(); // TODO Auto-generated method stub return result; } }