/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.query.ui.sqleditor.component; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.query.IQueryService; import org.teiid.designer.query.sql.IGroupCollectorVisitor; import org.teiid.designer.query.sql.lang.ICommand; import org.teiid.designer.query.sql.lang.ILanguageObject; import org.teiid.designer.query.sql.symbol.IGroupSymbol; /** This class, along with SqlIndexLocator provides actions and panels a way to narrow down the * scope of the query that is currently selected or the cursor is currently in. * @since 8.0 */ public class GroupSymbolFinder { SqlIndexLocator locator; Collection externalGroups; /** * Constructor * @since 4.2 * @param locator = SqlIndexLocator instance * @param exGroups - Any external groups which may be added to the returned list if appropriate */ public GroupSymbolFinder(SqlIndexLocator locator, Collection exGroups) { super(); this.locator = locator; if( exGroups.isEmpty() ) externalGroups = Collections.EMPTY_LIST; else this.externalGroups = new ArrayList(exGroups); } private IGroupCollectorVisitor getGroupVisitor() { IQueryService queryService = ModelerCore.getTeiidQueryService(); return queryService.getGroupCollectorVisitor(true); } /** * Method returns any group symbols in scope for populating the attribute tree in builders * * @return * @since 4.2 */ public List find() { Set groups = new HashSet(); if(locator.getCommandDisplayNode() !=null) { // If the Command is within a SubQuery, handle as a special case. // Need to walk all the way up the chain, gathering groups if(locator.isCriteriaQuerySelected()) { if( !externalGroups.isEmpty() ) groups.addAll(externalGroups); groups.addAll(getGroupsForCriteria()); } else if(locator.isSubQuerySelected() ) { return getGroupsForSubQuery(); } else if( locator.isUnionSegmentSelected() ) { // Defect 17714 - Needed to add external groups here (i.e. InputSet) when selecting // a Union Segement (From clause?) if( !externalGroups.isEmpty() ) groups.addAll(externalGroups); groups.addAll(getGroupsForUnionSegment()); } else { return getGroups(); } } return new ArrayList(groups); } private List getGroupsForCriteria() { IGroupCollectorVisitor groupVisitor = getGroupVisitor(); Set groups = new HashSet(); if( locator.isSelectScopeSelected() || locator.isWhereSelected() ) { groups.addAll(groupVisitor.findGroups(locator.getPrimaryLanguageObject())); List groupsInScope = locator.collectCriteriaParentQueries(locator.isSelectScopeSelected()); DisplayNode dNode = null; for( Iterator iter = groupsInScope.iterator(); iter.hasNext(); ) { dNode = (DisplayNode)iter.next(); groups.addAll(groupVisitor.findGroups(dNode.getLanguageObject())); } } return new ArrayList(groups); } private List getGroupsForSubQuery() { IGroupCollectorVisitor groupVisitor = getGroupVisitor(); Set allGroups = new HashSet(); // Get this commands groupSymbols allGroups.addAll(groupVisitor.findGroups(locator.getPrimaryLanguageObject())); // Get parent node, keep going up until parent is null if( !locator.isUnionSegmentSelected() ) { DisplayNode parentNode = locator.getCommandDisplayNode().getParent(); while(parentNode!=null) { ILanguageObject parentLangObj = parentNode.getLanguageObject(); parentNode = parentNode.getParent(); // Check if Parent Node is UNION (then Stop) if( parentNode instanceof SetQueryDisplayNode) parentNode = null; if(parentNode != null && parentLangObj instanceof ICommand) { allGroups.addAll(groupVisitor.findGroups(parentLangObj)); } } // Now let's add for the real selected Select query if( locator.isSelectScopeSelected() ) { DisplayNode selectedSelectQueryNode = locator.getSelectedSelectQuery(); if( selectedSelectQueryNode != null ) allGroups.addAll(groupVisitor.findGroups(selectedSelectQueryNode.getLanguageObject())); } if( locator.isCriteriaQuerySelected() ) { allGroups.addAll(getGroupsForCriteria()); } if( !externalGroups.isEmpty() ) allGroups.addAll(externalGroups); } return new ArrayList(allGroups); } private List getGroupsForUnionSegment() { Set allGroups = new HashSet(); allGroups.addAll(getGroupVisitor().findGroups(locator.getPrimaryLanguageObject())); return new ArrayList(allGroups); } private List getGroups() { Set allGroups = new HashSet(); // Not within subquery, or Union, get the treeView using the command ILanguageObject langObj = locator.getPrimaryLanguageObject(); // Language Object should be a Command if (langObj!=null && langObj instanceof ICommand) { // make sure no duplicates before adding in external groups Collection groups = getGroupVisitor().findGroupsIgnoreInlineViews(langObj); Collection clonedGrps = new ArrayList(groups.size()); Iterator grpIter = groups.iterator(); while(grpIter.hasNext()) { IGroupSymbol gSymbol = (IGroupSymbol)grpIter.next(); clonedGrps.add(gSymbol.clone()); } allGroups.addAll(externalGroups); allGroups.addAll(clonedGrps); } return new ArrayList(allGroups); } }