001/*
002 * The FML Forge Mod Loader suite.
003 * Copyright (C) 2012 cpw
004 *
005 * 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
006 * Software Foundation; either version 2.1 of the License, or any later version.
007 *
008 * 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
009 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
010 *
011 * 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
012 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
013 */
014
015package cpw.mods.fml.common;
016
017import static argo.jdom.JsonNodeBuilders.aStringBuilder;
018
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.HashSet;
022import java.util.List;
023import java.util.Map;
024import java.util.Set;
025import java.util.logging.Level;
026
027import argo.jdom.JsonNode;
028import argo.jdom.JsonStringNode;
029
030import com.google.common.base.Function;
031import com.google.common.base.Joiner;
032import com.google.common.base.Objects;
033import com.google.common.base.Optional;
034import com.google.common.base.Strings;
035import com.google.common.collect.Lists;
036import com.google.common.collect.Maps;
037
038import cpw.mods.fml.common.functions.ModNameFunction;
039import cpw.mods.fml.common.versioning.ArtifactVersion;
040import cpw.mods.fml.common.versioning.VersionParser;
041
042/**
043 * @author cpw
044 *
045 */
046public class ModMetadata
047{
048    private static final class JsonStringConverter implements Function<JsonNode, Object>
049    {
050        public Object apply(JsonNode arg0)
051        {
052            if (arg0.hasElements())
053            {
054                return Lists.transform(arg0.getElements(), new JsonArrayConverter());
055            }
056            else
057            {
058                return arg0.getText();
059            }
060        }
061    }
062
063    private static final class JsonArrayConverter implements Function<JsonNode, String>
064    {
065        public String apply(JsonNode arg0)
066        {
067            return arg0.getText();
068        }
069    }
070
071    public String modId;
072    public String name;
073    public String description;
074
075    public String url = "";
076    public String updateUrl = "";
077
078    public String logoFile = "";
079    public String version = "";
080    public List<String> authorList = Lists.newArrayList();
081    public String credits = "";
082    public String parent = "";
083    public String[] screenshots;
084
085    public ModContainer parentMod;
086    public List<ModContainer> childMods = Lists.newArrayList();
087
088    public boolean useDependencyInformation;
089    public Set<ArtifactVersion> requiredMods;
090    public List<ArtifactVersion> dependencies;
091    public List<ArtifactVersion> dependants;
092    public boolean autogenerated;
093
094    public ModMetadata(JsonNode node)
095    {
096        Map<JsonStringNode, Object> processedFields = Maps.transformValues(node.getFields(), new JsonStringConverter());
097        modId = (String)processedFields.get(aStringBuilder("modid"));
098        if (Strings.isNullOrEmpty(modId))
099        {
100            FMLLog.log(Level.SEVERE, "Found an invalid mod metadata file - missing modid");
101            throw new LoaderException();
102        }
103        name = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("name")));
104        description = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("description")));
105        url = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("url")));
106        updateUrl = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("updateUrl")));
107        logoFile = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("logoFile")));
108        version = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("version")));
109        credits = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("credits")));
110        parent =  Strings.nullToEmpty((String)processedFields.get(aStringBuilder("parent")));
111        authorList = Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authors"))),Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authorList"))), authorList));
112        requiredMods = processReferences(processedFields.get(aStringBuilder("requiredMods")), HashSet.class);
113        dependencies = processReferences(processedFields.get(aStringBuilder("dependencies")), ArrayList.class);
114        dependants = processReferences(processedFields.get(aStringBuilder("dependants")), ArrayList.class);
115        useDependencyInformation = Boolean.parseBoolean(Strings.nullToEmpty((String)processedFields.get(aStringBuilder("useDependencyInformation"))));
116    }
117
118    public ModMetadata()
119    {
120    }
121
122    private <T extends Collection<ArtifactVersion>> T processReferences(Object refs, Class<? extends T> retType)
123    {
124        T res = null;
125        try
126        {
127            res = retType.newInstance();
128        }
129        catch (Exception e)
130        {
131            // unpossible
132        }
133
134        if (refs == null)
135        {
136            return res;
137        }
138        for (String ref : ((List<String>)refs))
139        {
140            res.add(VersionParser.parseVersionReference(ref));
141        }
142        return res;
143    }
144
145    public String getChildModCountString()
146    {
147        return String.format("%d child mod%s", childMods.size(), childMods.size() != 1 ? "s" : "");
148    }
149
150    public String getAuthorList()
151    {
152        return Joiner.on(", ").join(authorList);
153    }
154
155    public String getChildModList()
156    {
157        return Joiner.on(", ").join(Lists.transform(childMods, new ModNameFunction()));
158    }
159
160    public String printableSortingRules()
161    {
162        return "";
163    }
164}