//This file is part of SECONDO. //Copyright (C) 2004, University in Hagen, Department of Computer Science, //Database Systems for New Applications. //SECONDO is free software; you can redistribute it and/or modify //it under the terms of the GNU General Public License as published by //the Free Software Foundation; either version 2 of the License, or //(at your option) any later version. //SECONDO is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. //You should have received a copy of the GNU General Public License //along with SECONDO; if not, write to the Free Software //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import java.io.*; import java.net.*; import java.util.*; import jpl.JPL; import jpl.Atom; import jpl.Query; import jpl.Term; import jpl.Variable; import jpl.fli.*; import jpl.Compound; import jpl.Util; public class OptimizerServer extends Thread{ static { System.loadLibrary( "jpl" ); System.loadLibrary("regSecondo"); } public static native int registerSecondo(); /** shows a prompt at the console */ private static void showPrompt(){ System.out.print("\n opt-server > "); } /** init prolog * register the secondo predicate * loads the optimizer prolog code */ private boolean initialize(){ // later here is to invoke the init function which // registers the Secondo(command,Result) predicate to prolog if(registerSecondo()!=0){ System.err.println("error in registering the secondo predicate "); return false; } try{ System.out.println("call JPL.init()"); JPL.init(); System.out.println("initialisation successful"); // VTA - 18.09.2006 // I added this piece of code in order to run with newer versions // of prolog. Without this code, the libraries (e.g. lists.pl) are // not automatically loaded. It seems that something in our code // (auxiliary.pl and calloptimizer.pl) prevents them to be // automatically loaded. In order to solve this problem I added // a call to 'member(x, [x]).' so that the libraries are loaded // before running our scripts. Term[] args = new Term[2]; args[0] = new Atom("x"); args[1] = jpl.Util.termArrayToList( new Term[] { new Atom("x") } ); Query q = new Query("member",args); if(!q.query()){ System.out.println("error in the member call'"); return false; } args = new Term[1]; args[0] = new Atom("auxiliary"); q = new Query("consult",args); if(!q.query()){ System.out.println("error in loading 'auxiliary.pl'"); return false; } args = new Term[1]; args[0] = new Atom("calloptimizer"); q = new Query("consult",args); if(!q.query()){ System.out.println("error in loading 'calloptimizer.pl'"); return false; } return true; } catch(Exception e){ System.out.println("Exception in initialization "+e); return false; } } /** invokes a prolog predicate * all terms in variables must be contained in arguments * variables and results can be null if no result is desired */ synchronized private static boolean command(Query pl_query, NamedVariable[] variables,Vector results){ if(pl_query==null) return false; try{ if(trace){ System.out.println("execute query: "+pl_query); } String ret =""; int number =0; // the number of solutions if(results!=null) results.clear(); while(pl_query.hasMoreSolutions(Prolog.Q_NODEBUG)){ number++; Hashtable solution = pl_query.nextSolution(); if(results!=null){ ret = ""; if(variables==null || variables.length==0) results.add("yes"); else{ for(int i=0;i0) ret += " $$$ "; ret += ( P.getName() + " = " + solution.get(P.getVariable())); } results.add(ret); } } } if(number == 0){ if(trace) System.out.println("no solution found for' "+pl_query.atom() +"/"+pl_query.args().length); return false; } else{ // check if a new database is opened Variable X = new Variable(); Query dbQuery = new Query("databaseName",X); Hashtable sol = dbQuery.oneSolution(); if(sol==null){ System.out.println("Error in getting database name "); return false; } String name = sol.get(X).toString(); if(!name.equals(openedDatabase)){ if(trace){ System.out.println("use database "+name); } openedDatabase = name; } return true; } } catch(Exception e){ if(trace) System.out.println("exception in calling the "+pl_query.atom()+"-predicate"+e); return false; } } /** analyzed the given string and extract the command and the argumentlist *
then the given command is executed * all Solutions are stored into the Vector Solution */ private synchronized static boolean execute(String command,Vector Solution){ if(Solution!=null) Solution.clear(); // clients should not have the possibility // to shut down the Optimizer-Server command = command.trim(); if(command.startsWith("halt ") || command.equals("halt")) return false; Vector TMPVars = new Vector(); if(trace){ System.out.println("analyse command: "+command); } Query pl_query = Parser.parse(command,TMPVars); if(pl_query==null){ if(trace) System.out.println("error in parsing command: "+command); return false; } NamedVariable[] variables = new NamedVariable[TMPVars.size()]; for(int i=0;i")){ out.write("\n",0,12); out.flush(); running = true; }else{ if(trace) System.out.println("protocol-error , close connection (expect: , received :"+First); showPrompt(); running = false; } }catch(Exception e){ if(trace){ System.out.println("Exception occured "+e); e.printStackTrace(); } showPrompt(); running = false; } } /** disconnect this server from a client */ private void disconnect(){ // close Connection if possible try{ if(S!=null) S.close(); }catch(Exception e){ if(trace){ System.out.println("Exception in closing connection "+e); e.printStackTrace(); } } OptimizerServer.Clients--; if(trace){ System.out.println("\nbye client"); System.out.println("number of clients is :"+ OptimizerServer.Clients); } showPrompt(); } /** processes requests from clients until the client * finish the connection or an error occurs */ public void run(){ if(!running){ disconnect(); return; } boolean execFlag=false; // flags for control execute or optimize request try{ String input = in.readLine(); if(input==null){ if(trace) System.out.println("connection is broken"); disconnect(); return; } while(!input.equals("")){ if(!input.equals("") && !input.equals("") ){ // protocol_error if(trace) System.out.println("protocol error( expect: or , found:"+input); disconnect(); return; } execFlag = input.equals(""); // read the database name input = in.readLine(); if(input==null){ if(trace) System.out.println("connection is broken"); disconnect(); return; } if(!input.equals("")){ // protocol_error if(trace) System.out.println("protocol error( expect: , found:"+input); disconnect(); return; } String Database = in.readLine(); if(Database==null){ System.out.println("connection is broken"); disconnect(); return; }else { Database = Database.trim(); } input = in.readLine(); if(input==null){ if(trace) System.out.println("connection is broken"); disconnect(); return; }else{ input = input.trim(); } if(!input.equals("")){ // protocol error if(trace) System.out.println("protocol error( expect: , found:"+input); disconnect(); return; } input = in.readLine(); if(input==null){ if(trace) System.out.println("connection is broken"); disconnect(); return; }else{ input = input.trim(); } if(!input.equals("")){ // protocol error if(trace) System.out.println("protocol error( expect: , found:"+input); disconnect(); return; } StringBuffer res = new StringBuffer(); // build the query from the next lines input = in.readLine(); //System.out.println("receive"+input); if(input==null){ if(trace) System.out.println("connection is broken"); disconnect(); return; } while(!input.equals("")){ res.append(input + "\n"); input = in.readLine(); //System.out.println("receive"+input); if(input==null){ if(trace) System.out.println("connection is broken"); disconnect(); return; } } input = in.readLine(); if(input==null){ System.out.println("connection is broken"); disconnect(); return; } if(! (input.equals("") & !execFlag) & !(input.equals("") & execFlag)){ //protocol-error if(trace) System.out.println("protocol error( expect: or , found:"+input); disconnect(); return; } String Request = res.toString().trim(); Vector V = new Vector(); synchronized(SyncObj){ useDatabase(Database); if(!execFlag){ String opt = OptimizerServer.this.optimize(Request); if(!opt.equals(Request)) V.add(opt); }else{ execute(Request,V); } } showPrompt(); out.write("\n",0,9); String answer; for(int i=0;i\n",0,10); out.flush(); input = in.readLine().trim(); if (input==null){ System.out.println("connection broken"); showPrompt(); disconnect(); return; } } // while System.out.println("connection ended normally"); showPrompt(); }catch(IOException e){ System.out.println("error in socket-communication"); disconnect(); showPrompt(); return; } disconnect(); } private BufferedReader in; private BufferedWriter out; private boolean running; private Socket S; } /** creates the server process */ private boolean createServer(){ SS=null; try{ SS = new ServerSocket(PortNr); } catch(Exception e){ System.out.println("unable to create a ServerSocket"); e.printStackTrace(); return false; } return true; } /** waits for request from clients * for each new client a new socket communicationis created */ public void run(){ System.out.println("\nwaiting for requests"); showPrompt(); while(running){ try{ Socket S = SS.accept(); Clients++; if(trace){ System.out.println("\na new client is connected"); System.out.println("number of clients :"+Clients); showPrompt(); } (new Server(S)).start(); } catch(Exception e){ System.out.println("error in communication"); showPrompt(); } } } /** creates a new server object * process inputs from the user * available commands are * client : prints out the number of connected clients * quit : shuts down the server */ public static void main(String[] args){ if(args.length<1){ System.err.println("usage: java OptimizerServer -classpath .: OptimizerServer PortNumber"); System.exit(1); } // process options Runtime rt = Runtime.getRuntime(); int pos = 1; while(pos"); String command = ""; Vector ResVector = new Vector(); while(!command.equals("quit")){ command = in.readLine().trim(); if(command.equals("clients")){ System.out.println("Number of Clients: "+ Clients); }else if(command.equals("quit")){ if( Clients > 0){ System.out.print("clients exists ! shutdown anyway (y/n) >"); String answer = in.readLine().trim().toLowerCase(); if(!answer.startsWith("y")) command=""; } } else if(command.equals("trace-on")){ trace=true; System.out.println("tracing is activated"); } else if(command.equals("trace-off")){ trace=false; System.out.println("tracing is deactivated"); } else if(command.equals("help") | command.equals("?") ){ System.out.println("quit : quits the server "); System.out.println("clients : prints out the number of connected clients"); System.out.println("trace-on : prints out messages about command, optimized command, open database"); System.out.println("trace-off : disable messages"); } else if(command.startsWith("exec")){ String cmdline = command.substring(4,command.length()).trim(); execute(cmdline,ResVector); }else{ System.out.println("unknow command, try help show a list of valid commands"); } if(!command.equals("quit")) showPrompt(); } OS.running = false; }catch(Exception e){ OS.running = false; System.out.println("error in reading commands"); if(trace) e.printStackTrace(); } try{ JPL.halt(); } catch(Exception e){ System.err.println(" error in shutting down the prolog engine"); } } /** Prints out the licence information of this software **/ public static void printLicence(PrintStream out){ out.println(" Copyright (C) 2004, University in Hagen, "); out.println(" Department of Computer Science, "); out.println(" Database Systems for New Applications. \n"); out.println(" This is free software; see the source for copying conditions."); out.println(" There is NO warranty; not even for MERCHANTABILITY or FITNESS "); out.println(" FOR A PARTICULAR PURPOSE."); } private static PrologParser Parser = new PrologParser(); private boolean optimizer_loaded = false; private int PortNr = 1235; private static int Clients = 0; private ServerSocket SS; private boolean running; private static String openedDatabase =""; private static boolean trace = true; private static Object SyncObj = new Object(); }