/* * 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.designer.mapping.factory; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.mapping.MappingRoot; import org.teiid.core.designer.ModelerCoreException; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.util.ListAndMapUtil; import org.teiid.designer.core.util.ModelContents; import org.teiid.designer.mapping.PluginConstants; import org.teiid.designer.metamodels.transformation.FragmentMappingRoot; import org.teiid.designer.metamodels.transformation.MappingClass; import org.teiid.designer.metamodels.transformation.MappingClassColumn; import org.teiid.designer.metamodels.transformation.StagingTable; import org.teiid.designer.metamodels.transformation.TreeMappingRoot; /** * TreeMappingClassLocator provides a data-structure and data management methods to maintain an efficient set of information about * Mapping Classes and Staging Tables mapped and referenced to a specific XML Document & XML Root * This class is designed to work in conjunction with the MappingClassFactory and contains a companion locator: * TreeMappingClassColumnLocator to handle the Mapping Class Column mappings and locations. * * This improves performance and simplifies follow-on code maintenance. * Created: BML 5/9/07 * @since 8.0 */ public class TreeMappingClassLocator implements PluginConstants { // --------------------------------------------------------------------------------------------------------------------------- // CONSTANTS // --------------------------------------------------------------------------------------------------------------------------- //private PerformanceTracker pTracker = new PerformanceTracker(getClass().getName()); // --------------------------------------------------------------------------------------------------------------------------- // FIELDS // --------------------------------------------------------------------------------------------------------------------------- /** The model contents object to assist in creating an EMF Tree iterator */ private ModelContents modelContents; /** The tree root. */ private EObject root; /** ITreeToRelationalMapper */ private ITreeToRelationalMapper mapper; /** Adapter for fragments. */ private FragmentMappingAdapter fragmentAdapter; /** Mapping Class Column Locator */ private TreeMappingClassColumnLocator columnMappingLocator; /** Collection of {@link org.eclipse.emf.mapping.MappingRoot}s. */ private List mappingRoots; /** Collection of {@link org.teiid.designer.metamodels.transformation.FragmentMappingRoot}s. */ private List fragmentRoots; /** Maps to give quicker access to mapping class, staging table, tree root and location info */ // KEY = StagingTable, VALUE = TreeMappingRoot private HashMap stagingTablesToRootMap = new HashMap(); // KEY = MappingClass, VALUE = TreeMapping Root private HashMap mappingClassesToRootMap = new HashMap(); // KEY = tree location (EObject), VALUE = MappingClass // Note: Multiple locations can reference the same mapping class private HashMap locationToMappingClassMap = new HashMap(); // KEY = tree location, VALUE = StagingTable private HashMap locationToStagingTableMap = new HashMap(); // KEY = StagingTable, VALUE = location private HashMap stagingTableLocationMap = new HashMap(); // KEY = MappingClass Name, Value = MappingClassName private HashMap mappingClassesNameMap = new HashMap(); // Ordered list of MappingClasses private List mappingClassesArray = Collections.EMPTY_LIST; // Ordered List of StagingTables private List stagingTablesArray = Collections.EMPTY_LIST; /** Map of key=tree node, value=Mapping Class * This map relates each tree node to a mapping class, if any, * whose scope it is in, independent of whether or not it is currently * MAPPED. * */ private HashMap treeNodesToMappingClassScopeMap = new HashMap(); private boolean hasChanges = false; private boolean generatingMappingClasses = false; // --------------------------------------------------------------------------------------------------------------------------- // CONSTRUCTORS // --------------------------------------------------------------------------------------------------------------------------- /** * Basic Constructor. Requires a valid XML Document Tree Root object * @since 5.0 */ public TreeMappingClassLocator(EObject treeRoot) { super(); this.root = treeRoot; this.modelContents = ModelerCore.getModelEditor().getModelContents(root); this.mapper = ModelMapperFactory.createModelMapper(root); this.columnMappingLocator = new TreeMappingClassColumnLocator(this); initialize(); } // --------------------------------------------------------------------------------------------------------------------------- // PUBLIC METHODS // --------------------------------------------------------------------------------------------------------------------------- public boolean isGeneratingMappingClasses() { return generatingMappingClasses; } public void setGeneratingMappingClasses(boolean isGenerating) { boolean finished = false; if( this.generatingMappingClasses && !isGenerating) { finished = true; } this.generatingMappingClasses = isGenerating; if( finished ) { resetIfChanged(); } } // private void startTracking(String method) { // pTracker.start(method); // } // // private void stopTracking(String method) { // pTracker.stop(method); // } // // public void print() { // pTracker.print(); // columnMappingLocator.print(); // } // // public void resetTracker() { // pTracker.reset(); // columnMappingLocator.resetTracker(); // } /** * Get the XML Document tree root for this mapping * @return the root * @since 5.0 */ public EObject getDocumentTreeRoot() { return this.root; } /** * Get the ITreeToRelationalMapper for this mapping * @return the mapper * @since 5.0 */ public ITreeToRelationalMapper getMapper() { return this.mapper; } /** * return the FragmentMappingAdapter * @return * @since 5.0 */ public FragmentMappingAdapter getFragmentAdapter() { return this.fragmentAdapter; } /** * Get the ordered List of MappingClasses currently defined and referenced within the XML Document root * @return * @since 5.0 */ public List getMappingClasses() { resetIfChanged(); return this.mappingClassesArray; } /** * Get the mapping class referenced by this location. * @param treeNodeLocation * @return mapping class EObject, may be null * @since 5.0 */ public EObject getMappingClass(EObject treeNodeLocation) { //startTracking("getMappingClass()"); //$NON-NLS-1$ resetIfChanged(); EObject theMappingClass = (EObject)locationToMappingClassMap.get(treeNodeLocation); //stopTracking("getMappingClass()"); //$NON-NLS-1$ return theMappingClass; } /** * Get ordered List of StagingTable's currently defined and referenced within the XML Document root * @return * @since 5.0 */ public List getStagingTables() { resetIfChanged(); return stagingTablesArray; } public EObject getStagingTable(EObject treeNodeLocation) { return (EObject)locationToStagingTableMap.get(treeNodeLocation); } public List getFragmentRoots() { return fragmentRoots; } public List getMappingClassLocations(EObject mappingClass) { //startTracking("getMappingClassLocations()"); //$NON-NLS-1$ resetIfChanged(); List locations = new ArrayList(); Iterator iter = locationToMappingClassMap.keySet().iterator(); // Gather up all locations for this mapping class while( iter.hasNext() ) { EObject nextLoc = (EObject)iter.next(); EObject nextMC = (EObject)locationToMappingClassMap.get(nextLoc); if( nextMC == mappingClass ) { locations.add(nextLoc); } } //stopTracking("getMappingClassLocations()"); //$NON-NLS-1$ return locations; } public EObject getStagingTableLocation(EObject stagingTable) { resetIfChanged(); return (EObject)stagingTableLocationMap.get(stagingTable); } public boolean hasTreeRoot(MappingClass mappingClass) { return mappingClassesToRootMap.get(mappingClass) != null; } public EObject getMappingRoot(MappingClass mappingClass) { //startTracking("getMappingRoot()"); //$NON-NLS-1$ EObject mappingRoot = null; if( mappingClass instanceof StagingTable ) { mappingRoot = (EObject)stagingTablesToRootMap.get(mappingClass); } else { mappingRoot = (EObject)mappingClassesToRootMap.get(mappingClass); } //stopTracking("getMappingRoot()"); //$NON-NLS-1$ return mappingRoot; } public List getMappingRoots() { return mappingRoots; } public List getAllMappingClassLocations() { //startTracking("getAllMappingClassLocations()"); //$NON-NLS-1$ resetIfChanged(); List result = new ArrayList(locationToMappingClassMap.keySet()); //stopTracking("getAllMappingClassLocations()"); //$NON-NLS-1$ return result; } public void addMappingClassAtLocation(EObject treeMappingRoot, MappingClass mappingClass, EObject location) { //startTracking("addMappingClassAtLocation()"); //$NON-NLS-1$ hasChanges = true; // MAPPING CLASS if( mappingClass instanceof StagingTable ) { // MAPPING CLASS if( stagingTablesToRootMap.get(mappingClass) == null ) { stagingTablesToRootMap.put(mappingClass, treeMappingRoot); mappingRoots.add(treeMappingRoot); } // Note that Mapping Classes CAN be mapped to multiple locations locationToStagingTableMap.put( location, mappingClass ); stagingTableLocationMap.put(mappingClass, location); } else { if( mappingClassesToRootMap.get(mappingClass) == null ) { mappingClassesToRootMap.put(mappingClass, treeMappingRoot); mappingRoots.add(treeMappingRoot); mappingClassesNameMap.put(mappingClass.getName(), mappingClass.getName()); } // Note that Mapping Classes CAN be mapped to multiple locations locationToMappingClassMap.put( location, mappingClass ); } addOutputLocation(mappingClass, location); //stopTracking("addMappingClassAtLocation()"); //$NON-NLS-1$ } public void removeMappingClassFromLocation(EObject treeMappingRoot, MappingClass mappingClass, EObject location) { //startTracking("removeMappingClassFromLocation()"); //$NON-NLS-1$ hasChanges = true; // MAPPING CLASS if( mappingClassesToRootMap.get(mappingClass) != null ) { mappingClassesToRootMap.remove(mappingClass); mappingRoots.remove(treeMappingRoot); mappingClassesNameMap.remove(mappingClass.getName()); } // Note that Mapping Classes CAN be mapped to multiple locations locationToMappingClassMap.remove( location); removeOutputLocation(mappingClass, location); //stopTracking("removeMappingClassFromLocation()"); //$NON-NLS-1$ } public boolean containsLocation(EObject mappingClass, EObject location) { //startTracking("containsLocation()"); //$NON-NLS-1$ resetIfChanged(); boolean result = false; if( mappingClass instanceof StagingTable ) { EObject cachedST = (EObject)locationToStagingTableMap.get(location); result = cachedST != null && cachedST == mappingClass; } else { EObject cachedMC = (EObject)locationToMappingClassMap.get(location); result = cachedMC != null && cachedMC == mappingClass; } //stopTracking("containsLocation()"); //$NON-NLS-1$ return result; } public boolean containsMappingClassWithName(String someName) { return mappingClassesNameMap.get(someName) != null; } public boolean addOutputLocation(MappingClass theMappingClass, EObject theTreeNode) { boolean result = false; //startTracking("addOutputLocation()"); //$NON-NLS-1$ try { TreeMappingRoot treeMappingRoot = (TreeMappingRoot)getMappingRoot(theMappingClass); if( !treeMappingRoot.getOutputs().contains(theTreeNode) ) { ModelerCore.getModelEditor().addValue(treeMappingRoot, theTreeNode, treeMappingRoot.getOutputs()); //addEntryToTreeNodesToMappingClassScopeMap( theMappingClass ); hasChanges = true; } } catch (Exception e) { PluginConstants.Util.log(IStatus.ERROR, e, e.getMessage()); } //stopTracking("addOutputLocation()"); //$NON-NLS-1$ return result; } public boolean removeOutputLocation(MappingClass theMappingClass, EObject theTreeNode) { boolean result = false; //startTracking("removeOutputLocation()"); //$NON-NLS-1$ try { TreeMappingRoot treeMappingRoot = (TreeMappingRoot)getMappingRoot(theMappingClass); if( treeMappingRoot.getOutputs().contains(theTreeNode) ) { ModelerCore.getModelEditor().removeValue(treeMappingRoot, theTreeNode, treeMappingRoot.getOutputs()); removeEntryFromTreeNodesToMappingClassScopeMap(theMappingClass); hasChanges = true; } } catch (Exception e) { PluginConstants.Util.log(IStatus.ERROR, e, e.getMessage()); } //stopTracking("removeOutputLocation()"); //$NON-NLS-1$ return result; } public void deleteMappingClass(EObject mappingClass) throws ModelerCoreException { //startTracking("deleteMappingClass()"); //$NON-NLS-1$ if( mappingClass instanceof StagingTable) { EObject treeMappingRoot = (EObject)stagingTablesToRootMap.get(mappingClass); if( treeMappingRoot != null ) { mappingClassesToRootMap.remove(mappingClass); ModelerCore.getModelEditor().delete(treeMappingRoot,true,false); } ModelerCore.getModelEditor().delete(mappingClass); // Remove all "Locations" for this mapping Class EObject location = (EObject)stagingTableLocationMap.get(mappingClass); if( location != null ) { locationToStagingTableMap.remove(location); } stagingTableLocationMap.remove(mappingClass); } else { EObject treeMappingRoot = (EObject)mappingClassesToRootMap.get(mappingClass); if( treeMappingRoot != null ) { mappingClassesToRootMap.remove(mappingClass); ModelerCore.getModelEditor().delete(treeMappingRoot,true,false); } ModelerCore.getModelEditor().delete(mappingClass); // Remove all "Locations" for this mapping Class List locations = getMappingClassLocations(mappingClass); for( Iterator iter = locations.iterator(); iter.hasNext(); ) { locationToMappingClassMap.remove(iter.next()); } } mappingClassesNameMap.remove( ((MappingClass)mappingClass).getName()); //stopTracking("deleteMappingClass()"); //$NON-NLS-1$ hasChanges = true; } /** * Recursive method used by getCoarseExtentNodes to walk down a branch of the tree and find all visible nodes in the extent. * @param visibleNode the branch node that this method will look beneath * @param columnLocations a Collection of tree nodes that should automatically be added in the result * @param mappingClassLocations a Collection of mapping class locations. Any node inside this collection should * not be added to the result. * @param visibleTreeNodes a Collection of all tree nodes that are visible in the tree. Nodes that are not in this Collection * should not be added to the result. * @return */ public List gatherCoarseExtentNodes( EObject visibleNode, HashMap columnLocationsMap ) { ArrayList result = new ArrayList(); for ( Iterator childIter = getMapper().getMappableTree().getChildren(visibleNode).iterator() ; childIter.hasNext() ; ) { EObject node = (EObject) childIter.next(); // first, make sure the child is visible // next, check to see if this node is mapped into the MappingClass by checking columnLocations // jh PERFORMANCE: change columnLocations from a List to a Map, if ( columnLocationsMap.get(node) != null ) { // if so, then this node is in the extent result.add(node); // recurse down this node's children result.addAll( gatherCoarseExtentNodes( node, columnLocationsMap ) ); } else { // see if there is a mapping class located at this node // jh PERFORMANCE: change mappingClassLocations from a List to a Map, if ( getMappingClass(node) != null ) { // stop; this node is in another extent. do not check this node's children. } else { // this node is in the extent result.add(node); // recurse down this node's children result.addAll(gatherCoarseExtentNodes (node, columnLocationsMap ) ); } } } return result; } public MappingClass getMappingClassForTreeNode(EObject theTreeNode) { //startTracking("getMappingClassForTreeNode()"); //$NON-NLS-1$ MappingClass result = (MappingClass)treeNodesToMappingClassScopeMap.get(theTreeNode); //stopTracking("getMappingClassForTreeNode()"); //$NON-NLS-1$ return result; } /** * Obtain an ordered list of all locations visible in the TreeViewer that are in the extent * of the specified MappingClass. * This method is based on getCoarseMappingExtentNodes(MappingClass theMappingClass) from * MappingAdapterFilter. * @param theMappingClass * @return */ public List getTreeNodesInAMappingClassScope(MappingClass theMappingClass) { //startTracking("getTreeNodesInAMappingClassScope()"); //$NON-NLS-1$ resetIfChanged(); List columnLocations = getColumnLocations(theMappingClass); HashMap columnLocationsMap = ListAndMapUtil.createMapFromList(columnLocations); List locations = getMappingClassLocations(theMappingClass); List extentNodes = Collections.EMPTY_LIST; if (!locations.isEmpty()) { extentNodes = new ArrayList(); for (int size = locations.size(), i = 0; i < size; i++) { // iterate over every visible location node // add the location to the collection of extent nodes extentNodes.add(locations.get(i)); // recurse down this location and collect up the extent nodes extentNodes.addAll( gatherCoarseExtentNodes( (EObject) locations.get(i), columnLocationsMap ) ); } } //stopTracking("getTreeNodesInAMappingClassScope()"); //$NON-NLS-1$ return extentNodes; } public void loadTreeNodesToMappingClassScopeMap() { //startTracking("loadTreeNodesToMappingClassScopeMap()"); //$NON-NLS-1$ treeNodesToMappingClassScopeMap = new HashMap(mappingClassesArray.size()); // for each mapping class, get the treenodes in its scope for (int size = mappingClassesArray.size(), i = 0; i < size; i++) { MappingClass mappingClass = (MappingClass)mappingClassesArray.get(i); if (mappingClass != null) { addEntryToTreeNodesToMappingClassScopeMap( mappingClass ); } } columnMappingLocator.loadTreeNodesToMappingClassColumnsMap(); //stopTracking("loadTreeNodesToMappingClassScopeMap()"); //$NON-NLS-1$ } private void addEntryToTreeNodesToMappingClassScopeMap( MappingClass mappingClass ) { //startTracking("addEntryToTreeNodesToMappingClassScopeMap()"); //$NON-NLS-1$ List lstNodes = getTreeNodesInAMappingClassScope( mappingClass ); if ( ( lstNodes != null ) && !lstNodes.isEmpty() ) { for ( int iNodes = lstNodes.size(), j = 0; j < iNodes; j++ ) { EObject eoTemp = (EObject)lstNodes.get( j ); /* * Now qualify these the way you would the treenodes in MappingAdapterFilter, * namely, we only want mappable columns, so we ignore containers and elements * that have children. Can we ask isMappable() on elements to determine if it * has children? */ // is isMappable enough?? Let's hope so.......... if ( getMapper().isMappable( eoTemp ) ) { /* * jh Defect 21277: Shouldn't we also do this when we add a new MC? * ( Also see: getTreeNodesToMappingClassColumnsMap */ treeNodesToMappingClassScopeMap.put( eoTemp, mappingClass ); } } } //stopTracking("addEntryToTreeNodesToMappingClassScopeMap()"); //$NON-NLS-1$ } /* * jh Defect 21277: This method allows us to remove an MC from this map */ private void removeEntryFromTreeNodesToMappingClassScopeMap( MappingClass mappingClass ) { //startTracking("removeEntryFromTreeNodesToMappingClassScopeMap()"); //$NON-NLS-1$ Collection colNodes = treeNodesToMappingClassScopeMap.keySet(); if ( ( colNodes != null ) && !colNodes.isEmpty() ) { Iterator it = colNodes.iterator(); while( it.hasNext() ) { EObject tempNodeKey = (EObject)it.next(); // get the MC for this tree node key MappingClass tempMappingClass = (MappingClass)treeNodesToMappingClassScopeMap.get( tempNodeKey ); // if this MC is the same as our arg, remove the key if ( tempMappingClass == mappingClass ) { it.remove(); } } } //stopTracking("removeEntryFromTreeNodesToMappingClassScopeMap()"); //$NON-NLS-1$ } // ---------------------------- // Mapping Class Column Methods // ---------------------------- public void addMappingClassColumnLocation(MappingClassColumn theMappingColumn, EObject theTreeNode) { hasChanges = true; columnMappingLocator.addMappingClassColumnLocation(theMappingColumn, theTreeNode); } public void removeMappingClassColumnLocation(MappingClassColumn theMappingColumn, EObject theTreeNode) { hasChanges = true; columnMappingLocator.removeMappingClassColumnLocation(theMappingColumn, theTreeNode); } public MappingList getMappingClassColumnMappingList(MappingClassColumn theMappingColumn) { resetIfChanged(); return columnMappingLocator.getMappingClassColumnMappingList(theMappingColumn); } public MappingClassColumn getMappingClassColumn(EObject theTreeNode, MappingClass theMappingClass) { resetIfChanged(); return columnMappingLocator.getMappingClassColumn(theTreeNode, theMappingClass); } public MappingClassColumn getMappingClassColumn( EObject theTreeNode ) { resetIfChanged(); return columnMappingLocator.getMappingClassColumn(theTreeNode); } public List getMappingClassColumnOutputLocations(MappingClassColumn theMappingColumn) { resetIfChanged(); return columnMappingLocator.getMappingClassColumnOutputLocations(theMappingColumn); } /** * return a list of all location mapped to the attributes of the specified MappingClass * @param theMappingClass * @return */ public List getColumnLocations(MappingClass theMappingClass) { resetIfChanged(); List result = new ArrayList(); for (Iterator iter = theMappingClass.getColumns().iterator() ; iter.hasNext() ; ) { result.addAll(getMappingClassColumnOutputLocations((MappingClassColumn) iter.next())); } return result; } // // public void loadTreeNodesToMappingClassColumnsMap() { // columnMappingLocator.loadTreeNodesToMappingClassColumnsMap(); // } // --------------------------------------------------------------------------------------------------------------------------- // PRIVATE METHODS // --------------------------------------------------------------------------------------------------------------------------- /** * Interrogate this treeMappingRoot, find and organize the mapping classes and staging tables into maps */ private void initialize() { fragmentRoots = new ArrayList(); mappingRoots = modelContents.getTransformations(root); if ((mappingRoots == null) || mappingRoots.isEmpty()) { mappingRoots = new ArrayList(); } else { for (int size = mappingRoots.size(), i = 0; i < size; i++) { MappingRoot mappingRoot = (MappingRoot)mappingRoots.get(i); Iterator outputIter = mappingRoot.getOutputs().iterator(); if (mappingRoot instanceof TreeMappingRoot) { MappingClass mappingClass = getMappingClass(mappingRoot); if (mappingClass instanceof StagingTable) { // STAGING TABLE stagingTablesToRootMap.put(mappingClass, mappingRoot); while ( outputIter.hasNext() ) { // NOTE that STAGING Tables can NOT be mapped to multiple locations so we only have to get the // first output object Object oTreeNode = outputIter.next(); stagingTableLocationMap.put( mappingClass, oTreeNode ); locationToStagingTableMap.put(oTreeNode, mappingClass); } } else { // MAPPING CLASS mappingClassesToRootMap.put(mappingClass, mappingRoot); mappingClassesNameMap.put(mappingClass.getName(), mappingClass.getName()); // Note that Mapping Classes CAN be mapped to multiple locations while ( outputIter.hasNext() ) { Object oTemp = outputIter.next(); locationToMappingClassMap.put( oTemp, mappingClass ); } } } else if (mappingRoot instanceof FragmentMappingRoot) { fragmentRoots.add(mappingRoot); } } } fragmentAdapter = new FragmentMappingAdapter(root, getFragmentRoots()); resetOrderedLists(); } private void resetIfChanged() { if( hasChanges && !isGeneratingMappingClasses() ) { resetOrderedLists(); loadTreeNodesToMappingClassScopeMap(); } } private void resetOrderedLists() { //System.out.println(" <<<< TEMP LOGGING >>>> TreeMappingClassLocator.resetOrderedLists() # MC Locations =" + locationToMappingClassMap.size()); //$NON-NLS-1$ //startTracking("resetOrderedLists()"); //$NON-NLS-1$ if( mappingRoots.isEmpty() ) { // DON'T Want to do anything if there are NO roots except set the arrays to NULL (i.e. clear maps and arrays); clear(); return; } // MappingClasses // Get Copy of List of Locations XmlDocumentMappingClassVisitor visitor = new XmlDocumentMappingClassVisitor(locationToMappingClassMap, locationToStagingTableMap); MappableTreeIterator nodeIter = new MappableTreeIterator(mapper.getMappableTree()); if ( nodeIter.hasNext() ) { // skip over the root itself nodeIter.next(); } while ( nodeIter.hasNext() ) { visitor.visit((EObject) nodeIter.next()); } mappingClassesArray = visitor.getOrderedMappingClasses(); stagingTablesArray = visitor.getOrderedStagingTables(); hasChanges = false; //System.out.println(this.toString()); //stopTracking("resetOrderedLists()"); //$NON-NLS-1$ } private void clear() { // DON'T Want to do anything if there are NO roots except set the arrays to NULL; mappingClassesArray = Collections.EMPTY_LIST; stagingTablesArray = Collections.EMPTY_LIST; if( !locationToMappingClassMap.isEmpty() ) { locationToMappingClassMap.clear(); } if( !stagingTablesToRootMap.isEmpty() ) { stagingTablesToRootMap.clear(); } if( !mappingClassesToRootMap.isEmpty() ) { mappingClassesToRootMap.clear(); } if( !locationToMappingClassMap.isEmpty() ) { locationToMappingClassMap.clear(); } if( !locationToStagingTableMap.isEmpty() ) { locationToStagingTableMap.clear(); } if( !stagingTableLocationMap.isEmpty() ) { stagingTableLocationMap.clear(); } if( !treeNodesToMappingClassScopeMap.isEmpty() ) { treeNodesToMappingClassScopeMap.clear(); } if( !mappingClassesNameMap.isEmpty() ) { mappingClassesNameMap.clear(); } } /** * Obtains the <code>MappingClass</code> or <code>StagingTable</code> associated with the specified * <code>MappingRoot</code>. The return value can also be a <code>StagingTable</code> since it is * a subclass of <code>MappingClass</code>. * @param theMappingRoot the <code>MappingRoot</code> whose <code>MappingClass</code> is being requested * @return the <code>MappingClass</code> or <code>null</code> if none found * @throws IllegalArgumentException if input parameter is <code>null</code> */ private MappingClass getMappingClass(MappingRoot theMappingRoot) { CoreArgCheck.isNotNull(theMappingRoot); MappingClass result = null; List inputs = theMappingRoot.getInputs(); int size = inputs.size(); if (size > 0) { result = (MappingClass)inputs.get(0); } return result; } /** * * @see java.lang.Object#toString() * @since 5.0 */ @Override public String toString() { int buffSize = 100 + 80*mappingClassesArray.size() + 80*stagingTablesArray.size(); StringBuffer buffer = new StringBuffer(buffSize); buffer.append("\n TreeToEObjectMapping Contents:"); //$NON-NLS-1$ buffer.append('\n').append(" # Mapping Classes = " + mappingClassesArray.size()); //$NON-NLS-1$ Iterator iter = null; String name = null; EObject nextEObj = null; int count = 0; for( iter = mappingClassesArray.iterator(); iter.hasNext(); ) { nextEObj = (EObject)iter.next(); name = ModelerCore.getModelEditor().getName(nextEObj); buffer.append('\n').append(" [" + count + "] " + name); //$NON-NLS-1$ //$NON-NLS-2$ count++; } count = 0; buffer.append('\n').append(" # Staging Tables = " + stagingTablesArray.size()); //$NON-NLS-1$ for( iter = stagingTablesArray.iterator(); iter.hasNext(); ) { nextEObj = (EObject)iter.next(); name = ModelerCore.getModelEditor().getName(nextEObj); buffer.append('\n').append(" [" + count + "] " + name); //$NON-NLS-1$ //$NON-NLS-2$ count++; } buffer.append('\n'); return buffer.toString(); } }