KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > ui > compare > XMLStructureCreator


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.compare;
12
13 import java.io.BufferedReader JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.io.InputStreamReader JavaDoc;
17 import java.io.StringReader JavaDoc;
18 import java.io.UnsupportedEncodingException JavaDoc;
19 import com.ibm.icu.text.MessageFormat;
20 import java.util.HashMap JavaDoc;
21
22 import javax.xml.parsers.SAXParser JavaDoc;
23 import javax.xml.parsers.SAXParserFactory JavaDoc;
24
25 import org.eclipse.compare.IEditableContent;
26 import org.eclipse.compare.IEncodedStreamContentAccessor;
27 import org.eclipse.compare.IStreamContentAccessor;
28 import org.eclipse.compare.structuremergeviewer.IStructureComparator;
29 import org.eclipse.compare.structuremergeviewer.IStructureCreator;
30 import org.eclipse.core.runtime.CoreException;
31 import org.eclipse.jface.text.BadLocationException;
32 import org.eclipse.jface.text.Document;
33 import org.eclipse.jface.text.IDocument;
34 import org.eclipse.jface.text.IRegion;
35 import org.eclipse.jface.text.Position;
36 import org.eclipse.osgi.util.NLS;
37 import org.eclipse.pde.internal.ui.PDEPlugin;
38 import org.xml.sax.Attributes JavaDoc;
39 import org.xml.sax.InputSource JavaDoc;
40 import org.xml.sax.Locator JavaDoc;
41 import org.xml.sax.SAXException JavaDoc;
42 import org.xml.sax.SAXParseException JavaDoc;
43 import org.xml.sax.helpers.DefaultHandler JavaDoc;
44 import org.xml.sax.helpers.LocatorImpl JavaDoc;
45
46 /**
47  * This structure analyzer builds a parse tree of an XML document found in a
48  * <code>IByteContentAccessor</code> input by calling getStructure(Object)
49  */

