    001    package cpw.mods.fml.common.discovery;
    002
    003    import java.io.File;
    004    import java.io.FileFilter;
    005    import java.io.FileInputStream;
    006    import java.util.Arrays;
    007    import java.util.List;
    008    import java.util.logging.Level;
    009    import java.util.regex.Matcher;
    010
    011    import com.google.common.base.Throwables;
    012    import com.google.common.collect.Lists;
    013
    014    import cpw.mods.fml.common.FMLLog;
    015    import cpw.mods.fml.common.LoaderException;
    016    import cpw.mods.fml.common.MetadataCollection;
    017    import cpw.mods.fml.common.ModContainer;
    018    import cpw.mods.fml.common.ModContainerFactory;
    019    import cpw.mods.fml.common.discovery.asm.ASMModParser;
    020
    021    public class DirectoryDiscoverer implements ITypeDiscoverer
    022    {
    023        private class ClassFilter implements FileFilter
    024        {
    025            @Override
    026            public boolean accept(File file)
    027            {
    028                return (file.isFile() && classFile.matcher(file.getName()).find()) || file.isDirectory();
    029            }
    030        }
    031
    032        private ASMDataTable table;
    033
    034        @Override
    035        public List<ModContainer> discover(ModCandidate candidate, ASMDataTable table)
    036        {
    037            this.table = table;
    038            List<ModContainer> found = Lists.newArrayList();
    039            FMLLog.fine("Examining directory %s for potential mods", candidate.getModContainer().getName());
    040            exploreFileSystem("", candidate.getModContainer(), found, candidate, null);
    041            for (ModContainer mc : found)
    042            {
    043                table.addContainer(mc);
    044            }
    045            return found;
    046        }
    047
    048        public void exploreFileSystem(String path, File modDir, List<ModContainer> harvestedMods, ModCandidate candidate, MetadataCollection mc)
    049        {
    050            if (path.length() == 0)
    051            {
    052                File metadata = new File(modDir, "mcmod.info");
    053                try
    054                {
    055                    FileInputStream fis = new FileInputStream(metadata);
    056                    mc = MetadataCollection.from(fis,modDir.getName());
    057                    fis.close();
    058                    FMLLog.fine("Found an mcmod.info file in directory %s", modDir.getName());
    059                }
    060                catch (Exception e)
    061                {
    062                    mc = MetadataCollection.from(null,"");
    063                    FMLLog.fine("No mcmod.info file found in directory %s", modDir.getName());
    064                }
    065            }
    066
    067            File[] content = modDir.listFiles(new ClassFilter());
    068
    069            // Always sort our content
    070            Arrays.sort(content);
    071            for (File file : content)
    072            {
    073                if (file.isDirectory())
    074                {
    075                    FMLLog.finest("Recursing into package %s", path + file.getName());
    076                    exploreFileSystem(path + file.getName() + ".", file, harvestedMods, candidate, mc);
    077                    continue;
    078                }
    079                Matcher match = classFile.matcher(file.getName());
    080
    081                if (match.matches())
    082                {
    083                    ASMModParser modParser = null;
    084                    try
    085                    {
    086                        FileInputStream fis = new FileInputStream(file);
    087                        modParser = new ASMModParser(fis);
    088                        fis.close();
    089                    }
    090                    catch (LoaderException e)
    091                    {
    092                        FMLLog.log(Level.SEVERE, e, "There was a problem reading the file %s - probably this is a corrupt file", file.getPath());
    093                        throw e;
    094                    }
    095                    catch (Exception e)
    096                    {
    097                        Throwables.propagate(e);
    098                    }
    099
    100                    modParser.validate();
    101                    modParser.sendToTable(table, candidate);
    102                    ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate);
    103                    if (container!=null)
    104                    {
    105                        harvestedMods.add(container);
    106                        container.bindMetadata(mc);
    107                    }
    108                }
    109
    110
    111            }
    112        }
    113
    114    }