KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > compare > PropertiesStructureCreator


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.jdt.internal.ui.compare;
12
13 import java.io.IOException JavaDoc;
14
15 import org.eclipse.core.runtime.CoreException;
16 import org.eclipse.core.runtime.IAdaptable;
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.core.runtime.IStatus;
19 import org.eclipse.core.runtime.NullProgressMonitor;
20 import org.eclipse.core.runtime.OperationCanceledException;
21 import org.eclipse.core.runtime.Status;
22 import org.eclipse.core.runtime.SubProgressMonitor;
23
24 import org.eclipse.swt.graphics.Image;
25
26 import org.eclipse.jface.text.BadLocationException;
27 import org.eclipse.jface.text.IDocument;
28 import org.eclipse.jface.text.IDocumentPartitioner;
29 import org.eclipse.jface.text.IRegion;
30 import org.eclipse.jface.text.rules.FastPartitioner;
31
32 import org.eclipse.compare.CompareUI;
33 import org.eclipse.compare.IEditableContent;
34 import org.eclipse.compare.ISharedDocumentAdapter;
35 import org.eclipse.compare.IStreamContentAccessor;
36 import org.eclipse.compare.ITypedElement;
37 import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
38 import org.eclipse.compare.structuremergeviewer.IStructureComparator;
39 import org.eclipse.compare.structuremergeviewer.StructureCreator;
40 import org.eclipse.compare.structuremergeviewer.StructureRootNode;
41
42 import org.eclipse.jdt.internal.ui.JavaPlugin;
43 import org.eclipse.jdt.internal.ui.propertiesfileeditor.IPropertiesFilePartitions;
44 import org.eclipse.jdt.internal.ui.propertiesfileeditor.PropertiesFilePartitionScanner;
45
46
47 public class PropertiesStructureCreator extends StructureCreator {
48     
49     /**
50      * A PropertyNode represents a key/value pair of a Java property file.
51      * The text range of a leg/value pair starts with an optional
52      * comment and ends right after the value.
53      */

54     static class PropertyNode extends DocumentRangeNode implements ITypedElement, IAdaptable {
55         
56         public PropertyNode(DocumentRangeNode parent, int type, String JavaDoc id, String JavaDoc value, IDocument doc, int start, int length) {
57             super(parent, type, id, doc, start, length);
58             if (parent != null) {
59                 parent.addChild(this);
60             }
61         }
62                             
63         /* (non Java doc)
64          * see ITypedElement#getName
65          */

66         public String JavaDoc getName() {
67             return getId();
68         }
69
70         /* (non Java doc)
71          * see ITypedElement#getType
72          */

73         public String JavaDoc getType() {
74             return "properties2"; //$NON-NLS-1$
75
}
76         
77         /* (non Java doc)
78          * see ITypedElement#getImage
79          */

80         public Image getImage() {
81             return CompareUI.getImage(getType());
82         }
83     }
84     
85     private static final String JavaDoc WHITESPACE= " \t\r\n\f"; //$NON-NLS-1$
86
private static final String JavaDoc SEPARATORS= "=:"; //$NON-NLS-1$
87
private static final String JavaDoc SEPARATORS2= SEPARATORS + WHITESPACE;
88             
89
90     public PropertiesStructureCreator() {
91     }
92     
93     public String JavaDoc getName() {
94         return CompareMessages.PropertyCompareViewer_title;
95     }
96     
97     protected IStructureComparator createStructureComparator(Object JavaDoc input,
98             IDocument document, ISharedDocumentAdapter sharedDocumentAdapter,
99             IProgressMonitor monitor) throws CoreException {
100         
101         final boolean isEditable;
102         if (input instanceof IEditableContent)
103             isEditable= ((IEditableContent) input).isEditable();
104         else
105             isEditable= false;
106
107         DocumentRangeNode root= new StructureRootNode(document, input, this, sharedDocumentAdapter) {
108             public boolean isEditable() {
109                 return isEditable;
110             }
111         };
112                 
113         try {
114             monitor = beginWork(monitor);
115             parsePropertyFile(root, document, monitor);
116         } catch (IOException JavaDoc ex) {
117             if (sharedDocumentAdapter != null)
118                 sharedDocumentAdapter.disconnect(input);
119             throw new CoreException(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), 0, CompareMessages.PropertiesStructureCreator_error_occurred, ex));
120         } finally {
121             monitor.done();
122         }
123         
124         return root;
125     }
126         
127     public IStructureComparator locate(Object JavaDoc path, Object JavaDoc source) {
128         return null;
129     }
130     
131     public String JavaDoc getContents(Object JavaDoc node, boolean ignoreWhitespace) {
132         if (node instanceof IStreamContentAccessor) {
133             IStreamContentAccessor sca= (IStreamContentAccessor) node;
134             try {
135                 return JavaCompareUtilities.readString(sca);
136             } catch (CoreException ex) {
137                 JavaPlugin.log(ex);
138             }
139         }
140         return null;
141     }
142     
143     private String JavaDoc readLine(int[] args, IDocument doc) {
144         int line= args[0]++;
145         try {
146             IRegion region= doc.getLineInformation(line);
147             int start= region.getOffset();
148             int length= region.getLength();
149             
150             try {
151                 region= doc.getLineInformation(line+1);
152                 args[1]= region.getOffset();
153             } catch (BadLocationException ex) {
154                 args[1]= doc.getLength();
155             }
156             
157             return doc.get(start, length);
158         } catch (BadLocationException ex) {
159             // silently ignored
160
}
161         return null;
162     }
163             
164     private void parsePropertyFile(DocumentRangeNode root, IDocument doc, IProgressMonitor monitor) throws IOException JavaDoc {
165         
166         int start= -1;
167         int lineStart= 0;
168         
169         int[] args= new int[2];
170         args[0]= 0; // here we return the line number
171
args[1]= 0; // and here the offset of the first character of the line
172

173         for (;;) {
174             worked(monitor);
175             lineStart= args[1]; // start of current line
176
String JavaDoc line= readLine(args, doc);
177             if (line == null)
178                 return;
179                 
180             if (line.length() <= 0)
181                 continue; // empty line
182

183             char firstChar= line.charAt(0);
184             if (firstChar == '#' || firstChar == '!') {
185                 if (start < 0) // comment belongs to next key/value pair
186
start= lineStart;
187                 continue; // comment
188
}
189                                 
190             // find continuation lines
191
while (needNextLine(line)) {
192                 String JavaDoc nextLine= readLine(args, doc);
193                 if (nextLine == null)
194                     nextLine= ""; //$NON-NLS-1$
195
String JavaDoc line2= line.substring(0, line.length()-1);
196                 int startPos= 0;
197                 for (; startPos < nextLine.length(); startPos++)
198                     if (WHITESPACE.indexOf(nextLine.charAt(startPos)) == -1)
199                         break;
200                 nextLine= nextLine.substring(startPos, nextLine.length());
201                 line= line2 + nextLine;
202             }
203             
204             // key start
205
int len= line.length();
206             int keyPos= 0;
207             for (; keyPos < len; keyPos++) {
208                 if (WHITESPACE.indexOf(line.charAt(keyPos)) == -1)
209                     break;
210             }
211             
212             // key/value separator
213
int separatorPos;
214             for (separatorPos= keyPos; separatorPos < len; separatorPos++) {
215                 char c= line.charAt(separatorPos);
216                 if (c == '\\')
217                     separatorPos++;
218                 else if (SEPARATORS2.indexOf(c) != -1)
219                     break;
220             }
221
222             int valuePos;
223             for (valuePos= separatorPos; valuePos < len; valuePos++)
224                 if (WHITESPACE.indexOf(line.charAt(valuePos)) == -1)
225                     break;
226
227             if (valuePos < len)
228                 if (SEPARATORS.indexOf(line.charAt(valuePos)) != -1)
229                     valuePos++;
230
231             while (valuePos < len) {
232                 if (WHITESPACE.indexOf(line.charAt(valuePos)) == -1)
233                     break;
234                 valuePos++;
235             }
236     
237             String JavaDoc key= convert(line.substring(keyPos, separatorPos));
238             if (key.length() > 0) {
239                         
240                 if (start < 0)
241                     start= lineStart;
242                 
243                 String JavaDoc value= ""; //$NON-NLS-1$
244
if (separatorPos < len)
245                     value= convert(line.substring(valuePos, len));
246                                                     
247                 int length= args[1] - start;
248                 
249                 try {
250                     String JavaDoc s= doc.get(start, length);
251                     for (int i= s.length()-1; i >= 0; i--) {
252                         char c= s.charAt(i);
253                         if (c !='\r' && c != '\n')
254                             break;
255                         length--;
256                     }
257                 } catch (BadLocationException e) {
258                     // silently ignored
259
}
260                 
261                 new PropertyNode(root, 0, key, value, doc, start, length);
262                 start= -1;
263             }
264         }
265     }
266
267     private boolean needNextLine(String JavaDoc line) {
268         int slashes= 0;
269         int ix= line.length() - 1;
270         while ((ix >= 0) && (line.charAt(ix--) == '\\'))
271             slashes++;
272         return slashes % 2 == 1;
273     }
274
275     /*
276      * Converts escaped characters to Unicode.
277      */

278     private String JavaDoc convert(String JavaDoc s) {
279         int l= s.length();
280         StringBuffer JavaDoc buf= new StringBuffer JavaDoc(l);
281         int i= 0;
282         
283         while (i < l) {
284             char c= s.charAt(i++);
285             if (c == '\\') {
286                 c= s.charAt(i++);
287                 if (c == 'u') {
288                     int v= 0;
289                     for (int j= 0; j < 4; j++) {
290                         c= s.charAt(i++);
291                         switch (c) {
292                         case '0': case '1': case '2': case '3': case '4':
293                         case '5': case '6': case '7': case '8': case '9':
294                             v= (v << 4) + (c-'0');
295                             break;
296                         case 'a': case 'b': case 'c':
297                         case 'd': case 'e': case 'f':
298                             v= (v << 4) + 10+(c-'a');
299                             break;
300                         case 'A': case 'B': case 'C':
301                         case 'D': case 'E': case 'F':
302                             v= (v << 4) + 10+(c - 'A');
303                             break;
304                         default:
305                             throw new IllegalArgumentException JavaDoc(CompareMessages.PropertyCompareViewer_malformedEncoding);
306                         }
307                     }
308                     buf.append((char)v);
309                 } else {
310                     switch (c) {
311                     case 't':
312                         c= '\t';
313                         break;
314                     case 'r':
315                         c= '\r';
316                         break;
317                     case 'n':
318                         c= '\n';
319                         break;
320                     case 'f':
321                         c= '\f';
322                         break;
323                     }
324                     buf.append(c);
325                 }
326             } else
327                 buf.append(c);
328         }
329         return buf.toString();
330     }
331
332     protected IDocumentPartitioner getDocumentPartitioner() {
333         return new FastPartitioner(new PropertiesFilePartitionScanner(), IPropertiesFilePartitions.PARTITIONS);
334     }
335     
336     protected String JavaDoc getDocumentPartitioning() {
337         return IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING;
338     }
339     
340     private void worked(IProgressMonitor monitor) {
341         if (monitor.isCanceled())
342             throw new OperationCanceledException();
343         monitor.worked(1);
344     }
345
346     private IProgressMonitor beginWork(IProgressMonitor monitor) {
347         if (monitor == null)
348             return new NullProgressMonitor();
349         return new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN);
350     }
351     
352 }
353
Popular Tags