Java tutorial
/* * Minecraft Forge * Copyright (c) 2016. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package net.minecraftforge.fml.common.discovery; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.LoaderException; import net.minecraftforge.fml.common.MetadataCollection; import net.minecraftforge.fml.common.ModContainer; import net.minecraftforge.fml.common.ModContainerFactory; import net.minecraftforge.fml.common.discovery.asm.ASMModParser; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.Level; import com.google.common.base.Throwables; import com.google.common.collect.Lists; import javax.annotation.Nullable; public class DirectoryDiscoverer implements ITypeDiscoverer { private class ClassFilter implements FileFilter { @Override public boolean accept(File file) { return (file.isFile() && classFile.matcher(file.getName()).matches()) || file.isDirectory(); } } private ASMDataTable table; @Override public List<ModContainer> discover(ModCandidate candidate, ASMDataTable table) { this.table = table; List<ModContainer> found = Lists.newArrayList(); FMLLog.fine("Examining directory %s for potential mods", candidate.getModContainer().getName()); exploreFileSystem("", candidate.getModContainer(), found, candidate, null); for (ModContainer mc : found) { table.addContainer(mc); } return found; } public void exploreFileSystem(String path, File modDir, List<ModContainer> harvestedMods, ModCandidate candidate, @Nullable MetadataCollection mc) { if (path.length() == 0) { File metadata = new File(modDir, "mcmod.info"); try { FileInputStream fis = new FileInputStream(metadata); try { mc = MetadataCollection.from(fis, modDir.getName()); } finally { IOUtils.closeQuietly(fis); } FMLLog.fine("Found an mcmod.info file in directory %s", modDir.getName()); } catch (Exception e) { mc = MetadataCollection.from(null, ""); FMLLog.fine("No mcmod.info file found in directory %s", modDir.getName()); } } File[] content = modDir.listFiles(new ClassFilter()); // Always sort our content Arrays.sort(content); for (File file : content) { if (file.isDirectory()) { FMLLog.finer("Recursing into package %s", path + file.getName()); exploreFileSystem(path + file.getName() + "/", file, harvestedMods, candidate, mc); continue; } Matcher match = classFile.matcher(file.getName()); if (match.matches()) { ASMModParser modParser = null; FileInputStream fis = null; try { fis = new FileInputStream(file); modParser = new ASMModParser(fis); candidate.addClassEntry(path + file.getName()); } catch (LoaderException e) { FMLLog.log(Level.ERROR, e, "There was a problem reading the file %s - probably this is a corrupt file", file.getPath()); throw e; } catch (Exception e) { throw Throwables.propagate(e); } finally { IOUtils.closeQuietly(fis); } modParser.validate(); modParser.sendToTable(table, candidate); ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer(), candidate); if (container != null) { harvestedMods.add(container); container.bindMetadata(mc); } } } } }