Package flex2.compiler.media

Source Code of flex2.compiler.media.AbstractTranscoder

/*
*
*  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.media;

import flash.swf.tags.DefineBits;
import flash.swf.tags.DefineButton;
import flash.swf.tags.DefineFont;
import flash.swf.tags.DefineSound;
import flash.swf.tags.DefineSprite;
import flash.swf.tags.DefineTag;
import flash.swf.tags.DefineText;
import flash.util.Trace;
import flex2.compiler.SymbolTable;
import flex2.compiler.Transcoder;
import flex2.compiler.TranscoderException;
import flex2.compiler.common.PathResolver;
import flex2.compiler.io.NetworkFile;
import flex2.compiler.io.VirtualFile;
import flex2.compiler.mxml.lang.StandardDefs;
import flex2.compiler.util.ThreadLocalToolkit;
import flex2.compiler.util.VelocityManager;

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

import org.apache.flex.forks.velocity.Template;
import org.apache.flex.forks.velocity.VelocityContext;

/**
* This is the default transcoder implementation.  The only thing that
* a subclass needs to do to override is to give the right information
* in the constructor and provide an implementation of doTranscode().
*
* @author Brian Deitte
*/
public abstract class AbstractTranscoder implements Transcoder
{
    private static final String CODEGEN_TEMPLATE_PATH = "flex2/compiler/as3/";

    // TODO - move these once ImageTranscoder gets refactored
    public static final String SCALE9TOP = "scaleGridTop";
    public static final String SCALE9LEFT = "scaleGridLeft";
    public static final String SCALE9BOTTOM = "scaleGridBottom";
    public static final String SCALE9RIGHT = "scaleGridRight";

    public static final String FONTSTYLE = "fontStyle";
    public static final String FONTWEIGHT = "fontWeight";
    public static final String FONTNAME = "fontName";
    public static final String FONTFAMILY = "fontFamily";

    protected String[] mimeTypes;
    protected Class defineTag;
    protected boolean cacheTags;

    protected Map<String, TranscodingResults> transcodingCache = new HashMap<String, TranscodingResults>();

    public static final String ASSET_TYPE = StandardDefs.PACKAGE_FLASH_DISPLAY + ".DisplayObject";
   
    public AbstractTranscoder(String[] mimeTypes, Class defineTag, boolean cacheTags)
    {
        this.mimeTypes = mimeTypes;
        this.defineTag = defineTag;
        this.cacheTags = cacheTags;
    }

    public boolean isSupported(String mimeType)
    {
        for (int i = 0; i < mimeTypes.length; i++)
        {
            if (mimeTypes[i].equalsIgnoreCase(mimeType))
            {
                return true;
            }
        }
        return false;
    }

    public TranscodingResults transcode(PathResolver context, SymbolTable symbolTable,
                                         Map<String, Object> args, String className,
                                         boolean generateSource)
            throws TranscoderException
    {
        for (Iterator<String> it = args.keySet().iterator(); it.hasNext();)
        {
            String attr = it.next();
            if (attr.startsWith( "_") || Transcoder.SOURCE.equalsIgnoreCase( attr ) || Transcoder.MIMETYPE.equalsIgnoreCase( attr ) || Transcoder.NEWNAME.equalsIgnoreCase( attr ))
            {
                continue;
            }
            if (!Transcoder.ORIGINAL.equals(attr) && !isSupportedAttribute( attr ))
            {
                throw new UnsupportedAttribute( attr, getClass().getName() );
            }
        }

        String cacheKey = null;

        TranscodingResults results = null;

        if (cacheTags)
        {
            cacheKey = getCacheKey( args );
            results = transcodingCache.get( cacheKey );
        }

        if (results == null)
        {
            results = doTranscode(context, symbolTable, args, className, generateSource);

            if (cacheTags)
            {
              // reget the cacheKey, since RESOLVED_SOURCE could have been added to the args
              cacheKey = getCacheKey( args );
                transcodingCache.put(cacheKey, results);
            }
        }
        else if (Trace.embed)
        {
            Trace.trace("Found cached DefineTag for " + cacheKey);
        }

        return results;
    }

