package org.nodeclipse.ui.contentassist;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Using Orion IndexFiles for libraries for content assist</br>
* This is logic class without Eclipse API dependencies. Just run it as Java App
<pre>
express={
"!define": {
"response": {
"send": {"!type": "fn(body: String) -> response"},
"get": {"!type": "fn(field: String) -> String"},
"location": {"!type": "fn(url: String) -> response"},
"status": {"!type": "fn(code: Number) -> response"},
"set": {"!type": "fn(field: Object, val: String) -> response"},
"links": {"!type": "fn(links: Object) -> response"},
"download": {"!type": "fn(path: String, filename: String, fn: fn())"}, *
</pre>
* @author Paul Verest
* @since 0.12
*/
public class ContentFromOrionIndexFiles // implements IModelFiller
{
private static boolean verbose = true;
private static int errorCounter = 0;
private static Model model = null;
/*
* Run this As Java Application to check .indexFiles
*
* Reading Libraries IndexFiles finished in 40 ms. errorCounter=2
* */
public static void main(String[] args) {
model = new Model();
initModel(model);
//code example from https://github.com/demodays/bjdd/issues/1
// model.processWith(new EntryProcessor(){
// entry -> System.out.println(entry.toFullString());
// }
model.processWith(new EntryProcessor(){
@Override
public void process(Entry entry) {
System.out.println(entry.toFullString());
}
});
}
//@Override
public static void initModel(Model model) {
long startTime = System.currentTimeMillis(); //nanoTime();
addIndexFile(model, "amqp");
// addIndexFile(model, "browser");
// addIndexFile(model, "ecma5");
addIndexFile(model, "express");
addIndexFile(model, "mongodb");
addIndexFile(model, "mysql");
// addIndexFile(model, "node");
addIndexFile(model, "postgres");
addIndexFile(model, "redis");
long time = System.currentTimeMillis() - startTime;
log("Reading Libraries IndexFiles finished in "+time+" ms. errorCounter="+errorCounter);
}
// see analog ContentFromSources.populateModel()
private static boolean addIndexFile(Model model, String libname) {
JSONObject libraryIndex = jsonForLibrary(libname);
if (libraryIndex == null){
return false;
}
try {
String moduleName = libraryIndex.getString("!name");
debug(", " + moduleName);
Module moduleObj = new Module(moduleName);
model.addModule(moduleObj);
JSONObject module = (JSONObject) libraryIndex.get("!define");
if (verbose) debug("(("+module.length()+")):");
//DONE add moduleDesc as list of higher level objects
String moduleDesc = formatedName(moduleName)+module.names();
Entry moduleEntry = new Entry(moduleObj,EntryType.module,moduleName,moduleName,moduleDesc,null);
model.addEntry(moduleEntry);
if (verbose) debug("\n Model size="+model.entries.size());
// "response": {
// "send": {"!type": "fn(body: String) -> response"},
Iterator keysIterator = module.keys();
while (keysIterator.hasNext()){
String key = keysIterator.next().toString();
JSONObject obj = (JSONObject) module.get(key);
if (verbose) debug("\n"+key+"("+obj.length()+"):");
String trigger = moduleName+'.'+key;
String name = key;
String desc = formatedName(name,trigger);
//read !proto, !type to make desc
String proto = obj.optString("!proto");
if (""!=proto){ desc+="prototype:"+proto+' ';}
String type = obj.optString("!type");
if (""!=type){ desc+="type:"+type+' ';}
Entry entry = new Entry(moduleObj,EntryType.unknown,name,trigger,desc,moduleEntry);
model.addEntry(entry);
// obj may have other objects inside
populateCheckObj(model, obj, name, moduleObj, entry);
if (verbose) debug("\n Model size="+model.entries.size());
}
if (verbose) debug(";\n");
} catch (ClassCastException e) {
errorCounter++;
error(e.getLocalizedMessage() + "\n" + e + "\n");
} catch (JSONException e) {
errorCounter++;
error(e.getLocalizedMessage() + "\n" + e + "\n");
}
return true;
}
public static boolean checkProperties = true;
private static void populateCheckObj(Model model, JSONObject obj, String word, Module moduleObj, Entry parent) throws JSONException {
if (!checkProperties){
return;
}
Iterator keysIterator = obj.keys();
while (keysIterator.hasNext()){
String key = keysIterator.next().toString();
if (verbose) debug(key+'`');
if (key.equals("!proto")||key.equals("!type")) {
continue;
}
//JSONObject objEement = (JSONObject) obj.get(key);
Object objEementObject = obj.get(key);
JSONObject objEement = null;
String trigger = word+'.'+key;
String name = key;
String desc = formatedName(name,trigger);
if (objEementObject instanceof String ){
// "express": {
// "response": "response",
} else{
objEement = (JSONObject) objEementObject;
//read !proto, !type to make desc
String proto = objEement.optString("!proto");
if (""!=proto){ desc+="prototype:"+proto+' ';}
String type = objEement.optString("!type");
if (""!=type){ desc+="type:"+type+' ';}
}
Entry entry = new Entry(moduleObj,EntryType.unknown,name,trigger,desc,parent);
model.addEntry(entry);
}
}
private static String formatedName(String name) {
return "<b>"+name+"</b><br/>";
}
private static String formatedName(String name, String trigger) {
return formatedName(name)+"<code>"+trigger+"</code><br/>";
}
private static JSONObject jsonForLibrary(String libname){
if (libname==null || libname.length()==0)
return null;
String filename = "org/nodeclipse/ui/contentassist/indexFiles/"+libname+"Index.js";
JSONObject libraryIndex = null;
try {
InputStream is = ContentFromSources.class.getClassLoader().getResourceAsStream(filename);
String index = inputStream2StringWithJson(is);
libraryIndex = new JSONObject(index);
if (verbose) debug( libname+'='+ libraryIndex.toString(2)+'\n');
} catch (JSONException e) {
errorCounter++;
error("error "+errorCounter+" in "+libname+": "+ e.getLocalizedMessage()+"\n");
} catch (IOException e) {
error(e.getLocalizedMessage()+"\n");
}
return libraryIndex;
}
private static String inputStream2StringWithJson(InputStream is) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(is));
StringBuilder buffer = new StringBuilder();
String line = "";
boolean isJsonStarted = false;
while ((line = in.readLine()) != null) {
if (!isJsonStarted){ //skipping header
if (!line.contains("return")){
continue;
}
isJsonStarted = true;
buffer.append("{");
continue;
}
buffer.append(line);
}
return buffer.toString();
}
private static void error(String s){
//NodeclipseConsole.write(s);
System.err.print(s);
}
private static void debug(String s){
//NodeclipseConsole.write(s);
System.out.print(s);
}
private static void log(String s){
//NodeclipseConsole.write(s);
System.out.print(s);
}
}