Package flex2.compiler.as3

Source Code of flex2.compiler.as3.EmbedUtil

/*
*
*  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 flex2.compiler.as3;

import flash.util.Trace;
import flex2.compiler.AssetInfo;
import flex2.compiler.CompilationUnit;
import flex2.compiler.Source;
import flex2.compiler.SymbolTable;
import flex2.compiler.Transcoder;
import flex2.compiler.TranscoderException;
import flex2.compiler.common.LocalFilePathResolver;
import flex2.compiler.common.PathResolver;
import flex2.compiler.common.SinglePathResolver;
import flex2.compiler.io.VirtualFile;
import flex2.compiler.util.MimeMappings;
import flex2.compiler.util.ThreadLocalToolkit;

import java.util.List;
import java.util.Map;
import java.util.Iterator;

/**
* This class contains utility methods used to transcode embedded
* assets.
*
* @author Brian Deitte
*/
public class EmbedUtil
{
    public static Transcoder.TranscodingResults transcode(Transcoder[] transcoders,
                                                          CompilationUnit unit, SymbolTable symbolTable,
                                                          String className, Map<String, Object> args, int line, int col,
                                                          boolean generateCode)
    {
    PathResolver context = new PathResolver();
    Transcoder.TranscodingResults results = null;
        Source source = unit.getSource();

        if (!args.containsKey(Transcoder.RESOLVED_SOURCE))
        {
            String embedSource = (String) args.get(Transcoder.SOURCE);

            // paths starting with slash are either relative to a source path root or
            // fully qualified.
            if (embedSource != null && embedSource.charAt(0) == '/')
            {
                VirtualFile pathRoot = source.getPathRoot();
                if (pathRoot != null)
                {
                    context.addSinglePathResolver(pathRoot);
                }
                Object owner = source.getOwner();
                if (owner instanceof SinglePathResolver)
                {
                    context.addSinglePathResolver((SinglePathResolver) owner);
                }
            }
            else
            {
                if ( args.containsKey(Transcoder.FILE) )
                {
                  String path = (String) args.get(Transcoder.FILE);
                  String pathSep = (String) args.get(Transcoder.PATHSEP);
                  if ("true".equals(pathSep))
                  {
                    path = path.replace('/', '\\');
                  }
                 
                    VirtualFile contextFile = LocalFilePathResolver.getSingleton().resolve(path);

                    // If the contextFile is the same as the Source's file, then don't add
                    // it as a path resolver, because we'll rely on the Source's
                    // delegate/backing file.  If we don't do this, then some relative
                    // paths might incorrectly be resolved relative to the generated .as
                    // file, instead of the original mxml file.
                    if ((contextFile != null) && !contextFile.getName().equals(source.getName()))
                    {
                        context.addSinglePathResolver(contextFile);
                    }
                }

                VirtualFile backingFile = source.getBackingFile();

                if (backingFile != null)
                {
                    context.addSinglePathResolver(backingFile);
                }
            }
            context.addSinglePathResolver( ThreadLocalToolkit.getPathResolver() );
        }
        else
        {
            // This is necessary to handle FlexInit's Embeds, because
            // FlexInit is recompiled any time something changes in an
            // incremental compilation and the original document might
            // not have needed to be recompiled, so the resolved
            // VirtualFile won't be cached in the ThreadLocalToolkit.
            // The LocalFilePathResolver should be sufficient to turn
            // the resolved path into a VirtualFile.
            context.addSinglePathResolver(LocalFilePathResolver.getSingleton());
        }

    if (!unit.hasAssets() || !unit.getAssets().contains(className))
    {
            results = transcode(transcoders, symbolTable, className, args, line, col, generateCode, source, context);
       if (results != null) // else there was an error
         {
           if (results.defineTag != null) // else its a pure-code asset
           {
               unit.getAssets().add(className, new AssetInfo(results.defineTag,
                      results.assetSource, results.modified, args));
           }

           // Look for additional assets
           List<Transcoder.TranscodingResults> additionalAssets = results.additionalAssets;
           if (additionalAssets != null)
           {
               for (int i = 0; i < additionalAssets.size(); i++)
               {
                   Transcoder.TranscodingResults asset = additionalAssets.get(i);
                   if (asset.defineTag != null)
                       unit.getAssets().add(asset.className, new AssetInfo(asset.defineTag, results.assetSource, results.modified, args));
               }
           }
         }
        }
        else
    {
      assert false : "Asset already added for " + className;
    }

    return results;
  }

    // Flex Builder is using this temporarily.
    public static Transcoder.TranscodingResults transcode(Transcoder[] transcoders, String className,
                                                          Map<String, Object> args, int line, int col,
                                                          boolean generateCode, Source s,
                                                          PathResolver context)
    {
        return transcode(transcoders, null, className, args, line, col, generateCode, s, context);
    }

