001/* 002 GRANITE DATA SERVICES 003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S. 004 005 This file is part of Granite Data Services. 006 007 Granite Data Services is free software; you can redistribute it and/or modify 008 it under the terms of the GNU Library General Public License as published by 009 the Free Software Foundation; either version 2 of the License, or (at your 010 option) any later version. 011 012 Granite Data Services is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License 015 for more details. 016 017 You should have received a copy of the GNU Library General Public License 018 along with this library; if not, see <http://www.gnu.org/licenses/>. 019*/ 020 021package org.granite.builder.util; 022 023import java.io.File; 024import java.io.FileFilter; 025import java.io.FileInputStream; 026import java.io.FileOutputStream; 027import java.io.IOException; 028import java.io.InputStream; 029import java.io.OutputStream; 030import java.util.ArrayList; 031import java.util.Arrays; 032import java.util.Collections; 033import java.util.List; 034import java.util.Properties; 035 036import org.eclipse.core.resources.IProject; 037import org.granite.builder.BuilderConfiguration; 038import org.granite.builder.BuilderListener; 039import org.granite.builder.properties.Gas3Source; 040import org.granite.builder.properties.GraniteProperties; 041import org.granite.generator.Listener; 042 043/** 044 * @author Franck WOLFF 045 */ 046public class FlexConfigGenerator { 047 048 private static final String AS3_METADATA_RES = "org/granite/tide/as3-metadata.properties"; 049 050 public static final String FILE_NAME="granite-flex-config.xml"; 051 052 private static final String PREFIX = 053 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 054 "<flex-config>\n" + 055 " <compiler>\n" + 056 " <keep-as3-metadata>\n"; 057 058 private static final String INFIX = 059 " </keep-as3-metadata>\n" + 060 " </compiler>\n" + 061 " <includes>\n"; 062 063 private static final String SUFFIX = 064 " </includes>\n" + 065 "</flex-config>"; 066 067 private static final FileFilter AS_FILE_FILTER = new FileFilter() { 068 @Override 069 public boolean accept(File file) { 070 return file.isDirectory() || file.getName().endsWith(".as"); 071 } 072 }; 073 074 public static boolean generateFlexConfig(BuilderConfiguration config, BuilderListener listener, IProject project) throws Exception { 075 GraniteProperties properties = config.getProperties(); 076 077 if (properties.getGas3().getSources() == null || properties.getGas3().getSources().isEmpty()) 078 return false; 079 if (!ProjectUtil.isFlexBuilderProject(project)) 080 return false; 081 082 List<String> asClasses = new ArrayList<String>(); 083 for (Gas3Source source : properties.getGas3().getSources()) { 084 File output = new File(ProjectUtil.getProjectFile(project), source.getOutputDir()); 085 asClasses.addAll(listAsFiles(output)); 086 } 087 Collections.sort(asClasses); 088 089 File flexConfigFile = FileUtil.getLocationFile(project.getFile(FILE_NAME)); 090 091 StringBuilder sb = new StringBuilder(1024); 092 sb.append(PREFIX); 093 try { 094 Properties as3Metadata = new Properties(); 095 InputStream is = config.getClassLoader().getResourceAsStream(AS3_METADATA_RES); 096 // If null -> granite.jar isn't in the classpath or is outdated... 097 if (is != null) { 098 try { 099 as3Metadata.load(is); 100 } 101 finally { 102 is.close(); 103 } 104 String[] names = as3Metadata.keySet().toArray(new String[as3Metadata.size()]); 105 Arrays.sort(names); 106 for (Object name : names) 107 sb.append(" <name>").append(name).append("</name>\n"); 108 } 109 } 110 catch (IOException e) { 111 // ignore... 112 } 113 sb.append(INFIX); 114 for (String asClass : asClasses) 115 sb.append(" <symbol>").append(asClass).append("</symbol>\n"); 116 sb.append(SUFFIX); 117 118 byte[] bs = sb.toString().getBytes("UTF-8"); 119 120 boolean writeFile = true; 121 122 String message = Listener.MSG_FILE_UPTODATE; 123 if (flexConfigFile.exists()) { 124 if (flexConfigFile.length() == bs.length) { 125 InputStream is = new FileInputStream(flexConfigFile); 126 try { 127 byte[] fc = new byte[bs.length]; 128 is.read(fc); 129 writeFile = !Arrays.equals(bs, fc); 130 } 131 finally { 132 is.close(); 133 } 134 } 135 if (writeFile) 136 message = Listener.MSG_FILE_OUTDATED; 137 } 138 else 139 message = Listener.MSG_FILE_NOT_EXISTS; 140 141 if (writeFile) { 142 listener.generating(flexConfigFile.toString(), message); 143 OutputStream os = new FileOutputStream(flexConfigFile); 144 try { 145 os.write(bs); 146 } 147 finally { 148 os.close(); 149 } 150 } 151 else 152 listener.skipping(flexConfigFile.toString(), message); 153 154 return writeFile; 155 } 156 157 private static List<String> listAsFiles(File root) throws Exception { 158 List<String> files = new ArrayList<String>(); 159 listAsFiles(root, root, files); 160 return files; 161 } 162 163 private static void listAsFiles(File root, File dir, List<String> files) throws Exception { 164 if (dir.exists() && dir.isDirectory()) { 165 for (File file : dir.listFiles(AS_FILE_FILTER)) { 166 if (file.isDirectory()) 167 listAsFiles(root, file, files); 168 else { 169 StringBuilder sb = new StringBuilder(); 170 sb.append(file.getName().substring(0, file.getName().length() - 3)); 171 for (File parent = file.getParentFile(); parent != null && !root.equals(parent); parent = parent.getParentFile()) 172 sb.insert(0, '.').insert(0, parent.getName()); 173 files.add(sb.toString()); 174 } 175 } 176 } 177 } 178}