package org.okip.util.hierarchy.impl;/*   Copyright (c) 2002 Massachusetts Institute of Technology   This work, including any software, documents, or other related items   (the "Work"), is being provided by the copyright holder(s) subject to   the terms of the MIT OKI(TM) API Definition License. By obtaining,   using and/or copying this Work, you agree that you have read,   understand, and will comply with the following terms and conditions of   the MIT OKI(TM) API Definition License:   You may use, copy, and distribute unmodified versions of this Work for   any purpose, without fee or royalty, provided that you include the   following on ALL copies of the Work that you make or distribute:    *  The full text of the MIT OKI(TM) API Definition License in a       location viewable to users of the redistributed Work.    *  Any pre-existing intellectual property disclaimers, notices, or       terms and conditions. If none exist, a short notice similar to the       following should be used within the body of any redistributed       Work: "Copyright (c) 2002 Massachusetts Institute of Technology. All       Rights Reserved."   You may modify or create Derivatives of this Work only for your   internal purposes. You shall not distribute or transfer any such   Derivative of this Work to any location or any other third party. For   purposes of this license, "Derivative" shall mean any derivative of   the Work as defined in the United States Copyright Act of 1976, such   as a translation or modification.   THIS WORK PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE WORK   OR THE USE OR OTHER DEALINGS IN THE WORK.   The name and trademarks of copyright holder(s) and/or MIT may NOT be   used in advertising or publicity pertaining to the Work without   specific, written prior permission. Title to copyright in the Work and   any associated documentation will at all times remain with the   copyright holders.*/import org.okip.util.hierarchy.api.HierarchyException;/** * <p>Hierarchy is the main class in the Hierarchy API.  It is used for * creating nodes and, along with Node, maintaining their relationships. * It also contains methods for examining the Hierarchy itself, and accessing * sets of Nodes. */public class Hierarchy implements org.okip.util.hierarchy.api.Hierarchy{	public static final int KEY_LENGTH         = 128;	public static final int NAME_LENGTH        = 256;	public static final int DESCRIPTION_LENGTH = 1024;	private String mKey = null;	private String mName = null;	private String mDescription = null;	private org.okip.service.dbc.api.Connection mConnection = null;	Hierarchy( java.io.Serializable qKey,	           String qName,	           String qDescription,	           org.okip.service.dbc.api.Connection qConnection )	{		// validate key		if( ! isValidKey( qKey ) )		{			throw new IllegalArgumentException( "Invalid Key" );		}				// validate other args		if( qName == null ||			qDescription == null ||			qConnection == null )		{			throw new NullPointerException();		}		if( qName.length() > NAME_LENGTH )		{			throw new IllegalArgumentException();		}		if( qDescription.length() > DESCRIPTION_LENGTH )		{			throw new IllegalArgumentException();		}			mKey = ( String )qKey;		mName = qName;		mDescription = qDescription;		mConnection = qConnection;	}	/**	 * <p>Gets this Hierarchy's key.	 *	 * @return The Serializable key used to identify this Hierarchy.	 */	public java.io.Serializable getKey()	{		return mKey;	}	/**	 * <p>Gets this Hierarchy's name.	 *	 * @return The name of this Hierarchy.	 */	public String getName()	{		return mName;	}	/**	 * <p>Gets this Hierarchy's description.	 *	 * @return The description for this Hierarchy.	 */	public String getDescription()	{		return mDescription;	}	/**	 * <p>Creates a new Node with root status.  The Node is created with the	 * specified key, and, unlike Nodes created with createNode, initially has	 * no parents or children.	 *	 * @param qKey The key associated with the new root Node.  qKey cannot be	 *        null.	 * @return The new root Node.	 */	public org.okip.util.hierarchy.api.Node createRootNode( java.io.Serializable qKey, String qName )		throws HierarchyException	{		// validate args		if( ! isValidKey( qKey ) )		{			throw new IllegalArgumentException( "Invalid Key" );		}		String key = ( String )qKey;		if( qName == null )		{			throw new IllegalArgumentException( "Name cannot be null" );		}		String name = qName;		// make sure the key isn't already in the table		if( getNode( key ) != null )		{			throw new HierarchyException();		}		// create the node		Node n = new Node( this, key, mConnection );		n.create( name );		return n;	}	/**	 * <p>Creates a new Node.  The Node is created with the specified key and	 * initially has only the one specified parent.	 *	 * @param qKey The key associated with the new Node.  qKey cannot be null.	 * @param qParent The initial parent of the new Node.  qParent cannot be	 *        null.	 * @return The new Node.	 */	public org.okip.util.hierarchy.api.Node createNode( java.io.Serializable qKey, java.io.Serializable qParentKey, String qName )		throws HierarchyException	{		org.okip.util.hierarchy.api.Node n = createRootNode( qKey, qName );		n.addParent( qParentKey );		return n;	}	/**	 * <p>Get the Nodes in this Hierarchy.	 * <p>Note that this function may exclude Nodes for which the client does	 * not have authorization to access.  In this case it will simply return a	 * subset of the Nodes in this Hierarchy.	 *	 * @return The Nodes in this Hierarchy, or a zero-length array if there are	 *         none.	 */	public org.okip.util.hierarchy.api.Node[] getNodes()		throws HierarchyException	{		java.util.ArrayList nodes = new java.util.ArrayList();		try		{			org.okip.service.dbc.api.PreparedStatement ps = mConnection.prepareStatement( "select * from nodes where hierarchy = '" + mKey + "'" );			org.okip.service.dbc.api.ResultSet rs = ps.executeQuery();			while( rs.next() )			{				String key = rs.getString( 1 );  // "key"				Node n = new Node( this, key, mConnection );				if( n.validate() )				{					nodes.add( n );				}			}		}		catch( org.okip.service.dbc.api.DbcException ex )		{			ex.printStackTrace();			throw new HierarchyException();		}		return ( org.okip.util.hierarchy.api.Node[] )nodes.toArray( new org.okip.util.hierarchy.api.Node[ nodes.size() ] );	}	/**	 * <p>Get the root Nodes in this Hierarchy.  The root Nodes are defined	 * as all Nodes in this Hierarchy for which Node.isRoot() returns true.	 * <p>Note that this function may exclude Nodes for which the client does	 * not have authorization to access.  In this case it will simply return a	 * subset of the root Nodes in this Hierarchy.	 *	 * @return The root Nodes in this Hierarchy, or a zero-length array if	 *         there are none.	 */	public org.okip.util.hierarchy.api.Node[] getRootNodes()		throws HierarchyException	{		// TODO: fix this		java.util.ArrayList rootNodes = new java.util.ArrayList();		org.okip.util.hierarchy.api.Node[] allNodes = getNodes();		for( int i = 0 ; i < allNodes.length ; i ++ )		{			org.okip.util.hierarchy.api.Node node = allNodes[ i ];			if( node.isRoot() )			{				rootNodes.add( node );			}		}		return ( org.okip.util.hierarchy.api.Node[] )rootNodes.toArray( new org.okip.util.hierarchy.api.Node[ rootNodes.size() ] );	}	/**	 * <p>Get a Node is this Hierarchy.	 *	 * @return The Node corresponding to the specified key if it exists in this	 *         Hierarchy and if the client has authorization to access it.	 *         Otherwise return null.	 */	public org.okip.util.hierarchy.api.Node getNode( java.io.Serializable qKey )		throws HierarchyException	{		// validate args		if( ! isValidKey( qKey ) )		{			throw new IllegalArgumentException( "Invalid Key" );		}		String key = ( String )qKey;				Node n = new Node( this, key, mConnection );		if( ! n.validate() )		{			n = null;		}		return n;	}		static boolean isValidKey( java.io.Serializable qKey )	{		if( qKey == null )		{			return false;		}		if( ! ( qKey instanceof String ) )		{			return false;		}		String key = ( String )qKey;		if( key.length() > KEY_LENGTH ||			key.length() < 1 )		{			return false;		}		return true;	}}