intial source from ttp://www.sf.net/projects/wdte
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.css.ui / src / net / sourceforge / phpeclipse / css / ui / internal / text / CssPairMatcher.java
1 /*
2  * Copyright (c) 2003-2004 Christopher Lenz and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     Christopher Lenz - initial API and implementation
10  * 
11  * $Id: CssPairMatcher.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
12  */
13
14 package net.sourceforge.phpeclipse.css.ui.internal.text;
15
16 import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
17
18 import org.eclipse.jface.text.BadLocationException;
19 import org.eclipse.jface.text.IDocument;
20 import org.eclipse.jface.text.IRegion;
21 import org.eclipse.jface.text.Region;
22 import org.eclipse.jface.text.source.ICharacterPairMatcher;
23 import org.eclipse.jface.util.Assert;
24
25 /**
26  * 
27  */
28 public class CssPairMatcher implements ICharacterPairMatcher {
29
30         // Constants ---------------------------------------------------------------
31
32         private static final char PAIRS[] = {
33                 '{', '}', '(', ')', '[', ']'
34         };
35
36         // Instance Variables ------------------------------------------------------
37
38         private IDocument document;
39
40         private int offset;
41
42         private int anchor;
43
44         // ICharacterPairMatcher Implementation ------------------------------------
45
46         /*
47          * @see ICharacterPairMatcher#clear
48          */
49         public void clear() {
50                 document = null;
51                 offset = -1;
52                 anchor = 0;
53         }
54
55         /*
56          * @see ICharacterPairMatcher#dispose
57          */
58         public void dispose() {
59                 document = null;
60         }
61
62         /*
63          * @see ICharacterPairMatcher#match
64          */
65         public IRegion match(IDocument document, int offset) {
66                 Assert.isNotNull(document);
67                 Assert.isLegal(offset >= 0);
68                 this.document = document;
69                 this.offset = offset;
70
71                 IRegion retVal = null;
72                 try {
73                         retVal = matchPairsAt();
74                 } catch (BadLocationException e) {
75                         // ignore, there's probably no matching character to highlight
76                 }
77                 return retVal;
78         }
79
80         /*
81          * @see ICharacterPairMatcher#getAnchor
82          */
83         public int getAnchor() {
84                 return anchor;
85         }
86
87         // Private Methods ---------------------------------------------------------
88
89         private boolean isClosingCharacter(char ch) {
90                 for (int i = 1; i < PAIRS.length; i += 2) {
91                         if (ch == PAIRS[i]) {
92                                 return true;
93                         }
94                 }
95                 return false;
96         }
97
98         private boolean isOpeningCharacter(char ch) {
99                 for (int i = 0; i < PAIRS.length; i += 2) {
100                         if (ch == PAIRS[i]) {
101                                 return true;
102                         }
103                 }
104                 return false;
105         }
106
107         private IRegion matchPairsAt() throws BadLocationException {
108                 int startPos = -1, endPos = -1;
109                 char prevChar = document.getChar(Math.max(offset - 1, 0));
110                 if (isOpeningCharacter(prevChar)) {
111                         startPos = offset - 1;
112                         if (startPos >= 0) {
113                                 anchor = LEFT;
114                                 endPos = CssTextUtils.findMatchingClosingPeer(
115                                         document, startPos + 1, prevChar);
116                                 if (endPos > -1) {
117                                         return new Region(startPos, endPos - startPos + 1);
118                                 }
119                         }
120                 }
121                 if (isClosingCharacter(prevChar)) {
122                         endPos = offset - 1;
123                         if (endPos >= 0) {
124                                 anchor = RIGHT;
125                                 startPos = CssTextUtils.findMatchingOpeningPeer(
126                                         document, endPos - 1, prevChar);
127                                 if (startPos > -1) {
128                                         return new Region(startPos, endPos - startPos + 1);
129                                 }
130                         }
131                 } 
132                 return null;
133         }
134
135 }