| /** |
| * Created on 2004-12-1 |
| * |
| * Copyright (c) Sybase, Inc. 2004-2006 All rights reserved. |
| */ |
| package org.eclipse.datatools.sqltools.sqleditor.internal.sql; |
| |
| import org.eclipse.jface.text.rules.ICharacterScanner; |
| import org.eclipse.jface.text.rules.IToken; |
| import org.eclipse.jface.text.rules.MultiLineRule; |
| import org.eclipse.jface.text.rules.Token; |
| |
| /** |
| * @author Hui Cao |
| * |
| */ |
| public class NestedMultiLineRule extends MultiLineRule |
| { |
| protected int _commentNestingDepth = 0; |
| |
| /** |
| * @param startSequence |
| * @param endSequence |
| * @param token |
| */ |
| public NestedMultiLineRule(String startSequence, String endSequence, IToken token) |
| { |
| super(startSequence, endSequence, token); |
| // TODO Auto-generated constructor stub |
| } |
| |
| /** |
| * @param startSequence |
| * @param endSequence |
| * @param token |
| * @param escapeCharacter |
| */ |
| public NestedMultiLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter) |
| { |
| super(startSequence, endSequence, token, escapeCharacter); |
| // TODO Auto-generated constructor stub |
| } |
| |
| /** |
| * @param startSequence |
| * @param endSequence |
| * @param token |
| * @param escapeCharacter |
| * @param breaksOnEOF |
| */ |
| public NestedMultiLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter, |
| boolean breaksOnEOF) |
| { |
| super(startSequence, endSequence, token, escapeCharacter, breaksOnEOF); |
| // TODO Auto-generated constructor stub |
| } |
| |
| protected boolean endSequenceDetected(ICharacterScanner scanner) |
| { |
| int c; |
| char[][] delimiters = scanner.getLegalLineDelimiters(); |
| boolean previousWasEscapeCharacter = false; |
| while ((c = scanner.read()) != ICharacterScanner.EOF) |
| { |
| if (c == fEscapeCharacter) |
| { |
| // Skip the escaped character. |
| scanner.read(); |
| } |
| else if (fStartSequence.length > 0 && c == fStartSequence[0]) |
| { |
| // Check if the nested start sequence has been found. |
| if (sequenceDetected(scanner, fStartSequence, false)) |
| { |
| _commentNestingDepth++; |
| } |
| } |
| else if (fEndSequence.length > 0 && c == fEndSequence[0]) |
| { |
| // Check if the specified end sequence has been found. |
| if (sequenceDetected(scanner, fEndSequence, true)) |
| { |
| _commentNestingDepth--; |
| } |
| if (_commentNestingDepth <= 0) |
| { |
| return true; |
| } |
| } |
| previousWasEscapeCharacter = (c == fEscapeCharacter); |
| } |
| if (fBreaksOnEOF) |
| { |
| return true; |
| } |
| scanner.unread(); |
| return false; |
| } |
| |
| protected IToken doEvaluate(ICharacterScanner scanner, boolean resume) |
| { |
| if (resume) |
| { |
| _commentNestingDepth = 0; |
| if (scanner instanceof SQLPartitionScanner) |
| { |
| String scanned = ((SQLPartitionScanner) scanner).getScannedPartitionString(); |
| if (scanned != null && scanned.length() > 0) |
| { |
| String startSequence = new String(fStartSequence); |
| int index = 0; |
| while ((index = scanned.indexOf(startSequence, index)) >= 0) |
| { |
| index++; |
| _commentNestingDepth++; |
| } |
| //must be aware of the closing sequences |
| String endSequence = new String(fEndSequence); |
| index = 0; |
| while ((index = scanned.indexOf(endSequence, index)) >= 0) |
| { |
| index++; |
| _commentNestingDepth--; |
| } |
| } |
| } |
| if (endSequenceDetected(scanner)) |
| { |
| return fToken; |
| } |
| |
| } |
| else |
| { |
| |
| int c = scanner.read(); |
| if (c == fStartSequence[0]) |
| { |
| if (sequenceDetected(scanner, fStartSequence, false)) |
| { |
| _commentNestingDepth = 1; |
| if (endSequenceDetected(scanner)) |
| { |
| return fToken; |
| } |
| } |
| } |
| } |
| |
| scanner.unread(); |
| return Token.UNDEFINED; |
| |
| } |
| } |