/* * $Id: ParentGroupsRecursiveProcedure.java,v 1.1.2.1 2007/01/12 19:32:13 idegaweb Exp $ * Created on 1.9.2004 * * Copyright (C) 2004 Idega Software hf. All Rights Reserved. * * This software is the proprietary information of Idega hf. * Use is subject to license terms. */ package com.idega.user.data; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.ejb.EJBException; import javax.ejb.FinderException; import com.idega.data.DatastoreInterface; import com.idega.data.GenericProcedure; import com.idega.data.IDOLookup; import com.idega.data.IDOLookupException; import com.idega.data.MSSQLServerDatastoreInterface; import com.idega.util.ListUtil; /** * * Last modified: $Date: 2007/01/12 19:32:13 $ by $Author: idegaweb $ * * @author <a href="mailto:gummi@idega.com">gummi</a> * @version $Revision: 1.1.2.1 $ */ public class ParentGroupsRecursiveProcedure extends GenericProcedure { private static Class[] parameterType = new Class[] {Integer.class}; private String[] _groupTypes = null; private boolean _returnSpecifiedGroupTypes = true; private Group _gr = null; //private boolean _usedFallBackProcedure = false; /** * */ private ParentGroupsRecursiveProcedure() { super(); } public static ParentGroupsRecursiveProcedure getInstance(){ return new ParentGroupsRecursiveProcedure(); } /* (non-Javadoc) * @see com.idega.data.IDOProcedure#getName() */ public String getName() { return "get_ic_parent_groups_recursive"; } /* (non-Javadoc) * @see com.idega.data.IDOProcedure#getReturnType() */ public Class getReturnType() { return Collection.class; } /* (non-Javadoc) * @see com.idega.data.IDOProcedure#getParameterTypes() */ public Class[] getParameterTypes() { return parameterType; } /* (non-Javadoc) * @see com.idega.data.GenericProcedure#getIDOEntityInterfaceClass() */ public Class getIDOEntityInterfaceClass() { return Group.class; } /* (non-Javadoc) * @see com.idega.data.IDOProcedure#executeProcedure() */ protected Object executeProcedure(Object[] parameters) throws Exception { return executeFindProsedure(parameters); } /* (non-Javadoc) * @see com.idega.data.IDOProcedure#executeFallBackProcedure() */ protected Object executeFallBackProcedure(Object[] parameters) throws Exception { //_usedFallBackProcedure=true; return getParentGroupsRecursive(parameters[0],this._groupTypes,this._returnSpecifiedGroupTypes,new HashMap(),new HashMap()); //Using temporary local variables set in the method findParentGroupsRecursive and there again } /* (non-Javadoc) * @see com.idega.data.GenericProcedure#getCreateProcedureScript(com.idega.data.DatastoreInterface) */ protected String getCreateProcedureScript(DatastoreInterface i) { // CREATE PROCEDURE get_ic_parent_groups_recursive (@current Integer) as --This is a non-recursive preorder traversal. // SET NOCOUNT ON // DECLARE @lvl int // // CREATE TABLE #stack (item Integer, lvl int) --Create a tempory stack. // CREATE TABLE #result (parent_ic_group_id int) --Create a result stack. // INSERT INTO #stack VALUES (@current, 1) --Insert current node to the stack. // SELECT @lvl = 1 // WHILE @lvl > 0 --From the top level going down. // BEGIN // IF EXISTS (SELECT * FROM #stack WHERE lvl = @lvl) // BEGIN // SELECT @current = item --Find the first node that matches current node's name. // FROM #stack // WHERE lvl = @lvl // // IF NOT EXISTS (SELECT * FROM #result where parent_ic_group_id = @current) // BEGIN // // insert #result values (@current) --Insert current into result // // DELETE FROM #stack // WHERE lvl = @lvl // AND item = @current --Remove the current node from the stack. // // INSERT #stack --Insert the childnodes of the current node into the stack. // SELECT IC_GROUP_ID, @lvl + 1 // FROM IC_GROUP_RELATION // WHERE RELATED_IC_GROUP_ID=@current // AND (RELATIONSHIP_TYPE='GROUP_PARENT' OR RELATIONSHIP_TYPE IS NULL) // AND ( GROUP_RELATION_STATUS='ST_ACTIVE' OR GROUP_RELATION_STATUS='PASS_PEND' ) // // IF @@ROWCOUNT > 0 --If the previous statement added one or more nodes, go down for its first child. // SELECT @lvl = @lvl + 1 --If no nodes are added, check its brother nodes. // END // ELSE // SELECT @lvl = @lvl - 1 --Back to the level immediately above. // END // ELSE // SELECT @lvl = @lvl - 1 --Back to the level immediately above. // // END --While // SELECT * FROM #result // DROP TABLE #stack // DROP TABLE #result // SET NOCOUNT OFF return null; } public synchronized Collection findParentGroupsRecursive(Group gr, String[] groupTypes, boolean returnSpecifiedGroupTypes) throws EJBException { this._groupTypes = groupTypes; this._returnSpecifiedGroupTypes = returnSpecifiedGroupTypes; this._gr = gr; Collection c; try { c = (Collection) getResult(new Object[] {gr.getPrimaryKey()}); } catch (Exception e) { throw new EJBException(e); } List specifiedGroups = new ArrayList(); List notSpecifiedGroups = new ArrayList(); int j = 0; int k = 0; Iterator iter2 = c.iterator(); if(groupTypes != null && groupTypes.length > 0){ boolean specified = false; while (iter2.hasNext()) { Group tempObj = (Group)iter2.next(); for (int i = 0; i < groupTypes.length; i++) { if (tempObj.getGroupType().equals(groupTypes[i])){ specifiedGroups.add(j++, tempObj); specified = true; } } if(!specified){ notSpecifiedGroups.add(k++, tempObj); }else{ specified = false; } } notSpecifiedGroups.remove(gr); specifiedGroups.remove(gr); } else { while (iter2.hasNext()) { Group tempObj = (Group)iter2.next(); notSpecifiedGroups.add(j++, tempObj); } notSpecifiedGroups.remove(gr); returnSpecifiedGroupTypes = false; } this._groupTypes=null; this._returnSpecifiedGroupTypes=true; this._gr=null; //_usedFallBackProcedure = false; return (returnSpecifiedGroupTypes) ? specifiedGroups : notSpecifiedGroups; } /** * Optimized version of getParentGroupsRecursive(Group,String[],boolean) by Sigtryggur 22.06.2004 * Database access is minimized by passing a Map of cached groupParents and Map of cached groups to the method */ private Collection getParentGroupsRecursive(Object grPK, String[] groupTypes, boolean returnSpecifiedGroupTypes, Map cachedParents, Map cachedGroups) throws EJBException{ //public Collection getGroupsContaining(Group groupContained, String[] groupTypes, boolean returnSepcifiedGroupTypes) throws EJBException,RemoteException{ Group aGroup; try { aGroup = (Group)IDOLookup.findByPrimaryKey(Group.class,(Integer)grPK); } catch (IDOLookupException e) { throw new EJBException(e); } catch (FinderException e) { throw new EJBException(e); } Collection groups = aGroup.getParentGroups(cachedParents, cachedGroups); if (groups != null && groups.size() > 0){ Map GroupsContained = new Hashtable(); String key = ""; Iterator iter = groups.iterator(); while (iter.hasNext()) { Group item = (Group)iter.next(); if(item!=null){ key = item.getPrimaryKey().toString(); if(!GroupsContained.containsKey(key)){ GroupsContained.put(key,item); putGroupsContaining( item, GroupsContained,groupTypes, returnSpecifiedGroupTypes, cachedParents, cachedGroups ); } } } return GroupsContained.values(); /////REMOVE AFTER IMPLEMENTING PUTGROUPSCONTAINED BETTER }else{ return ListUtil.getEmptyList(); } } /** * Optimized version of putGroupsContaining(Group, Map, String[], boolean) by Sigtryggur 22.06.2004 * Database access is minimized by passing a Map of cached groupParents and Map of cached groups to the method */ private void putGroupsContaining(Group group, Map GroupsContained , String[] groupTypes, boolean returnGroupTypes, Map cachedParents, Map cachedGroups ) { Collection pGroups = null; if (cachedParents == null) { pGroups = group.getParentGroups();//TODO EIKI FINISH THIS groupTypes,returnGroupTypes); } else { pGroups = group.getParentGroups(cachedParents, cachedGroups); } if (pGroups != null ){ String key = ""; Iterator iter = pGroups.iterator(); while (iter.hasNext()) { Group item = (Group)iter.next(); if(item!=null){ key = item.getPrimaryKey().toString(); if(!GroupsContained.containsKey(key)){ GroupsContained.put(key,item); putGroupsContaining(item, GroupsContained,groupTypes,returnGroupTypes, cachedParents, cachedGroups); } } } } } /* (non-Javadoc) * @see com.idega.data.IDOProcedure#processResultSet(java.sql.ResultSet) */ public Object processResultSet(ResultSet rs) { Collection c = new ArrayList(); if (rs != null ){ try { while(rs.next()) { c.add(rs.getObject(1)); } } catch (SQLException e) { e.printStackTrace(); } } return c; } /* (non-Javadoc) * @see com.idega.data.GenericProcedure#useStoredProcedure(com.idega.data.DatastoreInterface) */ protected boolean isSupportedForDatabase(DatastoreInterface i) { return (i instanceof MSSQLServerDatastoreInterface); } }