]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-after/core refactoring/org/eclipse/jdt/internal/corext/refactoring/nls/PropertyFileDocumentModel.java
0e226586f41717c79d49618dd7b49b45932ab87f
[ifi-stolz-refaktor.git] / case-study / jdt-after / core refactoring / org / eclipse / jdt / internal / corext / refactoring / nls / PropertyFileDocumentModel.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 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.corext.refactoring.nls;
12
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Collections;
16 import java.util.Comparator;
17 import java.util.Iterator;
18 import java.util.List;
19
20 import com.ibm.icu.text.Collator;
21
22 import org.eclipse.text.edits.DeleteEdit;
23 import org.eclipse.text.edits.InsertEdit;
24 import org.eclipse.text.edits.ReplaceEdit;
25
26 import org.eclipse.jface.text.IDocument;
27 import org.eclipse.jface.text.TextUtilities;
28
29 import org.eclipse.ltk.core.refactoring.TextChange;
30
31 import org.eclipse.jdt.internal.ui.propertiesfileeditor.PropertiesFileEscapes;
32
33 public class PropertyFileDocumentModel {
34
35         List<KeyValuePairModell> fKeyValuePairs;
36     private String fLineDelimiter;
37
38     public PropertyFileDocumentModel(IDocument document) {
39         parsePropertyDocument(document);
40         fLineDelimiter= TextUtilities.getDefaultLineDelimiter(document);
41     }
42
43     /**
44          * @return the line delimiter used by the document described by this model
45          */
46     public String getLineDelimiter() {
47                 return fLineDelimiter;
48         }
49
50     /**
51          * Return the key value pair in this model with the key <code>key</code>
52          *
53          * @param key the key of the pair
54          * @return the pair with the key or <b>null</b> if no such pair.
55          */
56     public KeyValuePair getKeyValuePair(String key) {
57         for (int i= 0; i < fKeyValuePairs.size(); i++) {
58             KeyValuePairModell keyValuePair = fKeyValuePairs.get(i);
59             if (keyValuePair.getKey().equals(key)) {
60                 return keyValuePair;
61             }
62         }
63         return null;
64     }
65
66     InsertEdit insert(KeyValuePair keyValuePair) {
67         KeyValuePairModell keyValuePairModell = new KeyValuePairModell(keyValuePair);
68         int index = findInsertPosition(keyValuePairModell);
69         KeyValuePairModell insertHere = fKeyValuePairs.get(index);
70         int offset = insertHere.fOffset;
71
72         String extra= ""; //$NON-NLS-1$
73         if (insertHere instanceof LastKeyValuePair && ((LastKeyValuePair)insertHere).needsNewLine()) {
74                 extra= fLineDelimiter;
75                 ((LastKeyValuePair)insertHere).resetNeedsNewLine();
76                 offset-= insertHere.fLeadingWhiteSpaces;
77         } else if (index > 0) {
78                 String beforeKey= fKeyValuePairs.get(index - 1).fKey;
79                         String afterKey= insertHere.fKey;
80                         String key= keyValuePair.fKey;
81                         int distBefore= NLSUtil.invertDistance(key, beforeKey);
82                         int distAfter= NLSUtil.invertDistance(key, afterKey);
83                         if (distBefore > distAfter) {
84                                 offset-= insertHere.fLeadingWhiteSpaces;
85                         } else if (distBefore == distAfter && Collator.getInstance().compare(beforeKey, afterKey) < 0) {
86                                 offset-= insertHere.fLeadingWhiteSpaces;
87                         } else {
88                                 //insert it before afterKey -> move the leading white spaces to the inserted pair
89                                 keyValuePairModell.fLeadingWhiteSpaces= insertHere.fLeadingWhiteSpaces;
90                                 insertHere.fLeadingWhiteSpaces= 0;
91                         }
92         }
93
94         String text= keyValuePairModell.generated_875148158285524824(this, index, offset, extra);
95                 return new InsertEdit(offset, text);
96     }
97
98         /**
99      * Inserts the given key value pairs into this model at appropriate
100      * positions. Records all required text changes in the given change
101      *
102      * @param keyValuePairs the key value pairs to insert
103      * @param change the change to use to record text changes
104      */
105     public void insert(KeyValuePair[] keyValuePairs, TextChange change) {
106
107         ArrayList<KeyValuePair> sorted= new ArrayList<KeyValuePair>(Arrays.asList(keyValuePairs));
108         Collections.sort(sorted, new Comparator<KeyValuePair>() {
109                         public int compare(KeyValuePair p1, KeyValuePair p2) {
110                                 return Collator.getInstance().compare(p1.fKey, p2.fKey);
111                         }
112         });
113
114         for (int i = 0; i < sorted.size(); i++) {
115             KeyValuePair curr= sorted.get(i);
116                         curr.generated_45942992453355874(change, this);
117         }
118     }
119
120         public DeleteEdit remove(String key) {
121         for (Iterator<KeyValuePairModell> iter = fKeyValuePairs.iterator(); iter.hasNext();) {
122             KeyValuePairModell keyValuePair = iter.next();
123             if (keyValuePair.fKey.equals(key)) {
124                 return keyValuePair.generated_6789650072710353462(this);
125             }
126         }
127         return null;
128     }
129
130         public ReplaceEdit replace(KeyValuePair toReplace, KeyValuePair replaceWith) {
131         for (Iterator<KeyValuePairModell> iter = fKeyValuePairs.iterator(); iter.hasNext();) {
132             KeyValuePairModell keyValuePair = iter.next();
133             if (keyValuePair.fKey.equals(toReplace.getKey())) {
134                 String newText= new KeyValuePairModell(replaceWith).getKeyValueText();
135                 return keyValuePair.generated_6698145679089660767(this, newText);
136             }
137         }
138         return null;
139     }
140
141         private int findInsertPosition(KeyValuePairModell keyValuePair) {
142         ArrayList<String> keys= new ArrayList<String>();
143         for (int i= 0; i < fKeyValuePairs.size(); i++) {
144             KeyValuePairModell element = fKeyValuePairs.get(i);
145             element.generated_326054000021849204(keys);
146         }
147         int insertIndex= NLSUtil.getInsertionPosition(keyValuePair.getKey(), keys);
148
149         if (insertIndex < fKeyValuePairs.size() - 1) {
150             insertIndex++;
151         }
152
153         return insertIndex;
154     }
155
156         private void parsePropertyDocument(IDocument document) {
157         fKeyValuePairs = new ArrayList<KeyValuePairModell>();
158
159         SimpleLineReader reader = new SimpleLineReader(document);
160         int offset = 0;
161         LastKeyValuePair lastKeyValuePair= reader.generated_689189764367573075(document, this, offset);
162                 fKeyValuePairs.add(lastKeyValuePair);
163     }
164
165         int getIndexOfSeparationCharacter(String line) {
166         int minIndex = -1;
167         int indexOfEven = line.indexOf('=');
168         int indexOfColumn = line.indexOf(':');
169         int indexOfBlank = line.indexOf(' ');
170
171         if ((indexOfEven != -1) && (indexOfColumn != -1)) {
172             minIndex = Math.min(indexOfEven, indexOfColumn);
173         } else {
174             minIndex = Math.max(indexOfEven, indexOfColumn);
175         }
176
177                 if ((minIndex == -1) && (indexOfBlank != -1)) {
178                         minIndex= indexOfBlank;
179         }
180
181         return minIndex;
182     }
183
184         public static String escape(String s, boolean escapeCommentCharsAndLeadingWhitespaces) {
185                 StringBuffer sb= new StringBuffer(s.length());
186                 int length= s.length();
187                 for (int i= 0; i < length; i++){
188                         char c= s.charAt(i);
189                         sb.append(PropertiesFileEscapes.escape(c));
190                 }
191                 if(!escapeCommentCharsAndLeadingWhitespaces)
192                         return sb.toString();
193                 return escapeLeadingWhiteSpaces(escapeCommentChars(sb.toString()));
194         }
195
196         private static String escapeCommentChars(String string) {
197             StringBuffer sb = new StringBuffer(string.length() + 5);
198             for (int i = 0; i < string.length(); i++) {
199               char c = string.charAt(i);
200               switch (c) {
201               case '!':
202                 sb.append("\\!"); //$NON-NLS-1$
203                 break;
204               case '#':
205                 sb.append("\\#"); //$NON-NLS-1$
206                 break;
207               default:
208                 sb.append(c);
209               }
210             }
211             return sb.toString();
212         }
213
214         private static String escapeLeadingWhiteSpaces(String str) {
215                 int firstNonWhiteSpace= findFirstNonWhiteSpace(str);
216                 StringBuffer buf= new StringBuffer(firstNonWhiteSpace);
217                 for (int i = 0; i < firstNonWhiteSpace; i++) {
218                         buf.append('\\');
219                     buf.append(str.charAt(i));
220                 }
221                 buf.append(str.substring(firstNonWhiteSpace));
222                 return buf.toString();
223         }
224
225         /**
226          * @param s the string to inspect
227          * @return the first non whitespace character, the length if only whitespace characters
228          */
229         private static int findFirstNonWhiteSpace(String s) {
230                 for (int i = 0; i < s.length(); i++) {
231                         if (!Character.isWhitespace(s.charAt(i)))
232                                 return i;
233                 }
234                 return s.length();
235         }
236
237         static class KeyValuePairModell extends KeyValuePair {
238
239         int fOffset;
240         int fLength;
241         int fLeadingWhiteSpaces;
242
243         public KeyValuePairModell(String key, String value, int offset, int length, int leadingWhiteSpaces) {
244             super(key, value);
245             fOffset = offset;
246             fLength = length;
247             fLeadingWhiteSpaces = leadingWhiteSpaces;
248         }
249
250                 public KeyValuePairModell(KeyValuePair keyValuePair) {
251             super(keyValuePair.fKey, keyValuePair.fValue);
252         }
253
254                 public int getLength() {
255                         return fLength;
256                 }
257                 
258         String getKeyValueText() {
259                         return fKey + '=' + fValue;
260         }
261
262                 public String generated_875148158285524824(PropertyFileDocumentModel propertyfiledocumentmodel, int index, int offset, String extra) {
263                         String text= extra + getKeyValueText();
264                     fOffset= offset;
265                     fLength= text.length();
266                     propertyfiledocumentmodel.fKeyValuePairs.add(index, this);
267                         return text;
268                 }
269
270                 public DeleteEdit generated_6789650072710353462(PropertyFileDocumentModel propertyfiledocumentmodel) {
271                         return new DeleteEdit(fOffset, getLength());
272                 }
273
274                 public ReplaceEdit generated_6698145679089660767(PropertyFileDocumentModel propertyfiledocumentmodel, String newText) {
275                         return new ReplaceEdit(fOffset, getLength(), newText);
276                 }
277
278                 public void generated_326054000021849204(ArrayList<String> keys) {
279                         if (! (this instanceof LastKeyValuePair))
280                                 keys.add(getKey());
281                 }
282     }
283
284     /**
285      * anchor element for a list of KeyValuePairs. (it is greater than every
286      * other KeyValuePair)
287      */
288     static class LastKeyValuePair extends KeyValuePairModell {
289
290         private boolean fNeedsNewLine;
291
292         public LastKeyValuePair(int offset, boolean needsNewLine) {
293             super("zzzzzzz", "key", offset, 7 + 1 + 3, 0); //$NON-NLS-1$ //$NON-NLS-2$
294             fNeedsNewLine= needsNewLine;
295         }
296         public boolean needsNewLine() {
297                 return fNeedsNewLine;
298         }
299         public void resetNeedsNewLine() {
300                 fNeedsNewLine= false;
301         }
302     }
303 }