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    
015    package cpw.mods.fml.common;
016    
017    import static argo.jdom.JsonNodeBuilders.aStringBuilder;
018    
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.HashSet;
022    import java.util.List;
023    import java.util.Map;
024    import java.util.Set;
025    import java.util.logging.Level;
026    
027    import argo.jdom.JsonNode;
028    import argo.jdom.JsonStringNode;
029    
030    import com.google.common.base.Function;
031    import com.google.common.base.Joiner;
032    import com.google.common.base.Objects;
033    import com.google.common.base.Optional;
034    import com.google.common.base.Strings;
035    import com.google.common.collect.Lists;
036    import com.google.common.collect.Maps;
037    
038    import cpw.mods.fml.common.functions.ModNameFunction;
039    import cpw.mods.fml.common.versioning.ArtifactVersion;
040    import cpw.mods.fml.common.versioning.VersionParser;
041    
042    /**
043     * @author cpw
044     *
045     */
046    public 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    }