1 11 package org.eclipse.jdt.internal.corext.refactoring.nls; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 import org.eclipse.jface.text.BadLocationException; 17 import org.eclipse.jface.text.Document; 18 import org.eclipse.jface.text.IDocument; 19 import org.eclipse.jface.text.IRegion; 20 21 import org.eclipse.jdt.core.ICompilationUnit; 22 import org.eclipse.jdt.core.JavaModelException; 23 import org.eclipse.jdt.core.ToolFactory; 24 import org.eclipse.jdt.core.compiler.IScanner; 25 import org.eclipse.jdt.core.compiler.ITerminalSymbols; 26 import org.eclipse.jdt.core.compiler.InvalidInputException; 27 28 public class NLSScanner { 29 30 private NLSScanner() { 32 } 33 34 37 public static NLSLine[] scan(ICompilationUnit cu) throws JavaModelException, InvalidInputException { 38 return scan(cu.getBuffer().getCharacters()); 39 } 40 41 44 public static NLSLine[] scan(String s) throws InvalidInputException { 45 return scan(s.toCharArray()); 46 } 47 48 private static NLSLine[] scan(char[] content) throws InvalidInputException { 49 List lines= new ArrayList (); 50 IScanner scanner= ToolFactory.createScanner(true, true, false, true); 51 scanner.setSource(content); 52 int token= scanner.getNextToken(); 53 int currentLineNr= -1; 54 int previousLineNr= -1; 55 NLSLine currentLine= null; 56 int nlsElementIndex= 0; 57 58 while (token != ITerminalSymbols.TokenNameEOF) { 59 switch (token) { 60 case ITerminalSymbols.TokenNameStringLiteral: 61 currentLineNr= scanner.getLineNumber(scanner.getCurrentTokenStartPosition()); 62 if (currentLineNr != previousLineNr) { 63 currentLine= new NLSLine(currentLineNr - 1); 64 lines.add(currentLine); 65 previousLineNr= currentLineNr; 66 nlsElementIndex= 0; 67 } 68 String value= new String (scanner.getCurrentTokenSource()); 69 currentLine.add( 70 new NLSElement( 71 value, 72 scanner.getCurrentTokenStartPosition(), 73 scanner.getCurrentTokenEndPosition() + 1 - scanner.getCurrentTokenStartPosition(), 74 nlsElementIndex++, 75 false)); 76 break; 77 case ITerminalSymbols.TokenNameCOMMENT_LINE: 78 if (currentLineNr != scanner.getLineNumber(scanner.getCurrentTokenStartPosition())) 79 break; 80 81 parseTags(currentLine, scanner); 82 break; 83 } 84 token= scanner.getNextToken(); 85 } 86 NLSLine[] result; 87 try { 88 result= (NLSLine[]) lines.toArray(new NLSLine[lines.size()]); 89 IDocument document= new Document(String.valueOf(scanner.getSource())); 90 for (int i= 0; i < result.length; i++) { 91 setTagPositions(document, result[i]); 92 } 93 } catch (BadLocationException exception) { 94 throw new InvalidInputException(); 95 } 96 return result; 97 } 98 99 private static void parseTags(NLSLine line, IScanner scanner) { 100 String s= new String (scanner.getCurrentTokenSource()); 101 int pos= s.indexOf(NLSElement.TAG_PREFIX); 102 while (pos != -1) { 103 int start= pos + NLSElement.TAG_PREFIX_LENGTH; 104 int end= s.indexOf(NLSElement.TAG_POSTFIX, start); 105 if (end < 0) 106 return; 108 String index= s.substring(start, end); 109 int i= 0; 110 try { 111 i= Integer.parseInt(index) - 1; } catch (NumberFormatException e) { 113 return; } 115 if (line.exists(i)) { 116 NLSElement element= line.get(i); 117 element.setTagPosition(scanner.getCurrentTokenStartPosition() + pos, end - pos + 1); 118 } else { 119 return; } 121 pos= s.indexOf(NLSElement.TAG_PREFIX, start); 122 } 123 } 124 125 private static void setTagPositions(IDocument document, NLSLine line) throws BadLocationException { 126 IRegion info= document.getLineInformation(line.getLineNumber()); 127 int defaultValue= info.getOffset() + info.getLength(); 128 NLSElement[] elements= line.getElements(); 129 for (int i= 0; i < elements.length; i++) { 130 NLSElement element= elements[i]; 131 if (!element.hasTag()) { 132 element.setTagPosition(computeInsertOffset(elements, i, defaultValue), 0); 133 } 134 } 135 } 136 137 private static int computeInsertOffset(NLSElement[] elements, int index, int defaultValue) { 138 NLSElement previousTagged= findPreviousTagged(index, elements); 139 if (previousTagged != null) 140 return previousTagged.getTagPosition().getOffset() + previousTagged.getTagPosition().getLength(); 141 NLSElement nextTagged= findNextTagged(index, elements); 142 if (nextTagged != null) 143 return nextTagged.getTagPosition().getOffset(); 144 return defaultValue; 145 } 146 147 private static NLSElement findPreviousTagged(int startIndex, NLSElement[] elements){ 148 int i= startIndex - 1; 149 while (i >= 0){ 150 if (elements[i].hasTag()) 151 return elements[i]; 152 i--; 153 } 154 return null; 155 } 156 157 private static NLSElement findNextTagged(int startIndex, NLSElement[] elements){ 158 int i= startIndex + 1; 159 while (i < elements.length){ 160 if (elements[i].hasTag()) 161 return elements[i]; 162 i++; 163 } 164 return null; 165 } 166 } 167 168 | Popular Tags |