/*
* 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.model;
import java.util.*;
import java.io.*;
import java.util.logging.Logger;
import org.topicquests.common.ResultPojo;
import org.topicquests.common.api.IResult;
import org.topicquests.common.api.ITopicQuestsOntology;
import org.topicquests.model.api.node.INode;
import org.topicquests.model.api.node.ITuple;
import org.topicquests.model.api.ITicket;
import org.topicquests.topicmap.json.model.api.IExporterListener;
import org.topicquests.topicmap.json.model.api.IJSONTopicDataProvider;
import org.topicquests.util.LoggingPlatform;
/**
* @author park
*
*/
public class TopicMapXMLExporter {
public LoggingPlatform log = LoggingPlatform.getLiveInstance();
private IJSONTopicDataProvider database;
private IExporterListener listener = null;
private List<String> loopStopper = null;
/**
*
*/
public TopicMapXMLExporter(IJSONTopicDataProvider db) {
database = db;
loopStopper = new ArrayList<String>();
}
public void setListener(IExporterListener l) {
listener = l;
}
/**
* <p>Export a tree root and it's entire subtree.</p>
* <p>This entails finding all {@link INode} and {@link ITuple} instances
* related to <code>treeRootLocator</code> and recursing on them as well.</p>
* @param treeRootLocator
* @param out
* @param standAlone <code>true</code> if this is the only method called
* @param credentials
* @return
*/
public IResult exportXmlTreeFile(String treeRootLocator, Writer out, ITicket credentials, boolean standAlone) {
if (standAlone)
loopStopper = new ArrayList<String>();
IResult result = new ResultPojo();
INode n = (INode)database.getNode(treeRootLocator, credentials).getResultObject();
System.out.println("TopicMapXMLExporter.exportXmlTreeFile- "+n);
if (n != null) {
new Worker(n,out,credentials,0);
System.out.println("TopicMapXMLExporter.exportXmlTreeFile+");
}
return result;
}
class Worker extends Thread {
private INode n;
private Writer out;
private ITicket credentials;
private int depth;
private Object waiter = new Object();
public Worker(INode n, Writer out, ITicket credentials, int depth) {
this.n = n;
this.out = out;
this.credentials = credentials;
this.depth = depth;
this.run();
}
public void run() {
exportTree(n,out,credentials,depth);
if (listener != null)
listener.exportDone();
}
/**
* Recursive tree descent; export <code>n</code> and all of its child nodes
* @param n
* @param out
* @param credentials
* @param depth // for diagnostics
* @return
*/
private IResult exportTree(INode n, Writer out, ITicket credentials, int depth) {
/* synchronized(waiter) {
try {
waiter.wait(1000);
} catch (Exception e) {
e.printStackTrace();
}
} */
Thread.yield();
String locator = n.getLocator();
IResult result = new ResultPojo();
if (!loopStopper.contains(locator)) {
int mydepth = depth++;
loopStopper.add(locator);
//Export this node
String xml = n.toXML();
//TODO should check for null string
System.out.println(depth+" EXPORT- "+locator+" | "+xml);
try {
out.write(xml);
} catch (Exception e) {
//TODO
result.addErrorString(e.getMessage());
}
//Now pick up children
//What are children? subclasses, instances, IBIS nodes, etc...
//Must pick up ITuples as well
//we ignore any superclass or parent types; just start here and go down and out
int start = 0, count = 50, fetched =50;
//instances first
INode theNode = null;
INode tNode = null;
IResult xx = listInstanceNodes(locator,start,count,credentials);
Iterator<INode>nitr = null;
List<INode>nodes = (List<INode>)xx.getResultObject();
// if (locator.equals("f7b7084f-442b-47b8-b925-95a678db62d5Cluster"))
// log.debug("EXXXXXP: "+nodes);
System.out.println("EXPORT 0 "+nodes+" | "+result.getErrorString());
while (nodes != null && nodes.size() > 0) {
fetched = nodes.size();
nitr = nodes.iterator();
while (nitr.hasNext())
exportTree(nitr.next(),out,credentials,mydepth);
start += fetched;
count += 50;
xx = listInstanceNodes(locator,start,count,credentials);
nodes =(List<INode>)xx.getResultObject();
}
//subclasses next
start = 0; count = 50;
xx = listSubclassNodes(locator,start,count,credentials);
nodes = (List<INode>)xx.getResultObject();
System.out.println(depth+" EXPORT 1 "+locator+" "+nodes+" | "+result.getErrorString());
while (nodes != null && nodes.size() > 0) {
fetched = nodes.size();
nitr = nodes.iterator();
while (nitr.hasNext())
exportTree(nitr.next(),out,credentials,mydepth);
start += fetched;
count += 50;
xx = listSubclassNodes(locator,start,count,credentials);
nodes = (List<INode>)xx.getResultObject();
}
//tuples next
/** List<String> tuples = n.listTuples();
String tox;
// System.out.println("EXPORT 2 "+tuples+" | "+result.getErrorString());
if (tuples != null && tuples.size() > 0) {
Iterator<String>itr = tuples.iterator();
while (itr.hasNext()) {
tox = itr.next();
//TODO should check for null
tNode = (INode)database.getNode(tox, credentials).getResultObject();
if (tNode != null) {
exportTree(tNode,out,credentials,mydepth);
//Now, take apart source and target nodes in case we haven't plucked them yet
tox = ((ITuple)tNode).getSubjectLocator();
theNode = (INode)database.getNode(tox, credentials).getResultObject();
if (theNode != null)
exportTree(theNode,out,credentials,mydepth);
tox = ((ITuple)tNode).getObject();
if (((ITuple)tNode).getObjectType().equals(ITopicQuestsOntology.NODE_TYPE) ||
((ITuple)tNode).getObjectType().equals(ITopicQuestsOntology.VIRTUAL_NODE_TYPE)) {
theNode = (INode)database.getNode(tox, credentials).getResultObject();
if (theNode != null)
exportTree(theNode,out,credentials,mydepth);
}
} else
result.addErrorString("SolrExporter.exportTree missing tuple "+tox);
}
}
// System.out.println("EXPORT 3 "+tuples+" | "+result.getErrorString());
tuples = n.listRestrictedTuples();
if (tuples != null && tuples.size() > 0) {
Iterator<String>itr = tuples.iterator();
while (itr.hasNext()) {
tox = itr.next();
//TODO should check for null
tNode = (INode)database.getNode(tox, credentials).getResultObject();
if (tNode != null) {
exportTree(tNode,out,credentials,mydepth);
//Now, take apart source and target nodes in case we haven't plucked them yet
tox = ((ITuple)tNode).getSubjectLocator();
theNode = (INode)database.getNode(tox, credentials).getResultObject();
if (theNode != null)
exportTree(theNode,out,credentials,mydepth);
tox = ((ITuple)tNode).getObject();
if (((ITuple)tNode).getObjectType().equals(ITopicQuestsOntology.NODE_TYPE) ||
((ITuple)tNode).getObjectType().equals(ITopicQuestsOntology.VIRTUAL_NODE_TYPE)) {
theNode = (INode)database.getNode(tox, credentials).getResultObject();
if (theNode != null)
exportTree(theNode,out,credentials,mydepth);
}
} else
result.addErrorString("SolrExporter.exportTree missing tuple "+tox);
}
}*/
// System.out.println("EXPORT 4 "+tuples+" | "+result.getErrorString());
System.out.println(depth+" EXPORT+ "+locator);
}
return result;
}
}
private IResult listInstanceNodes(String locator, int start, int count, ITicket credentials) {
System.out.println("LISTINSTANCENODES "+locator);
return database.listInstanceNodes(locator, start, count, credentials);
}
private IResult listSubclassNodes(String locator, int start, int count, ITicket credentials) {
return database.listSubclassNodes(locator, start, count, credentials);
}
}