public interface Install {
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resource the URL of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @throws Exception
	 */
	public void install(URL resource, URL dest) throws Exception;
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resource the InputStream of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @throws Exception
	 */
	public void install(InputStream resource, URL dest) throws Exception;
	
	public void validate(URL url) throws Exception;
} public class ZipLocate extends AbstractLocate {

	public ZipLocate() {
		super(new ZipPathBinder());
	}

} public interface AppInstall {
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resource the URL of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(URL resource, URL dest, String format, String version) throws Exception;
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resources the URL to the resources that are going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(URL[] resource, URL dest, String format, String version) throws Exception;
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resource the URL of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(URL resource, URL dest, String format, String version, InputStreamFactory factory) throws Exception;
	
	
	/**
	 * Install the given resources in a given URL.
	 * 
	 * @param resources the URL of the resources that are going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(URL[] resources, URL dest, String format, String version, InputStreamFactory isFactory) throws Exception;
	
	public void install(URL resource, File dest, InputStreamFactory isFactory) throws Exception;
	
	public void install(URL[] resource, File dest, InputStreamFactory isFactory) throws Exception;
	
	public void validate(URL url, String format, String version) throws Exception;
	
	public void register(URL url, String format, String version) throws Exception;
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param resource the InputStream of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(InputStream source, URL dest, String format, String version) throws Exception;
	
	/**
	 * Install a given resource in a given URL.
	 * 
	 * @param sources the InputStreams of the resource that is going to be published.
	 * @param dest the URL where the resource is going to be published.
	 * @param format the format.
	 * @param version the version.
	 * 
	 * @throws Exception
	 */
	public void install(InputStream sources[], URL dest, String format, String version) throws Exception;
	
	public void install(InputStream source, File target) throws Exception;
	
	public void install(InputStream[] sources, File target) throws Exception;
} public interface Listener {
	public void starting();
	public void started();
} public class Server {
	
	private int port = 3030;
	private DatasetGraph dsg = null;
	private String subDomain = null;
	private String pagePath = null;
	private Listener listener = null;
	
	public Server(int port, String pagePath, String subDomain, long timeout, Model model, Listener listener) {
		this(port, pagePath, subDomain, model, listener);
		ARQ.getContext().set(ARQ.queryTimeout, Long.toString(timeout));
	}

	public Server(int port, String pagePath, String subDomain, Model model, Listener listener) {
		this.port = port;
		this.subDomain = subDomain;
		this.pagePath = pagePath;
		Dataset dataset = DatasetFactory.create(model);
		this.dsg = dataset.asDatasetGraph();
		this.listener = listener;
	}
	
	public Server(int port, String pagePath, String subDomain, String datasetPath) {
		this.port = port;
		this.subDomain = subDomain;
		this.pagePath = pagePath;
		this.dsg = TDBFactory.createDatasetGraph(datasetPath);
	}

	public void start() throws ServerStartException {
		try {
			listener.starting();			
			String staticContentDir = pagePath;
			FusekiServer server = FusekiServer.create()
					.add("/" + subDomain, dsg)
					.enablePing(true)
					.enableStats(true)
					.staticFileBase(staticContentDir)
					.port(port)
					.build();
			server.start();
			listener.started();
		} catch (Exception e) {
			throw new ServerStartException("Failed to start the server.", e);
		}
	}
} public class ServerStartException extends Exception {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8495102644748797751L;

	public ServerStartException(String message, Exception e) {
		super(message, e);
	}
} public class ConsoleInstallInputStreamFactory implements InputStreamFactory {
	
	private final static String MESSAGE = "Installing";

	@Override
	public InputStream get(URL url) throws IOException {
		ConsoleStreamListener listener = new ConsoleStreamListener(MESSAGE + " " + url, URLUtils.getContentLength(url));
		InputStreamInstaller installer = new InputStreamInstaller(url.openStream(), listener);
		return installer;
	}

} public class KBDereferencingException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8762611547404229890L;

	public KBDereferencingException() {
		super("The knowledge base could not be dereferenced.");
	}
	
	public KBDereferencingException(String kb) {
		super("The knowledge base " + kb + " could not be dereferenced.");
	}
	
	public KBDereferencingException(String kb, Exception e) {
		super("The knowledge base " + kb + " could not be dereferenced.", e);
	}
} public class KBNotLocatedException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8762611547404229890L;

	public KBNotLocatedException() {
		super("The knowledge base could not be located.");
	}
	
	public KBNotLocatedException(String message) {
		super(message);
	}
} public class CustomKNSServerList extends CustomParams implements KNSServerList {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -3697460272426263415L;
	
	public final static String CONTEXT_NAME = "kbox.kns";
	public final static String KNS_FILE_NAME = CONTEXT_NAME;
	
	private KNSServerListVisitor visitor = null;
	private boolean next = false;
	private CustomParamKNSServerListVisitor customParamKNSServerListVisitor = null;
	
	public CustomKNSServerList(String path, String contex) {
		super(path 
				+ File.separator
				+ KNS_FILE_NAME, 
				CONTEXT_NAME);
		customParamKNSServerListVisitor = new CustomParamKNSServerListVisitor();
		
	}
	
	public CustomKNSServerList() {
		this(KBox.KBOX_DIR,
				CONTEXT_NAME);
	}
	
	public boolean visit(KNSServerListVisitor visitor) throws Exception {
		this.visitor = visitor;
		return super.visit(customParamKNSServerListVisitor);
	}
	
	private class CustomParamKNSServerListVisitor implements CustomParamVisitor {

		@Override
		public boolean visit(String param) throws Exception {
			KNSServer knsServer = new KBoxKNSServer(new URL(param));
			next = visitor.visit(knsServer);
			return next;
		}
		
	}
} public class InstallFactory {

	private Map<String, AppInstall> methods = new HashMap<String, AppInstall>();

	public AppInstall get(KN kn) {
		String decoder = kn.getTargets().get(0).getInstall();
		if(decoder == null) {
			return new ResourceAppInstall();
		}
		decoder = decoder.toLowerCase();
		return methods.get(decoder);
	}
	
	public void put(String id, AppInstall install) {
		methods.put(id.toLowerCase(), install);
	}
	
	public AppInstall get(String format) {
		return methods.get(format.toLowerCase());
	}

} public interface KNSServerListVisitor extends Visitor<KNSServer> {	
} public class ServerAddress {
	
	private String url = null;
	
	public ServerAddress(String url) {
		this.url = url;
	}
	
	public String getURL() {
		return url;
	}
	
	public String getQueryURL() {
		return url;
	}
} public class Source {
	private String install;
	private URL url;
	private Map<String,String> checksum;
	
	public String getInstall() {
		return install;
	}

	public void setInstall(String install) {
		this.install = install;
	}

	public URL getURL() {
		return url;
	}

	public void setURL(URL url) {
		this.url = url;
	}

	public Map<String,String> getChecksum() {
		return checksum;
	}

	public void setChecksum(Map<String,String> checksum) {
		this.checksum = checksum;
	}
	
	public static List<Source> toTarget(String json) throws Exception {
		JSONParser jsonParser = new JSONParser();
		Reader stringReader = new StringReader(json);
		JSONArray jsonArray = (JSONArray) jsonParser.parse(stringReader);
		return toTarget(jsonArray);
	}
	
	public static List<Source> toTarget(JSONArray targetArray) throws Exception {
		java.util.List<Source> sources = new ArrayList<Source>();
		if(targetArray != null) {
			for(int m = 0; m < targetArray.size(); m++) {
				JSONArray jsonMirror = (JSONArray) targetArray.get(m);
				for(int s = 0; s < jsonMirror.size(); s++) {
					JSONObject jsonSource = (JSONObject) jsonMirror.get(s);
					String install = (String) jsonSource.keySet().toArray()[0];
					JSONArray jsonSources = (JSONArray) jsonSource.values().toArray()[0];
					if(jsonSources != null) {
						for(int i= 0; i < jsonSources.size(); i++) {
							JSONObject jsonSourceEntry = (JSONObject)jsonSources.get(i);
							String url = (String)jsonSourceEntry.get(KN.URL);
							JSONObject jsonChecksum = (JSONObject) jsonSourceEntry.get(KN.CHECKSUM);
							Map<String, String> checksum = new HashMap<String, String>();
							if(jsonChecksum != null) {
								for(int c = 0; c < jsonChecksum.keySet().size(); c++) {
									String key = (String) jsonChecksum.keySet().toArray()[c];
									String value = (String) jsonChecksum.values().toArray()[c];
									checksum.put(key, value);
								}
							}
							JSONObject jsonDataId = (JSONObject) jsonSourceEntry.get(KN.DATAID);
							Map<String, String> dataId = new HashMap<String, String>();
							if(jsonDataId != null) {
								for(int di = 0; di < jsonDataId.keySet().size(); di++) {
									String key = (String) jsonDataId.keySet().toArray()[di];
									String value = (String) jsonDataId.values().toArray()[di];
									dataId.put(key, value);
								}
							}
							Source source = new Source();
							source.setInstall(install);
							source.setChecksum(checksum);
							URI uri = new URI(url);
							URL knName = null;
							if(uri.isAbsolute() && URLUtils.hasValidURLHost(uri)) {
								knName = new URL(url);
							} else {
								File file = new File(url);
								knName = file.toURI().toURL();
							}
							source.setURL(knName);
							sources.add(source);
						}
					}
				}
			}
		}
		return sources;
	}
} public class ResourceNotResolvedException extends Exception {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8762611547404229890L;

	public ResourceNotResolvedException() {
		super("The resource could not be resolved.");
	}
	
	public ResourceNotResolvedException(String message) {
		super(message);
	}
} public class GzipUtils {

    public static void pack(File input, File output) throws IOException {
        try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(new FileOutputStream(output))){
            IOUtils.copy(new FileInputStream(input), out);
        }
    }
    
    public static void pack(InputStream input, File output) throws IOException {
        try (GzipCompressorOutputStream out = new GzipCompressorOutputStream(new FileOutputStream(output))){
            IOUtils.copy(input, out);
        }
    }

    public static void unpack(InputStream input, File output) throws IOException {
        try (GzipCompressorInputStream in = new GzipCompressorInputStream(input)){
        	try(FileOutputStream out = new FileOutputStream(output)){
        		IOUtils.copy(in, out);
        	}
        }
    }
} public class URLUtils {
	
	private static Set<String> protocolsWithHost = new HashSet<String>( 
		      Arrays.asList( new String[]{ "file", "ftp", "http", "https" } ) 
		  );
	
	public static URL[] stringToURL(String... urls) throws Exception {
		URL[] urlArray = new URL[urls.length];
		for(int i=0; i < urls.length; i++) {
			urlArray[i]  = new URL(urls[i]);
		}
		return urlArray;
	}
	
	public static boolean checkStatus(URL url, int code) throws IOException {
		URLConnection conn = url.openConnection();
		if(conn instanceof HttpURLConnection) {
			HttpURLConnection huc =  (HttpURLConnection) conn;
			huc.setRequestMethod("HEAD");
			conn.connect();
			return huc.getResponseCode() == code;
		}
		return false;
	}
	
	public static URL[] fileToURL(File... files) throws MalformedURLException {
		URL[] urls = new URL[files.length];
		int i = 0;
		for(File file : files) {
			urls[i] = file.toURI().toURL();
			i++;
		}		
		return urls;
	}
	
	public static long getContentLength(URL url) throws IOException {
        URLConnection conn = url.openConnection();
        Long contentLength = conn.getContentLengthLong();
        if(contentLength != null && contentLength >= 0) {
        	return contentLength;
        }
		String contentLengthValue = conn.getHeaderField("content-length");
		if(contentLengthValue != null) {
			return Long.valueOf(contentLengthValue);
		}
		return -1;
	}
	
	public static URL getURLForward(URL url) throws Exception {
		URLConnection con = url.openConnection();
		String location = con.getHeaderField("Location");
		if(location != null) {
			return new URL(location);
		}
		return url;
	}
	
	public static boolean hasValidURLHost(URI uri) {
		return protocolsWithHost.contains(uri.getScheme());
	}
	
	public static String getContentType(URL url) throws Exception {
		URL forwardURL = getURLForward(url);
		HttpURLConnection connection = (HttpURLConnection)  forwardURL.openConnection();
		connection.setRequestMethod("HEAD");
		connection.connect();
		return connection.getContentType();
	}
}
import org.aksw.kbox.Install;
import org.aksw.kbox.ZipLocate;
import org.aksw.kbox.apple.AppInstall;
import org.aksw.kbox.fusca.Listener;
import org.aksw.kbox.fusca.Server;
import org.aksw.kbox.fusca.exception.ServerStartException;
import org.aksw.kbox.kibe.console.ConsoleInstallInputStreamFactory;
import org.aksw.kbox.kibe.exception.KBDereferencingException;
import org.aksw.kbox.kibe.exception.KBNotLocatedException;
import org.aksw.kbox.kns.CustomKNSServerList;
import org.aksw.kbox.kns.InstallFactory;
import org.aksw.kbox.kns.KNSServerListVisitor;
import org.aksw.kbox.kns.ServerAddress;
import org.aksw.kbox.kns.Source;
import org.aksw.kbox.kns.exception.ResourceNotResolvedException;
import org.aksw.kbox.utils.GzipUtils;
import org.aksw.kbox.utils.URLUtils;
import org.apache.jena.query.ResultSet;
import org.apache.jena.query.ResultSetFormatter;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.sparql.engine.http.QueryExceptionHTTP;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.zeroturnaround.zip.ZipUtil;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
					jsonSerializer.printOutput(message);
					jsonSerializer.printResourceDirectoryAsJsonResponse(message, resourceDir);
				} catch (Exception e) {
					String errorMessage = "Error changing KBox resource repository to " + resourceDir + ".";
					jsonSerializer.printOutput(errorMessage);
					jsonSerializer.printErrorInJsonFormat(errorMessage, true);
					logger.error(errorMessage, e);
				}
			} else {
				resourceDir = KBox.getResourceFolder();
				String message = "Your current resource directory is: " + resourceDir;
				jsonSerializer.printOutput(message);
				jsonSerializer.printResourceDirectoryAsJsonResponse(message, resourceDir);
			}
		} else if (commands.containsKey(SEARCH_COMMAND)) {
			String pattern = getSingleParam(commands, SEARCH_COMMAND);
			String format = getSingleParam(commands, FORMAT_COMMAND);
			String version = getSingleParam(commands, VERSION_COMMAND);
			SearchKBKNSVisitor searchVisitor = new SearchKBKNSVisitor(pattern, format, version,
					commands.containsKey(PAGINATION_COMMAND));
			try {
				KBox.visit(searchVisitor);
				jsonSerializer.printVisitedKNAsJsonResponse("searching completed.");
			} catch (Exception e) {
				String message = "An error occurred while enquiring search using the pattern: " + pattern;
				jsonSerializer.printOutput(message);
				logger.error(message, e);
				jsonSerializer.printErrorInJsonFormat(message, true);
			}
		} else if (commands.containsKey(INFO_COMMAND)) {
			String kn = getSingleParam(commands, INFO_COMMAND);
			String format = getSingleParam(commands, FORMAT_COMMAND);
			String version = getSingleParam(commands, VERSION_COMMAND);
			InfoKBKNSVisitor visitor = new InfoKBKNSVisitor(kn, format, version);
			try {
				KBox.visit(visitor);
				jsonSerializer.printKNInfoAsJsonResponse("Information has been fetched.");
			} catch (Exception e) {
				String message = "An error occurred while enquiring information from the KN " + kn;
				jsonSerializer.printOutput(message);
				jsonSerializer.printErrorInJsonFormat(message, true);
				logger.error(message, e);
			}
		} else if (commands.containsKey(LOCATE_COMMAND) && !commands.containsKey(KB_COMMAND)
				&& !commands.containsKey(FORMAT_COMMAND)) {
			String resourceURL = getSingleParam(commands, LOCATE_COMMAND);
			try {
				String path = org.aksw.kbox.KBox.locate(new URL(resourceURL)).getAbsolutePath();
				jsonSerializer.printOutput(path);
				jsonSerializer.printLocateCommandJsonResponse("Action Completed.",path);
			} catch (Exception e) {
				String message = "An error occurred while resolving the resource: " + resourceURL;
				jsonSerializer.printOutput(message);
				jsonSerializer.printErrorInJsonFormat(message, true);
				logger.error(message, e);
			}
		} else if (commands.containsKey(LOCATE_COMMAND) && commands.containsKey(KB_COMMAND)) {
			String kbURL = getSingleParam(commands, KB_COMMAND);
			String version = getSingleParam(commands, VERSION_COMMAND);
			try {
				String path = KBox.locate(new URL(kbURL), KBox.KIBE_FORMAT, version).getAbsolutePath();
				jsonSerializer.printOutput(path);
				jsonSerializer.printLocateCommandJsonResponse("Action Completed.", path);
			} catch (Exception e) {
				String message = "An error occurred while resolving the KB: " + kbURL;
				jsonSerializer.printOutput(message);
				jsonSerializer.printErrorInJsonFormat(message, true);
				logger.error(message, e);
			}
		} else if (commands.containsKey(LOCATE_COMMAND) && commands.containsKey(FORMAT_COMMAND)) {
			String kbURL = getSingleParam(commands, LOCATE_COMMAND);
			String format = getSingleParam(commands, FORMAT_COMMAND);
			String version = getSingleParam(commands, VERSION_COMMAND);
			try {
				String path = KBox.locate(new URL(kbURL), format, version).getAbsolutePath();
				jsonSerializer.printOutput(path);
				jsonSerializer.printLocateCommandJsonResponse("Action Completed.", path);
			} catch (Exception e) {
				String message = "An error occurred while resolving the KB: " + kbURL;
				jsonSerializer.printOutput(message);
				jsonSerializer.printErrorInJsonFormat(message, true);
				logger.error(message, e);
			}
		} else if (commands.containsKey(LOCATE_COMMAND) && commands.containsKey(KN_COMMAND)) {
			String kbURL = getSingleParam(commands, KN_COMMAND);
			String format = getSingleParam(commands, FORMAT_COMMAND);
			String version = getSingleParam(commands, VERSION_COMMAND);
			try {
				String path = KBox.locate(new URL(kbURL), format, version).getAbsolutePath();
				jsonSerializer.printOutput(path);
				jsonSerializer.printLocateCommandJsonResponse("Action Completed.", path);
			} catch (Exception e) {
				String message = "An error occurred while resolving the KN: " + kbURL;
				jsonSerializer.printOutput(message);
				jsonSerializer.printErrorInJsonFormat(message, true);
				logger.error(message, e);
			}
		} else if (commands.containsKey(SERVER_COMMAND)) {
			int port = 8080;
			String subDomain = "kbox";
			if (commands.containsKey(SERVER_COMMAND_PORT)) {
				port = Integer.parseInt(getSingleParam(commands, SERVER_COMMAND_PORT));
			}
			if (commands.containsKey(SEVER_COMMAND_SUBDOMAIN)) {
				subDomain = getSingleParam(commands, SEVER_COMMAND_SUBDOMAIN);
			}
			try {
				System.out.println("Loading Model...");
				Model model = null;
				if(commands.containsKey(KB_COMMAND)) {
					String graphNamesList = getSingleParam(commands, KB_COMMAND);
					String[] graphNames = graphNamesList.split(KB_COMMAND_SEPARATOR);
					boolean install = commands.containsKey(INSTALL_COMMAND);
					URL[] urls = new URL[graphNames.length];
					for (int i = 0; i < graphNames.length; i++) {
						urls[i] = new URL(graphNames[i]);
					}
					model = KBox.createModel(inputStreamFactory, install, urls);
				} if(commands.containsKey(TARGET_COMMAND)) {
					String targetArray = getSingleParam(commands, TARGET_COMMAND);
					List<Source> sources = Source.toTarget(targetArray);