]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
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.Collections; | |
15 | import java.util.Comparator; | |
16 | import java.util.HashSet; | |
17 | import java.util.Iterator; | |
18 | import java.util.List; | |
19 | ||
20 | import com.ibm.icu.text.Collator; | |
21 | ||
22 | import org.eclipse.core.runtime.CoreException; | |
23 | import org.eclipse.core.runtime.IPath; | |
24 | import org.eclipse.core.runtime.IProgressMonitor; | |
25 | import org.eclipse.core.runtime.IStatus; | |
26 | ||
27 | import org.eclipse.core.resources.IFile; | |
28 | import org.eclipse.core.resources.IProject; | |
29 | import org.eclipse.core.resources.IResource; | |
30 | import org.eclipse.core.resources.ResourcesPlugin; | |
31 | ||
32 | import org.eclipse.text.edits.TextEdit; | |
33 | ||
34 | import org.eclipse.ltk.core.refactoring.Change; | |
35 | ||
36 | import org.eclipse.jdt.core.ICompilationUnit; | |
37 | import org.eclipse.jdt.core.IJavaElement; | |
38 | import org.eclipse.jdt.core.IJavaProject; | |
39 | import org.eclipse.jdt.core.IPackageFragment; | |
40 | import org.eclipse.jdt.core.IPackageFragmentRoot; | |
41 | import org.eclipse.jdt.core.JavaCore; | |
42 | import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; | |
43 | import org.eclipse.jdt.core.formatter.CodeFormatter; | |
44 | ||
45 | import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; | |
46 | import org.eclipse.jdt.internal.corext.refactoring.nls.changes.CreateTextFileChange; | |
47 | import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil; | |
48 | import org.eclipse.jdt.internal.corext.util.JavaModelUtil; | |
49 | ||
50 | import org.eclipse.jdt.ui.CodeGeneration; | |
51 | ||
52 | import org.eclipse.jdt.internal.ui.JavaPlugin; | |
53 | import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; | |
54 | import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache; | |
55 | ||
56 | public class AccessorClassCreator { | |
57 | ||
58 | private final ICompilationUnit fCu; | |
59 | public final String fAccessorClassName; | |
60 | private final IPath fAccessorPath; | |
61 | private final IPath fResourceBundlePath; | |
62 | private final IPackageFragment fAccessorPackage; | |
63 | private final boolean fIsEclipseNLS; | |
64 | private final NLSSubstitution[] fNLSSubstitutions; | |
65 | private final String fSubstitutionPattern; | |
66 | ||
67 | private AccessorClassCreator(ICompilationUnit cu, String accessorClassname, IPath accessorPath, IPackageFragment accessorPackage, IPath resourceBundlePath, boolean isEclipseNLS, NLSSubstitution[] nlsSubstitutions, String substitutionPattern) { | |
68 | fCu= cu; | |
69 | fAccessorClassName= accessorClassname; | |
70 | fAccessorPath= accessorPath; | |
71 | fAccessorPackage= accessorPackage; | |
72 | fResourceBundlePath= resourceBundlePath; | |
73 | fIsEclipseNLS= isEclipseNLS; | |
74 | fNLSSubstitutions= nlsSubstitutions; | |
75 | fSubstitutionPattern= substitutionPattern; | |
76 | } | |
77 | ||
78 | public static Change create(ICompilationUnit cu, String accessorClassname, IPath accessorPath, IPackageFragment accessorPackage, IPath resourceBundlePath, boolean isEclipseNLS, NLSSubstitution[] nlsSubstitutions, String substitutionPattern, IProgressMonitor pm) throws CoreException { | |
79 | AccessorClassCreator accessorClass= new AccessorClassCreator(cu, accessorClassname, accessorPath, accessorPackage, resourceBundlePath, isEclipseNLS, nlsSubstitutions, substitutionPattern); | |
80 | ||
81 | return new CreateTextFileChange(accessorPath, accessorClass.createAccessorCUSource(pm), null, "java"); //$NON-NLS-1$ | |
82 | } | |
83 | ||
84 | private String createAccessorCUSource(IProgressMonitor pm) throws CoreException { | |
85 | IProject project= getFileHandle(fAccessorPath).getProject(); | |
86 | String lineDelimiter= StubUtility.getLineDelimiterPreference(project); | |
87 | return CodeFormatterUtil.format(CodeFormatter.K_COMPILATION_UNIT, getUnformattedSource(pm), 0, lineDelimiter, fCu.getJavaProject()); | |
88 | } | |
89 | ||
90 | private static IFile getFileHandle(IPath filePath) { | |
91 | if (filePath == null) | |
92 | return null; | |
93 | return ResourcesPlugin.getWorkspace().getRoot().getFile(filePath); | |
94 | } | |
95 | ||
96 | private String getUnformattedSource(IProgressMonitor pm) throws CoreException { | |
97 | ICompilationUnit newCu= null; | |
98 | try { | |
99 | newCu= fAccessorPackage.getCompilationUnit(fAccessorPath.lastSegment()).getWorkingCopy(null); | |
100 | ||
101 | String typeComment= null, fileComment= null; | |
102 | final IJavaProject project= newCu.getJavaProject(); | |
103 | final String lineDelim= StubUtility.getLineDelimiterUsed(project); | |
104 | if (StubUtility.doAddComments(project)) { | |
105 | typeComment= CodeGeneration.getTypeComment(newCu, fAccessorClassName, lineDelim); | |
106 | fileComment= CodeGeneration.getFileComment(newCu, lineDelim); | |
107 | } | |
108 | String classContent= createClass(lineDelim); | |
109 | String cuContent= CodeGeneration.getCompilationUnitContent(newCu, fileComment, typeComment, classContent, lineDelim); | |
110 | if (cuContent == null) { | |
111 | StringBuffer buf= new StringBuffer(); | |
112 | if (fileComment != null) { | |
113 | buf.append(fileComment).append(lineDelim); | |
114 | } | |
115 | if (!fAccessorPackage.isDefaultPackage()) { | |
116 | buf.append("package ").append(fAccessorPackage.getElementName()).append(';'); //$NON-NLS-1$ | |
117 | } | |
118 | buf.append(lineDelim).append(lineDelim); | |
119 | if (typeComment != null) { | |
120 | buf.append(typeComment).append(lineDelim); | |
121 | } | |
122 | buf.append(classContent); | |
123 | cuContent= buf.toString(); | |
124 | } | |
125 | ||
126 | newCu.getBuffer().setContents(cuContent); | |
127 | addImportsToAccessorCu(newCu, pm); | |
128 | return newCu.getSource(); | |
129 | } finally { | |
130 | if (newCu != null) { | |
131 | newCu.discardWorkingCopy(); | |
132 | } | |
133 | } | |
134 | } | |
135 | ||
136 | private void addImportsToAccessorCu(ICompilationUnit newCu, IProgressMonitor pm) throws CoreException { | |
137 | ImportRewrite is= StubUtility.createImportRewrite(newCu, true); | |
138 | if (fIsEclipseNLS) { | |
139 | is.addImport("org.eclipse.osgi.util.NLS"); //$NON-NLS-1$ | |
140 | } else { | |
141 | is.addImport("java.util.MissingResourceException"); //$NON-NLS-1$ | |
142 | is.addImport("java.util.ResourceBundle"); //$NON-NLS-1$ | |
143 | } | |
144 | TextEdit edit= is.rewriteImports(pm); | |
145 | JavaModelUtil.applyEdit(newCu, edit, false, null); | |
146 | } | |
147 | ||
148 | private String createClass(String lineDelim) throws CoreException { | |
149 | if (fIsEclipseNLS) { | |
150 | MembersOrderPreferenceCache sortOrder= JavaPlugin.getDefault().getMemberOrderPreferenceCache(); | |
151 | StringBuffer result= sortOrder.generated_7986711754580231851(lineDelim, this); | |
152 | ||
153 | return result.toString(); | |
154 | } else { | |
155 | MembersOrderPreferenceCache sortOrder= JavaPlugin.getDefault().getMemberOrderPreferenceCache(); | |
156 | int constructorIdx= sortOrder.getCategoryIndex(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX); | |
157 | int methodIdx= sortOrder.getCategoryIndex(MembersOrderPreferenceCache.METHOD_INDEX); | |
158 | ||
159 | String constructor= lineDelim + createConstructor(lineDelim); | |
160 | String method= lineDelim + createGetStringMethod(lineDelim); | |
161 | ||
162 | StringBuffer result= new StringBuffer(); | |
163 | result.append("public class ").append(fAccessorClassName).append(" {"); //$NON-NLS-1$ //$NON-NLS-2$ | |
164 | result.append("private static final String ").append(NLSRefactoring.BUNDLE_NAME_FIELD); //$NON-NLS-1$ | |
165 | result.append(" = \"").append(getResourceBundleName()).append("\"; ").append(NLSElement.createTagText(1)).append(lineDelim); //$NON-NLS-1$ //$NON-NLS-2$ | |
166 | ||
167 | result.append(lineDelim).append("private static final ResourceBundle ").append(getResourceBundleConstantName()); //$NON-NLS-1$ | |
168 | result.append("= ResourceBundle.getBundle(").append(NLSRefactoring.BUNDLE_NAME_FIELD).append(");").append(lineDelim); //$NON-NLS-1$ //$NON-NLS-2$ | |
169 | ||
170 | if (constructorIdx < methodIdx) { | |
171 | result.append(constructor); | |
172 | result.append(method); | |
173 | } else { | |
174 | result.append(constructor); | |
175 | result.append(method); | |
176 | } | |
177 | ||
178 | result.append(lineDelim).append('}').append(lineDelim); | |
179 | ||
180 | return result.toString(); | |
181 | } | |
182 | } | |
183 | ||
184 | private String getResourceBundleConstantName() { | |
185 | return "RESOURCE_BUNDLE";//$NON-NLS-1$ | |
186 | } | |
187 | ||
188 | public String createStaticFields() { | |
189 | HashSet<String> added= new HashSet<String>(); | |
190 | List<NLSSubstitution> subs= new ArrayList<NLSSubstitution>(); | |
191 | for (int i= 0; i < fNLSSubstitutions.length; i++) { | |
192 | NLSSubstitution substitution= fNLSSubstitutions[i]; | |
193 | substitution.generated_5383474165357702679(added, subs); | |
194 | } | |
195 | Collections.sort(subs, new Comparator<NLSSubstitution>() { | |
196 | private Collator fCollator= Collator.getInstance(); | |
197 | public int compare(NLSSubstitution s0, NLSSubstitution s1) { | |
198 | return fCollator.compare(s0.getKey(), s1.getKey()); | |
199 | } | |
200 | }); | |
201 | StringBuffer buf= new StringBuffer(); | |
202 | for (Iterator<NLSSubstitution> iter= subs.iterator(); iter.hasNext();) { | |
203 | NLSSubstitution element= iter.next(); | |
204 | appendStaticField(buf, element); | |
205 | } | |
206 | return buf.toString(); | |
207 | } | |
208 | ||
209 | private void appendStaticField(StringBuffer buf, NLSSubstitution substitution) { | |
210 | buf.append("public static String "); //$NON-NLS-1$ | |
211 | buf.append(substitution.getKey()); | |
212 | buf.append(';'); | |
213 | } | |
214 | ||
215 | private String createGetStringMethod(String lineDelim) { | |
216 | StringBuffer result= new StringBuffer(); | |
217 | ||
218 | result.append("public static String "); //$NON-NLS-1$ | |
219 | int i= fSubstitutionPattern.indexOf(NLSRefactoring.KEY); | |
220 | if (i != -1) { | |
221 | result.append(fSubstitutionPattern.substring(0, i)); | |
222 | result.append("String key"); //$NON-NLS-1$ | |
223 | result.append(fSubstitutionPattern.substring(i + NLSRefactoring.KEY.length())); | |
224 | } else { | |
225 | //fallback | |
226 | result.append("getString(String key)"); //$NON-NLS-1$ | |
227 | } | |
228 | result.append('{').append(lineDelim); | |
229 | ||
230 | result.append("try {").append(lineDelim) //$NON-NLS-1$ | |
231 | .append("return ") //$NON-NLS-1$ | |
232 | .append(getResourceBundleConstantName()).append(".getString(key);").append(lineDelim) //$NON-NLS-1$ | |
233 | .append("} catch (MissingResourceException e) {").append(lineDelim) //$NON-NLS-1$ | |
234 | .append("return '!' + key + '!';").append(lineDelim) //$NON-NLS-1$ | |
235 | .append("}"); //$NON-NLS-1$ | |
236 | ||
237 | result.append(lineDelim).append('}'); | |
238 | return result.toString(); | |
239 | } | |
240 | ||
241 | public String createStaticInitializer(String lineDelim) { | |
242 | return "static {" //$NON-NLS-1$ | |
243 | + lineDelim | |
244 | + "// initialize resource bundle" //$NON-NLS-1$ | |
245 | + lineDelim | |
246 | + "NLS.initializeMessages(BUNDLE_NAME, " + fAccessorClassName + ".class);" //$NON-NLS-1$ //$NON-NLS-2$ | |
247 | + lineDelim | |
248 | + "}"; //$NON-NLS-1$ | |
249 | } | |
250 | ||
251 | public String createConstructor(String lineDelim) { | |
252 | return "private " + fAccessorClassName + "(){" + //$NON-NLS-2$//$NON-NLS-1$ | |
253 | lineDelim + '}'; | |
254 | } | |
255 | ||
256 | /* Currently not used. | |
257 | private String createGetStringMethodComment() throws CoreException { | |
258 | if (fCodeGenerationSettings.createComments) { | |
259 | String comment= CodeGeneration.getMethodComment(fCu, fAccessorClassName, "getString", //$NON-NLS-1$ | |
260 | new String[]{"key"}, //$NON-NLS-1$ | |
261 | new String[0], "QString;", //$NON-NLS-1$ | |
262 | null, lineDelim); | |
263 | if (comment == null) { | |
264 | return "";//$NON-NLS-1$ | |
265 | } | |
266 | ||
267 | return comment + lineDelim; | |
268 | } else { | |
269 | return "";//$NON-NLS-1$ | |
270 | } | |
271 | } | |
272 | */ | |
273 | ||
274 | private String getPropertyFileName() { | |
275 | return fResourceBundlePath.lastSegment(); | |
276 | } | |
277 | ||
278 | private String getPropertyFileNameWithoutExtension() { | |
279 | String fileName= getPropertyFileName(); | |
280 | return fileName.substring(0, fileName.indexOf(NLSRefactoring.PROPERTY_FILE_EXT)); | |
281 | } | |
282 | ||
283 | public String getResourceBundleName() throws CoreException { | |
284 | IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(fResourceBundlePath.removeLastSegments(1)); | |
285 | if (res != null && res.exists()) { | |
286 | IJavaElement el= JavaCore.create(res); | |
287 | if (el instanceof IPackageFragment) { | |
288 | IPackageFragment p= (IPackageFragment) el; | |
289 | return p.getElementName() + '.' + getPropertyFileNameWithoutExtension(); | |
290 | } else | |
291 | if ((el instanceof IPackageFragmentRoot) || (el instanceof IJavaProject)) { | |
292 | return getPropertyFileNameWithoutExtension(); | |
293 | } | |
294 | } | |
295 | throw new CoreException(new StatusInfo(IStatus.ERROR, "Resourcebundle not specified")); //$NON-NLS-1$ | |
296 | } | |
297 | } |