KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > text > syntax > dom > AttrImpl


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.text.syntax.dom;
21
22 import java.util.*;
23 import javax.swing.text.BadLocationException JavaDoc;
24
25 import org.w3c.dom.*;
26 import org.netbeans.modules.xml.text.syntax.*;
27 import org.netbeans.modules.xml.spi.dom.*;
28 import org.netbeans.editor.*;
29
30 /**
31  * Holds attribute: name-value pairs. It is returned by <code>Tag</code>
32  * syntax nodes. Note that attributes are not a part part of DOM Node
33  * hiearchy, but they are rather properties of <code>Element</code>.
34  * It matches well with fact taht attributes are not represented by
35  * <code>SyntaxNode</code>s.
36  *
37  * @author Petr Kuzel
38  * @author asgeir@dimonsoftware.com
39  */

40 public class AttrImpl extends AbstractNode implements Attr, XMLTokenIDs {
41     
42     private TokenItem first;
43     
44     private Element parent;
45     
46     private XMLSyntaxSupport syntax; // that produced us
47

48     AttrImpl(XMLSyntaxSupport syntax, TokenItem first, Element parent) {
49         this.parent = parent;
50         this.first = first;
51         this.syntax = syntax;
52     }
53     
54     public TokenItem getFirstToken() {
55         return first;
56     }
57     
58     /**
59      * @return list of child nodes (Text or EntityReference), never <code>null</code>
60      */

61     public NodeList getChildNodes() {
62         List list = new ArrayList(3);
63         
64         Node node = getFirstChild();
65         while (node != null) {
66             list.add(node);
67             node = node.getNextSibling();
68         }
69         
70         return new NodeListImpl(list);
71     }
72     
73     /**
74      * Get next sibling for non syntax element text.
75      */

76     Node getPreviousSibling(Text text) {
77         return null; //!!! todo
78
}
79     
80     Node getPreviousSibling(EntityReferenceImpl ref) {
81         return null;
82     }
83     
84     // NOTE: This method has to be implemented, unless the getChildNodes() method
85
// will only return the first child node.
86
Node getNextSibling(Text text) {
87         return null;
88     }
89     
90     Node getNextSibling(EntityReferenceImpl ref) {
91         return null;
92     }
93     
94     public Node getNextSibling() {
95         return null; //according to DOM-1spec
96
}
97     
98     public Node getPreviousSibling() {
99         return null; //according to DOM-1 spec
100
}
101     
102     public Node getFirstChild() {
103         TokenItem next = first;
104         for (; next != null; next = next.getNext()) {
105             if (next.getTokenID() == VALUE) {
106                 // fuzziness to relax minor tokenization changes
107
String JavaDoc image = next.getImage();
108                 if (image.length() == 1) {
109                     char test = image.charAt(0);
110                     if (test == '"' || test == '\'') {
111                         next = next.getNext();
112                     }
113                 }
114                 break; // we are after opening "'"
115
}
116         }
117         if (next == null) return null;
118         if (next.getTokenID() == VALUE) {
119             return new TextImpl(syntax, next, this); //!!! strip out ending "'", return standalone "'" token
120
} else {
121             throw new RuntimeException JavaDoc("Not recognized yet: " + next.getTokenID());
122         }
123     }
124     
125     public Node getLastChild() {
126         throw new RuntimeException JavaDoc("Not implemented yet");
127     }
128     
129     public String JavaDoc getNodeName() {
130         return getName();
131     }
132     
133     public String JavaDoc getName() {
134         return first.getImage();
135     }
136     
137     public boolean getSpecified() {
138         return true;
139     }
140     
141     public void setValue(String JavaDoc value) {
142         // Initialize oldValueStartPos and oldValueLength parameters
143
int oldValueStartPos = -1;
144         int oldValueLength = 0;
145         boolean notClosed = false;
146         char firstChar = '"';
147         char lastChar = '\0';
148         TokenItem next = first;
149         for (; next != null; next = next.getNext()) {
150             TokenID nextId = next.getTokenID();
151             
152             if (oldValueStartPos != -1 && nextId != VALUE && nextId != CHARACTER) {
153                 break;
154             }
155             
156             String JavaDoc nextImage = next.getImage();
157             
158             String JavaDoc actualImage = Util.actualAttributeValue(nextImage);
159             if (!nextImage.equals(actualImage)) {
160                 notClosed = true;
161                 nextImage = actualImage;
162             }
163             
164             if (nextId == VALUE && oldValueStartPos == -1 && nextImage.length() > 0) {
165                 oldValueStartPos = next.getOffset();
166                 if (nextImage.charAt(0) == '"' || nextImage.charAt(0) == '\'') {
167                     firstChar = nextImage.charAt(0);
168                     oldValueStartPos++;
169                     oldValueLength--;
170                 }
171             }
172             
173             if (oldValueStartPos != -1 && nextImage.length() > 0) {
174                 oldValueLength += nextImage.length();
175                 lastChar = nextImage.charAt(nextImage.length()-1);
176             }
177             
178             if (notClosed) {
179                 break;
180             }
181         }
182         
183         if (lastChar == firstChar) {
184             oldValueLength--;
185         }
186         
187         // Replace known entities
188
value = Util.replaceCharsWithEntityStrings(value);
189         
190         // Close the attribute if it was non-closed
191
if (notClosed) {
192             value += firstChar;
193         }
194         
195         // Replace the text in the document
196
BaseDocument doc = (BaseDocument)syntax.getDocument();
197         doc.atomicLock();
198         try {
199             doc.remove(oldValueStartPos, oldValueLength);
200             doc.insertString(oldValueStartPos, value, null);
201             doc.invalidateSyntaxMarks();
202         } catch( BadLocationException JavaDoc e ) {
203             throw new DOMException(DOMException.INVALID_STATE_ERR , e.getMessage());
204         } finally {
205             doc.atomicUnlock();
206         }
207         
208         // Update the status of this object
209
try {
210             int endOffset = oldValueStartPos + oldValueLength;
211             if (endOffset > doc.getLength()) {
212                 endOffset = doc.getLength();
213             }
214             first = syntax.getTokenChain(first.getOffset(), endOffset);
215         } catch (BadLocationException JavaDoc e) {
216             throw new DOMException(DOMException.INVALID_STATE_ERR , e.getMessage());
217         }
218     }
219     
220     public void setNodeValue(String JavaDoc value) {
221         setValue(value);
222     }
223     
224     /**
225      * Iterate over children to get value.
226      * @return a String never <code>null</code>
227      */

228     public String JavaDoc getNodeValue() {
229         return getValue();
230     }
231     
232     public String JavaDoc getValue() {
233         // Find the first value token. Should be after "name="
234
TokenItem next = first;
235         for (; next != null; next = next.getNext()) {
236             if (next.getTokenID() == VALUE) {
237                 break;
238             }
239         }
240         
241         // Add values of all value and character entity
242
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
243         while (next.getTokenID() == VALUE || next.getTokenID() == CHARACTER) {
244             String JavaDoc image = next.getImage();
245             String JavaDoc actual = Util.actualAttributeValue(image);
246             if (!image.equals(actual)) {
247                 buf.append(actual);
248                 break;
249             } else {
250                 buf.append(image);
251             }
252             next = next.getNext();
253         }
254         
255         // Remove " and ' around the attribute value
256
if (buf.length() > 0) {
257             char firstChar = buf.charAt(0);
258             if (firstChar == '"' || firstChar == '\'') {
259                 buf.deleteCharAt(0);
260                 if (buf.length() > 0 && buf.charAt(buf.length()-1) == firstChar) {
261                     buf.deleteCharAt(buf.length()-1);
262                 }
263             }
264         }
265         
266         return Util.replaceEntityStringsWithChars(buf.toString());
267     }
268     
269     public short getNodeType() {
270         return Node.ATTRIBUTE_NODE;
271     }
272     
273     public Node getParentNode() {
274         return null; //accordnig to DOM-1 specs
275
}
276     
277     public Element getOwnerElement() {
278         ((Tag)parent).retokenizeObject();
279         return parent;
280     }
281     
282     /**
283      * Get owner document or <code>null</code>
284      */

285     public org.w3c.dom.Document JavaDoc getOwnerDocument() {
286         Node parent = getOwnerElement();
287         if (parent == null) return null;
288         return parent.getOwnerDocument();
289     }
290     
291     /**
292      * Return string representation of the object for debug purposes.
293      */

294     public String JavaDoc toString() {
295         return "Attr(" + getName() + "='" + getValue() + "')";
296     }
297     
298 }
299
Popular Tags