private boolean writeSWC()

in compiler-jx/src/main/java/org/apache/royale/compiler/clients/COMPJSCRoyale.java [205:570]


    private boolean writeSWC() throws IOException, InterruptedException
    {
        Collection<ICompilerProblem> errors = new ArrayList<ICompilerProblem>();
        Collection<ICompilerProblem> warnings = new ArrayList<ICompilerProblem>();

        if (!config.getCreateTargetWithErrors())
        {
            problems.getErrorsAndWarnings(errors, warnings);
            if (errors.size() > 0)
                return false;
        }

        boolean packingSWC = false;
        String outputFolderName = getOutputFilePath();
        File swcFile = new File(outputFolderName);
        File jsOut = new File("js/out");
        File externsOut = new File("externs");
        ZipFile zipFile = null;
        ZipOutputStream zipOutputStream = null;
        String catalog = null;
        StringBuilder fileList = new StringBuilder();
        if (outputFolderName.endsWith(".swc"))
        {
            packingSWC = true;
            if (!swcFile.exists())
            {
                problems.add(new LibraryNotFoundProblem(outputFolderName));
                return false;
            }
            zipFile = new ZipFile(swcFile, ZipFile.OPEN_READ);
            final InputStream catalogInputStream = SWCReader.getInputStream(zipFile, SWCReader.CATALOG_XML);
            
            catalog = IOUtils.toString(catalogInputStream);
            catalogInputStream.close();
            zipOutputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outputFolderName + ".new")));
            zipOutputStream.setLevel(Deflater.NO_COMPRESSION);
            for (final Enumeration<? extends ZipEntry> entryEnum = zipFile.entries(); entryEnum.hasMoreElements();)
            {
                final ZipEntry entry = entryEnum.nextElement();
                if (!entry.getName().contains("js/out") &&
                    !entry.getName().contains(SWCReader.CATALOG_XML))
                {
                    if (config.isVerbose())
                    {
                        System.out.println("Copy " + entry.getName());
                    }
                    InputStream input = zipFile.getInputStream(entry);
                    ZipEntry ze = new ZipEntry(entry.getName());
                    ze.setMethod(ZipEntry.STORED);
                    ze.setSize(entry.getSize());
                    ze.setCompressedSize(entry.getCompressedSize());
                    ze.setCrc(entry.getCrc());
                    long fileDate = System.currentTimeMillis();
                    long zipFileDate = fileDate;
                    String metadataDate = targetSettings.getSWFMetadataDate();
                    if (metadataDate != null)
                    {
                        String metadataFormat = targetSettings.getSWFMetadataDateFormat();
                        try {
                            SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
                            Date d = sdf.parse(metadataDate);
                            Calendar cal = new GregorianCalendar();
                            cal.setTime(d);
                            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
                            d = sdf.parse(metadataDate);
                            fileDate = d.getTime();
                            ZonedDateTime zdt = ZonedDateTime.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH), 
                                                    cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), 0, ZoneId.systemDefault());
                            zipFileDate = zdt.toInstant().toEpochMilli();
                        } catch (ParseException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IllegalArgumentException e1) {
                            e1.printStackTrace();
                        }
                    }
                    ze.setTime(zipFileDate);
                    zipOutputStream.putNextEntry(ze);
                    IOUtils.copy(input, zipOutputStream);
                    zipOutputStream.flush();
                    zipOutputStream.closeEntry();
                }
            }
            int filesIndex = catalog.indexOf("<files>");
            if (filesIndex != -1)
            {
                int filesIndex2 = catalog.indexOf("</files>");
                String files = catalog.substring(filesIndex, filesIndex2);
                int fileIndex = files.indexOf("<file", 6);
                int pathIndex = files.indexOf("path=");
                while (pathIndex != -1)
                {
                    int pathIndex2 = files.indexOf("\"", pathIndex + 6);
                    int fileIndex2 = files.indexOf("/>", fileIndex);
                    String path = files.substring(pathIndex + 6, pathIndex2);
                    if (!path.startsWith("js/out"))
                    {
                        fileList.append(files.substring(fileIndex - 8, fileIndex2 + 3));
                    }
                    pathIndex = files.indexOf("path=", pathIndex2);
                    fileIndex = files.indexOf("<file", fileIndex2);
                }
                catalog = catalog.substring(0, filesIndex) + catalog.substring(filesIndex2 + 8);
            }
        }

        File outputFolder = null;
        if (!packingSWC) 
            outputFolder = new File(outputFolderName);

        Set<String> externs = config.getExterns();
        Collection<ICompilationUnit> roots = ((RoyaleSWCTarget)target).getReachableCompilationUnits(errors);
        Collection<ICompilationUnit> reachableCompilationUnits = project.getReachableCompilationUnitsInSWFOrder(roots);
        for (final ICompilationUnit cu : reachableCompilationUnits)
        {
            ICompilationUnit.UnitType cuType = cu.getCompilationUnitType();

            if (cuType == ICompilationUnit.UnitType.AS_UNIT
                    || cuType == ICompilationUnit.UnitType.MXML_UNIT)
            {
                String symbol = cu.getQualifiedNames().get(0);
                if (externs.contains(symbol)) continue;
                
                if (project.isExternalLinkage(cu)) continue;
                
                if (!packingSWC)
                {
                    final File outputClassFile = getOutputClassFile(
                            cu.getQualifiedNames().get(0), outputFolder, true);

                    if (config.isVerbose())
                    {
                        System.out.println("Compiling file: " + outputClassFile);
                    }

                    ICompilationUnit unit = cu;

                    IJSWriter writer;
                    if (cuType == ICompilationUnit.UnitType.AS_UNIT)
                    {
                        writer = (IJSWriter) project.getBackend().createWriter(project,
                                (List<ICompilerProblem>) problems.getProblems(), unit,
                                false);
                    }
                    else
                    {
                        writer = (IJSWriter) project.getBackend().createMXMLWriter(
                                project, (List<ICompilerProblem>) problems.getProblems(),
                                unit, false);
                    }

                    BufferedOutputStream out = new BufferedOutputStream(
                            new FileOutputStream(outputClassFile));
                    BufferedOutputStream sourceMapOut = null;
                    File outputSourceMapFile = null;
                    if (project.config.getSourceMap())
                    {
                        outputSourceMapFile = getOutputSourceMapFile(
                                cu.getQualifiedNames().get(0), outputFolder, true);
                        sourceMapOut = new BufferedOutputStream(
                            new FileOutputStream(outputSourceMapFile));
                    }
                    writer.writeTo(out, sourceMapOut, outputSourceMapFile);
                    out.flush();
                    out.close();
                    if (sourceMapOut != null)
                    {
                        sourceMapOut.flush();
                        sourceMapOut.close();
                    }
                    writer.close();
                }
                else
                {
                    if (config.isVerbose())
                    {
                        System.out.println("Compiling file: " + cu.getQualifiedNames().get(0));
                    }
                    
                    ICompilationUnit unit = cu;

                    IJSWriter writer;
                    if (cuType == ICompilationUnit.UnitType.AS_UNIT)
                    {
                        writer = (IJSWriter) project.getBackend().createWriter(project,
                                (List<ICompilerProblem>) problems.getProblems(), unit,
                                false);
                    }
                    else
                    {
                        writer = (IJSWriter) project.getBackend().createMXMLWriter(
                                project, (List<ICompilerProblem>) problems.getProblems(),
                                unit, false);
                    }

                    ByteArrayOutputStream temp = new ByteArrayOutputStream();
                    ByteArrayOutputStream sourceMapTemp = null;
                    
                    boolean isExterns = false;
                    if(cu.getDefinitionPromises().size() > 0)
                    {
                        isExterns = project.isExterns(cu.getDefinitionPromises().get(0).getQualifiedName());
                    }
                    
                    // if the file is @externs DON'T create source map file
                    if (project.config.getSourceMap() && !isExterns)
                    {
                        sourceMapTemp = new ByteArrayOutputStream();
                    }
                    writer.writeTo(temp, sourceMapTemp, null);

                    File outputClassFile = getOutputClassFile(
                            cu.getQualifiedNames().get(0),
                            isExterns ? externsOut : jsOut,
                            false);
                    String outputClassFilePath = outputClassFile.getPath();
                    outputClassFilePath = outputClassFilePath.replace('\\', '/');
                    if (config.isVerbose())
                    {
                        System.out.println("Writing file: " + outputClassFilePath);     	
                    }
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    temp.writeTo(baos);
                    writeFileToZip(zipOutputStream, outputClassFilePath, baos, fileList);
                    
                    if(sourceMapTemp != null)
                    {
                        String sourceMapFilePath = getOutputSourceMapFile(
                            cu.getQualifiedNames().get(0),
                            isExterns ? externsOut : jsOut,
                            false).getPath();
                        sourceMapFilePath = sourceMapFilePath.replace('\\', '/');
                        if (config.isVerbose())
                        {
                            System.out.println("Writing file: " + sourceMapFilePath);
                        }
                        baos = new ByteArrayOutputStream();
                        processSourceMap(sourceMapTemp, baos, outputClassFile, symbol);
                        writeFileToZip(zipOutputStream, sourceMapFilePath, baos, fileList);
                    }
                    writer.close();
                }
            }
            else if (cuType == ICompilationUnit.UnitType.SWC_UNIT)
            {
                String symbol = cu.getQualifiedNames().get(0);
                if (externs.contains(symbol)) continue;
                if (project.isExternalLinkage(cu)) continue;
                if (!packingSWC)
                {
                    // we probably shouldn't skip this -JT
                    continue;
                }

                // if another .swc file is on our library-path, we must
                // include the .js (and .js.map) files because the
                // bytecode will also be included. if we have the
                // bytecode, but not the .js files, the compiler won't
                // know where to find the .js files. that's really bad.

                // if the bytecode and .js files should not be included,
                // then the developer is expected to use
                // external-library-path instead of library-path.

                SWCCompilationUnit swcCU = (SWCCompilationUnit) cu;
                String outputClassFile = getOutputClassFile(
                        cu.getQualifiedNames().get(0),
                        jsOut,
                        false).getPath();
                outputClassFile = outputClassFile.replace('\\', '/');
                ISWCFileEntry fileEntry = swcCU.getSWC().getFile(outputClassFile);
                if (fileEntry == null)
                {
                    continue;
                }
                if (config.isVerbose())
                {
                    System.out.println("Writing file: " + outputClassFile + " from SWC: " + swcCU.getAbsoluteFilename());
                }
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                InputStream fileStream = fileEntry.createInputStream();
                IOUtils.copy(fileStream, baos);
                fileStream.close();
                writeFileToZip(zipOutputStream, outputClassFile, baos, fileList);

                String outputMapFile = outputClassFile + ".map";
                fileEntry = swcCU.getSWC().getFile(outputMapFile);
                if (fileEntry == null)
                {
                    continue;
                }
                if (config.isVerbose())
                {
                    System.out.println("Writing file: " + outputMapFile + " from SWC: " + swcCU.getAbsoluteFilename());
                }
                baos = new ByteArrayOutputStream();
                fileStream = fileEntry.createInputStream();
                IOUtils.copy(fileStream, baos);
                fileStream.close();
                writeFileToZip(zipOutputStream, outputMapFile, baos, fileList);
            }
        }
        if (!config.getCreateTargetWithErrors())
        {
            errors.clear();
            warnings.clear();
            problems.getErrorsAndWarnings(errors, warnings);
            if (errors.size() > 0)
                return false;
        }
        if (packingSWC)
        {
            zipFile.close();
            long fileDate = System.currentTimeMillis();
            long zipFileDate = fileDate;
            String metadataDate = targetSettings.getSWFMetadataDate();
            if (metadataDate != null)
            {
                String metadataFormat = targetSettings.getSWFMetadataDateFormat();
                try {
                    SimpleDateFormat sdf = new SimpleDateFormat(metadataFormat);
                    Date d = sdf.parse(metadataDate);
                    Calendar cal = new GregorianCalendar();
                    cal.setTime(d);
                    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
                    d = sdf.parse(metadataDate);
                    fileDate = d.getTime();
                    ZonedDateTime zdt = ZonedDateTime.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH), 
                                            cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), 0, ZoneId.systemDefault());
                    zipFileDate = zdt.toInstant().toEpochMilli();
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalArgumentException e1) {
                    e1.printStackTrace();
                }
            }
            int libraryIndex = catalog.indexOf("</libraries>");
            catalog = catalog.substring(0, libraryIndex + 13) +
                "    <files>\n" + fileList.toString() + "    </files>" + 
                catalog.substring(libraryIndex + 13);
            ZipEntry ze = new ZipEntry(SWCReader.CATALOG_XML);
            ze.setTime(zipFileDate);
            ze.setMethod(ZipEntry.STORED);
            
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            baos.write(catalog.getBytes());
            ze.setSize(baos.size());
            ze.setCompressedSize(baos.size());
            CRC32 crc = new CRC32();
            crc.reset();
            crc.update(baos.toByteArray());
            ze.setCrc(crc.getValue());
            
            zipOutputStream.putNextEntry(ze);
            baos.writeTo(zipOutputStream);
            zipOutputStream.flush();
            zipOutputStream.closeEntry();
            zipOutputStream.flush();
            zipOutputStream.close();
            swcFile.delete();
            File newSWCFile = new File(outputFolderName + ".new");
            newSWCFile.renameTo(swcFile);
        }
        return true;
    }