50 public class XMLStructureCreator implements IStructureCreator {
51
52     protected static final boolean DEBUG_MODE = true;
53     public static final String JavaDoc DEFAULT_NAME = "XML Compare"; //$NON-NLS-1$
54
public static final String JavaDoc USE_UNORDERED = "Unordered"; //$NON-NLS-1$
55
public static final String JavaDoc USE_ORDERED = "Ordered"; //$NON-NLS-1$
56

57     public static final String JavaDoc DEFAULT_IDMAP = XMLStructureMapping.ECLIPSE_PLUGIN;
58     public static final String JavaDoc TYPE_ROOT = "plugin"; //$NON-NLS-1$
59
public static final String JavaDoc TYPE_EXTENSION = "extension"; //$NON-NLS-1$
60
public static final String JavaDoc TYPE_EXTENSIONPOINT = "extension-point"; //$NON-NLS-1$
61
public static final String JavaDoc TYPE_ELEMENT = "element"; //$NON-NLS-1$
62
public static final String JavaDoc TYPE_TEXT = "text"; //$NON-NLS-1$
63
public static final String JavaDoc TYPE_ATTRIBUTE = "attribute"; //$NON-NLS-1$
64

65     // for signatures
66
public static final String JavaDoc ROOT_ID = "root"; //$NON-NLS-1$
67
public static final char SIGN_SEPARATOR = '>';//'.'
68
public static final char SIGN_ENCLOSING = '$';
69     public static final String JavaDoc SIGN_ELEMENT = SIGN_ENCLOSING + TYPE_ELEMENT + SIGN_ENCLOSING;
70     public static final String JavaDoc SIGN_TEXT = SIGN_ENCLOSING + TYPE_TEXT + SIGN_ENCLOSING;
71     public static final String JavaDoc SIGN_ATTRIBUTE = SIGN_ENCLOSING + TYPE_ATTRIBUTE + SIGN_ENCLOSING;
72     public static final char ID_SEPARATOR = '<';
73     public static final char ID_TYPE_BODY = '<';
74
75     private XMLNode fCurrentParent;
76     private String JavaDoc fSignature;
77     private Document fDoc;
78     private boolean ignoreBodies = false;
79     private HashMap JavaDoc fIdMapsInternal;
80     private HashMap JavaDoc idMap;
81     private String JavaDoc fIdMapToUse;
82     private boolean fRemoveWhiteSpace;
83
84     protected class XMLHandler extends DefaultHandler JavaDoc {
85
86         protected Locator JavaDoc prevlocator; //previous locator
87
protected Locator JavaDoc locator; //current locator
88

89         public void setDocumentLocator(Locator JavaDoc locator) {
90             this.locator = locator;
91         }
92
93         public void processingInstruction(String JavaDoc target, String JavaDoc data) {
94             prevlocator = new LocatorImpl JavaDoc(locator);
95         }
96
97         public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId) throws SAXException JavaDoc {
98             // Prevent the resolution of external entities in order to
99
// prevent the parser from accessing the Internet
100
// This will prevent huge workbench performance degradations and hangs
101
return new InputSource JavaDoc(new StringReader JavaDoc("")); //$NON-NLS-1$
102
}
103         
104         public void startDocument() {
105             prevlocator = new LocatorImpl JavaDoc(locator);
106         }
107
108         public void startElement(String JavaDoc uri, String JavaDoc local, String JavaDoc raw, Attributes JavaDoc attrs) {
109             /* add root node for this element */
110             if (XMLStructureCreator.DEBUG_MODE) {
111                 if (locator != null && prevlocator != null) {
112                     System.out.println("prevlocator: line " + prevlocator.getLineNumber() + " column " + prevlocator.getColumnNumber() + " id " + prevlocator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
113
System.out.println("locator: line " + locator.getLineNumber() + " column " + locator.getColumnNumber() + " id " + locator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
114
}
115             }
116
117             try {
118                 if (XMLStructureCreator.DEBUG_MODE)
119                     System.out.println("Node where children field accessed: " + fCurrentParent.getId()); //$NON-NLS-1$
120
XMLChildren currentParent = (XMLChildren) fCurrentParent;
121                 currentParent.children++;
122                 String JavaDoc elementId;
123                 String JavaDoc elementName;
124                 IRegion r = fDoc.getLineInformation(prevlocator.getLineNumber() - 1);
125
126                 fSignature = fSignature + raw + SIGN_SEPARATOR;
127
128                 if (idMap.containsKey(fSignature)) {
129                     String JavaDoc attrName = (String JavaDoc) idMap.get(fSignature);
130                     String JavaDoc attrValue = attrs.getValue(attrName);
131                     elementId = raw + new Character JavaDoc(ID_SEPARATOR) + attrValue;
132                     elementName = raw;
133                     if (attrValue != null)
134                         elementName += " [" + attrName + "=" + attrs.getValue(attrName) + "]"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
135
} else {
136                     if (!currentParent.childElements.containsKey(raw)) {
137                         currentParent.childElements.put(raw, new Integer JavaDoc(1));
138                     } else {
139                         currentParent.childElements.put(raw, new Integer JavaDoc(((Integer JavaDoc) currentParent.childElements.get(raw)).intValue() + 1));
140                     }
141                     elementId = raw + new Character JavaDoc(ID_SEPARATOR) + "[" + currentParent.childElements.get(raw) + "]"; //$NON-NLS-2$ //$NON-NLS-1$
142
elementName = MessageFormat.format("{0} [{1}]", new String JavaDoc[] { raw, currentParent.childElements.get(raw).toString() }); //$NON-NLS-1$
143
}
144                 int start = r.getOffset() + prevlocator.getColumnNumber() - 1;
145                 if (start < 0)
146                     start = 0;
147                 String JavaDoc type = TYPE_ELEMENT;
148                 if (currentParent.getId() == ROOT_ID && elementName.startsWith(TYPE_ROOT))
149                     type = TYPE_ROOT;
150                 else if (currentParent.getXMLType().equals(TYPE_ROOT)) {
151                     if (elementName.startsWith(TYPE_EXTENSIONPOINT))
152                         type = TYPE_EXTENSIONPOINT;
153                     else if (elementName.startsWith(TYPE_EXTENSION))
154                         type = TYPE_EXTENSION;
155                 }
156                 XMLNode currentElement = new XMLChildren(type, elementId, elementId,
157                         (fSignature + SIGN_ELEMENT), fDoc, start, 0);
158                 currentElement.setName(elementName);
159                 if (idMap.containsKey(fSignature))
160                     currentElement.setUsesIDMAP(true);
161             
162                 fCurrentParent.addChild(currentElement);
163                 currentElement.setParent(fCurrentParent);
164                 fCurrentParent = currentElement;
165                 if (XMLStructureCreator.DEBUG_MODE)
166                     System.out.println("\nAdded Element " + raw + " with offset " + r.getOffset()); //$NON-NLS-2$ //$NON-NLS-1$
167
if (XMLStructureCreator.DEBUG_MODE)
168                     System.out.println("fcurrentParent1: " + fCurrentParent.getId()); //$NON-NLS-1$
169

170                 if (attrs != null) {
171                     if (XMLStructureCreator.DEBUG_MODE)
172                         System.out.println("attrs != null, fcurrentParent is " + fCurrentParent.getId()); //$NON-NLS-1$
173
int len = attrs.getLength();
174                     int element_lines_length_size;
175                     int[] element_lines_length;
176                     int column_offset;
177                     String JavaDoc element_string;
178                     if (fCurrentParent.getParent().getId().equals(ROOT_ID)) {
179                         element_lines_length_size = locator.getLineNumber() - prevlocator.getLineNumber();
180                         element_lines_length = new int[element_lines_length_size];
181                         column_offset = 0;
182                         element_string = ""; //$NON-NLS-1$
183
for (int i_ell = 0; i_ell < element_lines_length.length; i_ell++) {
184                             IRegion attr_r = fDoc.getLineInformation(i_ell + prevlocator.getLineNumber());
185                             element_lines_length[i_ell] = fDoc.get(attr_r.getOffset(), attr_r.getLength()).length() + 1;
186                             element_string = element_string + fDoc.get(attr_r.getOffset(), attr_r.getLength()) + " "; //$NON-NLS-1$
187
}
188                     } else {
189                         element_lines_length_size = locator.getLineNumber() - prevlocator.getLineNumber() + 1;
190                         //if (element_lines_length_size < 1)
191
// element_lines_length_size = 1;
192
element_lines_length = new int[element_lines_length_size];
193                         IRegion first_line = fDoc.getLineInformation(prevlocator.getLineNumber() - 1);
194                         column_offset = prevlocator.getColumnNumber() - 1;
195                         int first_line_relevant_offset = first_line.getOffset() + column_offset;
196                         int first_line_relevant_length = first_line.getLength() - column_offset;
197                         element_string = fDoc.get(first_line_relevant_offset, first_line_relevant_length) + " "; //$NON-NLS-1$
198
element_lines_length[0] = element_string.length();
199                         for (int i_ell = 1; i_ell < element_lines_length.length; i_ell++) {
200                             IRegion attr_r = fDoc.getLineInformation(i_ell + prevlocator.getLineNumber() - 1);
201                             element_lines_length[i_ell] = fDoc.get(attr_r.getOffset(), attr_r.getLength()).length() + 1;
202                             element_string = element_string + fDoc.get(attr_r.getOffset(), attr_r.getLength()) + " "; //$NON-NLS-1$
203
}
204                     }
205
206                     for (int i_attr = 0; i_attr < len; i_attr++) {
207                         String JavaDoc attr_name = attrs.getQName(i_attr);
208                         String JavaDoc attr_value = attrs.getValue(i_attr);
209
210                         /*
211                          * find range of attribute in doc; manually parses the
212                          * line
213                          */

214                         boolean found = false;
215                         int first_quotes = -1;
216                         int second_quotes = -1;
217                         int id_index = -1;
218                         while (!found) {
219                             first_quotes = element_string.indexOf("\"", second_quotes + 1); //$NON-NLS-1$
220
second_quotes = element_string.indexOf("\"", first_quotes + 1); //$NON-NLS-1$
221
String JavaDoc value;
222                             try {
223                                 value = element_string.substring(first_quotes + 1, second_quotes);
224                             } catch (Exception JavaDoc e) {
225                                 value = ""; //$NON-NLS-1$
226
}
227                             if (value.equals("")) //$NON-NLS-1$
228
found = true;
229                             else if (value.equals(attr_value)) {
230                                 id_index = element_string.lastIndexOf(attr_name, first_quotes - 1);
231                                 boolean wrong = false;
232                                 boolean found_equal = false;
233                                 for (int i_char = id_index + attr_name.length(); i_char < first_quotes && !wrong; i_char++) {
234                                     if (element_string.charAt(i_char) == '=')
235                                         if (!found_equal)
236                                             found_equal = true;
237                                         else
238                                             wrong = true;
239                                     else if (!Character.isWhitespace(element_string.charAt(i_char)))
240                                         wrong = true;
241                                 }
242                                 if (!wrong)
243                                     found = true;
244                             }
245                         }
246                         //id_index has one char missing for every line (the
247
// final cr)
248
int line_of_index = 0;
249                         for (line_of_index = 0; id_index > element_lines_length[line_of_index] - 1; line_of_index++)
250                             id_index -= (element_lines_length[line_of_index]);
251                         if (line_of_index == 0)
252                             id_index += column_offset;
253                         if (fCurrentParent.getParent().getId().equals(ROOT_ID))
254                             line_of_index += prevlocator.getLineNumber();
255                         else
256                             line_of_index += prevlocator.getLineNumber() - 1;
257                         //index at line line_of_index, line offset id_index
258
int line_of_end_of_value = 0;
259                         int end_of_value_index = second_quotes;
260                         for (line_of_end_of_value = 0; end_of_value_index > element_lines_length[line_of_end_of_value] - 1; line_of_end_of_value++)
261                             end_of_value_index -= (element_lines_length[line_of_end_of_value]);
262                         if (line_of_end_of_value == 0)
263                             end_of_value_index += column_offset;
264                         if (fCurrentParent.getParent().getId().equals(ROOT_ID))
265                             line_of_end_of_value += prevlocator.getLineNumber();
266                         else
267                             line_of_end_of_value += prevlocator.getLineNumber() - 1;
268                         //end of value at line line_of_end_of_value, line
269
// offset end_of_value_index
270

271                         int attr_start_doc_offset = fDoc.getLineInformation(line_of_index).getOffset() + id_index;
272                         //int attr_length_doc_offset =
273
// fdoc.getLineInformation(line_of_value).getOffset()+value_index+attr_value.length()+1+(line_of_end_of_value-line_of_index)
274
// - attr_start_doc_offset;
275
int attr_length_doc_offset = fDoc.getLineInformation(line_of_end_of_value).getOffset() + end_of_value_index + 1 - attr_start_doc_offset;
276                         currentElement = new XMLNode(TYPE_ATTRIBUTE, attr_name, attr_value, (fSignature + attr_name + SIGN_SEPARATOR + SIGN_ATTRIBUTE), fDoc, attr_start_doc_offset, attr_length_doc_offset);
277                         currentElement.setName(attr_name);
278                         fCurrentParent.addChild(currentElement);
279                         currentElement.setParent(fCurrentParent);
280                         if (XMLStructureCreator.DEBUG_MODE)
281                             System.out.println("added attribute " + currentElement.getId() + " with value >" + currentElement.getValue() + "<" + " to element " + fCurrentParent.getId() + " which has parent " + fCurrentParent.getParent().getId()); //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
282
}
283                 }
284             } catch (BadLocationException ex) {
285                 if (XMLStructureCreator.DEBUG_MODE)
286                     System.out.println("BadLocationException in startElement(...) " + ex); //$NON-NLS-1$
287
new XMLChildren(TYPE_ELEMENT, raw+ "_(" + ((XMLChildren) fCurrentParent).children + ")", raw + "_(" + ((XMLChildren) fCurrentParent).children + ")", (fSignature + SIGN_ELEMENT), fDoc, 0, 0); //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
288
}
289             if (XMLStructureCreator.DEBUG_MODE)
290                 System.out.println("At the end of startElement(...), fcurrentParent is " + fCurrentParent.getId()); //$NON-NLS-1$
291
prevlocator = new LocatorImpl JavaDoc(locator);
292         }
293
294         public void characters(char ch[], int start, int length) {
295             if (!ignoreBodies) {
296                 String JavaDoc chars = new String JavaDoc(ch, start, length);
297                 if (XMLStructureCreator.DEBUG_MODE)
298                     System.out.println("characters: >" + chars + "<"); //$NON-NLS-2$ //$NON-NLS-1$
299
if (XMLStructureCreator.DEBUG_MODE)
300                     System.out.println("Body Location: line " + locator.getLineNumber() + " column " + locator.getColumnNumber()); //$NON-NLS-2$ //$NON-NLS-1$
301

302                 //if text contains only white space, it will be ignored.
303
if (!trimWhiteSpace(chars).equals("")) { //$NON-NLS-1$
304
if (XMLStructureCreator.DEBUG_MODE)
305                         System.out.println("Adding body"); //$NON-NLS-1$
306
try {
307                         IRegion r = fDoc.getLineInformation(locator.getLineNumber() - 1);
308                         //location returns the END of the characters
309
//offset of BEGINNING of characters:
310
int offset = r.getOffset() + locator.getColumnNumber() - 1 - length;
311                         fCurrentParent.bodies++;
312                         String JavaDoc body_value = new String JavaDoc(ch, start, length);
313                         if (fRemoveWhiteSpace) {
314                             body_value = removeWhiteSpace(body_value);
315                         }
316                         XMLNode bodynode = new XMLNode(TYPE_TEXT, "body_(" + fCurrentParent.bodies + ")", body_value, (fSignature + SIGN_TEXT), fDoc, offset, length); //$NON-NLS-2$ //$NON-NLS-1$
317
bodynode.setName(NLS.bind("{0} ({1})", "body", Integer.toString(fCurrentParent.bodies))); //$NON-NLS-1$ //$NON-NLS-2$
318
fCurrentParent.addChild(bodynode);
319                         bodynode.setParent(fCurrentParent);
320                         if (XMLStructureCreator.DEBUG_MODE)
321                             System.out.println("Created body " + fCurrentParent.bodies //$NON-NLS-1$
322
+ " with offset " + offset + " and length " + length //$NON-NLS-2$ //$NON-NLS-1$
323
+ " with parent " + bodynode.getParent().getId()); //$NON-NLS-1$
324
//bodies as id attributes
325
String JavaDoc popsig = fCurrentParent.getParent().getSignature(); //signature of parent of
326
// parent
327
popsig = popsig.substring(0, popsig.lastIndexOf(SIGN_ELEMENT));
328                         if (fCurrentParent.bodies == 1 && idMap.containsKey(popsig)) {
329                             String JavaDoc pid = fCurrentParent.getId();//id of parent
330
String JavaDoc pelementname = pid.substring(0, pid.indexOf("<")); //name of parent element //$NON-NLS-1$
331
if (((String JavaDoc) idMap.get(popsig)).equals(ID_TYPE_BODY + pelementname)) {
332                                 XMLNode pop = fCurrentParent.getParent();
333                                 String JavaDoc popid = pop.getId();
334                                 String JavaDoc popelementname = popid.substring(0, popid.indexOf("<")); //$NON-NLS-1$
335
pop.setId(popelementname + "<" + body_value); //$NON-NLS-1$
336
pop.setOrigId(popelementname + "<" + body_value); //$NON-NLS-1$
337
pop.setName(MessageFormat.format("{0} [{1}={2}]", new String JavaDoc[] { popelementname, pelementname, body_value })); //$NON-NLS-1$
338
pop.setUsesIDMAP(true);
339                             }
340                         }
341                     } catch (BadLocationException ex) {
342                         if (XMLStructureCreator.DEBUG_MODE)
343                             System.out.println("BadLocationException in characters(...) " + ex); //$NON-NLS-1$
344
fCurrentParent.addChild(new XMLNode(TYPE_TEXT,"body_(" + fCurrentParent.bodies + ")", new String JavaDoc(ch, start, length), (fSignature + SIGN_TEXT), fDoc, 0, 0)); //$NON-NLS-2$ //$NON-NLS-1$
345
}
346                 }
347             }
348             prevlocator = new LocatorImpl JavaDoc(locator);
349         }
350
351         public void ignorableWhitespace(char ch[], int start, int length) {
352             prevlocator = new LocatorImpl JavaDoc(locator);
353         }
354
355         public void endElement(String JavaDoc uri, String JavaDoc local, String JavaDoc raw) {
356             if (XMLStructureCreator.DEBUG_MODE)
357                 System.out.println("\nExiting element " + fCurrentParent.getId()); //$NON-NLS-1$
358

359             if (XMLStructureCreator.DEBUG_MODE)
360                 System.out.println("prevlocator: line " + prevlocator.getLineNumber() + " column " + prevlocator.getColumnNumber() + " id " + prevlocator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
361
if (XMLStructureCreator.DEBUG_MODE)
362                 System.out.println("locator: line " + locator.getLineNumber() + " column " + locator.getColumnNumber() + " id " + locator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
363

364             if (fCurrentParent.getParent() != null) {
365                 try {
366                     IRegion r2 = fDoc.getLineInformation(locator.getLineNumber() - 1);
367                     Position pos = fCurrentParent.getRange();
368
369                     int elem_length = r2.getOffset() + locator.getColumnNumber() - 1 - pos.getOffset();//length of element from
370
// start tag to end tag
371
fCurrentParent.setLength(elem_length);
372                     if (XMLStructureCreator.DEBUG_MODE)
373                         System.out.println("pos.getOffset: " + pos.getOffset() + " elem_length: " + elem_length); //$NON-NLS-2$ //$NON-NLS-1$
374
if (XMLStructureCreator.DEBUG_MODE)
375                         System.out.println("fdoc.get(pos.getOffset()+elem_length-5,4): >" + fDoc.get(pos.getOffset() + elem_length - 5, 4) + "<"); //$NON-NLS-2$ //$NON-NLS-1$
376

377                     try {
378                         fCurrentParent.setValue(fDoc.get(pos.getOffset(), elem_length));
379                     } catch (BadLocationException ex) {
380                         try {
381                             fCurrentParent.setValue(fDoc.get(pos.getOffset(), elem_length - 1));
382                         } catch (BadLocationException ex2) {
383                             if (XMLStructureCreator.DEBUG_MODE) {
384                                 System.out.println("BadLocationException in endElement(...) while attempting fcurrentParent.setValue(...): " + ex); //$NON-NLS-1$
385
System.out.println("Attempt to correct BadLocationException failed: " + ex2); //$NON-NLS-1$
386
}
387                         }
388                     }
389                     if (XMLStructureCreator.DEBUG_MODE)
390                         System.out.println("Value of " + fCurrentParent.getId() + " is >" + fCurrentParent.getValue() + "<"); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
391

392                     //going from ending element to parent element
393
fCurrentParent = fCurrentParent.getParent();
394                     if (XMLStructureCreator.DEBUG_MODE)
395                         System.out.println("fcurrentParent = fcurrentParent.getParent();"); //$NON-NLS-1$
396
} catch (BadLocationException ex) {
397                     if (XMLStructureCreator.DEBUG_MODE) {
398                         System.out.println("BadLocationException in endElement(...): " + ex); //$NON-NLS-1$
399
System.out.println("fcurrentParent.getId(): " + fCurrentParent.getId()); //$NON-NLS-1$
400
}
401                 }
402             } else {
403                 if (XMLStructureCreator.DEBUG_MODE)
404                     System.out.println("Error: Cannot reach Parent of Parent"); //$NON-NLS-1$
405
}
406             if (XMLStructureCreator.DEBUG_MODE)
407                 System.out.println("fcurrentParent is now " + fCurrentParent.getId()); //$NON-NLS-1$
408

409             prevlocator = new LocatorImpl JavaDoc(locator);
410             if (XMLStructureCreator.DEBUG_MODE)
411                 System.out.println("Signature before cutting: " + fSignature); //$NON-NLS-1$
412
int ssi = fSignature.lastIndexOf(SIGN_SEPARATOR);
413             // second-last
414
// separator index
415
ssi = fSignature.lastIndexOf(SIGN_SEPARATOR, ssi - 1);
416             
417             fSignature = fSignature.substring(0, ssi + 1);
418             if (XMLStructureCreator.DEBUG_MODE)
419                 System.out.println("Signature after cutting: " + fSignature); //$NON-NLS-1$
420
}
421
422         //
423
// ErrorHandler methods
424
//
425

426         /* Warning. */
427         public void warning(SAXParseException JavaDoc ex) {
428             System.err.println("[Warning] " + //$NON-NLS-1$
429
getLocationString(ex) + ": " + //$NON-NLS-1$
430
ex.getMessage());
431         }
432
433         /* Error. */
434         public void error(SAXParseException JavaDoc ex) {
435             System.err.println("[Error] " + //$NON-NLS-1$
436
getLocationString(ex) + ": " + //$NON-NLS-1$
437
ex.getMessage());
438         }
439
440         /* Fatal error. */
441         public void fatalError(SAXParseException JavaDoc ex) throws SAXException JavaDoc {
442             System.err.println("[Fatal Error] " + //$NON-NLS-1$
443
getLocationString(ex) + ": " + //$NON-NLS-1$
444
ex.getMessage());
445             //System.out.println(ex);
446
//throw ex;
447
}
448
449         /* Returns a string of the location. */
450         private String JavaDoc getLocationString(SAXParseException JavaDoc ex) {
451             StringBuffer JavaDoc str = new StringBuffer JavaDoc();
452
453             String JavaDoc systemId = ex.getSystemId();
454             if (systemId != null) {
455                 int index = systemId.lastIndexOf('/');
456                 if (index != -1)
457                     systemId = systemId.substring(index + 1);
458                 str.append(systemId);
459             }
460             str.append(':');
461             str.append(ex.getLineNumber());
462             str.append(':');
463             str.append(ex.getColumnNumber());
464
465             return str.toString();
466
467         }
468     }
469
470     public XMLStructureCreator() {
471         // set default idmap
472
fIdMapToUse = DEFAULT_IDMAP;
473         fIdMapsInternal = XMLStructureMapping.getMappings();
474         fRemoveWhiteSpace = false;
475     }
476
477     /*
478      * This title will be shown in the title bar of the structure compare pane.
479      */

480     public String JavaDoc getName() {
481         return DEFAULT_NAME;
482     }
483
484     /*
485      * Set File extension of the parsed file. This extension will be used to choose an Id Map scheme.
486      */

487     public void setFileExtension(String JavaDoc ext) {
488         if (ext.equals("xml")) //$NON-NLS-1$
489
setIdMap(XMLStructureMapping.ECLIPSE_PLUGIN);
490         else if (ext.equals("exsd")) //$NON-NLS-1$
491
setIdMap(XMLStructureMapping.ECLIPSE_SCHEMA);
492     }
493
494     /**
495      * Initialize the Id Mappings for the Id Mapping Scheme and the Ordered Elements
496      * This method must be called before getStructure(Object) is called on the two/three inputs of the compare
497      */

498     public void initIdMaps() {
499         if (fIdMapsInternal.containsKey(fIdMapToUse)) {
500             idMap = (HashMap JavaDoc) fIdMapsInternal.get(fIdMapToUse);
501         } else {
502             idMap = new HashMap JavaDoc();
503         }
504
505     }
506
507     /*
508      * Returns the XML parse tree of the input.
509      */

510     public IStructureComparator getStructure(Object JavaDoc input) {
511         if (XMLStructureCreator.DEBUG_MODE)
512             System.out.println("Starting parse"); //$NON-NLS-1$
513

514         if (!(input instanceof IStreamContentAccessor))
515             return null;
516
517         IStreamContentAccessor sca = (IStreamContentAccessor) input;
518
519         try {
520             String JavaDoc contents = readString(sca);
521             if (contents == null)
522                 contents = ""; //$NON-NLS-1$
523
fDoc = new Document(contents);
524
525             fSignature = ROOT_ID + SIGN_SEPARATOR;
526             XMLChildren root = new XMLChildren(TYPE_ELEMENT, ROOT_ID, "", (fSignature + SIGN_ELEMENT), fDoc, 0, fDoc.getLength()); //$NON-NLS-1$
527
fCurrentParent = root;
528
529             XMLHandler handler = new XMLHandler();
530
531             try {
532                 SAXParserFactory JavaDoc factory = SAXParserFactory.newInstance();
533                 SAXParser JavaDoc parser = factory.newSAXParser();
534                 parser.parse(new InputSource JavaDoc(new StringReader JavaDoc(contents)), handler);
535
536                 if (XMLStructureCreator.DEBUG_MODE)
537                     System.out.println("End of parse"); //$NON-NLS-1$
538
} catch (SAXParseException JavaDoc e) {
539                 PDEPlugin.log(e);
540                 return null;
541             } catch (Exception JavaDoc e) {
542                 PDEPlugin.log(e);
543                 return null;
544             }
545             return root;
546         } catch (CoreException ex) {
547             PDEPlugin.log(ex);
548         }
549         return null;
550     }
551
552     public void save(IStructureComparator structure, Object JavaDoc input) {
553         if (input instanceof IEditableContent && structure instanceof XMLNode) {
554             IDocument document = ((XMLNode) structure).getDocument();
555             IEditableContent bca = (IEditableContent) input;
556             String JavaDoc contents = document.get();
557             String JavaDoc encoding = null;
558             if (input instanceof IEncodedStreamContentAccessor) {
559                 try {
560                     encoding = ((IEncodedStreamContentAccessor) input).getCharset();
561                 } catch (CoreException e) {
562                     // ignore
563
}
564             }
565             if (encoding == null)
566                 encoding = "UTF-8"; //$NON-NLS-1$
567
try {
568                 bca.setContent(contents.getBytes(encoding));
569             } catch (UnsupportedEncodingException JavaDoc e) {
570                 bca.setContent(contents.getBytes());
571             }
572         }
573     }
574
575     public String JavaDoc getContents(Object JavaDoc node, boolean ignoreWhitespace) {
576         if (node instanceof XMLNode) {
577             String JavaDoc s = ((XMLNode) node).getValue();
578             if (ignoreWhitespace)
579                 s = s.trim();
580             return s;
581         }
582         return null;
583     }
584
585     public IStructureComparator locate(Object JavaDoc path, Object JavaDoc source) {
586         return null;
587     }
588
589     static String JavaDoc readString(IStreamContentAccessor sa) throws CoreException {
590         InputStream JavaDoc is = sa.getContents();
591         String JavaDoc encoding = null;
592         if (sa instanceof IEncodedStreamContentAccessor)
593             encoding = ((IEncodedStreamContentAccessor) sa).getCharset();
594         if (encoding == null)
595             encoding = "UTF-8"; //$NON-NLS-1$
596
return readString(is, encoding);
597     }
598
599     /*
600      * Returns null if an error occurred.
601      */

602     private static String JavaDoc readString(InputStream JavaDoc is, String JavaDoc encoding) {
603         if (is == null)
604             return null;
605         BufferedReader JavaDoc reader = null;
606         try {
607             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
608             char[] part = new char[2048];
609             int read = 0;
610             reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(is, encoding));
611
612             while ((read = reader.read(part)) != -1)
613                 buffer.append(part, 0, read);
614
615             return buffer.toString();
616
617         } catch (IOException JavaDoc ex) {
618             // NeedWork
619
} finally {
620             if (reader != null) {
621                 try {
622                     reader.close();
623                 } catch (IOException JavaDoc ex) {
624                     // silently ignored
625
}
626             }
627         }
628         return null;
629     }
630
631     protected Attributes JavaDoc sortAttributes(Attributes JavaDoc attrs) {
632         AttributesImpl attributes = new AttributesImpl();
633         int len = (attrs != null) ? attrs.getLength() : 0;
634         for (int i = 0; i < len; i++) {
635             String JavaDoc name = attrs.getQName(i);
636             int count = attributes.getLength();
637             int j = 0;
638             while (j < count) {
639                 if (name.compareTo(attributes.getQName(j)) < 0)
640                     break;
641                 j++;
642             }
643             attributes.insertAttributeAt(j, name, attrs.getType(i), attrs.getValue(i));
644         }
645         return attributes;
646
647     }
648
649     public void setIdMap(String JavaDoc idmap) {
650         fIdMapToUse = idmap;
651     }
652
653     public String JavaDoc getIdMap() {
654         return fIdMapToUse;
655     }
656
657     protected boolean isWhiteSpace(char c) {
658         return c == '\t' || c == '\n' || c == '\r' || c == ' ';
659     }
660
661     protected String JavaDoc removeWhiteSpace(String JavaDoc str) {
662         str = trimWhiteSpace(str);
663         StringBuffer JavaDoc retStr = new StringBuffer JavaDoc();
664         int start = 0, end = 0;
665         outer_while: while (true) {
666             while (end < str.length() && !isWhiteSpace(str.charAt(end))) {
667                 end++;
668             }
669             if (end > str.length())
670                 break outer_while;
671             if (start != 0)
672                 retStr.append(' ');
673             retStr.append(str.substring(start, end));
674             end++;
675             while (end < str.length() && isWhiteSpace(str.charAt(end))) {
676                 end++;
677             }
678             start = end;
679         }
680         return retStr.toString();
681     }
682
683     protected String JavaDoc trimWhiteSpace(String JavaDoc str) {
684         int start = 0, end = str.length() - 1;
685         while (start < str.length() && isWhiteSpace(str.charAt(start))) {
686             start++;
687         }
688         if (start == str.length())
689             return ""; //$NON-NLS-1$
690
while (end >= 0 && isWhiteSpace(str.charAt(end))) {
691             end--;
692         }
693         return str.substring(start, end + 1);
694     }
695
696     public void setRemoveWhiteSpace(boolean removeWhiteSpace) {
697         fRemoveWhiteSpace = removeWhiteSpace;
698     }
699
700     public boolean getRemoveWhiteSpace() {
701         return fRemoveWhiteSpace;
702     }
703     
704 }
705
Popular Tags