Package org.apache.flex.compiler.internal.targets

Source Code of org.apache.flex.compiler.internal.targets.FlexRSLInfo

/*
*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You 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.apache.flex.compiler.internal.targets;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;

import org.apache.flex.compiler.common.DependencyType;
import org.apache.flex.compiler.common.DependencyTypeSet;
import org.apache.flex.compiler.config.RSLSettings;
import org.apache.flex.compiler.exceptions.LibraryCircularDependencyException;
import org.apache.flex.compiler.internal.projects.FlexProject;
import org.apache.flex.compiler.targets.ITargetSettings;
import org.apache.flex.swc.ISWC;

/**
* Class that contains information about RSLs used by a flex application SWF.
* <p>
* The information about RSLs is computed from {@link ITargetSettings} and
* {@code FlexApplicationFrame1Info}.
*/
final class FlexRSLInfo
{
    FlexRSLInfo(FlexApplicationFrame1Info frame1Info, FlexProject flexProject, ITargetSettings targetSettings)
    {
        this.frame1Info = frame1Info;
        this.flexProject = flexProject;
        this.targetSettings = targetSettings;
        requiredRSLs = new ArrayList<RSLSettings>();
        placeholderRSLs = new ArrayList<RSLSettings>();
       
        // The required RSLs are put in "requiredRSLs", the others are put in "placeholderRSLs".
        final List<RSLSettings> cdRSLs = targetSettings.getRuntimeSharedLibraryPath();
       
        final Set<String> unusedRSLs = getUnusedRSLs(cdRSLs);
       
        for (RSLSettings rslSettings : cdRSLs)
        {
            if (unusedRSLs.contains(rslSettings.getLibraryFile().getAbsolutePath()))
                placeholderRSLs.add(rslSettings);
            else
                requiredRSLs.add(rslSettings);
        }
    }
   
    private final FlexApplicationFrame1Info frame1Info;
    private final ITargetSettings targetSettings;
    private final FlexProject flexProject;
   
    /**
     * {@link RSLSettings} for RSLs that must be loaded for the flex application
     * to load properly.
     */
    final ArrayList<RSLSettings> requiredRSLs;
   
    /**
     * {@link RSLSettings} for RSLs were specified by
     * {@link ITargetSettings#getRuntimeSharedLibraryPath()}, but that were not
     * required by the flex application and were not marked as force load by
     * {@link RSLSettings#isForceLoad()}.
     */
    final ArrayList<RSLSettings> placeholderRSLs;
   
    private Set<String> getUnusedRSLs(List<RSLSettings> cdRSLs)
    {
        if (!targetSettings.removeUnusedRuntimeSharedLibraryPaths())
            return Collections.emptySet();
       
        List<String> unusedRSLs = new LinkedList<String>(); // running list of unused rsls
        Set<String>loadedDownstreamRSLs = new HashSet<String>()// loaded rsls downstream from first unused rsl
        boolean addDownstreamRSL = false;
       
        // Get unused RSLs and verify that there are no downstream RSLs that have
        // and inheritance dependency on them.
        for (RSLSettings info : cdRSLs)
        {
            String swcPath = info.getLibraryFile().getAbsolutePath();
           
            // skip if the associated swc is filtered from our context.
            if (isSWCFiltered(swcPath))
                continue;

            // skip loading the RSL if it does not contribute any classes to
            // the application and it is not forced.
            if (!frame1Info.contributingSWCs.contains(swcPath) &&
                !info.isForceLoad())
            {
                unusedRSLs.add(swcPath);
                addDownstreamRSL = true;
            }
            else if (addDownstreamRSL)
            {
                loadedDownstreamRSLs.add(swcPath);
            }
        }

        if (unusedRSLs.size() == 0)
            return Collections.emptySet();
       
        Set<String> requiredInheritanceRSLs = filterBasedOnInheritanceDependencies(unusedRSLs, loadedDownstreamRSLs);
        unusedRSLs.removeAll(requiredInheritanceRSLs);
        if (unusedRSLs.size() == 0)
            return Collections.emptySet();
       
        return new HashSet<String>(unusedRSLs);
    }
   
    /**
     * Create a set of swcs by filtering a list of swcs, choosing the swcs that
     * contain any inheritance dependencies from a set of filter swcs.
     *
     * @param swcPaths A list of swc paths to filter against the inheritance dependencies
     * of the swcPathFilters.
     * @param swcPathsFilter set of swc paths used as the inheritance dependendcy filter.
     *
     * @return subset of the swcPaths that contain inheritance dependencies
     * found in the swcPathsFilter.
     */
    private Set<String> filterBasedOnInheritanceDependencies(List<String>swcPaths,
                                                    Set<String>swcPathsFilter)
    {
        if (swcPathsFilter.isEmpty())
            return Collections.emptySet();
       
        // Loop over the filter swcs to see if they have any inheritance
        // dependencies on input swcs.
        Set<String> inheritanceDependencies = new HashSet<String>(swcPathsFilter.size());
        DependencyTypeSet inheritanceDependency = DependencyTypeSet.of(DependencyType.INHERITANCE);

        // get the inheritance dependencies of all filter swcs
        for (String swcPath : swcPathsFilter)
        {
            Set<String> swcDependencies;
            try
            {
                swcDependencies = flexProject.computeLibraryDependencies(new File(swcPath), inheritanceDependency);
            }
            catch (LibraryCircularDependencyException e)
            {
                // Should never get a circular dependency when asking for
                // inheritance dependencies. RSLs could never be loaded in the
                // correct order.
                // Skip this swc and move on to the next.
                assert false : e.getMessage();
                continue;
            }
           
            inheritanceDependencies.addAll(swcDependencies);
        }

        if (inheritanceDependencies.isEmpty())
            return Collections.emptySet();

        // check to see if any of the inheritance dependencies live in the
        // input swcs.
        // move thru the list backwards to we can handle the case where a
        // newly found swc can be used to test an upstream swc.
        Set<String> results = new HashSet<String>();
        for (ListIterator<String> iter = swcPaths.listIterator(swcPaths.size()); iter.hasPrevious();)
        {
            String targetSWC = iter.previous();
            if (inheritanceDependencies.contains(targetSWC))
            {
                results.add(targetSWC);

                // add the found swc to the list of inheritance dependencies.
                if (iter.hasPrevious())
                {
                    try
                    {
                        inheritanceDependencies.addAll(
                                flexProject.computeLibraryDependencies(new File(targetSWC),
                                        inheritanceDependency));
                    }
                    catch (LibraryCircularDependencyException e)
                    {
                        // Should never get a circular dependency when asking for
                        // inheritance dependencies. RSLs could never be loaded in the
                        // correct order.
                        // Skip this swc and move on to the next.
                        assert false : e.getMessage();
                    }
                }
            }
        }

        return results;
    }
   
    /**
     * Check if this SWC should be ignored because its min supported version is
     * greater than the current compatibility version.
     *
     * @param swcPath
     * @return true if the SWC should be filtered, false otherwise.
     */
    private boolean isSWCFiltered(String swcPath)
    {
        // if compatibility-version is not set then we won't be doing any filtering.
        if (flexProject.getCompatibilityVersion() == null)
            return false;
       
        int compatibilityVersion = flexProject.getCompatibilityVersion();
        ISWC swc = flexProject.getWorkspace().getSWCManager().get(new File(swcPath));
        if (compatibilityVersion < swc.getVersion().getFlexMinSupportedVersionInt())
        {
            return true;
        }
       
        return false;
    }
}
TOP

Related Classes of org.apache.flex.compiler.internal.targets.FlexRSLInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.