Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
*
* 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.tools.oem;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.royale.compiler.clients.MXMLJSC;
import org.apache.royale.compiler.clients.problems.ProblemFormatter;
import org.apache.royale.compiler.clients.problems.ProblemQuery;
import org.apache.royale.compiler.problems.CompilerProblemSeverity;
import org.apache.royale.compiler.problems.ICompilerProblem;
import org.apache.royale.compiler.problems.annotations.DefaultSeverity;
import org.apache.royale.swf.ISWF;
import org.apache.royale.swf.types.RGB;
import flash.swf.tags.SetBackgroundColor;
import flex2.compiler.CompilerException;
import flex2.compiler.Source;
import flex2.compiler.SourceList;
import flex2.compiler.io.FileUtil;
import flex2.compiler.io.LocalFile;
import flex2.compiler.io.VirtualFile;
import flex2.compiler.util.Benchmark;
import flex2.compiler.util.CompilerControl;
import flex2.compiler.util.CompilerMessage;
import flex2.compiler.util.MimeMappings;
import flex2.compiler.util.PerformanceData;
import flex2.compiler.util.ThreadLocalToolkit;
import flex2.linker.SimpleMovie;
import flex2.tools.ToolsConfiguration;
import flex2.tools.oem.internal.ApplicationCompilerConfiguration;
import flex2.tools.oem.internal.OEMConfiguration;
import flex2.tools.oem.internal.OEMReport;
import flex2.tools.oem.internal.OEMUtil;
/**
* The Application class represents a Flex application. It implements the Builder interface
* which allows for building the application incrementally. There are many ways to define
* a Flex application. The most common way is specify the location of the target source file
* on disk:
*
*
* Application app = new Application(new File("MyApp.mxml"));
*
*
* Before the Application object starts the compilation, it must be configured. The most common methods that the client
* calls are setLogger(), setConfiguration(), and setOutput().
*
* A logger must implement flex2.tools.oem.Logger and use the implementation as the Logger
* for the compilation. The following is an example Logger implementation:
*
*
*
* To specify compiler options for the Application object, the client
* must get a Configuration object populated with default values. Then, the client can set
* compiler options programmatically.
*
* The setOutput() method lets clients specify where the Application object should write
* the output to. If you call the setOutput() method, the build(boolean) method builds and
* writes directly to the location specified by the setOutput() method. For example:
*
*
*
* If you do not call the setOutput() method, the client can use the build(OutputStream, boolean) method
* which requires the client to provide a buffered output stream. For example:
*
*
*
* Before the Application object is thrown away, it is possible to save the compilation
* data for reuse by using the save(OutputStream) method. Subsequent compilations can use the
* load(OutputStream) method to get the old data into the Application object.
*
*
*
* When a cache file (such as MyApp.incr) is available from a previous compilation, the client can
* call the load(OutputStream) method before calling the build(boolean) method. For example:
*
*
*
* The build(false) and build(OutputStream, false) methods always rebuild the application. If the Application
* object is new, the first build(true)/build(OutputStream, true) method call performs a full build, which
* is equivalent to build(false)/build(OutputStream, false), respectively. After a call to the clean() method,
* the Application object always performs a full build.
*
*
* The clean() method not only cleans up compilation data in the Application object, but also the output
* file if the setOutput() method was called.
*
*
* The Application class also supports building applications from a combination of source
* files from the file system and in-memory, dynamically-generated source objects. The client
* must use the Application(String, VirtualLocalFile) or Application(String, VirtualLocalFile[]) constructors.
*
*
* The Application class can be part of a Project. For more information, see the Project class's description.
*
* @see flex2.tools.oem.Configuration
* @see flex2.tools.oem.Project
* @version 2.0.1
* @author Clement Wong
*/
public class Application implements Builder
{
static
{
// find all the compiler temp files.
File[] list = null;
try
{
File tempDir = File.createTempFile("Flex2_", "").getParentFile();
list = tempDir.listFiles(new FilenameFilter()
{
public boolean accept(File dir, String name)
{
return name.startsWith("Flex2_");
}
});
}
catch (Exception e)
{
}
// get rid of compiler temp files.
for (int i = 0, len = list == null ? 0 : list.length; i < len; i++)
{
try { list[i].delete(); } catch (Exception t) {}
}
// use the protection domain to find the location of flex-compiler-oem.jar.
URL url = Application.class.getProtectionDomain().getCodeSource().getLocation();
try
{
File f = new File(new URI(url.toExternalForm()));
if (f.getAbsolutePath().endsWith("flex-compiler-oem.jar"))
{
// use the location of flex-compiler-oem.jar to set application.home
// assume that the jar file is in /lib/flex-compiler-oem.jar
String applicationHome = f.getParentFile().getParent();
System.setProperty("application.home", applicationHome);
}
}
catch (URISyntaxException ex)
{
}
catch (IllegalArgumentException ex)
{
}
}
/**
* Constructor.
*
* @param file The target source file.
* @throws FileNotFoundException Thrown when the specified source file does not exist.
*/
public Application(File file) throws FileNotFoundException
{
this(file, null);
}
/**
* Constructor.
*
* @param file The target source file.
* @param libraryCache A reference to a LibraryCache object. After
* building this Application object the cache may be saved
* and used to compile another Application object that uses
* a similar library path.
* @throws FileNotFoundException Thrown when the specified source file does not exist.
* @since 3.0
*/
public Application(File file, LibraryCache libraryCache) throws FileNotFoundException
{
if (file.exists())
{
init(new VirtualFile[] { new LocalFile(FileUtil.getCanonicalFile(file)) });
}
else
{
throw new FileNotFoundException(FileUtil.getCanonicalPath(file));
}
this.libraryCache = libraryCache;
}
/**
* Constructor.
*
* @param file An in-memory source object.
*/
public Application(VirtualLocalFile file)
{
init(new VirtualFile[] { file });
}
/**
* Constructor.
*
* @param files An array of in-memory source objects. The last element in the array is the target source object.
*/
public Application(VirtualLocalFile[] files)
{
init(files);
}
/**
* Constructor. Use to build resource modules which don't have a target
* source file.
*
*/
public Application()
{
init(new VirtualFile[0]);
}
/**
*
* @param files
*/
@SuppressWarnings("unchecked")
private void init(VirtualFile[] files)
{
this.files = new ArrayList(files.length);
for (int i = 0, length = files.length; i < length; i++)
{
this.files.add(files[i]);
}
oemConfiguration = null;
logger = null;
output = null;
mimeMappings = new MimeMappings();
meter = null;
resolver = null;
cc = new CompilerControl();
//isGeneratedTargetFile = false;
//data = null;
cacheName = null;
configurationReport = null;
messages = new ArrayList();
}
private List files;
private OEMConfiguration oemConfiguration;
private Logger logger;
private File output;
private MimeMappings mimeMappings;
private ProgressMeter meter;
protected PathResolver resolver;
private CompilerControl cc;
//private boolean isGeneratedTargetFile;
private ApplicationCache applicationCache;
private LibraryCache libraryCache;
// clean() would null out the following variables.
private String cacheName, configurationReport;
private List messages;
private boolean setOutputCalled;
private int loaded = 0;
/**
* @inheritDoc
*/
public void setConfiguration(Configuration configuration)
{
oemConfiguration = (OEMConfiguration) configuration;
}
/**
* @inheritDoc
*/
public Configuration getDefaultConfiguration()
{
return getDefaultConfiguration(false);
}
/**
*
* @param processDefaults
* @return
*/
private Configuration getDefaultConfiguration(boolean processDefaults)
{
return OEMUtil.getApplicationConfiguration(constructCommandLine(null), false, false,
OEMUtil.getLogger(logger, messages), resolver,
mimeMappings, processDefaults);
}
/**
* @inheritDoc
*/
public Map getCompilerBenchmarks()
{
return null;
}
/**
* @inheritDoc
*/
public Benchmark getBenchmark()
{
return null;
}
/**
* @inheritDoc
*/
public Configuration getConfiguration()
{
return oemConfiguration;
}
/**
* @inheritDoc
*/
public void setLogger(Logger logger)
{
this.logger = logger;
}
/**
* @inheritDoc
*/
public Logger getLogger()
{
return logger;
}
/**
* Sets the location of the compiler's output. This method is necessary if you call the build(boolean) method.
* If you use the build(OutputStream, boolean) method, in which an output stream
* is provided, there is no need to use this method.
*
* @param output An instance of the java.io.File class.
*/
public void setOutput(File output)
{
setOutputCalled = true;
this.output = output;
}
/**
* Gets the output destination. This method returns null if the setOutput() method was not called.
*
* @return An instance of the java.io.File class, or null if you did not call the setOutput() method.
*/
public File getOutput()
{
return output;
}
/**
* @inheritDoc
*/
public void setSupportedFileExtensions(String mimeType, String[] extensions)
{
mimeMappings.set(mimeType, extensions);
}
/**
* @inheritDoc
*/
public void setProgressMeter(ProgressMeter meter)
{
this.meter = meter;
}
/**
* @inheritDoc
* @since 3.0
*/
public void setPathResolver(PathResolver resolver)
{
this.resolver = resolver;
}
/**
* @inheritDoc
*/
// IMPORTANT: If you make changes here, you probably want to mirror them in Library.build()
public long build(boolean incremental) throws IOException
{
if (output != null)
{
InputStream tempIn = null;
ByteArrayOutputStream tempOut = null;
OutputStream out = null;
long size = 0;
//TODO PERFORMANCE: A lot of unnecessary recopying and buffering here
try
{
@SuppressWarnings("unused")
int result = compile(incremental);
return size;
}
catch (Exception e)
{
ThreadLocalToolkit.logError(e.getLocalizedMessage());
return 0;
}
finally
{
if (tempIn != null) { try { tempIn.close(); } catch (Exception ex) {} }
if (tempOut != null) { try { tempOut.close(); } catch (Exception ex) {} }
if (out != null) { try { out.close(); } catch (Exception ex) {} }
//runExtensions();
clean(false /* cleanData */,
false /* cleanCache */,
false /* cleanOutput */,
true /* cleanConfig */,
false /* cleanMessages */,
true /* cleanThreadLocals */);
}
}
else
{
return 0;
}
}
/*
private void runExtensions()
{
if (oemConfiguration != null)
{
Set extensions = ExtensionManager.getApplicationExtensions(oemConfiguration.getExtensions());
for ( IApplicationExtension extension : extensions )
{
if (ThreadLocalToolkit.errorCount() == 0)
{
extension.run( (Configuration) oemConfiguration.clone() );
}
}
}
}
*/
/**
* @inheritDoc
*/
public long build(OutputStream out, boolean incremental) throws IOException
{
try
{
@SuppressWarnings("unused")
int result = compile(incremental);
/*
if (result == OK || result == LINK)
{
runExtensions();
return link(out);
}
else if (result == SKIP)
{
runExtensions();
return encode(out);
}
else
{
*/
return 0;
// }
}
finally
{
clean(false /* cleanData */,
false /* cleanCache */,
false /* cleanOutput */,
true /* cleanConfig */,
false /* cleanMessages */,
true /* cleanThreadLocals */);
}
}
/**
* @inheritDoc
*/
public void stop()
{
cc.stop();
}
/**
* @inheritDoc
*/
public void clean()
{
// assuming FB takes care of deleting bin-release and bin-debug, we want to delete bin.
// but this also gets called when quitting FB.
setOutputCalled = false;
}
/**
* @inheritDoc
*/
public void load(InputStream in) throws IOException
{
loaded++;
}
/**
* @inheritDoc
*/
public long save(OutputStream out) throws IOException
{
loaded--;
return 1;
}
/**
* @inheritDoc
*/
public Report getReport()
{
//OEMUtil.setupLocalizationManager();
return new OEMReport( sources,
movie,
null,
sourceList,
configurationReport,
messages);
}
/**
* Compiles the Application object. This method does not link the Application.
*
* @param incremental If true, build incrementally; if false, rebuild.
* @return {@link Builder#OK} if this method call resulted in compilation of some/all parts of the application;
* {@link Builder#LINK} if this method call did not compile anything in the application but advise the caller to link again;
* {@link Builder#SKIP} if this method call did not compile anything in the application;
* {@link Builder#FAIL} if this method call encountered errors during compilation.
*/
protected int compile(boolean incremental)
{
try
{
messages.clear();
// if there is no configuration, use the default... but don't populate this.configuration.
OEMConfiguration tempOEMConfiguration;
if (oemConfiguration == null)
{
tempOEMConfiguration = (OEMConfiguration) getDefaultConfiguration(true);
}
else
{
tempOEMConfiguration = OEMUtil.getApplicationConfiguration(constructCommandLine(oemConfiguration),
oemConfiguration.keepLinkReport(),
oemConfiguration.keepSizeReport(),
OEMUtil.getLogger(logger, messages),
resolver, mimeMappings);
}
// if c is null, which indicates problems, this method will return.
if (tempOEMConfiguration == null)
{
clean(false /* cleanData */,
false /* cleanCache */,
false /* cleanOutput */,
true /* cleanConfig */,
false /* cleanMessages */,
false /* cleanThreadLocals */);
return FAIL;
}
else if (oemConfiguration != null && oemConfiguration.keepConfigurationReport())
{
configurationReport = OEMUtil.formatConfigurationBuffer(tempOEMConfiguration.cfgbuf);
}
if (oemConfiguration != null)
{
oemConfiguration.cfgbuf = tempOEMConfiguration.cfgbuf;
}
// initialize some ThreadLocal variables...
cc.run();
OEMUtil.init(OEMUtil.getLogger(logger, messages), mimeMappings, meter, resolver, cc);
//Map licenseMap = OEMUtil.getLicenseMap(tempOEMConfiguration.configuration);
mxmljsc = new MXMLJSC();
mxmljsc.noLink = true;
//int returnValue = mxmlc.mainCompileOnly(constructCommandLine2(tempOEMConfiguration.configuration), null);
int returnValue = mxmljsc.mainNoExit(constructCommandLine(oemConfiguration), null, true);
if (returnValue == 0 || returnValue == 2)
returnValue = OK;
else
returnValue = FAIL;
processMXMLCReport(mxmljsc, tempOEMConfiguration);
clean(returnValue == FAIL /* cleanData */,
false /* cleanCache */,
false /* cleanOutput */,
true /* cleanConfig */,
false /* cleanMessages */,
false /* cleanThreadLocals */);
return returnValue;
}
finally
{
// clean thread locals
OEMUtil.clean();
}
}
public long link(OutputStream output)
{
return mxmljsc.writeSWF(output);
}
private MXMLJSC mxmljsc = new MXMLJSC();
private List sources;
private SimpleMovie movie;
private SourceList sourceList;
void processMXMLCReport(MXMLJSC mxmljsc, OEMConfiguration config)
{
ApplicationCompilerConfiguration acc = ((ApplicationCompilerConfiguration)config.configuration);
sources = new ArrayList();
VirtualFile[] sourcePaths = acc.getCompilerConfiguration().getSourcePath();
List sourceFiles = mxmljsc.getSourceList();
String mainFile = mxmljsc.getMainSource();
VirtualFile mainVirtualFile = null;
for (String sourceFile : sourceFiles)
{
for (VirtualFile sourcePath : sourcePaths)
{
String pathName = sourcePath.getName();
if (sourceFile.indexOf(pathName) == 0)
{
String relPath = sourceFile.substring(pathName.length());
int lastSep = relPath.lastIndexOf(File.separator);
String shortName = relPath.substring(lastSep + 1);
relPath = relPath.substring(0, lastSep);
boolean isRoot = sourceFile.equals(mainFile);
Source source = new Source(sourcePath, relPath, shortName, null, false, isRoot);
sources.add(source);
if (pathName.equals(mainFile))
mainVirtualFile = sourcePath;
}
}
}
try {
sourceList = new SourceList(new ArrayList(), sourcePaths, mainVirtualFile, new String[0]);
} catch (CompilerException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
ProblemQuery pq = mxmljsc.getProblemQuery();
List probs = pq.getProblems();
for (ICompilerProblem prob : probs)
{
Class aClass = prob.getClass();
Annotation[] annotations = aClass.getAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof DefaultSeverity){
DefaultSeverity myAnnotation = (DefaultSeverity) annotation;
CompilerProblemSeverity cps = myAnnotation.value();
String level;
if (cps.equals(CompilerProblemSeverity.ERROR))
level = Message.ERROR;
else if (cps.equals(CompilerProblemSeverity.WARNING))
level = Message.WARNING;
else
break; // skip if IGNORE?
CompilerMessage msg = new CompilerMessage(level,
prob.getSourcePath(),
prob.getLine() + 1,
prob.getColumn());
try
{
String errText = ProblemFormatter.DEFAULT_FORMATTER.format(prob);
msg.setMessage(errText);
}
catch (IllegalArgumentException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
catch (SecurityException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
messages.add(msg);
try
{
logger.log(msg, aClass.getField("errorCode").getInt(null), prob.getSourcePath());
}
catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SecurityException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (NoSuchFieldException e)
{
try
{
logger.log(msg, aClass.getField("warningCode").getInt(null), prob.getSourcePath());
}
catch (IllegalArgumentException e1)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SecurityException e1)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e1)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (NoSuchFieldException e1)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
ISWF swf = mxmljsc.getSWFTarget();
movie = new SimpleMovie(null);
org.apache.royale.swf.types.Rect r = swf.getFrameSize();
flash.swf.types.Rect fr = new flash.swf.types.Rect();
fr.xMin = r.xMin();
fr.yMin = r.yMin();
fr.xMax = r.xMax();
fr.yMax = r.yMax();
movie.size = fr;
RGB bg = swf.getBackgroundColor();
int red = bg.getRed();
red = red << 16;
int green = bg.getGreen();
green = green << 8;
int blue = bg.getBlue();
movie.bgcolor = new SetBackgroundColor(red + green + blue);
movie.topLevelClass = swf.getTopLevelClass();
}
/**
*
* @param cleanData
* @param cleanCache
* @param cleanOutput
* @param cleanConfig
* @param cleanMessages
* @param cleanThreadLocals
*/
private void clean(boolean cleanData, boolean cleanCache, boolean cleanOutput,
boolean cleanConfig, boolean cleanMessages, boolean cleanThreadLocals)
{
if (cleanThreadLocals)
{
OEMUtil.clean();
}
if (oemConfiguration != null && cleanConfig)
{
oemConfiguration.reset();
}
if (cleanData)
{
configurationReport = null;
}
if (cleanCache)
{
if (cacheName != null)
{
File dead = FileUtil.openFile(cacheName);
if (dead != null && dead.exists())
{
dead.delete();
}
cacheName = null;
}
}
if (cleanOutput)
{
if (output != null && output.exists())
{
output.delete();
}
}
if (cleanMessages)
{
messages.clear();
}
}
/**
*
* @param localOEMConfiguration
* @return
*/
private String[] constructCommandLine(OEMConfiguration localOEMConfiguration)
{
String[] options = (localOEMConfiguration != null) ? localOEMConfiguration.getCompilerOptions() : new String[0];
String[] args = new String[options.length + files.size() + 1];
System.arraycopy(options, 0, args, 0, options.length);
args[options.length] = "--file-specs";// + Mxmlc.FILE_SPECS;
for (int i = 0, size = files.size(); i < size; i++)
{
args[options.length + 1 + i] = files.get(i).getName();
}
return args;
}
/**
*
* @param localOEMConfiguration
* @return
*/
private String[] constructCommandLine2(ToolsConfiguration localToolsConfiguration)
{
String[] options = (localToolsConfiguration != null) ? processToolsConfig(localToolsConfiguration): new String[0];
String[] args = new String[options.length + files.size() + 1];
System.arraycopy(options, 0, args, 0, options.length);
args[options.length] = "--file-specs";// + Mxmlc.FILE_SPECS;
for (int i = 0, size = files.size(); i < size; i++)
{
args[options.length + 1 + i] = files.get(i).getName();
}
return args;
}
private String[] processToolsConfig(ToolsConfiguration tc)
{
String[] results = new String[1];
results[0] = "-debug=" + (tc.debug() ? "true" : "false");
return results;
}
/**
* Returns the cache of sources in the source list and source
* path. After building this Application object, the cache may be
* used to compile another Application object with common sources.
*
* @return The active cache. May be null.
*
* @since 4.5
*/
public ApplicationCache getApplicationCache()
{
return applicationCache;
}
/**
* Sets the cache for sources in the source list and source path.
* After compiling an Application object, the cache may be reused
* to build another Application object with common sources.
*
* @param applicationCache A reference to the application cache.
*
* @since 4.5
*/
public void setApplicationCache(ApplicationCache applicationCache)
{
this.applicationCache = applicationCache;
}
// TODO: deprecate getSwcCache() and setSwcCache(), then add
// getLibraryCache() and setLibraryCache().
/**
* Get the cache of swcs in the library path. After building this Application
* object the cache may be saved and used to compile another Application object
* that uses the same library path.
*
* @return The active cache. May be null.
*
* @since 3.0
*/
public LibraryCache getSwcCache()
{
return libraryCache;
}
/**
* Set the cache for swcs in the library path. After compiling an
* Application object the cache may be reused to build another Application
* object that uses the same library path.
*
* @param swcCache A reference to an allocated swc cache.
*
* @since 3.0
*/
public void setSwcCache(LibraryCache libraryCache)
{
this.libraryCache = libraryCache;
}
}