| /******************************************************************************* |
| * Copyright (c) 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.jsp.ui.internal.text; |
| |
| import java.io.IOException; |
| |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IRegion; |
| import org.eclipse.jface.text.Region; |
| import org.eclipse.jface.text.source.ICharacterPairMatcher; |
| |
| |
| /** |
| * Helper class for match pairs of characters. |
| * |
| * Copied from org.eclipse.jdt.internal.ui.text so we don't have to |
| * depend on the org.eclipse.jdt.ui plugin. |
| * |
| * No modifications were made. |
| */ |
| class JavaPairMatcher implements ICharacterPairMatcher { |
| |
| protected char[] fPairs; |
| protected IDocument fDocument; |
| protected int fOffset; |
| |
| protected int fStartPos; |
| protected int fEndPos; |
| protected int fAnchor; |
| |
| protected JavaCodeReader fReader = new JavaCodeReader(); |
| |
| |
| public JavaPairMatcher(char[] pairs) { |
| fPairs = pairs; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.text.source.ICharacterPairMatcher#match(org.eclipse.jface.text.IDocument, int) |
| */ |
| public IRegion match(IDocument document, int offset) { |
| |
| fOffset = offset; |
| |
| if (fOffset < 0) |
| return null; |
| |
| fDocument = document; |
| |
| if (fDocument != null && matchPairsAt() && fStartPos != fEndPos) |
| return new Region(fStartPos, fEndPos - fStartPos + 1); |
| |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.text.source.ICharacterPairMatcher#getAnchor() |
| */ |
| public int getAnchor() { |
| return fAnchor; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.text.source.ICharacterPairMatcher#dispose() |
| */ |
| public void dispose() { |
| clear(); |
| fDocument = null; |
| fReader = null; |
| } |
| |
| /* |
| * @see org.eclipse.jface.text.source.ICharacterPairMatcher#clear() |
| */ |
| public void clear() { |
| if (fReader != null) { |
| try { |
| fReader.close(); |
| } |
| catch (IOException x) { |
| // ignore |
| } |
| } |
| } |
| |
| protected boolean matchPairsAt() { |
| |
| int i; |
| int pairIndex1 = fPairs.length; |
| int pairIndex2 = fPairs.length; |
| |
| fStartPos = -1; |
| fEndPos = -1; |
| |
| // get the chars preceding and following the start position |
| try { |
| |
| char prevChar = fDocument.getChar(Math.max(fOffset - 1, 0)); |
| // modified behavior for http://dev.eclipse.org/bugs/show_bug.cgi?id=16879 |
| // char nextChar= fDocument.getChar(fOffset); |
| |
| // search for opening peer character next to the activation point |
| for (i = 0; i < fPairs.length; i = i + 2) { |
| // if (nextChar == fPairs[i]) { |
| // fStartPos= fOffset; |
| // pairIndex1= i; |
| // } else |
| if (prevChar == fPairs[i]) { |
| fStartPos = fOffset - 1; |
| pairIndex1 = i; |
| } |
| } |
| |
| // search for closing peer character next to the activation point |
| for (i = 1; i < fPairs.length; i = i + 2) { |
| if (prevChar == fPairs[i]) { |
| fEndPos = fOffset - 1; |
| pairIndex2 = i; |
| } |
| // else if (nextChar == fPairs[i]) { |
| // fEndPos= fOffset; |
| // pairIndex2= i; |
| // } |
| } |
| |
| if (fEndPos > -1) { |
| fAnchor = RIGHT; |
| fStartPos = searchForOpeningPeer(fEndPos, fPairs[pairIndex2 - 1], fPairs[pairIndex2], fDocument); |
| if (fStartPos > -1) |
| return true; |
| else |
| fEndPos = -1; |
| } |
| else if (fStartPos > -1) { |
| fAnchor = LEFT; |
| fEndPos = searchForClosingPeer(fStartPos, fPairs[pairIndex1], fPairs[pairIndex1 + 1], fDocument); |
| if (fEndPos > -1) |
| return true; |
| else |
| fStartPos = -1; |
| } |
| |
| } |
| catch (BadLocationException x) { |
| } |
| catch (IOException x) { |
| } |
| |
| return false; |
| } |
| |
| protected int searchForClosingPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException { |
| |
| fReader.configureForwardReader(document, offset + 1, document.getLength(), true, true); |
| |
| int stack = 1; |
| int c = fReader.read(); |
| while (c != JavaCodeReader.EOF) { |
| if (c == openingPeer && c != closingPeer) |
| stack++; |
| else if (c == closingPeer) |
| stack--; |
| |
| if (stack == 0) |
| return fReader.getOffset(); |
| |
| c = fReader.read(); |
| } |
| |
| return -1; |
| } |
| |
| protected int searchForOpeningPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException { |
| |
| fReader.configureBackwardReader(document, offset, true, true); |
| |
| int stack = 1; |
| int c = fReader.read(); |
| while (c != JavaCodeReader.EOF) { |
| if (c == closingPeer && c != openingPeer) |
| stack++; |
| else if (c == openingPeer) |
| stack--; |
| |
| if (stack == 0) |
| return fReader.getOffset(); |
| |
| c = fReader.read(); |
| } |
| |
| return -1; |
| } |
| } |