1 11 package org.eclipse.jdt.internal.corext.refactoring.nls; 12 13 import java.util.Arrays ; 14 15 import org.eclipse.text.edits.DeleteEdit; 16 import org.eclipse.text.edits.InsertEdit; 17 import org.eclipse.text.edits.MultiTextEdit; 18 import org.eclipse.text.edits.ReplaceEdit; 19 import org.eclipse.text.edits.TextEdit; 20 21 import org.eclipse.core.runtime.CoreException; 22 23 import org.eclipse.jface.text.Region; 24 import org.eclipse.jface.text.TextUtilities; 25 26 import org.eclipse.ltk.core.refactoring.Change; 27 import org.eclipse.ltk.core.refactoring.TextChange; 28 29 import org.eclipse.jdt.core.IBuffer; 30 import org.eclipse.jdt.core.ICompilationUnit; 31 import org.eclipse.jdt.core.IPackageFragment; 32 import org.eclipse.jdt.core.IType; 33 import org.eclipse.jdt.core.compiler.InvalidInputException; 34 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 35 36 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 37 import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange; 38 import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility; 39 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 40 import org.eclipse.jdt.internal.corext.util.Messages; 41 42 public class NLSSourceModifier { 43 44 private final String fSubstitutionPattern; 45 private final boolean fIsEclipseNLS; 46 47 private NLSSourceModifier(String substitutionPattern, boolean isEclipseNLS) { 48 fSubstitutionPattern= substitutionPattern; 49 fIsEclipseNLS= isEclipseNLS; 50 } 51 52 public static Change create(ICompilationUnit cu, NLSSubstitution[] subs, String substitutionPattern, IPackageFragment accessorPackage, String accessorClassName, boolean isEclipseNLS) throws CoreException { 53 54 NLSSourceModifier sourceModification= new NLSSourceModifier(substitutionPattern, isEclipseNLS); 55 56 String message= Messages.format(NLSMessages.NLSSourceModifier_change_description, cu.getElementName()); 57 58 TextChange change= new CompilationUnitChange(message, cu); 59 MultiTextEdit multiTextEdit= new MultiTextEdit(); 60 change.setEdit(multiTextEdit); 61 62 accessorClassName= sourceModification.createImportForAccessor(multiTextEdit, accessorClassName, accessorPackage, cu); 63 64 for (int i= 0; i < subs.length; i++) { 65 NLSSubstitution substitution= subs[i]; 66 int newState= substitution.getState(); 67 if (substitution.hasStateChanged()) { 68 if (newState == NLSSubstitution.EXTERNALIZED) { 69 if (substitution.getInitialState() == NLSSubstitution.INTERNALIZED) { 70 sourceModification.addNLS(substitution, change, accessorClassName); 71 } else if (substitution.getInitialState() == NLSSubstitution.IGNORED) { 72 sourceModification.addAccessor(substitution, change, accessorClassName); 73 } 74 } else if (newState == NLSSubstitution.INTERNALIZED) { 75 if (substitution.getInitialState() == NLSSubstitution.IGNORED) { 76 sourceModification.deleteTag(substitution, change); 77 if (substitution.isValueRename()) { 78 sourceModification.replaceValue(substitution, change); 79 } 80 } else if (substitution.getInitialState() == NLSSubstitution.EXTERNALIZED) { 81 sourceModification.deleteAccessor(substitution, change, cu); 82 if (!isEclipseNLS) 83 sourceModification.deleteTag(substitution, change); 84 } 85 } else if (newState == NLSSubstitution.IGNORED) { 86 if (substitution.getInitialState() == NLSSubstitution.INTERNALIZED) { 87 sourceModification.addNLS(substitution, change, accessorClassName); 88 if (substitution.isValueRename()) { 89 sourceModification.replaceValue(substitution, change); 90 } 91 } else { 92 if (substitution.getInitialState() == NLSSubstitution.EXTERNALIZED) { 93 sourceModification.deleteAccessor(substitution, change, cu); 94 } 95 } 96 } 97 } else { 98 if (newState == NLSSubstitution.EXTERNALIZED) { 99 if (substitution.isKeyRename()) { 100 sourceModification.replaceKey(substitution, change); 101 } 102 if (substitution.isAccessorRename()) { 103 sourceModification.replaceAccessor(substitution, change); 104 } 105 } else { 106 if (substitution.isValueRename()) { 107 sourceModification.replaceValue(substitution, change); 108 } 109 } 110 } 111 } 112 113 return change; 114 } 115 116 120 private void replaceAccessor(NLSSubstitution substitution, TextChange change) { 121 AccessorClassReference accessorClassRef= substitution.getAccessorClassReference(); 122 if (accessorClassRef != null) { 123 Region region= accessorClassRef.getRegion(); 124 int len= accessorClassRef.getName().length(); 125 String [] args= {accessorClassRef.getName(), substitution.getUpdatedAccessor()}; 126 TextChangeCompatibility.addTextEdit(change, Messages.format(NLSMessages.NLSSourceModifier_replace_accessor, args), 127 new ReplaceEdit(region.getOffset(), len, substitution.getUpdatedAccessor())); } 129 130 } 131 132 private void replaceKey(NLSSubstitution substitution, TextChange change) { 133 Region region= substitution.getNLSElement().getPosition(); 134 String [] args= {substitution.getInitialKey(), substitution.getKey()}; 135 136 ReplaceEdit replaceEdit; 137 if (fIsEclipseNLS) 138 replaceEdit= new ReplaceEdit(region.getOffset(), region.getLength(), substitution.getKey()); 139 else 140 replaceEdit= new ReplaceEdit(region.getOffset(), region.getLength(), '\"' + unwindEscapeChars(substitution.getKey()) + '\"'); 142 TextChangeCompatibility.addTextEdit(change, Messages.format(NLSMessages.NLSSourceModifier_replace_key, args), replaceEdit); 143 } 144 145 private void replaceValue(NLSSubstitution substitution, TextChange change) { 146 Region region= substitution.getNLSElement().getPosition(); 147 String [] args= {substitution.getInitialValue(), substitution.getValueNonEmpty()}; 148 TextChangeCompatibility.addTextEdit(change, Messages.format(NLSMessages.NLSSourceModifier_replace_value, args), 149 new ReplaceEdit(region.getOffset(), region.getLength(), '\"' + unwindEscapeChars(substitution.getValueNonEmpty()) + '\"')); } 151 152 private void deleteAccessor(NLSSubstitution substitution, TextChange change, ICompilationUnit cu) throws CoreException { 153 AccessorClassReference accessorClassRef= substitution.getAccessorClassReference(); 154 if (accessorClassRef != null) { 155 Region region= accessorClassRef.getRegion(); 156 String [] args= {substitution.getValueNonEmpty(), substitution.getKey()}; 157 String label= Messages.format(NLSMessages.NLSSourceModifier_remove_accessor, args); 158 String replaceString= '\"' + unwindEscapeChars(substitution.getValueNonEmpty()) + '\"'; 159 TextChangeCompatibility.addTextEdit(change, label, new ReplaceEdit(region.getOffset(), region.getLength(), replaceString)); 160 if (fIsEclipseNLS && substitution.getState() != NLSSubstitution.INTERNALIZED) { 161 162 Region position= substitution.getNLSElement().getPosition(); 163 int lineStart= getLineStart(cu.getBuffer(), position.getOffset()); 164 int lineEnd= getLineEnd(cu.getBuffer(), position.getOffset()); 165 String cuLine= cu.getBuffer().getText(lineStart, lineEnd - lineStart); 166 StringBuffer buf= new StringBuffer (cuLine); 167 buf.replace(region.getOffset() - lineStart, region.getOffset() + region.getLength() - lineStart, replaceString); 168 try { 169 NLSLine[] allLines= NLSScanner.scan(buf.toString()); 170 171 NLSLine nlsLine= allLines[0]; 172 NLSElement element= findElement(nlsLine, position.getOffset() - lineStart - accessorClassRef.getName().length() - 1); 173 if (element == null || element.hasTag()) 174 return; 175 176 NLSElement[] elements= nlsLine.getElements(); 177 int indexInElementList= Arrays.asList(elements).indexOf(element); 178 String editText= ' ' + NLSElement.createTagText(indexInElementList + 1); TextChangeCompatibility.addTextEdit(change, label, new InsertEdit(lineEnd, editText)); 180 181 } catch (InvalidInputException e) { 182 183 } 184 } 185 } 186 } 187 188 private int getLineEnd(IBuffer buffer, int offset) { 189 int pos= offset; 190 int length= buffer.getLength(); 191 while (pos < length && !isDelemiter(buffer.getChar(pos))) { 192 pos++; 193 } 194 return pos; 195 } 196 197 private int getLineStart(IBuffer buffer, int offset) { 198 int pos= offset; 199 while (pos >= 0 && !isDelemiter(buffer.getChar(pos))) { 200 pos--; 201 } 202 return pos + 1; 203 } 204 205 private boolean isDelemiter(char ch) { 206 String [] delem= TextUtilities.DELIMITERS; 207 for (int i= 0; i < delem.length; i++) { 208 if (delem[i].length() == 1 && ch == delem[i].charAt(0)) 209 return true; 210 } 211 return false; 212 } 213 214 private static boolean isPositionInElement(NLSElement element, int position) { 215 Region elementPosition= element.getPosition(); 216 return (elementPosition.getOffset() <= position && position <= elementPosition.getOffset() + elementPosition.getLength()); 217 } 218 219 private static NLSElement findElement(NLSLine line, int position) { 220 NLSElement[] elements= line.getElements(); 221 for (int i= 0; i < elements.length; i++) { 222 NLSElement element= elements[i]; 223 if (isPositionInElement(element, position)) 224 return element; 225 } 226 return null; 227 } 228 229 private String unwindEscapeChars(String s) { 231 StringBuffer sb= new StringBuffer (s.length()); 232 int length= s.length(); 233 for (int i= 0; i < length; i++) { 234 char c= s.charAt(i); 235 sb.append(getUnwoundString(c)); 236 } 237 return sb.toString(); 238 } 239 240 private String getUnwoundString(char c) { 241 switch (c) { 242 case '\b' : 243 return "\\b"; case '\t' : 245 return "\\t"; case '\n' : 247 return "\\n"; case '\f' : 249 return "\\f"; case '\r' : 251 return "\\r"; case '\\' : 253 return "\\\\"; } 255 return String.valueOf(c); 256 } 257 258 private void deleteTag(NLSSubstitution substitution, TextChange change) { 259 Region textRegion= substitution.getNLSElement().getTagPosition(); 260 261 TextChangeCompatibility.addTextEdit(change, NLSMessages.NLSSourceModifier_remove_tag, 262 new DeleteEdit(textRegion.getOffset(), textRegion.getLength())); 263 } 264 265 private String createImportForAccessor(MultiTextEdit parent, String accessorClassName, IPackageFragment accessorPackage, ICompilationUnit cu) throws CoreException { 266 IType type= accessorPackage.getCompilationUnit(accessorClassName + JavaModelUtil.DEFAULT_CU_SUFFIX).getType(accessorClassName); 267 String fullyQualifiedName= type.getFullyQualifiedName(); 268 269 ImportRewrite importRewrite= StubUtility.createImportRewrite(cu, true); 270 String nameToUse= importRewrite.addImport(fullyQualifiedName); 271 TextEdit edit= importRewrite.rewriteImports(null); 272 parent.addChild(edit); 273 274 return nameToUse; 275 } 276 277 private void addNLS(NLSSubstitution sub, TextChange change, String accessorName) { 278 if (sub.getState() == NLSSubstitution.INTERNALIZED) 279 return; 280 281 NLSElement element= sub.getNLSElement(); 282 283 addAccessor(sub, change, accessorName); 284 285 if (!fIsEclipseNLS || sub.getState() == NLSSubstitution.IGNORED) { 286 String arg= sub.getState() == NLSSubstitution.EXTERNALIZED ? sub.getKey() : sub.getValueNonEmpty(); 288 String name= Messages.format(NLSMessages.NLSSourceModifier_add_tag, arg); 289 TextChangeCompatibility.addTextEdit(change, name, createAddTagChange(element)); 290 } 291 } 292 293 private void addAccessor(NLSSubstitution sub, TextChange change, String accessorName) { 294 if (sub.getState() == NLSSubstitution.EXTERNALIZED) { 295 NLSElement element= sub.getNLSElement(); 296 Region position= element.getPosition(); 297 String [] args= {sub.getValueNonEmpty(), sub.getKey()}; 298 String text= Messages.format(NLSMessages.NLSSourceModifier_externalize, args); 299 300 String resourceGetter= createResourceGetter(sub.getKey(), accessorName); 301 302 TextEdit edit= new ReplaceEdit(position.getOffset(), position.getLength(), resourceGetter); 303 if (fIsEclipseNLS && element.getTagPosition() != null) { 304 MultiTextEdit multiEdit= new MultiTextEdit(); 305 multiEdit.addChild(edit); 306 Region tagPosition= element.getTagPosition(); 307 multiEdit.addChild(new DeleteEdit(tagPosition.getOffset(), tagPosition.getLength())); 308 edit= multiEdit; 309 } 310 TextChangeCompatibility.addTextEdit(change, text, edit); 311 } 312 } 313 314 private TextEdit createAddTagChange(NLSElement element) { 315 int offset= element.getTagPosition().getOffset(); String text= ' ' + element.getTagText(); 317 return new InsertEdit(offset, text); 318 } 319 320 private String createResourceGetter(String key, String accessorName) { 321 StringBuffer buf= new StringBuffer (); 322 buf.append(accessorName); 323 buf.append('.'); 324 325 if (fIsEclipseNLS) 326 buf.append(key); 327 else { 328 int i= fSubstitutionPattern.indexOf(NLSRefactoring.KEY); 330 if (i != -1) { 331 buf.append(fSubstitutionPattern.substring(0, i)); 332 buf.append('"').append(key).append('"'); 333 buf.append(fSubstitutionPattern.substring(i + NLSRefactoring.KEY.length())); 334 } 335 } 336 return buf.toString(); 337 } 338 } 339 | Popular Tags |