src/java/isac/util/KEStoreCommunication.java
author wneuper
Thu, 17 Jan 2008 16:27:03 +0100
changeset 3881 72f0be16d83b
parent 3660 31cd9d16dc76
child 3928 d38196e9b162
permissions -rw-r--r--
start-work-070517 merged into HEAD
     1 /*
     2  * Created on 28.09.2005
     3  * 
     4  */
     5 package isac.util;
     6 
     7 import isac.browserdialog.BrowserDialog;
     8 import isac.browserdialog.IBrowserDialog;
     9 import isac.interfaces.IToGUI;
    10 import isac.session.IObjectManager;
    11 import isac.session.ObjectManager;
    12 import isac.users.UserSettings;
    13 import isac.wsdialog.IWorksheetDialog;
    14 
    15 import java.io.IOException;
    16 import java.io.StringReader;
    17 import java.io.StringWriter;
    18 import java.net.MalformedURLException;
    19 import java.rmi.Naming;
    20 import java.rmi.NotBoundException;
    21 import java.rmi.RemoteException;
    22 import java.util.Vector;
    23 
    24 import javax.xml.parsers.DocumentBuilder;
    25 import javax.xml.parsers.DocumentBuilderFactory;
    26 import javax.xml.parsers.ParserConfigurationException;
    27 import javax.xml.transform.Source;
    28 import javax.xml.transform.Transformer;
    29 import javax.xml.transform.TransformerConfigurationException;
    30 import javax.xml.transform.TransformerException;
    31 import javax.xml.transform.TransformerFactory;
    32 import javax.xml.transform.dom.DOMResult;
    33 import javax.xml.transform.dom.DOMSource;
    34 import javax.xml.transform.stream.StreamResult;
    35 
    36 import org.apache.log4j.Logger;
    37 import org.apache.xmlrpc.XmlRpcClient;
    38 import org.apache.xmlrpc.XmlRpcException;
    39 import org.w3c.dom.Document;
    40 import org.w3c.dom.Node;
    41 import org.w3c.dom.NodeList;
    42 import org.xml.sax.InputSource;
    43 import org.xml.sax.SAXException;
    44 
    45 /**
    46  * @author Martin Lang
    47  *
    48  * Handles the communication with the KEStore
    49  *
    50  */
    51 public class KEStoreCommunication {
    52 
    53     private static final Logger logger = Logger.getLogger(KEStoreCommunication.class.getName());
    54 
    55     protected static String id_;
    56 
    57     protected UserSettings user_settings_;
    58     
    59     protected IToGUI browser_frame_rmi_;
    60     
    61     private static XmlRpcClient client_ = null;
    62     
    63     public static IBrowserDialog getBDialog(String session) {
    64     	String name = KEStorePaths.OBJECT_MANAGER_PATH;
    65     	if(logger.isInfoEnabled())
    66     	    logger.info("WA<>SM: getBDialog(session=" + session + ")");
    67         try {
    68             System.out.println("connect to ObjectManager" + name);
    69             Object lookup = Naming.lookup(name);
    70             return ((IObjectManager) lookup).getBrowserDialog(session);
    71         } catch (RemoteException exc) {
    72             System.err.println("no rmiregistry runing on server " + name
    73                     + " no connection possible --- try later");
    74             System.err.println("serverCom exception: " + exc.getMessage());
    75         } catch (NotBoundException exc) {
    76             System.err.println("servercom: notboundexc: " + exc.getMessage());
    77             System.err.println("server not found - try to connect to Proxy");
    78         } catch (java.net.MalformedURLException exc) {
    79             System.err.println("servercom: MalformedURLException: "
    80                     + exc.getMessage());
    81             exc.printStackTrace();
    82         }
    83         return null;
    84     }
    85     
    86     /**
    87      * Loads the hierarchy_ of the type <code>type</code> from the KE-Store.
    88      * Accessible via RMI
    89      * 
    90      * @param type
    91      *                     requestet information-type to load the hierarchy_ for. e.g.
    92      *                     pbl, met, or exp
    93      * @return the hierarchy_ in its XML-representation. The result might be
    94      *                  filtered according to the current session the XBrowserDialog was
    95      *                  instantiated for
    96      */
    97     public static String loadHierarchy(String type) throws RemoteException {
    98          String hierarchy = loadHierarchy(id_, type);
    99         Vector keresult = null;
   100         keresult.add(hierarchy);
   101         if (keresult.size() == 0)
   102             return null;
   103         if(logger.isInfoEnabled())
   104             logger.info("    <-BD: loadHierarch");
   105         return (String) keresult.elementAt(0);
   106     }
   107 
   108     /**
   109      * Loads the hierarchy_ of the type <code>type</code> from the KE-Store.
   110      * XML-RPC version
   111      * 
   112      * @param session
   113      *                     ID of the session to load the KEObject for.
   114      * @param type
   115      *                     requestet information-type to load the hierarchy_ for. e.g.
   116      *                     pbl, met, or exp
   117      * @return the hierarchy_ in its XML-representation. The result might be
   118      *                  filtered according to the current session the XBrowserDialog was
   119      *                  instantiated for
   120      */
   121     public static String loadHierarchy(String session, String type) {
   122         Vector param = new Vector();
   123         param.add(type);
   124         Vector hierarchy = callKEStore("KEStore.loadHierarchy", param);
   125         return (String) hierarchy.elementAt(0);
   126     }
   127 
   128     /**
   129      * Loads the requested KE-Object of the type <code>type</code> from the
   130      * KE-Store <code>type</code> and <code>content_id</code> together give
   131      * the unique id. One and the same <code>content_id</code> might be used
   132      * in different types (<code>type</code> can be pbl, or met for the basic
   133      * items of the knowledge-base as well as an identifyer used for different
   134      * courses). If objects with equal <code>content_id</code> s reside in
   135      * different types, their only difference should reside within the
   136      * description.
   137      * 
   138      * @param type
   139      *                     requestet information-type to load the content for. e.g. pbl,
   140      *                     met, or exp
   141      * @param content_id
   142      *                     identifies the KE-Object within the <code>type</code>
   143      * @return requested KE-Object in its XML-representation. The result might
   144      *                  be filtered according to the current session the XBrowserDialog
   145      *                  was instantiated for
   146      */
   147     public static String loadContent(String type, String filename)
   148             throws RemoteException {
   149         String keresult = loadContent(id_, type, filename);
   150         return keresult;
   151     }
   152 
   153     public static String loadContent(String type, Vector idvect) {
   154         Vector keresult = loadContent(id_, type, idvect);
   155         return (String) keresult.elementAt(0);
   156     }
   157 
   158     protected static Vector loadContent(String session, String type, Vector idvect) {
   159         Vector parameter = new Vector();
   160         parameter.add(type);
   161         parameter.add(idvect);
   162         Vector result = callKEStore("KEStore.loadContent", parameter);
   163         if (result.size() == 0) {
   164             result.add(getErrorXML("Sorry, proper Content could not be found"));
   165             return result;
   166         }
   167         if (result.get(0) == "ERROR") {
   168             result.removeAllElements();
   169             result.add(getErrorXML("ERROR Sorry, Syntax Error"));
   170             return result;
   171         }
   172         return filterContent(session, result);
   173     }
   174 
   175     public static String loadContent(String session, String type, String filename) {
   176 
   177         Vector parameter = new Vector();
   178         parameter.add(type);
   179         parameter.add(filename);
   180         Vector result = callKEStore("KEStore.loadContent", parameter);
   181 
   182         //collecting the data for the error_log
   183         if ((result.firstElement()).toString().equals("ERROR")) {
   184 
   185             String file_name = result.get(1).toString();
   186             String problem_name = result.get(2).toString();
   187             result.removeAllElements();
   188             String error_information = "ERROR" + "FILE: " + file_name
   189                     + " =>  PROBLEM: " + problem_name;
   190             result.add(error_information);
   191             return result.elementAt(0).toString();
   192 
   193         }
   194          String stringresult = (String) result.elementAt(0);
   195          
   196          stringresult = decodeUmlauts(stringresult);
   197          result.set(0,stringresult);
   198           Vector content = filterContent(session, result);
   199           return content.elementAt(0).toString();
   200     }
   201 
   202     /**
   203      * Loads the requested KE-Object of the type <code>type</code> from the
   204      * KE-Store. <code>type</code> and <code>content_id</code> together give
   205      * the unique id. One and the same <code>content_id</code> might be used
   206      * in different types (<code>type</code> can be pbl, or met for the basic
   207      * items of the knowledge-base as well as an identifyer used for different
   208      * courses). If objects with equal <code>content_id</code> s reside in
   209      * different types, their only difference should reside within the
   210      * description. XML-RPC version.
   211      * 
   212      * @param session
   213      *                     session to fetch the KE-Object for.
   214      * @param type
   215      *                     requestet information-type to load the content for. e.g. pbl,
   216      *                     met, or exp
   217      * @param content_id
   218      *                     identifies the KE-Object within the <code>type</code>
   219      * @return requested KE-Object in its XML-representation. The result might
   220      *                  be filtered according to the session given py parameter
   221      *                  <code>session</code>
   222      */
   223     private static Vector filterContent(String session, Vector result) {
   224         //if session == "", no filtering is needed (author mode)
   225         if (session.equals("")) //no filtering necessary
   226             return result;
   227         try {
   228             TransformerFactory tFactory = TransformerFactory.newInstance();
   229             Transformer transformer = tFactory.newTransformer();
   230 
   231             String content = (String) result.firstElement();
   232             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
   233             DocumentBuilder db = dbf.newDocumentBuilder();
   234             StringReader sr = new StringReader(content);
   235             Document document = db.parse(new InputSource(sr));
   236             DOMSource source = new DOMSource(document);
   237             DOMResult dom_result = new DOMResult();
   238 
   239             transformer.transform(source, dom_result);
   240             Source filtered_source = filter(dom_result.getNode());
   241             StringWriter output = new StringWriter();
   242             StreamResult filterresult = new StreamResult(output);
   243             transformer.transform(filtered_source, filterresult);
   244             String resultxml = output.toString();
   245             System.out.print(resultxml);
   246 
   247             result = new Vector();
   248             result.add(resultxml);
   249         } catch (TransformerConfigurationException e) {
   250             result.removeAllElements();
   251             result.add(getErrorXML("TransformerConfigurationEception: "
   252                     + e.getMessage()));
   253             e.printStackTrace();
   254         } catch (ParserConfigurationException e) {
   255             result.removeAllElements();
   256             result.add(getErrorXML("ParserConfigurationEception: "
   257                     + e.getMessage()));
   258             e.printStackTrace();
   259         } catch (SAXException e) {
   260             result.removeAllElements();
   261             result.add(getErrorXML("SAXException: " + e.getMessage()));
   262             e.printStackTrace();
   263         } catch (IOException e) {
   264             result.removeAllElements();
   265             result.add(getErrorXML("IOEception: " + e.getMessage()));
   266             e.printStackTrace();
   267         } catch (TransformerException e) {
   268             result.removeAllElements();
   269             result.add(getErrorXML("TransformerEception: " + e.getMessage()));
   270             e.printStackTrace();
   271         }
   272 
   273         return result;       
   274     }
   275 
   276     /*
   277      * @param string @return
   278      */
   279     private static String getErrorXML(String string) {
   280         return "<ERROR><DESCRIPTION> <h1> Error in file XBrowserDialog.java </h1>"
   281                 + string + "</DESCRIPTION></ERROR>";
   282     }
   283 
   284     /*
   285      * @param node
   286      */
   287     private static Source filter(Node node) {
   288         recFilter(node, "EVAL_PRECOND");
   289         recFilter(node, "CAS");
   290         recFilter(node, "RELATE");
   291         return new DOMSource(node);
   292     }
   293 
   294     private static void recFilter(Node node, String removename) {
   295         NodeList nlist = node.getChildNodes();
   296         System.out.println(nlist);
   297         for (int indx = 0; indx < nlist.getLength(); indx++) {
   298             Node childnode = nlist.item(indx);
   299             System.out.println("removename:" + removename);
   300             if (childnode == null) {
   301                 System.out.println("child is null !!!");
   302                 return;
   303             }
   304             System.out.println("localname:" + childnode.getLocalName());
   305             if (childnode.getLocalName() == null)
   306                 System.out.println("localname is null !");
   307             else if (childnode.getLocalName().equals(removename)) {
   308                 System.out.println("i should have been deleted");
   309                 node.removeChild(childnode);
   310             } else
   311                 recFilter(childnode, removename);
   312         }
   313     }
   314 
   315     /**
   316      * Encapsulates the communication with KEStore. On each call, a new
   317      * XMLRPC-connection to the KESTore is established
   318      * 
   319      * @param function:
   320      *                     the function from the KEStore to call
   321      * @param parameters:
   322      *                     parameters nedded by the called function
   323      */
   324     private static Vector callKEStore(String function, Vector parameters) {
   325         Vector errvector = new Vector();
   326         try {
   327             if (client_ == null)
   328                 //fixed path, port: new XmlRpcClient("http://localhost:1030");
   329                 client_ = new XmlRpcClient("http://localhost:1030");
   330             return (Vector) client_.execute(function, parameters);
   331         } catch (MalformedURLException exc) {
   332             errvector.add("XBrowserDialog:MalformedURLException");
   333             exc.printStackTrace();
   334         } catch (XmlRpcException exc) {
   335             errvector.add("XBrowserDialog:XmlRpcException");
   336             exc.printStackTrace();
   337         } catch (IOException exc) {
   338             errvector.add("XBrowserDialog:IOException");
   339             exc.printStackTrace();
   340         }
   341         return errvector;
   342     }
   343     
   344     /**
   345      * decodes the german 'Umlaute'
   346      * \u00D6 is the unicode character for the german Umlaut 'Oe'
   347      * \u00F6 is the unicode character for the german Umlaut 'oe'
   348      * \u00DC is the unicode character for the german Umlaut 'Ue'
   349      * \u00FC is the unicode character for the german Umlaut 'ue'
   350      * \u00C4 is the unicode character for the german Umlaut 'Ae'
   351      * \u00E4 is the unicode character for the german Umlaut 'ae'
   352      * \u00DF is the unicode character for the german 'sz'
   353      * 
   354      * @param the input string
   355      *                    
   356      * @return the output string
   357      */
   358     public static String decodeUmlauts(String input) {
   359     	input = input.replaceAll("&Ouml;", "\u00D6");
   360     	input = input.replaceAll("&ouml;", "\u00F6");
   361     	input = input.replaceAll("&Uuml;", "\u00DC");
   362     	input = input.replaceAll("&uuml;", "\u00FC");
   363     	input = input.replaceAll("&Auml;", "\u00C4");
   364     	input = input.replaceAll("&auml;", "\u00E4");
   365         input = input.replaceAll("&szlig;","\u00DF");
   366     	return input;
   367     }
   368 }