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
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 @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 }