1 11 package org.eclipse.jdt.internal.ui.compare; 12 13 import java.io.IOException ; 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 54 static class PropertyNode extends DocumentRangeNode implements ITypedElement, IAdaptable { 55 56 public PropertyNode(DocumentRangeNode parent, int type, String id, String 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 66 public String getName() { 67 return getId(); 68 } 69 70 73 public String getType() { 74 return "properties2"; } 76 77 80 public Image getImage() { 81 return CompareUI.getImage(getType()); 82 } 83 } 84 85 private static final String WHITESPACE= " \t\r\n\f"; private static final String SEPARATORS= "=:"; private static final String SEPARATORS2= SEPARATORS + WHITESPACE; 88 89 90 public PropertiesStructureCreator() { 91 } 92 93 public String getName() { 94 return CompareMessages.PropertyCompareViewer_title; 95 } 96 97 protected IStructureComparator createStructureComparator(Object 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 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 path, Object source) { 128 return null; 129 } 130 131 public String getContents(Object 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 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 } 161 return null; 162 } 163 164 private void parsePropertyFile(DocumentRangeNode root, IDocument doc, IProgressMonitor monitor) throws IOException { 165 166 int start= -1; 167 int lineStart= 0; 168 169 int[] args= new int[2]; 170 args[0]= 0; args[1]= 0; 173 for (;;) { 174 worked(monitor); 175 lineStart= args[1]; String line= readLine(args, doc); 177 if (line == null) 178 return; 179 180 if (line.length() <= 0) 181 continue; 183 char firstChar= line.charAt(0); 184 if (firstChar == '#' || firstChar == '!') { 185 if (start < 0) start= lineStart; 187 continue; } 189 190 while (needNextLine(line)) { 192 String nextLine= readLine(args, doc); 193 if (nextLine == null) 194 nextLine= ""; String 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 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 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 key= convert(line.substring(keyPos, separatorPos)); 238 if (key.length() > 0) { 239 240 if (start < 0) 241 start= lineStart; 242 243 String value= ""; if (separatorPos < len) 245 value= convert(line.substring(valuePos, len)); 246 247 int length= args[1] - start; 248 249 try { 250 String 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 } 260 261 new PropertyNode(root, 0, key, value, doc, start, length); 262 start= -1; 263 } 264 } 265 } 266 267 private boolean needNextLine(String 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 278 private String convert(String s) { 279 int l= s.length(); 280 StringBuffer buf= new StringBuffer (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 (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 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 |