KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > model > DocumentHandler


1 /*******************************************************************************
2  * Copyright (c) 2003, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.ui.model;
12
13 import java.util.*;
14
15 import org.eclipse.jface.text.*;
16 import org.xml.sax.*;
17 import org.xml.sax.helpers.*;
18
19 public abstract class DocumentHandler extends DefaultHandler {
20
21     protected FindReplaceDocumentAdapter fFindReplaceAdapter;
22     protected Stack fDocumentNodeStack = new Stack();
23     protected int fHighestOffset = 0;
24     private Locator fLocator;
25     
26     public DocumentHandler() {
27     }
28
29     /* (non-Javadoc)
30      * @see org.xml.sax.helpers.DefaultHandler#startDocument()
31      */

32     public void startDocument() throws SAXException {
33         fDocumentNodeStack.clear();
34         fHighestOffset = 0;
35         fFindReplaceAdapter = new FindReplaceDocumentAdapter(getDocument());
36     }
37     
38     /* (non-Javadoc)
39      * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
40      */

41     public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName,
42             Attributes attributes) throws SAXException {
43         IDocumentNode parent = fDocumentNodeStack.isEmpty() ? null : (IDocumentNode)fDocumentNodeStack.peek();
44         IDocumentNode node = getDocumentNode(qName, parent);
45         node.setXMLTagName(qName);
46         try {
47             int nodeOffset = getStartOffset(qName);
48             node.setOffset(nodeOffset);
49             IDocument doc = getDocument();
50             int line = doc.getLineOfOffset(nodeOffset);
51             node.setLineIndent(node.getOffset() - doc.getLineOffset(line));
52             // create attributes
53
for (int i = 0; i < attributes.getLength(); i++) {
54                 String JavaDoc attName = attributes.getQName(i);
55                 String JavaDoc attValue = attributes.getValue(i);
56                 IDocumentAttribute attribute = getDocumentAttribute(attName, attValue, node);
57                 if (attribute != null) {
58                     IRegion region = getAttributeRegion(attName, attValue, nodeOffset);
59                     if (region != null) {
60                         attribute.setNameOffset(region.getOffset());
61                         attribute.setNameLength(attName.length());
62                         attribute.setValueOffset(region.getOffset() + region.getLength() - 1 - attValue.length());
63                         attribute.setValueLength(attValue.length());
64                     }
65                     node.setXMLAttribute(attribute);
66                 }
67             }
68         } catch (BadLocationException e) {
69         }
70         appendChildToParent(parent, node);
71         fDocumentNodeStack.push(node);
72     }
73     
74     protected void appendChildToParent(IDocumentNode parent, IDocumentNode child) {
75         if (parent != null && child != null) {
76             parent.addChildNode(child);
77         }
78     }
79     
80     protected abstract IDocumentNode getDocumentNode(String JavaDoc name, IDocumentNode parent);
81     
82     protected abstract IDocumentAttribute getDocumentAttribute(String JavaDoc name, String JavaDoc value, IDocumentNode parent);
83     
84     private int getStartOffset(String JavaDoc elementName) throws BadLocationException {
85         int line = fLocator.getLineNumber();
86         int col = fLocator.getColumnNumber();
87         IDocument doc = getDocument();
88         if (col < 0)
89             col = doc.getLineLength(line);
90         String JavaDoc text = doc.get(fHighestOffset + 1, doc.getLineOffset(line) - fHighestOffset - 1);
91
92         ArrayList commentPositions = new ArrayList();
93         for (int idx = 0; idx < text.length();) {
94             idx = text.indexOf("<!--", idx); //$NON-NLS-1$
95
if (idx == -1)
96                 break;
97             int end = text.indexOf("-->", idx); //$NON-NLS-1$
98
if (end == -1)
99                 break;
100             
101             commentPositions.add(new Position(idx, end - idx));
102             idx = end + 1;
103         }
104
105         int idx = 0;
106         for (; idx < text.length(); idx += 1) {
107             idx = text.indexOf("<" + elementName, idx); //$NON-NLS-1$
108
if (idx == -1)
109                 break;
110             boolean valid = true;
111             for (int i = 0; i < commentPositions.size(); i++) {
112                 Position pos = (Position)commentPositions.get(i);
113                 if (pos.includes(idx)) {
114                     valid = false;
115                     break;
116                 }
117             }
118             if (valid)
119                 break;
120         }
121         if (idx > -1)
122             fHighestOffset += idx + 1;
123         return fHighestOffset;
124     }
125     
126     private int getElementLength(IDocumentNode node, int line, int column) throws BadLocationException {
127         int endIndex = node.getOffset();
128         IDocument doc = getDocument();
129         int start = Math.max(doc.getLineOffset(line), node.getOffset());
130         column = doc.getLineLength(line);
131         String JavaDoc lineText= doc.get(start, column - start + doc.getLineOffset(line));
132         
133         int index = lineText.indexOf("</" + node.getXMLTagName() + ">"); //$NON-NLS-1$ //$NON-NLS-2$
134
if (index == -1) {
135             index= lineText.indexOf("/>"); //$NON-NLS-1$
136
if (index == -1 ) {
137                 endIndex = column;
138             } else {
139                 endIndex = index + 2;
140             }
141         } else{
142             endIndex = index + node.getXMLTagName().length() + 3;
143         }
144         return start + endIndex - node.getOffset();
145     }
146     
147     private IRegion getAttributeRegion(String JavaDoc name, String JavaDoc value, int offset) throws BadLocationException{
148         IRegion nameRegion = fFindReplaceAdapter.find(offset, name+"\\s*=\\s*\"", true, false, false, true); //$NON-NLS-1$
149
if (nameRegion != null) {
150             if (getDocument().get(nameRegion.getOffset() + nameRegion.getLength(), value.length()).equals(value))
151                 return new Region(nameRegion.getOffset(), nameRegion.getLength() + value.length() + 1);
152         }
153         return null;
154     }
155
156     
157     /* (non-Javadoc)
158      * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
159      */