    private static Transcoder.TranscodingResults transcode(Transcoder[] transcoders, SymbolTable symbolTable,
                                                           String className, Map<String, Object> args, int line, int col,
                                                           boolean generateCode, Source s,
                                                           PathResolver context)
    {
        String request = formatTranscodeRequest( args );
        Transcoder.TranscodingResults results = null;
        // Brian: one thing that we could still try here for performance is to have a switch that allows the className
        // that is passed in to be overriden.  For mxml and var level Embeds this could happen.  When this is allowed,
        // if we have already transcoded the given source location (as found out from a source->defineTag cache),
        // we could just return this location as well as the new className that should be used

        String mimeType = (String) args.get( Transcoder.MIMETYPE );
        String origin = (String) args.get( Transcoder.FILE );
        String pathSep = (String) args.get( Transcoder.PATHSEP );
        if ("true".equals(pathSep))
        {
          origin = origin.replace('/', '\\');
        }
        String nameForReporting = "";

        long mem = -1;
        if (Trace.embed)
        {
            Trace.trace("Transcoding " + request);
            if (ThreadLocalToolkit.getBenchmark() != null)
            {
              ThreadLocalToolkit.getBenchmark().startTime("Transcoded " + request);
              mem = ThreadLocalToolkit.getBenchmark().peakMemoryUsage(false);
            }
        }

        try
        {
            if (s != null)
            {
                if (origin == null)
                    origin = s.getName();

                nameForReporting = s.getNameForReporting();
            }

            if (mimeType == null)
            {
                if (args.containsKey(Transcoder.SOURCE))
                {
                    String source = (String) args.get( Transcoder.SOURCE );

                    // this is wrong for network URLs, but it solves a chicken and egg problem with
                    // moving the source processing down to the child transcoders
                    mimeType = MimeMappings.getMimeType( source );

                    if (mimeType == null)
                    {
                        logTranscoderException(new TranscoderException.UnrecognizedExtension(request), nameForReporting, line, col);
                        return null;
                    }
                }
                else if (args.containsKey(Transcoder.SKINCLASS))
                {
                    mimeType = MimeMappings.SKIN;
                }
            }

            Transcoder t = getTranscoder(transcoders, mimeType);

            if (t == null)
            {
                logTranscoderException(new TranscoderException.NoMatchingTranscoder(mimeType), nameForReporting, line, col);
            }
            else
            {
                if (!args.containsKey( Transcoder.SYMBOL ) &&
                    !args.containsKey( Transcoder.NEWNAME )) // FIXME - this should probably go away, no exports in fp9
                {
                    args.put( Transcoder.NEWNAME, className );
                }

                // put the transcoding output into the compilation unit
                results = t.transcode( context, symbolTable, args, className, generateCode );
            }
        }
        catch(TranscoderException transcoderException)
        {
            logTranscoderException(transcoderException, origin, line, col);
        }

        if (Trace.embed)
        {
          if (ThreadLocalToolkit.getBenchmark() != null)
          {
            ThreadLocalToolkit.getBenchmark().stopTime("Transcoded " + request);
          }

            if (mem != -1 && ThreadLocalToolkit.getBenchmark() != null)
            {
                long endMem = ThreadLocalToolkit.getBenchmark().peakMemoryUsage(false);
                Trace.trace("Increase in peak memory from transcoding: " + (endMem - mem) + " MB");
            }
        }

        return results;
    }

    public static Transcoder getTranscoder(Transcoder[] transcoders, String mimeType)
    {
        assert transcoders != null;
        for (int i = 0; i < transcoders.length; ++i)
        {
            if (transcoders[i].isSupported(mimeType))
            {
                return transcoders[i];
            }
        }

        return null;
    }

    public static String formatTranscodeRequest( Map<String, Object> args )
    {
        String s = (String) args.get( Transcoder.SOURCE );

        if (s != null)
            return s;

        s = "[";
        for (Iterator it = args.entrySet().iterator(); it.hasNext();)
        {
            Map.Entry e = (Map.Entry) it.next();
            s += (e.getKey() + "='" + e.getValue() + "'");
            if (it.hasNext()) s += ", ";
        }
        s += "]";
        return s;
    }

    public static void logTranscoderException(TranscoderException transcoderException, String path, int line, int column)
    {
        transcoderException.path = path;
        transcoderException.line = line;
        transcoderException.column = column;
        ThreadLocalToolkit.log(transcoderException);
    }
}
TOP

Related Classes of flex2.compiler.as3.EmbedUtil

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.