    001    package cpw.mods.fml.common.discovery;
    002
    003    import java.util.Collections;
    004    import java.util.List;
    005    import java.util.logging.Level;
    006    import java.util.regex.Matcher;
    007    import java.util.zip.ZipEntry;
    008    import java.util.zip.ZipFile;
    009
    010    import com.google.common.collect.Lists;
    011
    012    import cpw.mods.fml.common.FMLLog;
    013    import cpw.mods.fml.common.LoaderException;
    014    import cpw.mods.fml.common.MetadataCollection;
    015    import cpw.mods.fml.common.ModContainer;
    016    import cpw.mods.fml.common.ModContainerFactory;
    017    import cpw.mods.fml.common.discovery.asm.ASMModParser;
    018
    019    public class JarDiscoverer implements ITypeDiscoverer
    020    {
    021        @Override
    022        public List<ModContainer> discover(ModCandidate candidate, ASMDataTable table)
    023        {
    024            List<ModContainer> foundMods = Lists.newArrayList();
    025            FMLLog.fine("Examining file %s for potential mods", candidate.getModContainer().getName());
    026            ZipFile jar = null;
    027            try
    028            {
    029                jar = new ZipFile(candidate.getModContainer());
    030
    031                ZipEntry modInfo = jar.getEntry("mcmod.info");
    032                MetadataCollection mc = null;
    033                if (modInfo != null)
    034                {
    035                    FMLLog.finer("Located mcmod.info file in file %s", candidate.getModContainer().getName());
    036                    mc = MetadataCollection.from(jar.getInputStream(modInfo), candidate.getModContainer().getName());
    037                }
    038                else
    039                {
    040                    FMLLog.fine("The mod container %s appears to be missing an mcmod.info file", candidate.getModContainer().getName());
    041                    mc = MetadataCollection.from(null, "");
    042                }
    043                for (ZipEntry ze : Collections.list(jar.entries()))
    044                {
    045                    Matcher match = classFile.matcher(ze.getName());
    046                    if (match.matches())
    047                    {
    048                        ASMModParser modParser;
    049                        try
    050                        {
    051                            modParser = new ASMModParser(jar.getInputStream(ze));
    052                        }
    053                        catch (LoaderException e)
    054                        {
    055                            FMLLog.log(Level.SEVERE, e, "There was a problem reading the entry %s in the jar %s - probably a corrupt zip", ze.getName(), candidate.getModContainer().getPath());
    056                            jar.close();
    057                            throw e;
    058                        }
    059                        modParser.validate();
    060                        modParser.sendToTable(table, candidate);
    061                        ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate);
    062                        if (container!=null)
    063                        {
    064                            table.addContainer(container);
    065                            foundMods.add(container);
    066                            container.bindMetadata(mc);
    067                        }
    068                    }
    069                }
    070            }
    071            catch (Exception e)
    072            {
    073                FMLLog.log(Level.WARNING, e, "Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName());
    074            }
    075            finally
    076            {
    077                if (jar != null)
    078                {
    079                    try
    080                    {
    081                        jar.close();
    082                    }
    083                    catch (Exception e)
    084                    {
    085                    }
    086                }
    087            }
    088            return foundMods;
    089        }
    090
    091    }