vgritsenko 2004/02/11 06:03:10
Modified: . status.xml config system.xml java/src/org/apache/xindice/server UglyBrowser.java XindiceServlet.java Log: Support multiple databases in XindiceServlet and UglyBrowser Revision Changes Path 1.30 +8 -1 xml-xindice/status.xml Index: status.xml =================================================================== RCS file: /home/cvs/xml-xindice/status.xml,v retrieving revision 1.29 retrieving revision 1.30 diff -u -r1.29 -r1.30 --- status.xml 7 Feb 2004 19:34:20 -0000 1.29 +++ status.xml 11 Feb 2004 14:03:09 -0000 1.30 @@ -59,7 +59,14 @@ </todo> <changes> - <release version="1.1b4-dev" date="February 6 2004"> + <release version="1.1b4-dev" date="February 11 2004"> + <action dev="VG" type="update"> + Xindice server and XML-RPC driver support multiple database instances. + </action> + <action dev="VG" type="fix"> + Xindice now uses <link href="http://www.apache.org/licenses/LICENSE-2.0.html"> + Apache License, Version 2.0</link> + </action> <action dev="VG" type="fix"> In results of the queries like "//*", declare http://xml.apache.org/xindice/Query namespace just once. 1.17 +23 -16 xml-xindice/config/system.xml Index: system.xml =================================================================== RCS file: /home/cvs/xml-xindice/config/system.xml,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- system.xml 8 Feb 2004 01:11:34 -0000 1.16 +++ system.xml 11 Feb 2004 14:03:09 -0000 1.17 @@ -23,6 +23,7 @@ - - Version: $Revision$ $Date$ - Author: Kimbro Staken ([EMAIL PROTECTED]) + - Author: Vadim Gritsenko ([EMAIL PROTECTED]) --> <xindice> @@ -39,37 +40,43 @@ - for this database instance. --> <root-collection dbroot="./db/" name="db" use-metadata="on"> - <!-- TODO: Describe symbols config - <symbols> - </symbols> - --> - - <!-- TODO: Describe filer config - <filer class="" pagesize="" maxkeysize=""> - </filer> - --> <!-- - Query Engine Configuration. --> <queryengine> - <resolver autoindex="false" class="org.apache.xindice.core.query.XPathQueryResolver"/> + <!-- + - XPath query engine. Has single configuration parameter. + - autoindex: + - If true, for every XPath query, XPath query engine will create + - all the indexes it can use to evaluate the query. + --> + <resolver class="org.apache.xindice.core.query.XPathQueryResolver" + autoindex="false"/> + + <!-- + - XUpdate engine. Has no configuration parameters. + --> <resolver class="org.apache.xindice.core.xupdate.XUpdateQueryResolver"/> </queryengine> </root-collection> <!-- - - Embedded driver suuports several DB instances. - --> + - Xindice supports multiple DB instances. Uncomment entry below to have + - second database instance, named 'db2'. + - <root-collection dbroot="./db2/" name="db2" use-metadata="off"> <queryengine> - <resolver autoindex="false" class="org.apache.xindice.core.query.XPathQueryResolver"/> + <resolver class="org.apache.xindice.core.query.XPathQueryResolver" + autoindex="false"/> <resolver class="org.apache.xindice.core.xupdate.XUpdateQueryResolver"/> </queryengine> </root-collection> + --> <!-- - - TODO: Describe XML-RPC config + - XML-RPC configuration for the Xindice server. Specifies name of the parser + - to be used by XML-RPC. --> <xml-rpc> <driver name="xerces"/> 1.13 +24 -13 xml-xindice/java/src/org/apache/xindice/server/UglyBrowser.java Index: UglyBrowser.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/server/UglyBrowser.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- UglyBrowser.java 8 Feb 2004 02:54:25 -0000 1.12 +++ UglyBrowser.java 11 Feb 2004 14:03:09 -0000 1.13 @@ -36,7 +36,7 @@ /** * Moved out of XindiceServlet for separation of display and server bootstrapping. * - * @author kross + * @author Kevin Ross * @version CVS $Revision$, $Date$ */ public class UglyBrowser { @@ -50,8 +50,10 @@ super(); } - // Get handling to provide simple HTTP access to the Xindice instance. - public static void doGet(HttpServletRequest request, HttpServletResponse response, Database db) throws ServletException { + /** + * Get handling to provide simple HTTP access to the Xindice instance. + */ + public static void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { try { String contextPath = request.getContextPath(); StringBuffer sb = new StringBuffer(); @@ -59,11 +61,16 @@ sb.append("<html><body><center>"); if (path == null) { sb.append("<h2>THIS IS AN UGLY DEBUG TOOL!</h2><p>"); - sb.append("To browse the database, follow the link "); - sb.append("<a href=\"" + contextPath + "/?/" + db.getName() + "\">" + db.getName() + "</a>"); + sb.append("To browse the database, follow the link: "); + String [] databases = Database.listDatabases(); + for (int i = 0; i < databases.length; i++) { + String db = databases[i]; + sb.append("<a href=\"" + contextPath + "/?/" + db + "\">" + db + "</a> "); + } } else { // we have something to chew on XPathPseudoParser parser = new XPathPseudoParser(path); + Database db = Database.getDatabase(parser.getDatabase()); /* building the page once we have all the information */ sb.append("<table border=\"1\" width=\"90%\">\n"); @@ -128,7 +135,7 @@ String dbLoc = parser.getDatabase(); String parserPath = parser.getPath(); StringBuffer baseHref = new StringBuffer(); - baseHref.append("<a href=\"" + contextPath + "/?" + dbLoc); + baseHref.append("<a href=\"" + contextPath + "/?/" + dbLoc); if(parserPath.startsWith("/") || dbLoc.endsWith("/")) { baseHref.append(parserPath); } else { @@ -179,7 +186,7 @@ return "Document '" + document + "' not found"; } - return "Document '" + document + "'<p>\n" + return "Document '" + document + "'<p>\n" + escapeHtml(TextWriter.toString(doc)); } @@ -228,7 +235,6 @@ } public static class XPathPseudoParser { - private String query; public XPathPseudoParser(String query) throws Exception { @@ -240,12 +246,17 @@ } public String getDatabase() { + String db; int max = query.indexOf("/", 1); if (max > 1) { - return query.substring(0, max); + db = query.substring(0, max); } else { - return query; + db = query; + } + if (db.startsWith("/")) { + db = db.substring(1); } + return db; } public String getPath() { 1.30 +72 -66 xml-xindice/java/src/org/apache/xindice/server/XindiceServlet.java Index: XindiceServlet.java =================================================================== RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/server/XindiceServlet.java,v retrieving revision 1.29 retrieving revision 1.30 diff -u -r1.29 -r1.30 --- XindiceServlet.java 8 Feb 2004 02:54:25 -0000 1.29 +++ XindiceServlet.java 11 Feb 2004 14:03:09 -0000 1.30 @@ -49,6 +49,7 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Kimbro Staken</a> * @author <a href="mailto:[EMAIL PROTECTED]">Vladimir R. Bossicard</a> * @author <a href="mailto:[EMAIL PROTECTED]">Gianugo Rabellino</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a> * @version CVS $Revision$, $Date$ */ public class XindiceServlet extends HttpServlet { @@ -56,29 +57,29 @@ private static final Log log = LogFactory.getLog(XindiceServlet.class); private static final String DEFAULT_XMLRPC_DRIVER = "xerces"; - protected Database database; protected XmlRpcServer xmlrpcServer; public void destroy() { - try { - // When the servlet engine goes down we need to close the database instance. - // By the time destroy() is called, no more client requests can come in, - // so no need to worry about multithreading. - if (this.database != null) { - this.database.close(); - log.info("Database successfully closed"); + // When the servlet engine goes down we need to close the database instance. + // By the time destroy() is called, no more client requests can come in, + // so no need to worry about multithreading. + String[] databases = Database.listDatabases(); + for (int i = 0; i < databases.length; i++) { + String name = databases[i]; + try { + Database.getDatabase(name).close(); + log.info("Database '" + name + "' successfully closed"); + } catch (Exception e) { + log.error("Error closing database '" + name + "'", e); } - } catch (Exception e) { - log.error("Error closing database", e); } - this.database = null; } /** - * Delegate requests with method = GET to the UglyBrowser. + * Delegate GET requests to the UglyBrowser. */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - UglyBrowser.doGet(request, response, this.database); + UglyBrowser.doGet(request, response); } /** @@ -105,61 +106,66 @@ // The configuration is wrapped in a <xindice> element so we need to get the "root-collection" configuration. // try { - Configuration rootCollectionConfiguration = configuration.getChild("root-collection"); - if (rootCollectionConfiguration == null) { + Configuration[] rootConfigurations = configuration.getChildren("root-collection"); + if (rootConfigurations.length == 0) { throw new ConfigurationException("The database configuration is missing the <root-collection> element"); } else { - - // - // We need to ensure that the database points to a place where it makes - // sense. If the path in the system.xml file is an absolute path, then - // honor it. If it's not, we first check for the system property "xindice.db.home" - // and if the lookup is successful we use it as the database root parent. If - // the property is not set, we use /WEB-INF relative to the servlet context, unless - // the war has not been unpacked. In this case, we throw an exception and - // ask the user to specify the location of database root - // - String dbRoot = rootCollectionConfiguration.getAttribute(Database.DBROOT, Database.DBROOT_DEFAULT); - - // - // If there is no absolute path, we have to perform some checks. - // - if (!new File(dbRoot).isAbsolute()) { - - // Stupid hack but spec compliant: - // If getRealPath() returns null the war archive has not been unpacked. - String realPath = servletConfig.getServletContext().getRealPath("/WEB-INF"); - - // Let's see if the property was specified. - String home = System.getProperty(Xindice.PROP_XINDICE_DB_HOME); - if (log.isDebugEnabled()) { - log.debug(Xindice.PROP_XINDICE_DB_HOME + " is set to " + home); + for (int i = 0; i < rootConfigurations.length; i++) { + Configuration rootConfiguration = rootConfigurations[i]; + String name = rootConfiguration.getAttribute(Database.NAME); + + // + // We need to ensure that the database points to a place where it makes + // sense. If the path in the system.xml file is an absolute path, then + // honor it. If it's not, we first check for the system property "xindice.db.home" + // and if the lookup is successful we use it as the database root parent. If + // the property is not set, we use /WEB-INF relative to the servlet context, unless + // the war has not been unpacked. In this case, we throw an exception and + // ask the user to specify the location of database root + // + String dbRoot = rootConfiguration.getAttribute(Database.DBROOT, Database.DBROOT_DEFAULT); + + // + // If there is no absolute path, we have to perform some checks. + // + if (!new File(dbRoot).isAbsolute()) { + + // Stupid hack but spec compliant: + // If getRealPath() returns null the war archive has not been unpacked. + String realPath = servletConfig.getServletContext().getRealPath("/WEB-INF"); + + // Let's see if the property was specified. + String home = System.getProperty(Xindice.PROP_XINDICE_DB_HOME); + if (log.isDebugEnabled()) { + log.debug(Xindice.PROP_XINDICE_DB_HOME + " is set to " + home); + } + + if (home != null) { + dbRoot = new File(home + File.separator + dbRoot).getCanonicalPath(); + } else if (realPath != null) { + dbRoot = new File(realPath + File.separator + dbRoot).getCanonicalPath(); + log.warn("The database '" + name + "' root directory has been set to " + dbRoot + + ". Keep in mind that if a war upgrade will take place the database will be lost."); + } else { + throw new ConfigurationException( + "The database '" + name + "' configuration points to a relative path, " + + "but there was no " + Xindice.PROP_XINDICE_DB_HOME + " property set. " + + "Furthermore, the war was not unpacked by the application server " + + "so Xindice was unable to find a database location " + + "Please check /WEB-INF/system.xml and set an absolute path " + + "as the \"dbroot\" attribute of \"root-collection\" " + + "or specify a suitable " + Xindice.PROP_XINDICE_DB_HOME + " system property."); + } + rootConfiguration.setAttribute(Database.DBROOT, dbRoot); } - if (home != null) { - dbRoot = new File(home + File.separator + dbRoot).getCanonicalPath(); - } else if (realPath != null) { - dbRoot = new File(realPath + File.separator + dbRoot).getCanonicalPath(); - log.warn("The database root directory has been set to " + dbRoot + - ". Keep in mind that if a war upgrade will take place the database will be lost."); - } else { - throw new ConfigurationException( - "The database configuration points to a relative path, " - + "but there was no " + Xindice.PROP_XINDICE_DB_HOME + " property set. " - + "Furthermore, the war was not unpacked by the application server " - + "so Xindice was unable to find a database location " - + "Please check /WEB-INF/system.xml and set an absolute path " - + "as the \"dbroot\" attribute of \"root-collection\" " - + "or specify a suitable " + Xindice.PROP_XINDICE_DB_HOME + " system property."); - } - rootCollectionConfiguration.setAttribute(Database.DBROOT, dbRoot); + // + // We need to use this method to be consistent between deployments (embed, standalone, etc) + // and let the Database object maintain the set of Databases. + // + Database.getDatabase(rootConfiguration); + log.info("Database '" + name + "' successfully opened"); } - - // - // We need to use this method to be consistent between deployments (embed, standalone, etc) - // and let the Database object maintain the set of Databases. - // - this.database = Database.getDatabase(rootCollectionConfiguration); } // Setup the XML-RPC impl to support UTF-8 input via Xerces. @@ -196,7 +202,7 @@ throw new ConfigurationException("Failed to add default handler to XmlRpc server.", e); } - log.info("Database successfully started"); + log.info("Xindice server successfully started"); } catch (Exception e) { log.fatal("Failed to initialize database, throwing ServletException", e); // Make sure to close database if it was opened already.