AccessorClassCreator.java :  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » corext » refactoring » nls » Java Open Source

Java Open Source » IDE Eclipse » jdt 
jdt » org » eclipse » jdt » internal » corext » refactoring » nls » AccessorClassCreator.java
/*******************************************************************************
 * Copyright (c) 2000, 2008 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 added= new HashSet();
    List subs= new ArrayList();
    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() {
      private Collator fCollator= Collator.getInstance();
      public int compare(Object o1, Object o2) {
        NLSSubstitution s0= (NLSSubstitution)o1;
        NLSSubstitution s1= (NLSSubstitution)o2;
        return fCollator.compare(s0.getKey(), s1.getKey());
      }
    });
    StringBuffer buf= new StringBuffer();
    for (Iterator iter= subs.iterator(); iter.hasNext();) {
      NLSSubstitution element= (NLSSubstitution)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$
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.