| /** |
| * Copyright (c) 2005-2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.html |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| */ |
| package org.eclipse.emf.test.tools; |
| |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.SortedSet; |
| import java.util.TreeSet; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.emf.codegen.util.CodeGenUtil; |
| import org.eclipse.emf.common.EMFPlugin; |
| import org.eclipse.jdt.core.dom.ASTParser; |
| import org.eclipse.jdt.core.dom.CompilationUnit; |
| import org.eclipse.jdt.core.dom.ImportDeclaration; |
| |
| /** |
| * The ImportManager implementation from EMF 2.4. |
| */ |
| class OldImportManager |
| { |
| protected SortedSet<String> imports = new TreeSet<String>(); |
| protected HashMap<String, String> shortNameToImportMap = new HashMap<String, String>(); |
| protected HashSet<String> javaLangImports = null; |
| protected HashSet<String> importedPackages; |
| |
| public OldImportManager(String compilationUnitPackage) |
| { |
| importedPackages = new HashSet<String>(); |
| importedPackages.add(compilationUnitPackage); |
| } |
| |
| public Collection<String> getImports() |
| { |
| return imports; |
| } |
| |
| public String getImportedName(String qualifiedName) |
| { |
| String indices = ""; |
| int firstBracket = qualifiedName.indexOf("["); |
| if (firstBracket != -1) |
| { |
| indices = qualifiedName.substring(firstBracket); |
| qualifiedName = qualifiedName.substring(0, firstBracket); |
| } |
| |
| String baseName = qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1); |
| |
| String shortName = baseName; |
| int firstDollar = shortName.indexOf("$"); |
| if (firstDollar != -1) |
| { |
| shortName = shortName.substring(0, firstDollar); |
| } |
| |
| String registeredName = shortNameToImportMap.get(shortName); |
| if (registeredName == null) |
| { |
| registeredName = "java.lang." + shortName; |
| if (qualifiedName.equals(registeredName)) |
| { |
| if (javaLangImports != null && javaLangImports.contains(shortName)) |
| { |
| imports.add(qualifiedName); |
| } |
| return shortName + indices; |
| } |
| else |
| { |
| return qualifiedName + indices; |
| } |
| } |
| else |
| { |
| if (qualifiedName.startsWith(registeredName)) |
| { |
| if (qualifiedName.length () == registeredName.length()) |
| { |
| return baseName.replace('$', '.') + indices; |
| } |
| else |
| { |
| char character = qualifiedName.charAt(registeredName.length()); |
| if (character == '.' || character == '$') |
| { |
| return baseName.replace('$', '.') + indices; |
| } |
| } |
| } |
| return qualifiedName.replace('$', '.') + indices; |
| } |
| } |
| |
| public void addImport(String packageName, String shortName) |
| { |
| int firstBracket = shortName.indexOf("["); |
| if (firstBracket != -1) shortName = shortName.substring(0, firstBracket); |
| basicAdd(packageName, shortName, packageName + "." + shortName); |
| } |
| |
| public void addImport(String qualifiedName) |
| { |
| int firstBracket = qualifiedName.indexOf("["); |
| if (firstBracket != -1) qualifiedName = qualifiedName.substring(0, firstBracket); |
| |
| int lastDot = qualifiedName.lastIndexOf("."); |
| String shortName = qualifiedName.substring(lastDot + 1); |
| int firstDollar = shortName.indexOf("$"); |
| if (firstDollar != -1) |
| { |
| shortName = shortName.substring(0, firstDollar); |
| } |
| |
| String packageName = lastDot == -1 ? null : qualifiedName.substring(0, lastDot); |
| basicAdd(packageName, shortName, qualifiedName); |
| } |
| |
| public void addMasterImport(String packageName, String shortName) |
| { |
| shortNameToImportMap.put(shortName, packageName + "." + shortName); |
| } |
| |
| public void addJavaLangImports(List<String> javaLangClassNames) |
| { |
| if (!javaLangClassNames.isEmpty()) |
| { |
| javaLangImports = new HashSet<String>(); |
| javaLangImports.addAll(javaLangClassNames); |
| } |
| } |
| |
| public boolean hasImport(String shortName) |
| { |
| return shortNameToImportMap.containsKey(shortName); |
| } |
| |
| public void addCompilationUnitImports(String compilationUnitContents) |
| { |
| if (EMFPlugin.IS_ECLIPSE_RUNNING) |
| { |
| EclipseHelper.addCompilationUnitImports(importedPackages, shortNameToImportMap, compilationUnitContents); |
| } |
| else |
| { |
| Pattern importPattern = Pattern.compile("import\\s+([^\\s;]*);\\s*", Pattern.MULTILINE | Pattern.DOTALL); |
| Matcher matcher = importPattern.matcher(compilationUnitContents); |
| while (matcher.find()) |
| { |
| String qualifiedName = matcher.group(1); |
| int lastDot = qualifiedName.lastIndexOf("."); |
| String shortName = qualifiedName.substring(lastDot + 1); |
| if (shortName.equals("*")) |
| { |
| String packageName = qualifiedName.substring(0, lastDot); |
| importedPackages.add(packageName); |
| } |
| else |
| { |
| shortNameToImportMap.put(shortName, qualifiedName); |
| } |
| } |
| } |
| } |
| |
| private static class EclipseHelper |
| { |
| public static void addCompilationUnitImports |
| (Set<String> importedPackages, Map<String, String> shortNameToImportMap, String compilationUnitContents) |
| { |
| ASTParser parser = CodeGenUtil.EclipseUtil.newASTParser(true); |
| parser.setSource(compilationUnitContents.toCharArray()); |
| CompilationUnit compilationUnit = (CompilationUnit)parser.createAST(new NullProgressMonitor()); |
| for (Iterator<?> i = compilationUnit.imports().iterator(); i.hasNext();) |
| { |
| ImportDeclaration importDeclaration = (ImportDeclaration)i.next(); |
| String qualifiedName = importDeclaration.getName().getFullyQualifiedName(); |
| int lastDot = qualifiedName.lastIndexOf("."); |
| String shortName = qualifiedName.substring(lastDot + 1); |
| if (shortName.equals("*")) |
| { |
| String packageName = qualifiedName.substring(0, lastDot); |
| importedPackages.add(packageName); |
| } |
| else |
| { |
| shortNameToImportMap.put(shortName, qualifiedName); |
| } |
| } |
| } |
| } |
| |
| public void addPseudoImport(String qualifiedName) |
| { |
| int lastDot = qualifiedName.lastIndexOf("."); |
| String shortName = qualifiedName.substring(lastDot + 1); |
| if (shortName.equals("*")) |
| { |
| String packageName = qualifiedName.substring(0, lastDot); |
| importedPackages.add(packageName); |
| } |
| else |
| { |
| shortNameToImportMap.put(shortName, qualifiedName); |
| } |
| } |
| |
| private void basicAdd(String packageName, String shortName, String qualifiedName) |
| { |
| if (shortName.equals("*")) |
| { |
| importedPackages.add(packageName); |
| imports.add(qualifiedName); |
| } |
| else if (!shortNameToImportMap.containsKey(shortName) && (!CodeGenUtil.isJavaDefaultType(shortName))) |
| { |
| shortNameToImportMap.put(shortName, qualifiedName); |
| |
| if (!importedPackages.contains(packageName)) |
| { |
| imports.add(qualifiedName); |
| } |
| } |
| } |
| |
| public String computeSortedImports() |
| { |
| String NL = System.getProperties().getProperty("line.separator"); |
| StringBuffer imports = new StringBuffer(); |
| |
| String previousPackageName = null; |
| for (String importName : getImports()) |
| { |
| int index = importName.lastIndexOf("."); |
| if (index != -1) |
| { |
| String packageName = importName.substring(0, index); |
| if (previousPackageName != null && !previousPackageName.equals(packageName)) |
| { |
| imports.append(NL); |
| } |
| previousPackageName = packageName; |
| } |
| imports.append(NL + "import " + importName + ";"); |
| } |
| |
| return imports.toString(); |
| } |
| } |
| |
| /** |
| * Extension of the old ImportManager implementation that adds new APIs moved from GenModel in EMF 2.5. |
| * This class would exhibit exactly the same behavior as the new ImportManager, but for numerous bugs in the old implementation. |
| */ |
| public class ImportManager extends OldImportManager |
| { |
| private String lineDelimiter; |
| private StringBuilder importStringBuilder; |
| private StringBuffer importStringBuffer; |
| private int importInsertionPoint; |
| |
| public ImportManager(String compilationUnitPackage, String compilationUnitShortName) |
| { |
| this(compilationUnitPackage); |
| addMasterImport(compilationUnitPackage, compilationUnitShortName); |
| } |
| |
| public ImportManager(String compilationUnitPackage) |
| { |
| super(compilationUnitPackage); |
| } |
| |
| public String getImportedName(String qualifiedName, boolean autoImport) |
| { |
| int index = qualifiedName.indexOf("<"); |
| if (index >= 0) |
| { |
| String baseName = qualifiedName.substring(0, index); |
| StringBuilder result = new StringBuilder(getImportedName(baseName, autoImport)); |
| result.append("<"); |
| for (int start = ++index, end = qualifiedName.lastIndexOf(">") + 1; index < end; ++index) |
| { |
| char character = qualifiedName.charAt(index); |
| switch (character) |
| { |
| case ' ': |
| case ',': |
| case '<': |
| case '>': |
| case '&': |
| { |
| if (start != index) |
| { |
| String segment = qualifiedName.substring(start, index); |
| result.append(getImportedName(segment, autoImport)); |
| } |
| result.append(character); |
| start = index + 1; |
| break; |
| } |
| default: |
| { |
| break; |
| } |
| } |
| } |
| return result.toString(); |
| } |
| |
| index = qualifiedName.indexOf("$"); |
| String baseName = index == -1 ? qualifiedName : qualifiedName.substring(0, index); |
| if (baseName.contains(".")) |
| { |
| addImport(index == -1 ? qualifiedName : qualifiedName.substring(0, index)); |
| return super.getImportedName(qualifiedName); |
| } |
| else |
| { |
| return qualifiedName; |
| } |
| } |
| |
| public String getLineDelimiter() |
| { |
| return lineDelimiter == null ? System.getProperty("line.separator") : lineDelimiter; |
| } |
| |
| public void setLineDelimiter(String lineDelimiter) |
| { |
| this.lineDelimiter = lineDelimiter; |
| } |
| |
| public void markImportLocation(StringBuilder stringBuilder) |
| { |
| importStringBuffer = null; |
| importStringBuilder = stringBuilder; |
| importInsertionPoint = stringBuilder.length(); |
| addCompilationUnitImports(stringBuilder.toString()); |
| } |
| |
| public void markImportLocation(StringBuffer stringBuffer) |
| { |
| importStringBuilder = null; |
| importStringBuffer = stringBuffer; |
| importInsertionPoint = stringBuffer.length(); |
| addCompilationUnitImports(stringBuffer.toString()); |
| } |
| |
| public void emitSortedImports() |
| { |
| if (importStringBuilder != null) |
| { |
| importStringBuilder.insert(importInsertionPoint, computeSortedImports()); |
| } |
| else if (importStringBuffer != null) |
| { |
| importStringBuffer.insert(importInsertionPoint, computeSortedImports()); |
| } |
| } |
| } |