| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.corext.refactoring.nls; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import com.ibm.icu.text.Collator; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| |
| import org.eclipse.text.edits.TextEdit; |
| |
| import org.eclipse.ltk.core.refactoring.Change; |
| |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; |
| import org.eclipse.jdt.core.formatter.CodeFormatter; |
| |
| import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; |
| import org.eclipse.jdt.internal.corext.refactoring.nls.changes.CreateTextFileChange; |
| import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil; |
| import org.eclipse.jdt.internal.corext.util.JavaModelUtil; |
| |
| import org.eclipse.jdt.ui.CodeGeneration; |
| |
| import org.eclipse.jdt.internal.ui.JavaPlugin; |
| import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; |
| import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache; |
| |
| public class AccessorClassCreator { |
| |
| private final ICompilationUnit fCu; |
| private final String fAccessorClassName; |
| private final IPath fAccessorPath; |
| private final IPath fResourceBundlePath; |
| private final IPackageFragment fAccessorPackage; |
| private final boolean fIsEclipseNLS; |
| private final NLSSubstitution[] fNLSSubstitutions; |
| private final String fSubstitutionPattern; |
| |
| private AccessorClassCreator(ICompilationUnit cu, String accessorClassname, IPath accessorPath, IPackageFragment accessorPackage, IPath resourceBundlePath, boolean isEclipseNLS, NLSSubstitution[] nlsSubstitutions, String substitutionPattern) { |
| fCu= cu; |
| fAccessorClassName= accessorClassname; |
| fAccessorPath= accessorPath; |
| fAccessorPackage= accessorPackage; |
| fResourceBundlePath= resourceBundlePath; |
| fIsEclipseNLS= isEclipseNLS; |
| fNLSSubstitutions= nlsSubstitutions; |
| fSubstitutionPattern= substitutionPattern; |
| } |
| |
| public static Change create(ICompilationUnit cu, String accessorClassname, IPath accessorPath, IPackageFragment accessorPackage, IPath resourceBundlePath, boolean isEclipseNLS, NLSSubstitution[] nlsSubstitutions, String substitutionPattern, IProgressMonitor pm) throws CoreException { |
| AccessorClassCreator accessorClass= new AccessorClassCreator(cu, accessorClassname, accessorPath, accessorPackage, resourceBundlePath, isEclipseNLS, nlsSubstitutions, substitutionPattern); |
| |
| return new CreateTextFileChange(accessorPath, accessorClass.createAccessorCUSource(pm), null, "java"); //$NON-NLS-1$ |
| } |
| |
| private String createAccessorCUSource(IProgressMonitor pm) throws CoreException { |
| IProject project= getFileHandle(fAccessorPath).getProject(); |
| String lineDelimiter= StubUtility.getLineDelimiterPreference(project); |
| return CodeFormatterUtil.format(CodeFormatter.K_COMPILATION_UNIT, getUnformattedSource(pm), 0, lineDelimiter, fCu.getJavaProject()); |
| } |
| |
| private static IFile getFileHandle(IPath filePath) { |
| if (filePath == null) |
| return null; |
| return ResourcesPlugin.getWorkspace().getRoot().getFile(filePath); |
| } |
| |
| private String getUnformattedSource(IProgressMonitor pm) throws CoreException { |
| ICompilationUnit newCu= null; |
| try { |
| newCu= fAccessorPackage.getCompilationUnit(fAccessorPath.lastSegment()).getWorkingCopy(null); |
| |
| String typeComment= null, fileComment= null; |
| final IJavaProject project= newCu.getJavaProject(); |
| final String lineDelim= StubUtility.getLineDelimiterUsed(project); |
| if (StubUtility.doAddComments(project)) { |
| typeComment= CodeGeneration.getTypeComment(newCu, fAccessorClassName, lineDelim); |
| fileComment= CodeGeneration.getFileComment(newCu, lineDelim); |
| } |
| String classContent= createClass(lineDelim); |
| String cuContent= CodeGeneration.getCompilationUnitContent(newCu, fileComment, typeComment, classContent, lineDelim); |
| if (cuContent == null) { |
| StringBuffer buf= new StringBuffer(); |
| if (fileComment != null) { |
| buf.append(fileComment).append(lineDelim); |
| } |
| if (!fAccessorPackage.isDefaultPackage()) { |
| buf.append("package ").append(fAccessorPackage.getElementName()).append(';'); //$NON-NLS-1$ |
| } |
| buf.append(lineDelim).append(lineDelim); |
| if (typeComment != null) { |
| buf.append(typeComment).append(lineDelim); |
| } |
| buf.append(classContent); |
| cuContent= buf.toString(); |
| } |
| |
| newCu.getBuffer().setContents(cuContent); |
| addImportsToAccessorCu(newCu, pm); |
| return newCu.getSource(); |
| } finally { |
| if (newCu != null) { |
| newCu.discardWorkingCopy(); |
| } |
| } |
| } |
| |
| private void addImportsToAccessorCu(ICompilationUnit newCu, IProgressMonitor pm) throws CoreException { |
| ImportRewrite is= StubUtility.createImportRewrite(newCu, true); |
| if (fIsEclipseNLS) { |
| is.addImport("org.eclipse.osgi.util.NLS"); //$NON-NLS-1$ |
| } else { |
| is.addImport("java.util.MissingResourceException"); //$NON-NLS-1$ |
| is.addImport("java.util.ResourceBundle"); //$NON-NLS-1$ |
| } |
| TextEdit edit= is.rewriteImports(pm); |
| JavaModelUtil.applyEdit(newCu, edit, false, null); |
| } |
| |
| private String createClass(String lineDelim) throws CoreException { |
| if (fIsEclipseNLS) { |
| MembersOrderPreferenceCache sortOrder= JavaPlugin.getDefault().getMemberOrderPreferenceCache(); |
| int constructorIdx= sortOrder.getCategoryIndex(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX); |
| int fieldIdx= sortOrder.getCategoryIndex(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX); |
| int initIdx= sortOrder.getCategoryIndex(MembersOrderPreferenceCache.STATIC_INIT_INDEX); |
| |
| String constructor= createConstructor(lineDelim) + lineDelim; |
| String initializer= createStaticInitializer(lineDelim) + lineDelim; |
| String fields= createStaticFields() + lineDelim; |
| |
| StringBuffer result= new StringBuffer(); |
| result.append("public class ").append(fAccessorClassName).append(" extends NLS {"); //$NON-NLS-1$ //$NON-NLS-2$ |
| result.append("private static final String ").append(NLSRefactoring.BUNDLE_NAME).append(" = \"").append(getResourceBundleName()).append("\"; "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| result.append(NLSElement.createTagText(1)).append(lineDelim); |
| |
| if (constructorIdx < fieldIdx) { |
| if (fieldIdx < initIdx) { |
| result.append(constructor); |
| result.append(fields); |
| result.append(initializer); |
| } else { |
| result.append(constructor); |
| result.append(initializer); |
| result.append(fields); |
| } |
| } else { |
| if (constructorIdx < initIdx) { |
| result.append(fields); |
| result.append(constructor); |
| result.append(initializer); |
| } else { |
| result.append(fields); |
| result.append(initializer); |
| result.append(constructor); |
| } |
| } |
| |
| result.append('}').append(lineDelim); |
| |
| return result.toString(); |
| } else { |
| MembersOrderPreferenceCache sortOrder= JavaPlugin.getDefault().getMemberOrderPreferenceCache(); |
| int constructorIdx= sortOrder.getCategoryIndex(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX); |
| int methodIdx= sortOrder.getCategoryIndex(MembersOrderPreferenceCache.METHOD_INDEX); |
| |
| String constructor= lineDelim + createConstructor(lineDelim); |
| String method= lineDelim + createGetStringMethod(lineDelim); |
| |
| StringBuffer result= new StringBuffer(); |
| result.append("public class ").append(fAccessorClassName).append(" {"); //$NON-NLS-1$ //$NON-NLS-2$ |
| result.append("private static final String ").append(NLSRefactoring.BUNDLE_NAME); //$NON-NLS-1$ |
| result.append(" = \"").append(getResourceBundleName()).append("\"; ").append(NLSElement.createTagText(1)).append(lineDelim); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| result.append(lineDelim).append("private static final ResourceBundle ").append(getResourceBundleConstantName()); //$NON-NLS-1$ |
| result.append("= ResourceBundle.getBundle(").append(NLSRefactoring.BUNDLE_NAME).append(");").append(lineDelim); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| if (constructorIdx < methodIdx) { |
| result.append(constructor); |
| result.append(method); |
| } else { |
| result.append(constructor); |
| result.append(method); |
| } |
| |
| result.append(lineDelim).append('}').append(lineDelim); |
| |
| return result.toString(); |
| } |
| } |
| |
| private String getResourceBundleConstantName() { |
| return "RESOURCE_BUNDLE";//$NON-NLS-1$ |
| } |
| |
| private String createStaticFields() { |
| HashSet<String> added= new HashSet<String>(); |
| List<NLSSubstitution> subs= new ArrayList<NLSSubstitution>(); |
| for (int i= 0; i < fNLSSubstitutions.length; i++) { |
| NLSSubstitution substitution= fNLSSubstitutions[i]; |
| int newState= substitution.getState(); |
| if ((substitution.hasStateChanged() || substitution.isAccessorRename())&& newState == NLSSubstitution.EXTERNALIZED) { |
| if (added.add(substitution.getKey())) |
| subs.add(substitution); |
| } |
| } |
| Collections.sort(subs, new Comparator<NLSSubstitution>() { |
| private Collator fCollator= Collator.getInstance(); |
| public int compare(NLSSubstitution s0, NLSSubstitution s1) { |
| return fCollator.compare(s0.getKey(), s1.getKey()); |
| } |
| }); |
| StringBuffer buf= new StringBuffer(); |
| for (Iterator<NLSSubstitution> iter= subs.iterator(); iter.hasNext();) { |
| NLSSubstitution element= iter.next(); |
| appendStaticField(buf, element); |
| } |
| return buf.toString(); |
| } |
| |
| private void appendStaticField(StringBuffer buf, NLSSubstitution substitution) { |
| buf.append("public static String "); //$NON-NLS-1$ |
| buf.append(substitution.getKey()); |
| buf.append(';'); |
| } |
| |
| private String createGetStringMethod(String lineDelim) { |
| StringBuffer result= new StringBuffer(); |
| |
| result.append("public static String "); //$NON-NLS-1$ |
| int i= fSubstitutionPattern.indexOf(NLSRefactoring.KEY); |
| if (i != -1) { |
| result.append(fSubstitutionPattern.substring(0, i)); |
| result.append("String key"); //$NON-NLS-1$ |
| result.append(fSubstitutionPattern.substring(i + NLSRefactoring.KEY.length())); |
| } else { |
| //fallback |
| result.append("getString(String key)"); //$NON-NLS-1$ |
| } |
| result.append('{').append(lineDelim); |
| |
| result.append("try {").append(lineDelim) //$NON-NLS-1$ |
| .append("return ") //$NON-NLS-1$ |
| .append(getResourceBundleConstantName()).append(".getString(key);").append(lineDelim) //$NON-NLS-1$ |
| .append("} catch (MissingResourceException e) {").append(lineDelim) //$NON-NLS-1$ |
| .append("return '!' + key + '!';").append(lineDelim) //$NON-NLS-1$ |
| .append("}"); //$NON-NLS-1$ |
| |
| result.append(lineDelim).append('}'); |
| return result.toString(); |
| } |
| |
| private String createStaticInitializer(String lineDelim) { |
| return "static {" //$NON-NLS-1$ |
| + lineDelim |
| + "// initialize resource bundle" //$NON-NLS-1$ |
| + lineDelim |
| + "NLS.initializeMessages(BUNDLE_NAME, " + fAccessorClassName + ".class);" //$NON-NLS-1$ //$NON-NLS-2$ |
| + lineDelim |
| + "}"; //$NON-NLS-1$ |
| } |
| |
| private String createConstructor(String lineDelim) { |
| return "private " + fAccessorClassName + "(){" + //$NON-NLS-2$//$NON-NLS-1$ |
| lineDelim + '}'; |
| } |
| |
| /* Currently not used. |
| private String createGetStringMethodComment() throws CoreException { |
| if (fCodeGenerationSettings.createComments) { |
| String comment= CodeGeneration.getMethodComment(fCu, fAccessorClassName, "getString", //$NON-NLS-1$ |
| new String[]{"key"}, //$NON-NLS-1$ |
| new String[0], "QString;", //$NON-NLS-1$ |
| null, lineDelim); |
| if (comment == null) { |
| return "";//$NON-NLS-1$ |
| } |
| |
| return comment + lineDelim; |
| } else { |
| return "";//$NON-NLS-1$ |
| } |
| } |
| */ |
| |
| private String getPropertyFileName() { |
| return fResourceBundlePath.lastSegment(); |
| } |
| |
| private String getPropertyFileNameWithoutExtension() { |
| String fileName= getPropertyFileName(); |
| return fileName.substring(0, fileName.indexOf(NLSRefactoring.PROPERTY_FILE_EXT)); |
| } |
| |
| private String getResourceBundleName() throws CoreException { |
| IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(fResourceBundlePath.removeLastSegments(1)); |
| if (res != null && res.exists()) { |
| IJavaElement el= JavaCore.create(res); |
| if (el instanceof IPackageFragment) { |
| IPackageFragment p= (IPackageFragment) el; |
| return p.getElementName() + '.' + getPropertyFileNameWithoutExtension(); |
| } else |
| if ((el instanceof IPackageFragmentRoot) || (el instanceof IJavaProject)) { |
| return getPropertyFileNameWithoutExtension(); |
| } |
| } |
| throw new CoreException(new StatusInfo(IStatus.ERROR, "Resourcebundle not specified")); //$NON-NLS-1$ |
| } |
| } |