    private String getCacheKey(Map<String, Object> args)
    {
        TreeMap<String, Object> m = new TreeMap<String, Object>( args );
        String key = "" + m.hashCode();

        if (Trace.embed)
        {
            key += "_" + m.toString()// TODO: don't hard-code key
        }

        return key;
    }

    public VirtualFile resolve( PathResolver context, String path ) throws TranscoderException
    {
        String p = path;
        if (path.startsWith( "file:"))
            p = p.substring( "file:".length() );    // hate hate hate hate

        VirtualFile f = context.resolve( p );
        if (f == null)
        {
            throw new UnableToResolve( path );
        }
        if (f instanceof NetworkFile)
        {
            throw new NetworkTranscodingSource( path );
        }
        return f;
    }

    public VirtualFile resolveSource( PathResolver context, Map args ) throws TranscoderException
    {
        VirtualFile result = null;
        String resolvedSource = (String) args.get( Transcoder.RESOLVED_SOURCE );

        if (resolvedSource != null)
        {
            result = ThreadLocalToolkit.getResolvedPath(resolvedSource);
        }

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

            if (source == null)
            {
                throw new MissingSource();
            }

            result = resolve( context, source );
        }

        return result;
    }

    public abstract TranscodingResults doTranscode(PathResolver context, SymbolTable symbolTable,
                                                    Map<String, Object> args, String className,
                                                    boolean generateSource)
        throws TranscoderException;

    public abstract boolean isSupportedAttribute(String attr);

    public String getAssociatedClass(DefineTag tag)
    {
        if (tag == null)
        {
            return null;
        }

        StandardDefs standardDefs = ThreadLocalToolkit.getStandardDefs();

        String cls = null;
        String SKIN_SPRITE = standardDefs.getCorePackage() + ".SpriteAsset";

        if (tag instanceof DefineButton)
            cls = standardDefs.getCorePackage() + ".ButtonAsset";
        else if (tag instanceof DefineFont)
            cls = standardDefs.getCorePackage() + ".FontAsset";
        else if (tag instanceof DefineText)
            cls = standardDefs.getCorePackage() + ".TextFieldAsset";
        else if (tag instanceof DefineSound)
            cls = standardDefs.getCorePackage() + ".SoundAsset";
        else if (tag instanceof DefineBits)
            cls = standardDefs.getCorePackage() + ".BitmapAsset";
        else if (tag instanceof DefineSprite)
            cls = standardDefs.getCorePackage() + ".SpriteAsset";

        if (cls != null && (defineTag == null || defineTag.isAssignableFrom(tag.getClass())))
        {
            if (((tag instanceof DefineSprite) && ((DefineSprite)tag).framecount > 1) && (cls.equals( SKIN_SPRITE )))
            {
                cls = standardDefs.getCorePackage() + ".MovieClipAsset";
            }
            return cls;
        }

        if (defineTag == null)
        {
            if (Trace.embed)
            {
                Trace.trace("Couldn't find a matching class, so associating " + tag + " with " + SKIN_SPRITE);
            }
            return SKIN_SPRITE;
        }
        else
        {
            return null;
        }
    }

    public void clear()
    {
        if (transcodingCache.size() != 0)
        {
            transcodingCache = new HashMap<String, TranscodingResults>();
        }
    }
   
    public void generateSource(TranscodingResults asset, String fullClassName, Map<String, Object> embedMap)
        throws TranscoderException
    {
      generateSource(asset, fullClassName, embedMap, new HashMap());
    }

    public void generateSource(TranscodingResults asset, String fullClassName, Map<String, Object> embedMap, Map embedProps)
            throws TranscoderException
    {
        String baseClassName = getAssociatedClass(asset.defineTag);
        String packageName = "";
        String className = fullClassName;
        int dot = fullClassName.lastIndexOf( '.' );
        if (dot != -1)
        {
            packageName = fullClassName.substring( 0, dot );
            className = fullClassName.substring( dot + 1 );
        }

      if (asset.assetSource != null)
      {
            String path = asset.assetSource.getName().replace('\\', '/');
            embedMap.put(Transcoder.RESOLVED_SOURCE, path);
            ThreadLocalToolkit.addResolvedPath(path, asset.assetSource);
      }

        try
        {
            StandardDefs standardDefs = ThreadLocalToolkit.getStandardDefs();

            String templateName = standardDefs.getEmbedClassTemplate();
            Template template = VelocityManager.getTemplate(CODEGEN_TEMPLATE_PATH + templateName);
            if (template == null)
            {
                throw new TemplateException( templateName );
            }

            VelocityContext velocityContext = VelocityManager.getCodeGenContext();
            velocityContext.put( "packageName", packageName );
            velocityContext.put( "baseClass", baseClassName );
            if (embedProps.size() != 0)
            {
              velocityContext.put("assetType", ASSET_TYPE );
            }
            velocityContext.put( "embedClass", className );
            velocityContext.put( "embedMap", embedMap );
          velocityContext.put( "embedProps", embedProps );

            StringWriter stringWriter = new StringWriter();

            template.merge(velocityContext, stringWriter);
            // once we figure out a non-AS2 way to call stop, add this and put the generated code in EmbedClass.vm
            //velocityContext.put("needsStop", "" + (data.defineTag instanceof DefineSprite && ((DefineSprite)data.defineTag).needsStop));

            //long t2 = System.currentTimeMillis();
            //VelocityManager.parseTime += t2 - start;
            //VelocityManager.mergeTime += System.currentTimeMillis() - t2;

            asset.generatedCode = stringWriter.toString();

        }
        catch (Exception e)
        {
            if (Trace.error)
            {
                e.printStackTrace();
            }
            throw new UnableToGenerateSource( fullClassName );
        }
    }

    public static class TemplateException extends TranscoderException
    {
        private static final long serialVersionUID = 5180630712564309116L;
       
        public TemplateException( String templateName )
        {
            this.templateName = templateName;
        }
        public String templateName;
    }
    public static class SourceException extends TranscoderException
    {
        private static final long serialVersionUID = -6720698044756027846L;
       
        public SourceException( String className )
        {
            this.className = className;
        }
        public String className;
    }

    public static class UnsupportedAttribute extends TranscoderException
    {
        private static final long serialVersionUID = -5367245871779383272L;
       
        public UnsupportedAttribute( String attribute, String className )
        {
            this.attribute = attribute;
            this.className = className;
        }
        public String attribute;
        public String mimeType;
        public String className;
    }

    public static class UnableToResolve extends TranscoderException
    {
        private static final long serialVersionUID = 3955870312641262226L;
       
        public UnableToResolve( String source )
        {
            this.source = source;
        }
        public String source;
    }
    public static class NetworkTranscodingSource extends TranscoderException
    {
        private static final long serialVersionUID = 1258842409489634129L;
       
        public NetworkTranscodingSource( String url )
        {
            this.url = url;
        }
        public String url;
    }

    public static class MissingSource extends TranscoderException
    {
        private static final long serialVersionUID = -3672019858278058644L;
    }

    public static class UnableToGenerateSource extends TranscoderException
    {
        private static final long serialVersionUID = 5252588163882319246L;

        public UnableToGenerateSource( String className )
        {
            this.className = className;
        }
        public String className;
    }

    public static class UnableToReadSource extends TranscoderException
    {
        private static final long serialVersionUID = 157159356418747799L;
       
        public UnableToReadSource( String source )
        {
            this.source = source;
        }
        public String source;
    }

    public static class ExceptionWhileTranscoding extends TranscoderException
    {
        private static final long serialVersionUID = 3747245123304883388L;
       
        public ExceptionWhileTranscoding( Exception exception )
        {
            this.exception = exception.getMessage();
        }
        public String exception;
    }

    public static class EmbedRequiresCodegen extends TranscoderException
    {
        private static final long serialVersionUID = -1154861048587818696L;
       
        public EmbedRequiresCodegen( String source, String className )
        {
            this.source = source;
            this.className = className;
        }
        public String source;
        public String className;
    }

    public static final class IncompatibleTranscoderParameters extends TranscoderException
    {
        private static final long serialVersionUID = 5674351726161323512L;
       
        public IncompatibleTranscoderParameters( String param1, String param2 )
        {
            this.param1 = param1;
            this.param2 = param2;
        }
        public String param1;
        public String param2;
    }
}
TOP

Related Classes of flex2.compiler.media.AbstractTranscoder

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.