/* Copyright (c) 2001-2009, The HSQL Development Group * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the HSQL Development Group nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.hsqldb.dbinfo; import java.lang.reflect.Method; import org.hsqldb.Database; import org.hsqldb.Session; import org.hsqldb.lib.HashSet; import org.hsqldb.lib.Iterator; import org.hsqldb.lib.WrapperIterator; /* $Id: DINameSpace.java 3001 2009-06-04 12:31:11Z fredt $ */ // boucherb@users - 2004xxxx - patch 1.7.2 // -- canonical database uri for catalog name reporting // -- enumXXX methods to iterateXXX // -- simple support for SEQUENCE schema reporting // -- report built-in procedures/procedure columns without dependency on user grants; // Revision 1.8 2006/07/12 11:24:05 boucherb // - merging back remaining material overritten by Fred's type-system upgrades // - built-in calc uses more efficient set signature // - rework to use grantee (versus user) orientation for certain system table content /** * Provides catalog and schema related definitions and functionality. <p> * * Additional features include accessibility tests, class loading, filtered * iteration and inverted alias mapping functionality regarding Java Classes * and Methods defined within the context of this database name space support * object. <p> * * @author Campbell Boucher-Burnett (boucherb@users dot sourceforge.net) * @version 1.8.0 * @since 1.7.2 */ final class DINameSpace { /** The Database for which the name space functionality is provided */ private Database database; /** The catalog name reported by this namespace */ private String catalogName; /** * Set { <code>Class</code> FQN <code>String</code> objects }. <p> * * The Set contains the names of the classes providing the public static * methods that are automatically made accessible to the PUBLIC user in * support of the expected SQL CLI scalar functions and other core * HSQLDB SQL functions and stored procedures. <p> */ private static HashSet builtin = new HashSet(); // procedure columns // make temporary ad-hoc spec a little more "official" // until better system in place static { builtin.add("org.hsqldb.Library"); builtin.add("java.lang.Math"); } /** * Constructs a new name space support object for the specified Database * object. * * <p> * * @param database The Database object for which to provide name space * support */ public DINameSpace(Database database) { this.database = database; this.catalogName = database.getCatalogName().name; } /** * Retrieves the declaring <code>Class</code> object for the specified * fully qualified method name, using (if possible) the classLoader * attribute of this object's database. <p> * * @param fqn the fully qualified name of the method for which to * retrieve the declaring <code>Class</code> object. * @return the declaring <code>Class</code> object for the * specified fully qualified method name */ Class classForMethodFQN(String fqn) { try { return classForName(fqn.substring(0, fqn.lastIndexOf('.'))); } catch (Exception e) { return null; } } /** * Retrieves the <code>Class</code> object specified by the * <code>name</code> argument, using, if possible, the * classLoader attribute of the database. <p> * * @param name the fully qualified name of the <code>Class</code> * object to retrieve. * @throws ClassNotFoundException if the specified class object * cannot be found in the context of this name space * @return the <code>Class</code> object specified by the * <code>name</code> argument */ Class classForName(String name) throws ClassNotFoundException { if (name == null) { return Class.forName(name); } return Class.forName(name); } /** * Retrieves an <code>Iterator</code> whose elements form the set of * distinct names of all visible catalogs, relative to this object's * database. <p> * * If catalog reporting is turned off, then the empty Iterator is * returned. <p> * * <b>Note:</b> in the present implementation, if catalog reporting is * turned on, then the iteration consists of a single element that is the * uri of this object's database; HSQLDB currently does not support the * concept a single engine hosting multiple catalogs. <p> * * @return An Iterator whose elements are <code>String</code> objects * naming all visible catalogs, relative to this object's database. */ Iterator iterateCatalogNames() { return catalogName == null ? new WrapperIterator() : new WrapperIterator(catalogName); } /** * Retrieves the fully qualified name of the given Method object. <p> * * @param m The Method object for which to retreive the fully * qualified name * @return the fully qualified name of the specified Method object. */ static String getMethodFQN(Method m) { return m == null ? null : m.getDeclaringClass().getName() + '.' + m.getName(); } /** * Retrieves the specific name of the given Method object. <p> * * @param m The Method object for which to retreive the specific name * @return the specific name of the specified Method object. */ static String getMethodSpecificName(Method m) { return m == null ? null : m.getDeclaringClass().getName() + '.' + getSignature(m); } static String getSignature(Method method) { StringBuffer sb; String signature; Class[] parmTypes; int len; int last; sb = new StringBuffer(); parmTypes = method.getParameterTypes(); len = parmTypes.length; last = len - 1; sb.append(method.getName()).append('('); for (int i = 0; i < len; i++) { sb.append(parmTypes[i].getName()); if (i < last) { sb.append(','); } } sb.append(')'); signature = sb.toString(); return signature; } /** * Adds to the given Set the fully qualified names of the Class objects * internally granted to PUBLIC in support of core operation. * * @param set HashSet to which to add the fully qualified names of the * Class objects internally granted to PUBLIC in support of core * operation. */ void addBuiltinToSet(HashSet set) { set.addAll(builtin); } /** * Retrieves whether the indicated Class object is systematically * granted to PUBLIC in support of core operation. <p> * * @return whether the indicated Class object is systematically * granted to PUBLIC in support of core operation * @param clazz The Class object for which to make the determination */ boolean isBuiltin(Class clazz) { return clazz == null ? false : builtin.contains(clazz.getName()); } /** * Retrieves whether the Class object indicated by the fully qualified * class name is systematically granted to PUBLIC in support of * core operation. <p> * * @return true if system makes grant, else false * @param name fully qualified name of a Class */ boolean isBuiltin(String name) { return (name == null) ? false : builtin.contains(name); } /** @todo - fredt - there are no class grants in 1.9 */ /** * @return a composite <code>Iterator</code> * @param session The context in which to produce the iterator * @param andAliases true if the alias lists for the "ROUTINE" type method * elements are to be generated. */ Iterator iterateAllAccessibleMethods(Session session, boolean andAliases) { Iterator out; HashSet classNameSet; Iterator classNames; Iterator methods; String className; out = new WrapperIterator(); // classNameSet = session.getGrantee().getGrantedClassNames(true); // addBuiltinToSet(classNameSet); // classNames = classNameSet.iterator(); /* while (classNames.hasNext()) { className = (String) classNames.next(); methods = iterateRoutineMethods(className, andAliases); out = new WrapperIterator(out, methods); } */ return out; } /** * Retrieves the set of distinct, visible sessions connected to this * object's database, as a list. <p> * * @param session The context in which to produce the list * @return the set of distinct, visible sessions connected * to this object's database, as a list. */ Session[] listVisibleSessions(Session session) { return database.sessionManager.getVisibleSessions(session); } }