/**
*
*/
package edu.scripps.mwsync;
import java.io.IOException;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.logging.Level;
import javax.security.auth.login.LoginException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.wikipedia.Wiki;
import org.wikipedia.Wiki.Revision;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Extend Wiki with mwsync specific needs
* @author bgood
*
*/
public class WikiPlus extends Wiki {
/**
*
*/
public WikiPlus() {
// TODO Auto-generated constructor stub
}
/**
* @param domain
*/
public WikiPlus(String domain) {
super(domain);
// TODO Auto-generated constructor stub
}
/**
* @param domain
* @param scriptPath
*/
public WikiPlus(String domain, String scriptPath) {
super(domain, scriptPath);
// TODO Auto-generated constructor stub
}
/**
* Returns a list of revisions made on the watchlist between the start date
* and the current time.
* @param startCal a calendar specifying the exact start point
* @param includeBotEdits true to include bot edits, false to restrict to human editors
* @return a list of revisions
* @throws IOException if a network error occurs
*/
public List<Revision> getChangesFromWatchlist(Calendar startCal, boolean includeBotEdits, int limit) throws IOException {
SimpleDateFormat timestamp = new SimpleDateFormat("yyyyMMddHHmmss");
TimeZone tz = TimeZone.getTimeZone("GMT");
timestamp.setTimeZone(tz);
String start = timestamp.format(startCal.getTime());
List<Revision> revisions = new ArrayList<Revision>();
String url = query + "action=query" +
"&generator=watchlist" +
"&gwllimit=" +limit+
"&gwlnamespace=0" +
"&gwlshow=" + ((includeBotEdits)? "" : "!bot") +
"&gwlstart="+start+
"&gwldir=newer" +
"&prop=revisions" +
"&rvprop=user|timestamp|ids|size|flags|comment";
String line = fetch(url, "getRecentChangesFromWatchlist");
String[] revs = line.split("</revisions></page>");
for (String rev : revs) {
rev = rev.trim();
Revision revision;
if (rev.contains("revid=")) {
revision = parseRevision(rev, "");
revisions.add(revision);
}
}
return revisions;
}
public Map<String, List<String>> askQuery(String property, String target, String... otherProperties) throws IOException {
// Build the query (relying on the SMWAskAPI extension to be installed
StringBuilder prop = new StringBuilder("[["+property+"::"+target+"]]");
StringBuilder url = new StringBuilder(query);
url.append("action=ask&query=").append(prop).append("&po=");
for (String op : otherProperties) {
op = op.toLowerCase();
url.append(op).append("|");
}
String _url = url.toString();
// Submit it and receive XML
String xml = fetch(_url, "askQuery");
if(xml.contains("Category:Parkinson")){
System.out.println(xml);
}
// Check the returned SML for errors
// try {
// checkErrors(xml, "");
// } catch (LoginException e) {
// throw new IOException("User error.");
// }
// Create the XML document parser and read the XML
Document doc = null;
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = builder.parse(is);
} catch (ParserConfigurationException e) {
e.printStackTrace();
throw new IOException("Could not create XML parser.");
} catch (SAXException e) {
e.printStackTrace();
throw new IOException("Error parsing XML.");
}
// iterate through the results and build the map that will eventually be returned
Map<String, List<String>> results = new HashMap<String, List<String>>();
NodeList result_nodes = doc.getElementsByTagName("results");
if(result_nodes!=null){
for (int n=0; n < result_nodes.getLength(); n++) {
Node result_node = result_nodes.item(n);
NodeList nodes = result_node.getChildNodes();
if(nodes!=null){
for (int i=0; i < nodes.getLength(); i++) {
Element result = (Element) nodes.item(i);
String title = result.getAttribute("fulltext");
List<String> properties = new ArrayList<String>();
// Attempt to retrieve the properties
// Element propertiesNode = (Element) result.getFirstChild();
// try {
// // Get the type, which is always defined, and then get the optional ones specified
// String type = propertiesNode.getAttribute("type");
// properties.add(type);
// for (String op : otherProperties) {
// op = op.toLowerCase();
// String _prop = propertiesNode.getAttribute(op);
// properties.add(_prop);
// }
// } catch (NullPointerException e) {
// log(Level.WARNING, "Could not parse properties.", "askQuery");
// }
if (!title.equals(""))
results.put(title, properties);
}
}
}
}
return results;
}
//SMW API change... I hate them...
// Map<String, List<String>> results = new HashMap<String, List<String>>();
// NodeList nodes = doc.getElementsByTagName("list-item");
// for (int i=0; i < nodes.getLength(); i++) {
// Element result = (Element) nodes.item(i);
// String title = result.getAttribute("title");
//
// Element propertiesNode = (Element) result.getFirstChild();
// List<String> properties = new ArrayList<String>();
// // Attempt to retrieve the properties
// try {
// // Get the type, which is always defined, and then get the optional ones specified
// String type = propertiesNode.getAttribute("type");
// properties.add(type);
// for (String op : otherProperties) {
// op = op.toLowerCase();
// String _prop = propertiesNode.getAttribute(op);
// properties.add(_prop);
// }
// } catch (NullPointerException e) {
// log(Level.WARNING, "Could not parse properties.", "askQuery");
// }
// if (!title.equals(""))
// results.put(title, properties);
// }
}