/* * Copyright 2013 Google Inc. * * 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 com.google.gwt.core.ext.soyc.coderef; import com.google.gwt.thirdparty.guava.common.collect.Lists; import com.google.gwt.thirdparty.guava.common.collect.Maps; import java.util.ArrayList; import java.util.Collection; import java.util.Map; /** * It contains all packages and they reference to classes {@link ClassDescriptor}. * */ public class PackageDescriptor { public static final String DEFAULT_PKG = "<default>"; /** * Creates a package descriptor from a code model (mapping between class names and class * descriptors). */ public static PackageDescriptor from(Map<String, ClassDescriptor> codeModel) { PackageDescriptor topPackage = new PackageDescriptor(DEFAULT_PKG, ""); for (ClassDescriptor classDescriptor : codeModel.values()) { PackageDescriptor packageDescriptor = topPackage; if (!classDescriptor.getPackageName().equals(topPackage.longName)) { for (String packageName : classDescriptor.getPackageName().split("\\.")) { packageDescriptor = packageDescriptor.createOrGetChildPackage(packageName); } } packageDescriptor.addClass(classDescriptor); } topPackage.collapseEmptyPackages(); return topPackage; } private ArrayList<PackageDescriptor> packages = Lists.newArrayList(); private ArrayList<ClassDescriptor> classes = Lists.newArrayList(); private String name = DEFAULT_PKG; private String longName = ""; public PackageDescriptor(String packageName, String longPackageName) { name = packageName; longName = longPackageName; } /** * Condenses packages with single subpackages and no classes, eg. com {google {gwt {..}}} -> * com.google.gwt {..} */ private void collapseEmptyPackages() { if (packages.size() == 1 && classes.size() == 0) { PackageDescriptor childPackage = packages.get(0); childPackage.collapseEmptyPackages(); name = (name.equals(DEFAULT_PKG) ? "" : name + ".") + childPackage.name; longName = childPackage.longName; packages = childPackage.packages; classes = childPackage.classes; return; } for (PackageDescriptor pkg : packages) { pkg.collapseEmptyPackages(); } } private PackageDescriptor createOrGetChildPackage(String packageName) { // get child if any for (PackageDescriptor childPackage : packages) { if (childPackage.getName().equals(packageName)) { return childPackage; } } // create child PackageDescriptor childPackage = new PackageDescriptor(packageName, longName.length() > 0 ? longName + "." + packageName : packageName); this.addPackage(childPackage); return childPackage; } /** * Returns all classes in this package and its subpackages in a form of mapping between qualified * class name and class descriptor. */ public Map<String, ClassDescriptor> getAllClassesByName() { Map<String, ClassDescriptor> map = Maps.newTreeMap(); this.populateClassesByName(map); return map; } private void populateClassesByName(Map<String, ClassDescriptor> classesByName) { for (ClassDescriptor classDescriptor : this.getClasses()) { classesByName.put(classDescriptor.getFullName(), classDescriptor); } for (PackageDescriptor subPackage : this.getPackages()) { subPackage.populateClassesByName(classesByName); } } public void addClass(ClassDescriptor cls) { this.classes.add(cls); } public void addPackage(PackageDescriptor pkg) { this.packages.add(pkg); } /** * Returns the list of classes in this packages without including subpackages. */ public Collection<ClassDescriptor> getClasses() { return classes; } public String getName() { return name; } /** * Returns the list of subpackages. */ public Collection<PackageDescriptor> getPackages() { return packages; } }