Connection.java
Go to the documentation of this file.
00001 /*
00002  * (c) copyright 2008, Technische Universitaet Graz and Technische Universitaet Wien
00003  *
00004  * This file is part of jdiagengine.
00005  *
00006  * jdiagengine is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * jdiagengine is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * You should have received a copy of the GNU General Public License
00016  * along with jdiagengine. If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * Authors: Joerg Weber, Franz Wotawa
00019  * Contact: jweber@ist.tugraz.at (preferred), or fwotawa@ist.tugraz.at
00020  *
00021  */
00022 
00023 
00024 
00025 package ATPInterface;
00026 
00027 import java.net.*;
00028 import java.io.*;
00029 import java.util.*;
00030 
00031 import theoremprover.IllegalAssumption;
00032 
00047 public class Connection extends Thread {
00048 
00049     // These are the states of the connection.
00050     protected final static int STATE_WAIT_FIRST_POST = 0;  // init state: wait for first POST
00051     protected final static int STATE_DB_CHANGED = 1;  // after at least one POST is received
00052     protected final static int STATE_CLOSED = 2;  // a CLOSE request has been received
00053 
00054     // The period in which the connection checks if some data has arrived on the socket
00055     protected final static long SLEEP_MS = 20;
00056 
00057     // Response messages stating which error has occured.
00058     protected final static String MSG_ILLEGAL_HEADER = "Illegal request header";
00059     protected final static String MSG_ILLEGAL_RULE = "Syntax of logical sentence incorrect";
00060     protected final static String MSG_ILLEGAL_ASS = "Illegal assumption";
00061     protected final static String MSG_OK = "OK";
00062     protected final static String MSG_INTERNAL_SERVER_ERROR = "Internal server error";
00063 
00064     // The socket for the connection to the client.
00065     protected Socket socket;
00066 
00067     // Output stream for socket.
00068     protected DataOutputStream outputStream;
00069 
00070     // A container holding open sessions, see Server.openSessions.
00071     protected Map openSessions;
00072 
00073     // The session this connection is associated with.
00074     protected Session session;
00075 
00076     // The state of the connection, see the STATE_xy constants above.
00077     protected int state;
00078 
00079     // If true, then many data may be printed to the output.
00080     protected boolean verboseOutput;
00081     
00082 
00088     public Connection(Socket socket, Map openSessions, boolean verboseOutput) {
00089         
00090         assert(socket.isConnected());
00091 
00092         this.socket = socket;
00093         this.openSessions = openSessions;
00094         this.verboseOutput = verboseOutput;
00095         state = STATE_WAIT_FIRST_POST;        
00096     }
00097 
00098 
00110     public void run() {
00111         
00112         try {
00113             
00114             // create input and output streams; allocate collections for header/body
00115 
00116             InputStream inStream = socket.getInputStream();
00117             BufferedReader reader = new BufferedReader(new InputStreamReader(inStream));
00118             
00119             OutputStream outStream = socket.getOutputStream();
00120             outputStream = new DataOutputStream(new BufferedOutputStream(outStream));
00121             
00122             boolean expectHeader = true;  // true if next input belongs to header
00123             boolean expectBody = false;   // true if next input belongs to body
00124             boolean lastLineEmpty = false;   // true if the last entered line was empty
00125             
00126             ArrayList header = new ArrayList();
00127             ArrayList body = new ArrayList();
00128             
00129             // the loop which runs until a CLOSE is received
00130 
00131             while (state != STATE_CLOSED) {               
00132                 
00133                 String line = reader.readLine();
00134                 
00135                 // if nothing received: taka a nap :-)
00136                 
00137                 if (line == null) {
00138                     try {
00139                         Thread.sleep(SLEEP_MS);
00140                     } catch (InterruptedException excInterrupted) {}
00141                     continue;
00142                 }
00143                 
00144                 // data received on the socket
00145                 
00146                 if (line.length() > 0) {  // non-empty line received
00147                     if (expectHeader && !expectBody) {
00148                         header.add(line.trim());
00149                     } else if (!expectHeader && expectBody) {
00150                         body.add(line.trim());
00151                     } else {
00152                         assert(false);
00153                     }
00154                     
00155                     lastLineEmpty = false;
00156                     
00157                 } else {  // empty line entered
00158                                         
00159                     if (expectHeader) {  // start waiting for body
00160                         expectHeader = false;
00161                         expectBody = true;
00162                         
00163                     } else if (lastLineEmpty) {  
00164                         
00165                         // body received, process the request if 2 empty lines entered
00166 
00167                         Date startProcessTime = new Date();
00168                         boolean ok = processRequest(header, body);
00169                         Date endProcessTime = new Date();
00170 
00171                         if (ok) {
00172                             long passedTime = endProcessTime.getTime() - startProcessTime.getTime();
00173                             System.out.println("Request successfully processed! Time [ms]: " + 
00174                                 passedTime);
00175                         } else {
00176                             System.out.println("Error in request!");
00177                         }
00178                         
00179                         expectHeader = true;
00180                         expectBody = false;
00181                         
00182                         header.clear();
00183                         body.clear();
00184                     } 
00185                     
00186                     lastLineEmpty = true;
00187                 }  // empty line entered
00188                 
00189                 
00190             }  // while (state != STATE_CLOSED)
00191             
00192             // clean-up of socket
00193             socket.close();
00194             
00195         } catch (IOException e) {
00196             System.err.println("IOException in connection: " + e.getMessage());
00197             if (!socket.isClosed()) {
00198                 try {
00199                     socket.close();
00200                 } catch (IOException eIO) {}
00201             }
00202         } catch (Throwable eUnknown) {
00203             System.err.println("Unexpected error during request processing:");
00204             System.err.println(eUnknown.getMessage());
00205             eUnknown.printStackTrace();
00206             
00207             try {
00208                 if (!socket.isClosed()) {
00209                     sendResponse(ATPConstants.ERR_INTERNAL_SERVER_ERROR,
00210                                  MSG_INTERNAL_SERVER_ERROR, 
00211                                  new ArrayList(), new ArrayList());
00212                     socket.close();
00213                 }
00214             } catch (IOException e) {}
00215         }
00216     
00217         // remove session from openSessions, if there are no other conns relating to session
00218         if (session != null) {
00219             removeFromSession();
00220         }
00221     }        
00222 
00223     
00224     /*
00225      * Removes this connection from the session, if there are no other connections
00226      * associated with this session: close the connection forever.
00227      */
00228     protected void removeFromSession() {
00229         assert(session != null);
00230 
00231         synchronized(session) {
00232             Vector sessionConns = session.getConnections();
00233             boolean exists = sessionConns.remove(this);
00234             assert(exists);
00235             
00236             System.out.println("Connection removed from session: " + session.getName());
00237             System.out.println("Remaining number of connections for this session: "
00238                                + String.valueOf(sessionConns.size()));
00239             
00240             if (sessionConns.size() == 0) {
00241                 openSessions.remove(session.getName());
00242                 session.close();
00243             }
00244             session = null;
00245         }
00246     }
00247 
00248 
00259     protected boolean processRequest(ArrayList header, ArrayList body) throws IOException {
00260         
00261         System.out.println("processRequest");
00262 
00263         if (header.size() == 0) {
00264             sendResponse(ATPConstants.ERR_BAD_REQUEST, MSG_ILLEGAL_HEADER, new ArrayList(),
00265                          new ArrayList());
00266             return false;
00267         }
00268         else {
00269             String[] firstLine = ((String)header.get(0)).split(" ");
00270             
00271             if (firstLine.length == 0) {
00272                 sendResponse(ATPConstants.ERR_BAD_REQUEST, MSG_ILLEGAL_HEADER, new ArrayList(),
00273                          new ArrayList());
00274                 return false;
00275             }
00276             else {
00277                 if (firstLine[0].equals(ATPConstants.CMD_POST)) 
00278                     return processPOST(header, body);
00279                 else if (firstLine[0].equals(ATPConstants.CMD_GET)) 
00280                     return processGET(header, body);
00281                 else if (firstLine[0].equals(ATPConstants.CMD_CLOSE)) 
00282                     return processCLOSE(header, body);
00283                 else {
00284                     sendResponse(ATPConstants.ERR_BAD_REQUEST, MSG_ILLEGAL_HEADER, 
00285                                  new ArrayList(), new ArrayList());
00286                     return false;
00287                 }
00288             }            
00289         }
00290     }
00291 
00292     protected boolean processPOST(ArrayList header, ArrayList body) throws IOException {
00293         System.out.println("process POST");
00294 
00295         // check if header and its first line have the required length
00296 
00297         if (header.size() < 2) {
00298             sendBadRequestResponse();
00299             return false;
00300         }
00301         
00302         String[] firstLine = ((String)header.get(0)).split(" ");
00303         if (firstLine.length < 4) {
00304             sendBadRequestResponse();
00305             return false;
00306         }
00307 
00308         // create new session or use existing one
00309         String sessionName = firstLine[1];        
00310         if (!associateWithSession(sessionName)) {
00311             sendBadRequestResponse();
00312                 return false;
00313         }
00314         
00315         String subcmd = firstLine[2];  
00316         if (subcmd.equalsIgnoreCase(ATPConstants.SUBCMD_ADD_FDG_EDGES)) {
00317             
00318             if (firstLine.length != 4) {
00319                 sendBadRequestResponse();
00320                 return false;
00321             }
00322 
00323             if (!firstLine[3].equals(ATPConstants.STR_ATP)) {
00324                  sendBadRequestResponse();
00325                 return false;
00326             }
00327             return processPOST_FDG(header, body, false, firstLine);
00328 
00329         } else if (subcmd.equalsIgnoreCase(ATPConstants.SUBCMD_REPLACE_FDG_EDGES)) {
00330 
00331             if (firstLine.length != 4) {
00332                 sendBadRequestResponse();
00333                 return false;
00334             }
00335 
00336             if (!firstLine[3].equals(ATPConstants.STR_ATP)) {
00337                  sendBadRequestResponse();
00338                 return false;
00339             }
00340             return processPOST_FDG(header, body, true, firstLine);
00341 
00342         } else {
00343             
00344             if (firstLine.length != 5) {
00345                 sendBadRequestResponse();
00346                 return false;
00347             }
00348 
00349             if (!firstLine[4].equals(ATPConstants.STR_ATP)) {
00350                 sendBadRequestResponse();
00351                 return false;
00352             }
00353 
00354             boolean replace;
00355             if (subcmd.equalsIgnoreCase(ATPConstants.SUBCMD_ADD_SENTENCES)) replace = false;
00356             else if (subcmd.equalsIgnoreCase(ATPConstants.SUBCMD_REPLACE_SENTENCES)) replace = true;
00357             else {
00358                 sendBadRequestResponse();
00359                 return false;
00360             }
00361 
00362             return processPOST_SENTENCES(header, body, replace, firstLine);
00363         } 
00364             
00365     }  //processPOST()
00366     
00367     protected boolean processPOST_FDG(ArrayList header, ArrayList body,
00368                                       boolean replace,
00369                                       String[] firstLine) throws IOException {
00370 
00371         // read the remaining part of the header
00372         
00373         int numEdges = -1;
00374         for (int i = 1; i < header.size(); ++i) {
00375             String[] line = ((String)header.get(i)).split(" ");
00376             
00377             if (line.length != 2) return false;
00378             
00379             if (line[0].equalsIgnoreCase(ATPConstants.PARAM_CONTENT_TYPE)) {
00380                 // do nothing: so far, only the MIME-type "text/plain" is supported
00381                 
00382             } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_NUM_EDGES)) {
00383                 try {
00384                     numEdges = new Integer(line[1]).intValue();
00385                 } catch (NumberFormatException enf) {
00386                     sendBadRequestResponse();
00387                     return false;
00388                 }
00389             }
00390         }
00391 
00392         // check if all obligatory parameters are defined, and if body has right length
00393         
00394         if ((numEdges < 0) || (body.size() != numEdges)) {
00395             sendBadRequestResponse();
00396             return false;
00397         }
00398 
00399         // finally: add edges to FDG
00400   
00401         int totalNumEdges;
00402         try {
00403             synchronized(session) {
00404                 totalNumEdges = session.getDB().addFDGEdges(body, replace);
00405             }
00406         } catch (LogicParseException lpe) {
00407             sendParseErrorResponse(lpe.getLineNo());
00408             return false;
00409         }
00410         state = STATE_DB_CHANGED;
00411         
00412         // send OK response
00413         
00414         ArrayList respHeader = new ArrayList();
00415         String s = ATPConstants.PARAM_NUM_EDGES + " " + totalNumEdges;
00416         respHeader.add(s);
00417         sendResponse(ATPConstants.OK, MSG_OK, respHeader,
00418                      new ArrayList());
00419         return true;
00420     }
00421     
00422 
00423     // Process a POST request with logical sentences, update data base, create and send the response to the client.
00424     protected boolean processPOST_SENTENCES(ArrayList header, ArrayList body, boolean replace,
00425                                             String[] firstLine) throws IOException {
00426         
00427         String subDBName;
00428         int numRules = -1;
00429             
00430         // read parts of first line of header
00431         
00432         subDBName = firstLine[3];
00433         if (!validSubDBName(subDBName)) {
00434             sendBadRequestResponse();
00435             return false;
00436         }                                   
00437 
00438         // read the remaining part of the header
00439         
00440         for (int i = 1; i < header.size(); ++i) {
00441             String[] line = ((String)header.get(i)).split(" ");
00442             
00443             if (line.length != 2) return false;
00444             
00445             if (line[0].equalsIgnoreCase(ATPConstants.PARAM_CONTENT_TYPE)) {
00446                 // do nothing: so far, only the MIME-type "text/plain" is supported
00447                 
00448             } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_NUM_RULES)) {
00449                 try {
00450                     numRules = new Integer(line[1]).intValue();
00451                 } catch (NumberFormatException enf) {
00452                     sendBadRequestResponse();
00453                     return false;
00454                 }
00455             }
00456         }
00457         
00458         // check if all obligatory parameters are defined, and if body has right length
00459         
00460         if ((numRules < 0) || (body.size() != numRules)) {
00461             sendBadRequestResponse();
00462             return false;
00463         }
00464         
00465         // finally: update database!
00466         
00467         int numSubDBRules;
00468         try {
00469             synchronized(session) {
00470                 numSubDBRules = session.getDB().addRules(subDBName, replace, body);
00471             }
00472         } catch (LogicParseException lpe) {
00473             sendParseErrorResponse(lpe.getLineNo());
00474             return false;
00475         }
00476         state = STATE_DB_CHANGED;
00477         
00478         // send OK response
00479         
00480         ArrayList respHeader = new ArrayList();
00481         String s = ATPConstants.PARAM_SUBDB + " " + subDBName;
00482         respHeader.add(s);
00483         s = ATPConstants.PARAM_NUM_SUBDB_RULES + " " + numSubDBRules;
00484         respHeader.add(s);
00485         sendResponse(ATPConstants.OK, MSG_OK, respHeader,
00486                      new ArrayList());
00487         return true;
00488     
00489     }  // processPOST_SENTENCES()
00490 
00491     /*
00492      * When this method is called the first time, then it associates this connection with
00493      * a session (i.e. the "session" variable is set). If a session of this name does not
00494      * exist yet: create the session. 
00495      * In subsequent calls of this method, it is only checked if sessionName is equal to
00496      * the name of the associated session. If not: return "false" to denote an error.
00497      */ 
00498     protected boolean associateWithSession(String sessionName) {
00499         if (session == null) {   // so this is the first POST on this connection
00500             if (openSessions.containsKey(sessionName)) {
00501                 session = (Session)openSessions.get(sessionName);
00502                 System.out.println("Connection refers to existing session: "
00503                                    + sessionName);
00504             } else {
00505                 session = new Session(sessionName);
00506                 System.out.println("Create new session: " + sessionName);
00507                 openSessions.put(sessionName, session);
00508             }
00509 
00510             synchronized(session) {
00511                 session.getConnections().add(this);
00512             }
00513             return true;
00514         } else {  // this is not the first POST: check if right session name was sent
00515             return (sessionName.equals(session.getName()));
00516         }
00517     }
00518     
00519 
00520     // Process a GET request, query the data base, create and send the response to the client.
00521     protected boolean processGET(ArrayList header, ArrayList body) 
00522         throws IOException {
00523 
00524         System.out.println("process GET");
00525 
00526         // check if header and its first line have the required length
00527         
00528         if (header.size() < 1) {
00529             sendBadRequestResponse("Header line is missing");
00530             return false;
00531         }        
00532         String[] firstLine = ((String)header.get(0)).split(" ");
00533         if (firstLine.length != 3) {
00534             sendBadRequestResponse("First header line: wrong size");
00535             return false;
00536         }
00537 
00538         // check if a POST was sent before and if the right session name was passed
00539 
00540         String sessionName = firstLine[1];
00541         if ((session == null) || (!sessionName.equals(session.getName()))) {
00542             sendBadRequestResponse();
00543             return false;
00544         }
00545         
00546         // call appropriate method to process the request
00547         String actionStr = firstLine[2];
00548         if (actionStr.equals(ATPConstants.SUBCMD_CONSISTENCY)) {
00549             return processGET_CONSISTENCY(header); 
00550         } else if (actionStr.equals(ATPConstants.SUBCMD_CONSISTENCIES)) {
00551             return processGET_CONSISTENCIES(header, body); 
00552         } else if (actionStr.equals(ATPConstants.SUBCMD_MINDIAG)) {
00553             return processGET_MINDIAG(header);
00554         } else if (actionStr.equals(ATPConstants.SUBCMD_DBSTATS)) {
00555             return processGET_DBSTATS(header);
00556         } else if (actionStr.equals(ATPConstants.SUBCMD_DBCONTENT)) {
00557             return processGET_DBCONTENT(header);
00558         } else if (actionStr.equals(ATPConstants.SUBCMD_FDGSTATS)) {
00559             return processGET_FDGSTATS(header);
00560         } else if (actionStr.equals(ATPConstants.SUBCMD_DIAGENV)) {
00561             return processGET_DIAGENV(header);
00562         } else {
00563             System.out.println("000");
00564             sendBadRequestResponse();
00565             return false;
00566         }
00567 
00568     }  // processGET()
00569 
00570 
00571     // util method: returns true iff the subDBName is one of "SD", "OBS", "SDD".
00572     protected boolean validSubDBName(String subDBName) {
00573         return (subDBName.equals(ATPConstants.SUBDB_SD) || subDBName.equals(ATPConstants.SUBDB_OBS) 
00574                 || subDBName.equals(ATPConstants.SUBDB_SDD));
00575     }
00576 
00577     protected boolean processGET_FDGSTATS(ArrayList header) throws IOException {
00578         ArrayList respHeader = new ArrayList();
00579         ArrayList respBody = new ArrayList();
00580         FDGStat stat;
00581 
00582         // create stats
00583 
00584         synchronized(session) {
00585             LogicalDBInterface db = session.getDB();
00586             stat = db.createFDGStats();
00587         }
00588         
00589         // generate response header
00590 
00591         String headerLine = ATPConstants.PARAM_NUM_NODES + " " + stat.numNodes;
00592         respHeader.add(headerLine);
00593         headerLine = ATPConstants.PARAM_NUM_EDGES + " " + stat.numEdges;
00594         respHeader.add(headerLine);
00595 
00596         // send response
00597 
00598         sendResponse(ATPConstants.OK, MSG_OK, respHeader, respBody);        
00599         return true;
00600     }
00601 
00602     // Process a GET DBSTATS request.
00603     protected boolean processGET_DBSTATS(ArrayList header) throws IOException {
00604         
00605         // read the name of the subDB whose statistical data shall be returned
00606 
00607         String subDBName = null;
00608 
00609         if (header.size() >= 2) {
00610             String[] line = ((String)header.get(1)).split(" ");
00611             if ((line.length != 2) 
00612                 || (!line[0].equalsIgnoreCase(ATPConstants.PARAM_SUBDB))) {
00613                 
00614                 sendBadRequestResponse();
00615                 return false;
00616             }
00617             subDBName = line[1];
00618             if (!validSubDBName(subDBName)) {
00619                 sendBadRequestResponse();
00620                 return false;
00621             }
00622         }
00623 
00624         // generate statistics
00625 
00626         ArrayList respHeader = new ArrayList();
00627         ArrayList respBody = new ArrayList();
00628 
00629         if (subDBName == null) {  // return stats related to whole DB
00630             int numSubDBs;
00631             int numRules;
00632             ArrayList subDBStats;
00633 
00634             synchronized(session) {
00635                 LogicalDBInterface db = session.getDB();
00636                 numRules = db.getTotalNumRules();
00637                 subDBStats = db.createSubDBStats();
00638             }
00639 
00640             String headerLine = ATPConstants.PARAM_NUM_SUBDBS + " " + ATPConstants.NUM_SUBDBS;
00641             respHeader.add(headerLine);
00642             headerLine = ATPConstants.PARAM_NUM_RULES + " " + String.valueOf(numRules);
00643             respHeader.add(headerLine);
00644         
00645             Iterator itSubDB = subDBStats.iterator();
00646             while(itSubDB.hasNext()) {
00647                 SubDBStat stat = (SubDBStat)itSubDB.next();
00648                 String bodyLine = stat.name + ": " + String.valueOf(stat.numRules);
00649                 respBody.add(bodyLine);
00650             }
00651 
00652         } else {  // requested stats is related to a certain sub-DB.
00653             
00654             int numRules;
00655 
00656             synchronized(session) {
00657                 LogicalDBInterface db = session.getDB();
00658                 numRules = db.getSubDBNumRules(subDBName);
00659             }
00660 
00661             String headerLine = ATPConstants.PARAM_NUM_SUBDBS + " 1";
00662             respHeader.add(headerLine);
00663             headerLine = ATPConstants.PARAM_NUM_RULES + " " + String.valueOf(numRules);
00664             respHeader.add(headerLine);
00665         }
00666 
00667         // send response
00668         sendResponse(ATPConstants.OK, MSG_OK, respHeader, respBody);        
00669         return true;
00670     }  // processGET_DBSTATS()
00671 
00672 
00673     // Process a GET DBCONTENT request.
00674     protected boolean processGET_DBCONTENT(ArrayList header) throws IOException {
00675         
00676         String subDBName = null;
00677 
00678         // read the name of the subDB 
00679 
00680         if (header.size() > 1) {
00681             String[] line = ((String)header.get(1)).split(" ");
00682             if ((line.length != 2) 
00683                 || (!line[0].equalsIgnoreCase(ATPConstants.PARAM_SUBDB))) {
00684                 
00685                 sendBadRequestResponse();
00686                 return false;
00687             }
00688             subDBName = line[1];
00689             if (!validSubDBName(subDBName)) {
00690                 sendBadRequestResponse();
00691                 return false;
00692             }
00693         }
00694 
00695         // determine rules (body) of response
00696 
00697         ArrayList respHeader = new ArrayList();
00698         ArrayList respBody = new ArrayList();
00699 
00700         int numRules;
00701         int numSubDBs;
00702 
00703         if (subDBName == null) {  // request includes the whole DB
00704            ArrayList subDBStats;
00705 
00706             synchronized(session) {
00707                 LogicalDBInterface db = session.getDB();
00708                 numSubDBs = ATPConstants.NUM_SUBDBS;
00709                 numRules = db.getTotalNumRules();
00710                 subDBStats = db.createSubDBStats();
00711 
00712                 Iterator itSubDBStats = subDBStats.iterator();
00713                 while(itSubDBStats.hasNext()) {
00714                     SubDBStat stat = (SubDBStat)itSubDBStats.next();
00715                     ArrayList subDBRules = db.getSubDBRules(stat.name);
00716                     respBody.addAll(createSubDBRuleStrings(stat.name, subDBRules));
00717                 }
00718             }
00719 
00720         } else {  // request relates to selected subDBs only
00721             numRules = 0;
00722             numSubDBs = 1;
00723 
00724             synchronized(session) {
00725                 LogicalDBInterface db = session.getDB();
00726                 ArrayList subDBRules = db.getSubDBRules(subDBName);
00727                 numRules += subDBRules.size();
00728                     respBody.addAll(createSubDBRuleStrings(subDBName, subDBRules));
00729             }
00730         }
00731 
00732         // create header of response
00733 
00734         String headerLine = ATPConstants.PARAM_NUM_SUBDBS + " " 
00735             + String.valueOf(numSubDBs);
00736         respHeader.add(headerLine);
00737         headerLine = ATPConstants.PARAM_NUM_RULES + " " + String.valueOf(numRules);
00738         respHeader.add(headerLine);
00739 
00740         // send response
00741 
00742         sendResponse(ATPConstants.OK, MSG_OK, respHeader, respBody);        
00743         return true;
00744 
00745     }  // processGET_CONTENT()
00746     
00747 
00748     /* 
00749      * Helper method, creates a sequence of strings of the format "x: rule", where x is an ID
00750      * of a sub database, and rule is a logical rule. 
00751      * The size of the returned collections is equal to the size of parameter "rules".
00752      */
00753     protected ArrayList createSubDBRuleStrings(String subDBName, ArrayList rules) {
00754         ArrayList result = new ArrayList(rules.size());
00755 
00756         Iterator it = rules.iterator();
00757         while(it.hasNext()) {
00758             String rule = (String)it.next();
00759             String s = subDBName + ": " + rule;
00760             result.add(s);
00761         }
00762 
00763         return result;
00764     }
00765 
00766     // Process a GET CONSISTENCIES request.
00767     protected boolean processGET_CONSISTENCIES(ArrayList header, ArrayList body) throws IOException {
00768         boolean useFaultModes = false;
00769         int numQueries = -1;
00770 
00771         // process remaining part of header
00772         
00773         for (int i = 1; i < header.size(); ++i) {
00774             String[] line = ((String)header.get(i)).split(" ");
00775             if (line.length < 2) {
00776                 sendBadRequestResponse();
00777                 return false;
00778             }
00779             
00780             if (line[0].equalsIgnoreCase(ATPConstants.PARAM_USE_FAULT_MODES)) {
00781                 Boolean b = new Boolean(line[1]);
00782                 useFaultModes = b.booleanValue();
00783             } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_NUM_QUERIES)) {
00784                 try {
00785                     numQueries = new Integer(line[1]).intValue();
00786                 } catch (NumberFormatException enf) {
00787                     sendBadRequestResponse();
00788                     return false;
00789                 }
00790             } else {
00791                 sendBadRequestResponse();
00792                 return false;
00793             }
00794         }
00795 
00796         // check if body has the right length
00797         if (body.size() != numQueries) {
00798             sendBadRequestResponse();
00799             return false;
00800         }
00801 
00802         // perform consistency checks
00803 
00804         BitSet result = new BitSet();
00805 
00806         assert(session != null);
00807         try {
00808             synchronized(session) {
00809                 LogicalDBInterface db = session.getDB();
00810                 db.performConsistencyChecks(body, useFaultModes, result);
00811                 assert(result.length() <= numQueries);
00812             }
00813         } catch (LogicParseException e) {
00814             sendResponse(ATPConstants.ERR_ILLEGAL_RULE, MSG_ILLEGAL_RULE, new ArrayList(),
00815                          new ArrayList());
00816             return false;
00817         }
00818 
00819         // construct response header (empty)
00820         ArrayList respHeader = new ArrayList();
00821         
00822         // construct response body
00823         
00824         ArrayList respBody = new ArrayList();
00825         for (int i = 0; i < numQueries; ++i) 
00826         {
00827             boolean value = result.get(i);
00828             String line;
00829             if (value) line = ATPConstants.STR_YES;
00830             else line = ATPConstants.STR_NO;
00831             respBody.add(line);
00832         }
00833 
00834         // send response
00835 
00836         sendResponse(ATPConstants.OK, MSG_OK, respHeader, respBody);
00837         return true;
00838     }
00839 
00840     // Process a GET CONSISTENCY request.
00841     protected boolean processGET_CONSISTENCY(ArrayList header) throws IOException {
00842         boolean consistent;
00843 
00844         boolean useFaultModes = false;
00845 
00846         // process remaining part of header
00847         
00848         for (int i = 1; i < header.size(); ++i) {
00849             String[] line = ((String)header.get(i)).split(" ");
00850             if (line.length < 2) {
00851                 sendBadRequestResponse();
00852                 return false;
00853             }
00854 
00855             try {
00856                 if (line[0].equalsIgnoreCase(ATPConstants.PARAM_USE_FAULT_MODES)) {
00857                     Boolean b = new Boolean(line[1]);
00858                     useFaultModes = b.booleanValue();
00859                 } else {
00860                     sendBadRequestResponse();
00861                     return false;
00862                 }
00863             } catch (NumberFormatException e) {
00864                 sendBadRequestResponse();
00865                 return false;
00866             }
00867         }
00868 
00869         // call to theorem prover
00870 
00871         System.out.println("use fault modes: " + useFaultModes);
00872 
00873         assert(session != null);
00874         try {
00875             synchronized(session) {
00876                 LogicalDBInterface db = session.getDB();
00877                 consistent = db.checkConsistency(useFaultModes);
00878             }
00879         } catch (LogicParseException e) {
00880             sendResponse(ATPConstants.ERR_ILLEGAL_RULE, MSG_ILLEGAL_RULE, new ArrayList(),
00881                          new ArrayList());
00882             return false;
00883         }
00884 
00885         // construct response header
00886 
00887         String headerLine = ATPConstants.PARAM_CONSISTENT + " ";
00888         if (consistent) headerLine = headerLine + ATPConstants.STR_YES;
00889         else headerLine = headerLine + ATPConstants.STR_NO;
00890 
00891         ArrayList respHeader = new ArrayList();
00892         respHeader.add(headerLine);
00893 
00894         // send response
00895 
00896         sendResponse(ATPConstants.OK, MSG_OK, respHeader, new ArrayList());
00897         return true;
00898 
00899     }  // processGET_CONSISTENCY()
00900 
00901     protected boolean processGET_DIAGENV(ArrayList header) throws IOException {
00902         int maxExplSize = Integer.MAX_VALUE - 10;  // subtract a value: avoid overflows if there is a bug somewhere ;)
00903         int maxNumExpl = Integer.MAX_VALUE - 10;
00904         int maxDFChain = Integer.MAX_VALUE - 10;
00905         boolean inclBetaDEs = true;
00906         boolean mergeDEs = true;
00907         boolean discardOrderPerms = false;
00908 
00909         // process remaining part of header
00910 
00911         for (int i = 1; i < header.size(); ++i) {
00912             String[] line = ((String)header.get(i)).split(" ");
00913             if (line.length < 2) {
00914                 sendBadRequestResponse();
00915                 return false;
00916             }
00917 
00918             try {
00919                 if (line[0].equalsIgnoreCase(ATPConstants.PARAM_MAX_DIAG_SIZE)) {
00920                     Integer n = new Integer(line[1]);
00921                     maxExplSize = n.intValue();
00922                 } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_MAX_NUM_DIAG)) {
00923                     Integer n = new Integer(line[1]);
00924                     maxNumExpl = n.intValue();
00925                 } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_MAX_DF_CHAIN)) {
00926                     Integer n = new Integer(line[1]);
00927                     maxDFChain = n.intValue();   
00928                 } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_INCL_BETA_DE)) {
00929                     Boolean b = new Boolean(line[1]);
00930                     inclBetaDEs = b.booleanValue(); 
00931                 } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_MERGE_DES)) {
00932                     Boolean b = new Boolean(line[1]);
00933                     mergeDEs = b.booleanValue();  
00934                 } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_DISCARD_ORDER_PERMS)) {
00935                     Boolean b = new Boolean(line[1]);
00936                     discardOrderPerms = b.booleanValue();   
00937                 } else {
00938                     sendBadRequestResponse();
00939                     return false;
00940                 }
00941             } catch (NumberFormatException e) {
00942                 sendBadRequestResponse();
00943                 return false;
00944             }
00945         }
00946 
00947         // call to engine
00948 
00949         ArrayList diagEnvs;
00950         ArrayList minDiags = new ArrayList();
00951 
00952         boolean consistent;
00953         
00954         try {
00955             synchronized(session) {
00956                 LogicalDBInterface db = session.getDB();
00957                 consistent = db.checkConsistency(true);
00958                 diagEnvs = db.computeDEs(maxExplSize, maxNumExpl, inclBetaDEs, maxDFChain, 
00959                                          mergeDEs, discardOrderPerms, minDiags);
00960             }
00961         } catch (LogicParseException e) {
00962             sendResponse(ATPConstants.ERR_ILLEGAL_RULE, MSG_ILLEGAL_RULE, new ArrayList(),
00963                          new ArrayList());
00964             return false;
00965         } catch (IllegalAssumption e) {
00966             sendResponse(ATPConstants.ERR_ILLEGAL_ASS, MSG_ILLEGAL_ASS, new ArrayList(),
00967                          new ArrayList());
00968             return false;
00969         }
00970 
00971         // construct response header
00972 
00973         String headerLine = ATPConstants.PARAM_CONSISTENT + " ";
00974         if (consistent) headerLine = headerLine + ATPConstants.STR_YES;
00975         else headerLine = headerLine + ATPConstants.STR_NO;
00976 
00977         ArrayList respHeader = new ArrayList();
00978         respHeader.add(headerLine);
00979 
00980         headerLine = ATPConstants.PARAM_NUM_DIAG + " " + minDiags.size();
00981         respHeader.add(headerLine);
00982 
00983         headerLine = ATPConstants.PARAM_NUM_DIAGENV + " " + diagEnvs.size();
00984         respHeader.add(headerLine);
00985 
00986         // construct response body
00987         
00988         ArrayList respBody = new ArrayList();
00989         
00990         Iterator itDiags = minDiags.iterator();
00991         while (itDiags.hasNext()) {
00992             String diagStr = ATPConstants.LINE_PREFIX_DIAG + " " + (String)itDiags.next();
00993             respBody.add(diagStr);
00994         }
00995 
00996         Iterator itDE = diagEnvs.iterator();
00997         while(itDE.hasNext()) {
00998             String deStr = ATPConstants.LINE_PREFIX_DE + " " + (String)itDE.next();
00999             respBody.add(deStr);
01000         }
01001 
01002         // send response
01003 
01004         sendResponse(ATPConstants.OK, MSG_OK, respHeader, respBody);
01005         return true;
01006     }
01007 
01008     // Process a GET EXPLANATIONS request.
01009     protected boolean processGET_MINDIAG(ArrayList header) throws IOException {
01010         
01011         boolean consistent;
01012         ArrayList explanations;
01013         
01014         int maxExplSize = Integer.MAX_VALUE - 10;
01015         int maxNumExpl = Integer.MAX_VALUE - 10;
01016         boolean useFaultModes = false;
01017 
01018         // process remaining part of header
01019 
01020         for (int i = 1; i < header.size(); ++i) {
01021             String[] line = ((String)header.get(i)).split(" ");
01022             if (line.length < 2) {
01023                 sendBadRequestResponse();
01024                 return false;
01025             }
01026 
01027             try {
01028                 if (line[0].equalsIgnoreCase(ATPConstants.PARAM_MAX_DIAG_SIZE)) {
01029                     Integer n = new Integer(line[1]);
01030                     maxExplSize = n.intValue();
01031                 } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_MAX_NUM_DIAG)) {
01032                     Integer n = new Integer(line[1]);
01033                     maxNumExpl = n.intValue();
01034                 } else if (line[0].equalsIgnoreCase(ATPConstants.PARAM_USE_FAULT_MODES)) {
01035                     Boolean b = new Boolean(line[1]);
01036                     useFaultModes = b.booleanValue();
01037                     System.out.println("use fault modes: " + b);
01038                 } else {
01039                     sendBadRequestResponse();
01040                     return false;
01041                 }
01042             } catch (NumberFormatException e) {
01043                 sendBadRequestResponse();
01044                 return false;
01045             }
01046         }
01047 
01048         // call to theorem prover
01049 
01050         assert(session != null);
01051         try {
01052             synchronized(session) {
01053                 LogicalDBInterface db = session.getDB();
01054                 consistent = db.checkConsistency(useFaultModes);
01055                 explanations = db.computeMinDiag(maxExplSize, maxNumExpl, useFaultModes, verboseOutput);
01056             }
01057         } catch (LogicParseException e) {
01058             sendResponse(ATPConstants.ERR_ILLEGAL_RULE, MSG_ILLEGAL_RULE, new ArrayList(),
01059                          new ArrayList());
01060             return false;
01061         } catch (IllegalAssumption e) {
01062             sendResponse(ATPConstants.ERR_ILLEGAL_ASS, MSG_ILLEGAL_ASS, new ArrayList(),
01063                          new ArrayList());
01064             return false;
01065         }
01066 
01067         // construct response header
01068 
01069         String headerLine = ATPConstants.PARAM_CONSISTENT + " ";
01070         if (consistent) headerLine = headerLine + ATPConstants.STR_YES;
01071         else headerLine = headerLine + ATPConstants.STR_NO;
01072 
01073         ArrayList respHeader = new ArrayList();
01074         respHeader.add(headerLine);
01075 
01076         headerLine = ATPConstants.PARAM_NUM_DIAG + " " 
01077             + String.valueOf(explanations.size());
01078         respHeader.add(headerLine);
01079 
01080         // construct response body
01081         
01082         ArrayList respBody = new ArrayList();
01083         Iterator it = explanations.iterator();
01084         while(it.hasNext()) {
01085             ArrayList explanation = (ArrayList)it.next();
01086             StringBuffer explStr = new StringBuffer("");
01087             
01088             Iterator itExpl = explanation.iterator();
01089             while(itExpl.hasNext()) {
01090                 explStr.append((String)itExpl.next());
01091                 if (itExpl.hasNext()) explStr.append(" ");
01092             }
01093 
01094             respBody.add(explStr.toString());
01095         }
01096 
01097         // send response
01098 
01099         sendResponse(ATPConstants.OK, MSG_OK, respHeader, respBody);
01100         return true;
01101 
01102     }  // processGET_MINDIAG((
01103 
01104 
01105     // Process a CLOSE request.
01106     protected boolean processCLOSE(ArrayList header, ArrayList body) {
01107         System.out.println("process CLOSE");
01108 
01109         state = STATE_CLOSED;
01110         return true;
01111     }
01112 
01113     
01114     // Helper method: write a \r\n sequence to stream.
01115     protected void writeLineBreak(OutputStream stream) throws IOException {
01116         stream.write('\r');
01117         stream.write('\n');
01118     }
01119 
01120     protected void sendBadRequestResponse() {
01121         try {
01122             sendResponse(ATPConstants.ERR_BAD_REQUEST, MSG_ILLEGAL_HEADER,
01123                          new ArrayList(), new ArrayList());
01124         } catch (IOException e) {} 
01125     }
01126     
01127     // Send a BAD REQUEST response to the client (client error, request is illegal)
01128     protected void sendBadRequestResponse(String detailedMsg) {
01129         try {
01130             sendResponse(ATPConstants.ERR_BAD_REQUEST, MSG_ILLEGAL_HEADER
01131                          + ": " + detailedMsg, new ArrayList(),
01132                          new ArrayList());
01133         } catch (IOException e) {}            
01134     }
01135 
01136 
01137     // Send an response to the client stating that the syntax of a logical rule is incorrect.
01138     protected void sendParseErrorResponse(int lineNo) {
01139         ArrayList header = new ArrayList();
01140         header.add(ATPConstants.PARAM_LINE_NUMBER + " " + String.valueOf(lineNo));
01141         try {
01142             sendResponse(ATPConstants.ERR_ILLEGAL_RULE, MSG_ILLEGAL_RULE, header,
01143                          new ArrayList()); 
01144         } catch (IOException e) {}
01145     }
01146 
01147 
01148     // Util method, send a response to the client with an error code and a message.
01149     protected void sendResponse(int errorCode, String msg, ArrayList header,
01150                                 ArrayList body) throws IOException {
01151 
01152         String response = ATPConstants.STR_ATP + " " 
01153             + String.valueOf(errorCode) + " " + msg;
01154         outputStream.writeBytes(response);
01155         writeLineBreak(outputStream);
01156 
01157         for (int i = 0; i < header.size(); ++i) { 
01158             outputStream.writeBytes((String)header.get(i));
01159             writeLineBreak(outputStream);
01160         }
01161         writeLineBreak(outputStream);
01162 
01163         for (int i = 0; i < body.size(); ++i) {
01164             outputStream.writeBytes((String)body.get(i));
01165             writeLineBreak(outputStream);
01166         }
01167         writeLineBreak(outputStream);
01168         if (body.size() > 0) writeLineBreak(outputStream);
01169 
01170         outputStream.flush();
01171     }
01172 
01173 }


tug_ist_diagnosis_engine
Author(s): Safdar Zaman, Gerald Steinbauer
autogenerated on Mon Jan 6 2014 11:51:16