/* * Copyright 2003-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.openapi.editor.cells; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Stack; /** * @deprecated Use {@link CellTraversalUtil#iterateTree(EditorCell, EditorCell, boolean)} */ @Deprecated public class DfsTraverser implements Iterator<EditorCell>{ private EditorCell myCurrent; private boolean myVisitChildrenOnly; private EditorCell myCurrentDfsRoot; private boolean myForward; private Stack<Iterator<EditorCell>> myCellIteratorStack; public DfsTraverser(EditorCell start, boolean forward, boolean visitChildrenOnly) { myVisitChildrenOnly = visitChildrenOnly; myCurrentDfsRoot = start; myForward = forward; myCellIteratorStack = new Stack<Iterator<EditorCell>>(); pushIteratorByCell(start); cacheNext(); } private void cacheNext() { removeFinishedIteratorsFromStack(); if (myCellIteratorStack.empty()) { myCurrent = null; if (!myVisitChildrenOnly) { pushParent(); } } else { myCurrent = myCellIteratorStack.peek().next(); assert myCurrent != null : "cell for node " + myCurrentDfsRoot.getSNode().getPresentation() + " at " + myCurrentDfsRoot.getSNode().getContainingRoot() + " has null child cell"; pushIteratorByCell(myCurrent); } } private void removeFinishedIteratorsFromStack() { while (!myCellIteratorStack.empty() && !myCellIteratorStack.peek().hasNext()) { myCellIteratorStack.pop(); } } private void pushParent() { EditorCell_Collection parent = myCurrentDfsRoot.getParent(); if (!pushIteratorByCell(parent)) { return; } iterateToRoot(); myCurrentDfsRoot = parent; cacheNext(); } private void iterateToRoot() { Iterator<EditorCell> parentIterator = myCellIteratorStack.peek(); EditorCell nextCell = null; while (parentIterator.hasNext()) { nextCell = parentIterator.next(); if (nextCell == myCurrentDfsRoot) { break; } } //parent cell contains its children assert nextCell != null && nextCell == myCurrentDfsRoot; } private boolean pushIteratorByCell(EditorCell cell) { Iterator<EditorCell> iterator = iteratorByCell(cell); if (iterator == null) { return false; } myCellIteratorStack.push(iterator); return true; } private Iterator<EditorCell> iteratorByCell(EditorCell cell) { if (cell == null) { return null; } if (cell instanceof EditorCell_Collection) { return getCellCollectionIterator((EditorCell_Collection) cell); } else { return null; } } private Iterator<EditorCell> getCellCollectionIterator(EditorCell_Collection cell) { return myForward ? cell.iterator() : cell.reverseIterator(); } @Override public boolean hasNext() { return myCurrent != null; } @Override public EditorCell next() { if (!hasNext()) { throw new NoSuchElementException(); } EditorCell result = myCurrent; DfsTraverser.this.cacheNext(); return result; } @Override public void remove() { throw new UnsupportedOperationException(); } }