Java tutorial
/*** * Copyright 2013 Teoti Graphix, LLC. * * Licensed 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. * * * @author Michael Schmalle <mschmalle@teotigraphix.com> */ package randori.compiler.internal.driver.model; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Collection; import org.apache.commons.io.FilenameUtils; import org.apache.flex.compiler.tree.as.ITypeNode; import org.apache.flex.compiler.units.ICompilationUnit; import org.apache.flex.utils.FilenameNormalization; import randori.compiler.codegen.as.IASWriter; import randori.compiler.config.IRandoriTargetSettings; import randori.compiler.driver.IRandoriBackend; import randori.compiler.internal.utils.FileUtils; import randori.compiler.projects.IRandoriApplicationProject; /** * The compilation set for the base randori application project. * <p> * TODO There is going to be more logic needed in the class to determine * multiple projects? Still in the dark about how exactly the projects other * than the libraries can be setup. * * @author Michael Schmalle */ public class ApplicationModel extends BaseCompilationSet { public ApplicationModel(IRandoriApplicationProject project, IRandoriTargetSettings settings) { super(project, settings); } @Override protected boolean accept(ITypeNode node) { if (node == null) return false; // no -include-sources everything gets included (-source-path) Collection<File> sources = settings.getIncludeSources(); if (sources == null || sources.size() == 0) return true; // if incremental files have been passed, filter on them Collection<String> incrementals = settings.getIncrementalFiles(); if (incrementals != null && incrementals.size() > 0) { String path = FilenameNormalization.normalize(node.getSourcePath()); for (String filePath : incrementals) { if (FilenameUtils.equalsNormalized(path, filePath)) return true; } return false; } // filter out using the expanded -include-sources directory or files String path = FilenameNormalization.normalize(node.getSourcePath()); for (File file : sources) { if (FilenameUtils.equalsNormalized(path, file.getAbsolutePath())) return true; } return false; } @Override public void generate(IRandoriBackend backend, File output) { super.generate(backend, output); // as you can see, we override generate to allow monolithic or individual // file export here using the superclasses methods to do the dirty work boolean classesAsFiles = settings.getJsClassesAsFiles(); if (classesAsFiles) { for (ICompilationUnit unit : getCompilationUnits()) { try { write(unit); } catch (RuntimeException e) { // cancel compile break; } } } else { String basePath = settings.getJsBasePath(); String appName = settings.getAppName(); if (appName == null || appName.equals("")) { // TODO Create a Problem that app-name is not configured, this should actually // be done in the configure() method of the compiler throw new RuntimeException("no -app-name specified during monolithic generation"); } writeFull(basePath, appName + ".js"); } } /** * Writes an individual {@link ICompilationUnit} to file. * <p> * This method uses the unit's package name to calculate the directory * structure of the output class file. * * @param unit The {@link ICompilationUnit} to output. */ void write(ICompilationUnit unit) { String basePath = settings.getJsBasePath(); File outputFolder = new File(outputDirectory, basePath); if (!outputFolder.exists()) outputFolder.mkdirs(); File outputClassFile = null; IASWriter writer = null; BufferedOutputStream out = null; // TODO this is a mess, all this output needs to be refactored into the build target try { outputClassFile = FileUtils.toOutputFile(unit.getQualifiedNames().get(0), outputFolder, "js"); System.out.println("Compiling file: " + outputClassFile); writer = backend.createWriter(project, getProblems(), unit, false); out = new BufferedOutputStream(new FileOutputStream(outputClassFile)); writer.writeTo(out); out.flush(); } catch (InterruptedException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (RuntimeException e) { // XXX HACK not sure how to "not" create this file with the stream System.err.println("Compiling file failed " + outputClassFile.getName()); throw e; } finally { try { out.close(); writer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }