/* * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.java.decompiler.main.collectors; import org.jetbrains.java.decompiler.main.ClassesProcessor; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.struct.StructContext; import java.util.*; import java.util.Map.Entry; public class ImportCollector { private static final String JAVA_LANG_PACKAGE = "java.lang"; private Map<String, String> mapSimpleNames = new HashMap<String, String>(); private Set<String> setNotImportedNames = new HashSet<String>(); private String currentPackageSlash = ""; private String currentPackagePoint = ""; public ImportCollector(ClassNode root) { String clname = root.classStruct.qualifiedName; int index = clname.lastIndexOf("/"); if (index >= 0) { currentPackageSlash = clname.substring(0, index); currentPackagePoint = currentPackageSlash.replace('/', '.'); currentPackageSlash += "/"; } } public String getShortName(String fullname) { return getShortName(fullname, true); } public String getShortName(String fullname, boolean imported) { ClassesProcessor clproc = DecompilerContext.getClassProcessor(); ClassNode node = clproc.getMapRootClasses().get(fullname.replace('.', '/')); String retname = null; if (node != null && node.classStruct.isOwn()) { retname = node.simpleName; while (node.parent != null && node.type == ClassNode.CLASS_MEMBER) { retname = node.parent.simpleName + "." + retname; node = node.parent; } if (node.type == ClassNode.CLASS_ROOT) { fullname = node.classStruct.qualifiedName; fullname = fullname.replace('/', '.'); } else { return retname; } } else { fullname = fullname.replace('$', '.'); } String nshort = fullname; String npackage = ""; int lastpoint = fullname.lastIndexOf("."); if (lastpoint >= 0) { nshort = fullname.substring(lastpoint + 1); npackage = fullname.substring(0, lastpoint); } StructContext context = DecompilerContext.getStructContext(); boolean existsDefaultClass = (context.getClass(currentPackageSlash + nshort) != null && !npackage.equals(currentPackagePoint)) // current package || (context.getClass(nshort) != null); // default package if (existsDefaultClass || (mapSimpleNames.containsKey(nshort) && !npackage.equals(mapSimpleNames.get(nshort)))) { return fullname; } else if (!mapSimpleNames.containsKey(nshort)) { mapSimpleNames.put(nshort, npackage); if (!imported) { setNotImportedNames.add(nshort); } } return retname == null ? nshort : retname; } public int writeImports(TextBuffer buffer) { int importlines_written = 0; List<String> imports = packImports(); for (String s : imports) { buffer.append("import "); buffer.append(s); buffer.append(";"); buffer.appendLineSeparator(); importlines_written++; } return importlines_written; } private List<String> packImports() { List<Entry<String, String>> lst = new ArrayList<Entry<String, String>>(mapSimpleNames.entrySet()); Collections.sort(lst, new Comparator<Entry<String, String>>() { public int compare(Entry<String, String> par0, Entry<String, String> par1) { int res = par0.getValue().compareTo(par1.getValue()); if (res == 0) { res = par0.getKey().compareTo(par1.getKey()); } return res; } }); List<String> res = new ArrayList<String>(); for (Entry<String, String> ent : lst) { // exclude a current class or one of the nested ones, java.lang and empty packages if (!setNotImportedNames.contains(ent.getKey()) && !JAVA_LANG_PACKAGE.equals(ent.getValue()) && !ent.getValue().isEmpty()) { res.add(ent.getValue() + "." + ent.getKey()); } } return res; } }