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}