/*
* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Support for building the Maxine VM boot image, possibly including extension by third parties.
*
* Then general strategy for boot image building is:
* <ul>
* <li>Generate a set of packages, and hence classes, from some designated root packages that are <i>candidates</> for
* inclusion in the boot image.</li>
* <li>Apply configuration options to limit the set of packages (classes) that are actually included. Examples of
* configuration options would be hardware and operating system platforms and specific choices of the
* {@link com.sun.max.vm.VMScheme schemes} that provide Maxine with much of its configurability.</li>
* </ul>
* Note that while the boot image really is composed from a set of classes it almost always the case that all classes
* from a package are included, so we can use package as shorthand for all the classes in the package. This is true, in
* part, because we do not mix configuration-specific classes in the same package, but instead use sub-packages, e.g.
* {@code com.sun.max.vm.compiler.target} and {@code com.sun.max.vm.compiler.target.amd64}. In particular, there is no
* support for configuration-specific inclusion classes only entire packages. However, it is possible to specifically
* enumerate the set of classes to be included from a given package, which is used mostly for JDK classes.
* <p>
* {@link com.sun.max.config.BootImagePackage} provides the basic mechanisms for constructing the set of
* candidate packages. The check on whether to actually include a package is made later by the
* boot image builder. Key to a package being a candidate for inclusion is the existence of a class named
* {@code Package} in the package to be included. {@code Package} must be a subclass of
* {@link com.sun.max.config.BootImagePackage}. It is usually a direct subclass, but need not be.
* An extension could define a subclass of {@link com.sun.max.config.BootImagePackage} with
* extension-specific configuration methods and subclass that instead. The key is that the class must be
* named {@code Package}, since that is what the search mechanism looks for. An example of the simplest
* form of this class is {@link com.sun.max.config.Package here}.
* <p>
* The package discovery process is initiated by the
* {@link com.sun.max.config.BootImagePackage#getTransitiveSubPackages(com.sun.max.program.Classpath, BootImagePackage[])}
* method. The first argument denotes the class path that the boot image builder is using, which must contain
* all the packages needed for the build. The second argument is an array of root packages. These essentially define a forest
* of trees that will be used as the starting point to search for packages. The {@link com.sun.max.vm.hosted.BootImageGenerator
* boot image generator} passes exactly one root, {@code com.sun.max.config.Package}, so all packages must be reachable
* from this package. At first sight this seems highly restrictive. However, {@link com.sun.max.config.BootImagePackage}
* provides a <i>redirection</i> mechanism whereby additional roots can be specified using the
* {@link com.sun.max.config.BootImagePackage#BootImagePackage(String...) constructor variant}.
* <p>
* The virtue of the single root is that it is easy to find the starting point in either the Maxine VM codebase or
* an extension. Maxine use four sub-packages of {@code com.sun.max.config} to collect together the packages to include in the
* boot image, {@code base}, {@code c1x}, {@code jdk} and {@code vm}. The {@code Package} classes
* in each of the these sub-packages use the redirection constructor to include other packages in different
* parts of the package namespace. In general, those other packages do not contain {@code Package}
* classes as the system creates them automatically as needed. The only reason to have a {@code Package}
* class in a redirected sub-package is to override the default behavior of the parent. For example, platform-specific
* packages must have a definition for the method
* {@link com.sun.max.config.BootImagePackage#isPartOfMaxineVM(com.sun.max.vm.VMConfiguration)}.
* <p>
* Package discovery proceeds by iterating over the roots in order and, for each root,
* scanning every element of the given class path looking for packages that are sub-packages
* of the root (or the root itself). The class path scan handles both file system directories and jar files.
* A global map of discovered packages is maintained across the entire process
* and is used to produce the result. At this stage we are gathering package names as {@link java.lang.String strings}.
* The result for each root is a set of names stored as a {@link java.util.TreeSet}. Note that only packages
* that are non-empty are added to the set. The package names are then processed
* in the order returned by {@link java.util.TreeSet}, that is, lexicographic, so parent packages are processed
* before children. An attempt is made to instantiate a {@code Package} class in the given
* package using {@link java.lang.Class#forName(String)}. If this succeeds the {@code Package} instance is added
* to the map. Depending on which superclass constructor the {@code Package} class invoked, the resulting instance
* may contain redirection references to other packages. Any redirection references that are tagged
* as <i>recursive</i> become new roots that are added to the end of the root array for later processing.
* A redirection package is defined as one that is not with the subtree of the root being processed.
* <p>
* If the attempt is made to instantiate a {@code Package} class fails then a search is made
* in the parent hierarchy to find a {@code Package} instance to use as the clone with which to create a new substitute instance.
* The search proceeds back up the package hierarchy until a {@code Package} instance is found
* in the global map that matches the name associated with the node at that point in the hierarchy. Note that such a node must exist
* as roots always contain a {@code Package} instance. The discovered instance is then cloned and
* its name set appropriately. Other state is reset to the default values. Note that, if you subclass
* {@link com.sun.max.config.BootImagePackage} and add additional state it is your responsibility to decide
* whether the state should be reset or not after a clone (and you must override the {@link java.lang.Object#clone} method).
* The fact that the nearest parent is used for the clone ensures that any overridden methods
* in a {@code Package} class in an interior node carries forward to all child nodes. So, for example,
* platform-specific configuration in a sub-tree works as expected.
* <p>
* Once the package is discovered, it added to the global map. If the package contains references to other packages
* then each of these is also added to the map. Furthermore, any of these that refer to packages outside of this tree
* and are tagged as recursive are added as new roots to be processed later.
* <p>
* Once all the roots are processed the set of packages contained in the global map is returned as the result.
* <h2>Constructors</h2>
* Note that all constructors are {@code protected} to ensure that they are only invoked from {@code Package} classes.
* <ul>
* <li>{@code Package()}: this is typically only used in packages that need to override
* {@link com.sun.max.config.BootImagePackage#isPartOfMaxineVM}, and causes all of the classes
* in the package containing the {@code Package} class to be candidates for inclusion. Nested packages are not included unless
* some parent package was specified as recursive.</li>
* <li>{@code Package(String name, boolean recursive)}: this is the simplest form of redirection, designating a single
* root, {@code name}, and specifying via {@code recursive}, whether nested packages should be included (recursively).</li>
* <li>{@code Package(String name...)}: this is the most general form of constructor. {@code name} may designate a single (non-recursive) package,
* using {@code a.b.c.*}, a (recursive) package tree using {@code a.b.c.**} or a single class using {@code a.b.c.D}. In the latter case, several
* specifications may denote different classes from the package and the end result is the union of them all. Note that it is not possible, by design,
* to exclude a class. However, it is possible to exclude the classes of a package within an tree that is otherwise destined to be included by recursive inclusion.
* This is achieve by inheriting from {@link com.sun.max.config.ExcludedPackage}, which simply defines
* {@link com.sun.max.config.BootImagePackage#isPartOfMaxineVM} to return {@code false}.</li>
* </ul>
* <p>
*
*<h2>Scheme packages</h2>
* Packages that contain scheme definitions must always contain a {@code Package} class and
* override {@link com.sun.max.config.BootImagePackage#isPartOfMaxineVM}
* since schemes are configurable. The logic for deciding whether the package is to be included is limited to testing the
* instance or name of the {@link com.sun.max.config.BootImagePackage} that has been configured, or testing whether the
* scheme class itself is assignable to the scheme class defined by the package under test. In particular the scheme instance
* cannot be used since the schemes are no instantiated until after the configuration analysis is complete.
* <p>
* The constructor for the {@code Package} class must also register the scheme class using the
* {@link com.sun.max.config.BootImagePackage#registerScheme(Class, Class)} method.
*/
package com.sun.max.config;