001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2007-2010 ADEQUATE SYSTEMS SARL
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
021 package org.granite.builder.util;
022
023 import java.io.File;
024 import java.io.FileFilter;
025 import java.io.FileInputStream;
026 import java.io.FileOutputStream;
027 import java.io.IOException;
028 import java.io.InputStream;
029 import java.io.OutputStream;
030 import java.util.ArrayList;
031 import java.util.Arrays;
032 import java.util.Collections;
033 import java.util.List;
034 import java.util.Properties;
035
036 import org.eclipse.core.resources.IProject;
037 import org.granite.builder.BuilderConfiguration;
038 import org.granite.builder.BuilderListener;
039 import org.granite.builder.properties.Gas3Source;
040 import org.granite.builder.properties.GraniteProperties;
041 import org.granite.generator.Listener;
042
043 /**
044 * @author Franck WOLFF
045 */
046 public 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 public boolean accept(File file) {
069 return file.isDirectory() || file.getName().endsWith(".as");
070 }
071 };
072
073 public static boolean generateFlexConfig(BuilderConfiguration config, BuilderListener listener, IProject project) throws Exception {
074 GraniteProperties properties = config.getProperties();
075
076 if (properties.getGas3().getSources() == null || properties.getGas3().getSources().isEmpty())
077 return false;
078 if (!ProjectUtil.isFlexBuilderProject(project))
079 return false;
080
081 List<String> asClasses = new ArrayList<String>();
082 for (Gas3Source source : properties.getGas3().getSources()) {
083 File output = new File(ProjectUtil.getProjectFile(project), source.getOutputDir());
084 asClasses.addAll(listAsFiles(output));
085 }
086 Collections.sort(asClasses);
087
088 File flexConfigFile = new File(project.getFile(FILE_NAME).getLocationURI());
089
090 StringBuilder sb = new StringBuilder(1024);
091 sb.append(PREFIX);
092 try {
093 Properties as3Metadata = new Properties();
094 InputStream is = config.getClassLoader().getResourceAsStream(AS3_METADATA_RES);
095 // If null -> granite.jar isn't in the classpath or is outdated...
096 if (is != null) {
097 try {
098 as3Metadata.load(is);
099 }
100 finally {
101 is.close();
102 }
103 String[] names = as3Metadata.keySet().toArray(new String[as3Metadata.size()]);
104 Arrays.sort(names);
105 for (Object name : names)
106 sb.append(" <name>").append(name).append("</name>\n");
107 }
108 }
109 catch (IOException e) {
110 // ignore...
111 }
112 sb.append(INFIX);
113 for (String asClass : asClasses)
114 sb.append(" <symbol>").append(asClass).append("</symbol>\n");
115 sb.append(SUFFIX);
116
117 byte[] bs = sb.toString().getBytes("UTF-8");
118
119 boolean writeFile = true;
120
121 String message = Listener.MSG_FILE_UPTODATE;
122 if (flexConfigFile.exists()) {
123 if (flexConfigFile.length() == bs.length) {
124 InputStream is = new FileInputStream(flexConfigFile);
125 try {
126 byte[] fc = new byte[bs.length];
127 is.read(fc);
128 writeFile = !Arrays.equals(bs, fc);
129 }
130 finally {
131 is.close();
132 }
133 }
134 if (writeFile)
135 message = Listener.MSG_FILE_OUTDATED;
136 }
137 else
138 message = Listener.MSG_FILE_NOT_EXISTS;
139
140 if (writeFile) {
141 listener.generating(flexConfigFile.toString(), message);
142 OutputStream os = new FileOutputStream(flexConfigFile);
143 try {
144 os.write(bs);
145 }
146 finally {
147 os.close();
148 }
149 }
150 else
151 listener.skipping(flexConfigFile.toString(), message);
152
153 return writeFile;
154 }
155
156 private static List<String> listAsFiles(File root) throws Exception {
157 List<String> files = new ArrayList<String>();
158 listAsFiles(root, root, files);
159 return files;
160 }
161
162 private static void listAsFiles(File root, File dir, List<String> files) throws Exception {
163 if (dir.exists() && dir.isDirectory()) {
164 for (File file : dir.listFiles(AS_FILE_FILTER)) {
165 if (file.isDirectory())
166 listAsFiles(root, file, files);
167 else {
168 StringBuilder sb = new StringBuilder();
169 sb.append(file.getName().substring(0, file.getName().length() - 3));
170 for (File parent = file.getParentFile(); parent != null && !root.equals(parent); parent = parent.getParentFile())
171 sb.insert(0, '.').insert(0, parent.getName());
172 files.add(sb.toString());
173 }
174 }
175 }
176 }
177 }