160     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName)
161             throws SAXException {
162         IDocumentNode node = (IDocumentNode)fDocumentNodeStack.pop();
163         try {
164             node.setLength(getElementLength(node, fLocator.getLineNumber() - 1, fLocator.getColumnNumber()));
165             setTextNodeOffset(node);
166         } catch (BadLocationException e) {
167         }
168     }
169     
170     protected void setTextNodeOffset(IDocumentNode node) throws BadLocationException {
171         IDocumentTextNode textNode = node.getTextNode();
172         if (textNode != null && textNode.getText() != null) {
173             if (textNode.getText().trim().length() == 0) {
174                 node.removeTextNode();
175                 return;
176             }
177             IDocument doc = getDocument();
178             String JavaDoc text = doc.get(node.getOffset(), node.getLength());
179             textNode.setOffset(node.getOffset() + text.indexOf(textNode.getText()));
180             text = doc.get(textNode.getOffset(), node.getLength() - textNode.getOffset() + node.getOffset());
181             int index = text.indexOf('<');
182             for (index -= 1; index >= 0; index--) {
183                 if (!Character.isWhitespace(text.charAt(index))) {
184                     index += 1;
185                     break;
186                 }
187             }
188             textNode.setLength(index);
189             textNode.setText(doc.get(textNode.getOffset(), index));
190         }
191     }
192     
193     /* (non-Javadoc)
194      * @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
195      */

196     public void fatalError(SAXParseException e) throws SAXException {
197         generateErrorElementHierarchy();
198     }
199     
200     /**
201      *
202      */

203     private void generateErrorElementHierarchy() {
204         while (!fDocumentNodeStack.isEmpty()) {
205             ((IDocumentNode)fDocumentNodeStack.pop()).setIsErrorNode(true);
206         }
207     }
208
209     /* (non-Javadoc)
210      * @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
211      */

212     public void error(SAXParseException e) throws SAXException {
213         generateErrorElementHierarchy();
214     }
215     
216     /* (non-Javadoc)
217      * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
218      */

219     public void setDocumentLocator(Locator locator) {
220         fLocator = locator;
221     }
222     
223     protected abstract IDocument getDocument();
224 }
225
Popular Tags