public class DataFactory {

	/**
	 * @param props
	 *            The properties should contain: lib.domain.data.url,
	 *            ont.domain.data.url, ont.data.url tdb.repository.dir
	 *            (optional)
	 */
	public static DataAPI getAPI(Properties props) {
		return new DataKB(props, true);
	}
} public interface DataAPI {
	// Query
	DataTree getDataHierarchy(); // Tree List of Data and Datatypes
	
	DataTree getDatatypeHierarchy(); // Tree List of Datatypes

	DataTree getMetricsHierarchy(); // Tree List of Metrics and Metric
											// types

	ArrayList<String> getAllDatatypeIds();

	MetadataProperty getMetadataProperty(String propid);

	ArrayList<MetadataProperty> getMetadataProperties(String dtypeid, boolean direct);

	ArrayList<MetadataProperty> getAllMetadataProperties();

	DataItem getDatatypeForData(String dataid);

	ArrayList<DataItem> getDataForDatatype(String dtypeid, boolean direct);

	String getTypeNameFormat(String dtypeid);

	String getDataLocation(String dataid);

	ArrayList<MetadataValue> getMetadataValues(String dataid, ArrayList<String> propids);

	// Write
	boolean addDatatype(String dtypeid, String parentid);

	boolean removeDatatype(String dtypeid);

	boolean renameDatatype(String newtypeid, String oldtypeid);

	boolean moveDatatypeParent(String dtypeid, String fromtypeid, String totypeid);

	boolean addData(String dataid, String dtypeid);

	boolean renameData(String newdataid, String olddataid);

	boolean removeData(String dataid);

	boolean setDataLocation(String dataid, String locuri);

	boolean setTypeNameFormat(String dtypeid, String format);

	boolean addObjectPropertyValue(String dataid, String propid, String valid);

	boolean addDatatypePropertyValue(String dataid, String propid, Object val);

	boolean addDatatypePropertyValue(String dataid, String propid, String val, String xsdtype);

	boolean removePropertyValue(String dataid, String propid, Object val);

	boolean removeAllPropertyValues(String dataid, ArrayList<String> propids);

	boolean addMetadataProperty(String propid, String domain, String range);
	
	boolean addMetadataPropertyDomain(String propid, String domain);

	boolean removeMetadataProperty(String propid);
	
	boolean removeMetadataPropertyDomain(String propid, String domain);

	boolean renameMetadataProperty(String oldid, String newid);

	// Sync/Save
	boolean save();
	
	void end();
	
	void delete();
} public class DataItem extends URIEntity {
	private static final long serialVersionUID = 1L;
	
	public static int DATATYPE = 1;
	public static int DATA = 2;

	int type;

	public DataItem(String id, int type) {
		super(id);
		this.type = type;
	}

	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}
} public class DataTree {
	DataTreeNode root;

	public DataTree(DataTreeNode root) {
		this.root = root;
	}

	public DataTreeNode getRoot() {
		return root;
	}

	public void setRoot(DataTreeNode root) {
		this.root = root;
	}

	public ArrayList<DataTreeNode> flatten() {
		ArrayList<DataTreeNode> list = new ArrayList<DataTreeNode>();
		ArrayList<DataTreeNode> queue = new ArrayList<DataTreeNode>();
		queue.add(root);
		while (!queue.isEmpty()) {
			DataTreeNode node = queue.remove(0);
			list.add(node);
			queue.addAll(node.getChildren());
		}
		return list;
	}

	public DataTreeNode findNode(String nodeid) {
		ArrayList<DataTreeNode> queue = new ArrayList<DataTreeNode>();
		queue.add(root);
		while (!queue.isEmpty()) {
			DataTreeNode node = queue.remove(0);
			if (node.getItem().getID().equals(nodeid))
				return node;
			queue.addAll(node.getChildren());
		}
		return null;
	}
} public class MetadataProperty extends URIEntity {
	private static final long serialVersionUID = 1L;

	int type;
	ArrayList<String> domains;
	String range;

	public static int DATATYPE = 1;
	public static int OBJECT = 2;

	public MetadataProperty(String id, int type) {
		super(id);
		this.type = type;
		this.domains = new ArrayList<String>();
	}

	public void setType(int type) {
		this.type = type;
	}

	public int getType() {
		return this.type;
	}

	public boolean isDatatypeProperty() {
		if (this.type == DATATYPE)
			return true;
		return false;
	}

	public boolean isObjectProperty() {
		if (this.type == OBJECT)
			return true;
		return false;
	}

	public ArrayList<String> getDomains() {
		return this.domains;
	}

	public String getRange() {
		return this.range;
	}

	public void addDomain(String id) {
		this.domains.add(id);
	}

	public void setRange(String id) {
		this.range = id;
	}

	public String toString() {
		String str = "";
		str += "\n" + getName() + "(" + type + ")\nDomains:" + domains + "\nRange:" + range + "\n";
		return str;
	}
}
 public class MetadataValue {
	public final static int OBJECT = 1;
	public final static int DATATYPE = 2;

	String propertyId;
	Object value;
	int type;

	public MetadataValue(String propertyId, Object value, int type) {
		this.propertyId = propertyId;
		this.value = value;
		this.type = type;
	}

	public String getPropertyId() {
		return propertyId;
	}

	public void setPropertyId(String propertyId) {
		this.propertyId = propertyId;
	}

	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}

	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}
} public class KBUtils {
	public static String RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
	public static String RDFS = "http://www.w3.org/2000/01/rdf-schema#";
	public static String OWL = "http://www.w3.org/2002/07/owl#";
	public static String XSD = "http://www.w3.org/2001/XMLSchema#";

	// Map urls/url-prefixes to files/directories (remove any existing mappings
	// first)
	public static void createLocationMappings(Properties props, OntFactory fac) {
		for (String prop : props.stringPropertyNames()) {
			if (prop.endsWith(".url")) {
				String mapProp = prop.replaceAll("\\.url$", ".map");
				String map = props.getProperty(mapProp);
				String url = props.getProperty(prop);
				if (map != null) {
					// if this is a prefix mapping
					if (mapProp.endsWith(".dir.map"))
						fac.addAltPrefix(url, map);
					else
						fac.addAltEntry(url, map);
				}
			}
		}
	}

	public static String sanitizeID(String name) {
		name = name.replaceAll("[^a-zA-Z0-9_\\-\\.]", "_");
		if (name.matches("([0-9]|\\.|\\-).*"))
			name = "a" + name;
		return name;
	}

	public static void removeAllTriplesWith(KBAPI kb, String id, boolean prop) {
		KBObject obj = kb.getResource(id);
		ArrayList<KBTriple> triples = kb.genericTripleQuery(obj, null, null);
		if (prop) {
			obj = kb.getProperty(id);
			triples.addAll(kb.genericTripleQuery(null, obj, null));
		}
		triples.addAll(kb.genericTripleQuery(null, null, obj));
		for (KBTriple triple : triples)
			kb.removeTriple(triple);
	}

	public static void renameAllTriplesWith(KBAPI kb, String oldid, String newid, boolean prop) {
		KBObject oldobj = kb.getResource(oldid);
		KBObject newobj = kb.getResource(newid);
		ArrayList<KBTriple> triples = kb.genericTripleQuery(oldobj, null, null);
		for (KBTriple t : triples) {
			kb.removeTriple(t);
			t.setSubject(newobj);
			kb.addTriple(t);
		}
		if (prop) {
			oldobj = kb.getProperty(oldid);
			newobj = kb.getProperty(newid);
			triples = kb.genericTripleQuery(null, oldobj, null);
			for (KBTriple t : triples) {
				kb.removeTriple(t);
				t.setPredicate(newobj);
				kb.addTriple(t);
			}
		}
		triples = kb.genericTripleQuery(null, null, oldobj);
		for (KBTriple t : triples) {
			kb.removeTriple(t);
			t.setObject(newobj);
			kb.addTriple(t);
		}
	}
	
	public static void renameTripleNamespace(KBAPI kb, String oldns, String newns) {
		ArrayList<KBTriple> triples = kb.genericTripleQuery(null, null, null);
		for (KBTriple t : triples) {
			kb.removeTriple(t);
			t.setSubject(renameKBObjectNamespace(kb, t.getSubject(), oldns, newns));
			t.setPredicate(renameKBObjectNamespace(kb, t.getPredicate(), oldns, newns));
			t.setObject(renameKBObjectNamespace(kb, t.getObject(), oldns, newns));
			kb.addTriple(t);
		}
	}
	
	private static KBObject renameKBObjectNamespace(KBAPI kb, KBObject item, String oldns, String newns) {
		if(item.isLiteral())
			return item;
		if(item.isAnonymous())
			return item;
		if(item.getNamespace() == null)
			return item;
		if(item.getNamespace().equals(oldns)) {
			return kb.getResource(newns + item.getName());
		}
		return item;
	}
} public class Config {
  // The Portal configuration properties file. Order of checking:
  // 1. Check "config.file" servlet context parameter
  // 2. Check ${user.home}/.turbosoft/portal.properties if ${user.home} is
  // present
  // 3. Check /etc/wings/portal.properties
  private String configFile;

  // The following are loaded from the config file
  private String storageDirectory;
  private String tdbDirectory;
  private String dotFile;
  private String serverUrl;
  private String softwareOntologyUrl;
  private String dataOntologyUrl;
  private String communityOntologyUrl;
  private String resourceOntologyUrl;
  private HashMap<String, String> miscProperties;
  
  private String defaultStorageDir = ".turbosoft";
  private String ontdirurl = "http://www.isi.edu/ikcap/geosoft/ontology";
  
  private HashMap<String, String> standardNamesOntologies;

  // Some hardcoded values (TODO: override from config file)
  private String usersRelativeDir = "users";
  private String exportServletPath = "/export";
  private boolean isSandboxed = false;

  // The following are set from the "request" variable
  private String userId;
  private String sessionId;
  private String contextRootPath;
  private String scriptPath;

  // This following are user/domain specific properties
  private String userUrl;
  private String userDir;

  static String fsep = File.separator;
  static String usep = "/";

  public Config(HttpServletRequest request) {
    // Initialize portal config
    this.initializePortalConfig(request);

    // Initialize user config
    this.initializeUserConfig(request);
  }

  private void initializeUserConfig(HttpServletRequest request) {
    this.userId = request.getRemoteUser();
    if (this.userId == null)
      return;

    if(this.userId.equals("guest"))
      this.isSandboxed = true;
    
    this.sessionId = request.getSession().getId();
    this.userUrl = serverUrl + contextRootPath + exportServletPath; 
    //+ "/" + usersRelativeDir + "/" + userId;
    this.userDir = storageDirectory;
    // + File.separator + usersRelativeDir + File.separator + userId;

    // Create userDir (if it doesn't exist)
    File uf = new File(this.userDir);
    if (!uf.exists() && !uf.mkdirs())
      System.err.println("Cannot create user directory : "
          + uf.getAbsolutePath());
  }

  private void initializePortalConfig(HttpServletRequest request) {
    this.contextRootPath = request.getContextPath();
    this.scriptPath = this.contextRootPath + request.getServletPath();

    PropertyListConfiguration serverConfig = getPortalConfiguration(request);
    this.storageDirectory = serverConfig.getString("storage.local");
    this.tdbDirectory = serverConfig.getString("storage.tdb");
    this.serverUrl = serverConfig.getString("server");
    this.softwareOntologyUrl = serverConfig.getString("ontology.software");
    this.dataOntologyUrl = serverConfig.getString("ontology.data");
    this.communityOntologyUrl = serverConfig.getString("ontology.community");
    this.resourceOntologyUrl = serverConfig.getString("ontology.resource");
    if(this.communityOntologyUrl == null)
      this.communityOntologyUrl = ontdirurl + "/community.owl";
    
    this.standardNamesOntologies = new HashMap<String, String>();
    SubnodeConfiguration snconfig = serverConfig.configurationAt("ontology.standard_names");
    
    for(@SuppressWarnings("unchecked")
    Iterator<String> it = snconfig.getKeys(); it.hasNext(); ) {
      String snrepo = it.next();
      String snurl = snconfig.getString(snrepo);
      this.standardNamesOntologies.put(snrepo,  snurl);
    }
    
    this.miscProperties = new HashMap<String, String>();
    try {
      SubnodeConfiguration misc = serverConfig.configurationAt("misc");
      for(@SuppressWarnings("unchecked")
      Iterator<String> it = misc.getKeys(); it.hasNext(); ) {
        String key = it.next();
        String value = misc.getString(key);
        this.miscProperties.put(key,  value);
      }
    }
    catch (Exception e) { }
  }

  private PropertyListConfiguration getPortalConfiguration(
      HttpServletRequest request) {
    ServletContext app = request.getSession().getServletContext();
    this.configFile = app.getInitParameter("config.file");
    if (this.configFile == null) {
      String home = System.getProperty("user.home");
      if (home != null && !home.equals(""))
        this.configFile = home + File.separator + this.defaultStorageDir
            + File.separator + "portal.properties";
      else
        this.configFile = "/etc/wings/portal.properties";
    }
    // Create configFile if it doesn't exist (portal.properties)
    File cfile = new File(this.configFile);
    if (!cfile.exists()) {
      if (!cfile.getParentFile().mkdirs()) {
        System.err.println("Cannot create config file directory : "
            + cfile.getParent());
        return null;
      }
      createDefaultPortalConfig(request);
    }

    // Load properties from configFile
    PropertyListConfiguration props = new PropertyListConfiguration();
    try {
      props.load(this.configFile);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return props;
  }

  private void createDefaultPortalConfig(HttpServletRequest request) {
    String server = request.getScheme() + "://" + request.getServerName() + ":"
        + request.getServerPort();
    String storageDir = null;
    String home = System.getProperty("user.home");
    if (home != null && !home.equals(""))
      storageDir = home + File.separator + this.defaultStorageDir
          + File.separator + "storage";
    else
      storageDir = System.getProperty("java.io.tmpdir") + File.separator
          + "wings" + File.separator + "storage";
    if (!new File(storageDir).mkdirs())
      System.err.println("Cannot create storage directory: " + storageDir);

    PropertyListConfiguration config = new PropertyListConfiguration();
    config.addProperty("storage.local", storageDir);
    config.addProperty("storage.tdb", storageDir + File.separator + "TDB");
    config.addProperty("server", server);
    
    config.addProperty("ontology.software", ontdirurl + "/software.owl");
    config.addProperty("ontology.data", ontdirurl + "/data.owl");
    config.addProperty("ontology.resource", ontdirurl + "/resource.owl");
    config.addProperty("ontology.community", ontdirurl + "/community.owl");
    
    config.addProperty("misc.tikaUrl", "http://[Tika Server]/detect/stream");
    config.addProperty("misc.solrUrl", "http://[Solr Server]/solr");
    config.addProperty("misc.dratHome", "/path/to/drat");
    
    config.addProperty("ontology.standard_names.CSDMS", ontdirurl + "/CSDMS.owl");

    try {
      config.save(this.configFile);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  // Return Properties that are currently used by catalogs & planners
  public Properties getProperties() {
    Properties props = new Properties();
    props.setProperty("lib.software.url", this.userUrl + usep + "software/library.owl");
    props.setProperty("lib.community.url", this.userUrl + usep + "community/library.owl");
    props.setProperty("lib.domain.data.url", this.userUrl + usep + "data/library.owl");
    props.setProperty("ont.domain.data.url", this.userUrl + usep + "data/ontology.owl");
    props.setProperty("lib.domain.data.storage", this.userDir + fsep + "data");
    
    props.setProperty("rules.software.url", ontdirurl + "/software.rules");
    props.setProperty("ont.software.url", this.softwareOntologyUrl);
    props.setProperty("ont.data.url", this.dataOntologyUrl);
    if(this.resourceOntologyUrl != null)
      props.setProperty("ont.resource.url", this.resourceOntologyUrl);
    props.setProperty("ont.community.url", this.communityOntologyUrl);

    props.setProperty("tdb.repository.dir", this.getTripleStoreDir());
    return props;
  }

  public String getSoftwareOntologyUrl() {
    return this.softwareOntologyUrl;
  }

  public void setSoftwareOntologyUrl(String softwareOntologyUrl) {
    this.softwareOntologyUrl = softwareOntologyUrl;
  }

  public String getDataOntologyUrl() {
    return this.dataOntologyUrl;
  }

  public void setDataOntologyUrl(String dataOntologyUrl) {
    this.dataOntologyUrl = dataOntologyUrl;
  }

  public String getCommunityOnologyUrl() {
    return this.communityOntologyUrl;
  }

  public void setCommunityOnologyUrl(String communityOnologyUrl) {
    this.communityOntologyUrl = communityOnologyUrl;
  }
  
  public String getResourceOntologyUrl() {
    return resourceOntologyUrl;
  }

  public void setResourceOntologyUrl(String resourceOntologyUrl) {
    this.resourceOntologyUrl = resourceOntologyUrl;
  }

  public String getConfigFile() {
    return configFile;
  }

  public void setConfigFile(String configFile) {
    this.configFile = configFile;
  }

  public String getUsersRelativeDir() {
    return usersRelativeDir;
  }

  public void setUsersRelativeDir(String usersRelativeDir) {
    this.usersRelativeDir = usersRelativeDir;
  }

  public String getExportServletPath() {
    return exportServletPath;
  }

  public void setExportServletPath(String exportServletPath) {
    this.exportServletPath = exportServletPath;
  }

  public String getUserId() {
    return userId;
  }

  public void setUserId(String userId) {
    this.userId = userId;
  }

  public String getUserDir() {
    return userDir;
  }

  public void setUserDir(String userDir) {
    this.userDir = userDir;
  }

  public void setUserUrl(String userUrl) {
    this.userUrl = userUrl;
  }

  public String getServerUrl() {
    return serverUrl;
  }

  public void setServerUrl(String serverUrl) {
    this.serverUrl = serverUrl;
  }

  public String getContextRootPath() {
    return contextRootPath;
  }

  public void setContextRootPath(String root) {
    this.contextRootPath = root;
  }

  public String getScriptPath() {
    return scriptPath;
  }

  public void setScriptPath(String scriptPath) {
    this.scriptPath = scriptPath;
  }

  public String getUserUrl() {
    return userUrl;
  }

  public String getTripleStoreDir() {
    return tdbDirectory;
  }

  public void setTripleStoreDir(String tripleStoreDir) {
    this.tdbDirectory = tripleStoreDir;
  }

  public String getSessionId() {
    return sessionId;
  }

  public void setSessionId(String sessionId) {
    this.sessionId = sessionId;
  }

  public boolean isSandboxed() {
    return isSandboxed;
  }

  public void setSandboxed(boolean isSandboxed) {
    this.isSandboxed = isSandboxed;
  }

  public String getDotFile() {
    return dotFile;
  }

  public void setDotFile(String dotFile) {
    this.dotFile = dotFile;
  }

  public String getStorageDirectory() {
    return storageDirectory;
  }

  public void setStorageDirectory(String storageDirectory) {
    this.storageDirectory = storageDirectory;
  }

  public HashMap<String, String> getStandardNamesOntologies() {
    return standardNamesOntologies;
  }

  public void setStandardNamesOntologies(HashMap<String, String> standardNamesOntologies) {
    this.standardNamesOntologies = standardNamesOntologies;
  }

  public HashMap<String, String> getMiscProperties() {
    return miscProperties;
  }

  public String getMiscPropertyValue(String key) {
    return miscProperties.get(key);
  }
  
  public void setMiscProperties(HashMap<String, String> miscProperties) {
    this.miscProperties = miscProperties;
  }
  
  public void addMiscPropertyValue(String key, String value) {
    this.miscProperties.put(key, value);
  }
} public class JsonHandler {
	public static Gson createGson() {
		return new GsonBuilder().disableHtmlEscaping().create();
	}
	
	public static Gson createPrettyGson() {
		return new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
	}
	
  public static Gson createDataGson() {
    GsonBuilder gson = new GsonBuilder();
    gson.registerTypeAdapter(XSDDateTime.class, new XSDDateTimeSerializer());
    return gson.disableHtmlEscaping().setPrettyPrinting().create();
  }
} public class CSSLoader {
  static String theme = "gray";
  static String[] site_css = { "css/menu.css", "css/app.css"
    , "css/fontello/css/wings-icons.css" };
  static String[] extjs_css = { "lib/extjs/resources/ext-theme-" + theme
      + "/ext-theme-" + theme + "-all.css" };

  public static void loadLoginViewer(PrintWriter out, String path) {
    showCssTags(out, path, site_css);
    showCssTags(out, path, extjs_css);
  }

  public static void loadSoftwareViewer(PrintWriter out, String path) {
    showCssTags(out, path, site_css);
    showCssTags(out, path, extjs_css);
  }

  public static void loadDataViewer(PrintWriter out, String path) {
    showCssTags(out, path, site_css);
    showCssTags(out, path, extjs_css);
  }

  public static void loadCommunityViewer(PrintWriter out, String path) {
    showCssTags(out, path, site_css);
    showCssTags(out, path, extjs_css);
  }
  
  private static void showCssTags(PrintWriter out, String path, String[] css) {
    for (String href : css) {
      out.println("<link rel=\"stylesheet\" href=\"" + path + "/" + href
          + "\"/>");
    }
  }
} public class JSLoader {
  static String[] common_scripts = { "lib/extjs/ext-all.js",
      "js/util/common.js", "js/util/TreeMod.js" };
  static String[] software_scripts = { "js/gui/SoftwareViewer.js" };
  static String[] data_scripts = { "js/gui/DataViewer.js" };
  static String[] community_scripts = { "js/gui/CommunityViewer.js" };

  static String[] plupload_scripts = { "js/util/pluploadPanel.js",
      "lib/plupload/plupload.full.min.js" };

  public static void setContextInformation(PrintWriter out, Config config) {
    HashMap<String, Object> jsvars = new HashMap<String, Object>();
    jsvars.put("CONTEXT_ROOT", "'" + config.getContextRootPath() + "'");
    jsvars.put("USER_ID", "'" + config.getUserId() + "'");
    JSLoader.showScriptKeyVals(out, jsvars);
  }

  public static void loadLoginViewer(PrintWriter out, String path) {
    showScriptTags(out, path, common_scripts);
  }

  public static void loadSoftwareViewer(PrintWriter out, String path) {
    showScriptTags(out, path, common_scripts);
    showScriptTags(out, path, software_scripts);
    // showScriptTags(out, path, rule_scripts);
    showScriptTags(out, path, plupload_scripts);
  }

  public static void loadDataViewer(PrintWriter out, String path) {
    showScriptTags(out, path, common_scripts);
    showScriptTags(out, path, data_scripts);
    showScriptTags(out, path, plupload_scripts);
  }

  public static void loadCommunityViewer(PrintWriter out, String path) {
    showScriptTags(out, path, common_scripts);
    showScriptTags(out, path, community_scripts);
  }
  
  private static void showScriptTags(PrintWriter out, String path,
      String[] scripts) {
    for (String script : scripts) {
      out.println("<script src=\"" + path + "/" + script + "\"></script>");
    }
  }

  public static void showScriptKeyVals(PrintWriter out,
      HashMap<String, Object> map) {
    out.println("<script>");
    for (String key : map.keySet()) {
      Object val = map.get(key);
      out.println("var " + key + " = " + val + ";");
    }
    out.println("</script>");
  }
}
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.earthcube.geosoft.data.DataFactory;
import org.earthcube.geosoft.data.api.DataAPI;
import org.earthcube.geosoft.data.classes.DataItem;
import org.earthcube.geosoft.data.classes.DataTree;
import org.earthcube.geosoft.data.classes.MetadataProperty;
import org.earthcube.geosoft.data.classes.MetadataValue;
import org.earthcube.geosoft.util.KBUtils;
import org.earthcube.geosoft.portal.classes.Config;
import org.earthcube.geosoft.portal.classes.JsonHandler;
import org.earthcube.geosoft.portal.classes.html.CSSLoader;
import org.earthcube.geosoft.portal.classes.html.JSLoader;
package org.earthcube.geosoft.portal.controllers;






public class DataController {
	private int guid;

	private String dcns;
	private String domns;
	private String libns;
	
	private String uploadScript;

	private DataAPI dc;
	private boolean isSandboxed;
	private Config config;
	private Properties props;

	private Gson json;

	public DataController(int guid, Config config) {
		this.guid = guid;
		this.config = config;
		this.isSandboxed = config.isSandboxed();
		json = JsonHandler.createDataGson();
		this.props = config.getProperties();

		dc = DataFactory.getAPI(props);

		this.dcns = (String) props.get("ont.data.url") + "#";
		this.domns = (String) props.get("ont.domain.data.url") + "#";
		this.libns = (String) props.get("lib.domain.data.url") + "#";
		
		this.uploadScript = config.getContextRootPath() + "/upload";
	}

	public void show(PrintWriter out) {
		// Get Hierarchy
		try {
			String tree = this.getDataHierarchyJSON();
			String metrics = this.getMetricsHierarchyJSON();
	
			out.println("<html>");
			out.println("<head>");
			out.println("<title>Describe File Types</title>");
			JSLoader.setContextInformation(out, config);
			CSSLoader.loadDataViewer(out, config.getContextRootPath());
			JSLoader.loadDataViewer(out, config.getContextRootPath());
			out.println("</head>");
	
			out.println("<script>");
			out.println("var dataViewer_" + guid + ";");
			out.println("Ext.onReady(function() {"
					+ "dataViewer_" + guid + " = new DataViewer('" + guid + "', { "
							+ "tree: " + tree + ", "
							+ "metrics: " + metrics 
						+ " }, " 
						+ "'" + config.getScriptPath() + "', "
						+ "'" + this.uploadScript + "', "
						+ "'" + this.dcns + "', " 
						+ "'" + this.domns + "', " 
						+ "'" + this.libns + "', " 
						+ !this.isSandboxed + ", "
						+ false
						+ ");\n"
						+ "dataViewer_" + guid + ".initialize();\n"
					+ "});");
			out.println("</script>");
	
			out.println("</html>");
		}
		finally {
			if(dc != null)
				dc.end();
		}
	}

	/*
	 * Querying Methods
	 */
	public String getDataJSON(String dataid) {
		try {
			if (this.dc == null)
				return "{}";
			String location = this.dc.getDataLocation(dataid);
			DataItem dtype = this.dc.getDatatypeForData(dataid);
			ArrayList<MetadataProperty> props = this.dc.getMetadataProperties(dtype.getID(), false);