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        /**
095         * @param mod2
096         * @param type2
097         */
098        public ModMetadata(JsonNode node)
099        {
100            Map<JsonStringNode, Object> processedFields = Maps.transformValues(node.getFields(), new JsonStringConverter());
101            modId = (String)processedFields.get(aStringBuilder("modid"));
102            if (Strings.isNullOrEmpty(modId))
103            {
104                FMLLog.log(Level.SEVERE, "Found an invalid mod metadata file - missing modid");
105                throw new LoaderException();
106            }
107            name = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("name")));
108            description = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("description")));
109            url = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("url")));
110            updateUrl = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("updateUrl")));
111            logoFile = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("logoFile")));
112            version = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("version")));
113            credits = Strings.nullToEmpty((String)processedFields.get(aStringBuilder("credits")));
114            parent =  Strings.nullToEmpty((String)processedFields.get(aStringBuilder("parent")));
115            authorList = Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authors"))),Objects.firstNonNull(((List<String>)processedFields.get(aStringBuilder("authorList"))), authorList));
116            requiredMods = processReferences(processedFields.get(aStringBuilder("requiredMods")), HashSet.class);
117            dependencies = processReferences(processedFields.get(aStringBuilder("dependencies")), ArrayList.class);
118            dependants = processReferences(processedFields.get(aStringBuilder("dependants")), ArrayList.class);
119            useDependencyInformation = Boolean.parseBoolean(Strings.nullToEmpty((String)processedFields.get(aStringBuilder("useDependencyInformation"))));
120        }
121    
122        public ModMetadata()
123        {
124        }
125    
126        private <T extends Collection<ArtifactVersion>> T processReferences(Object refs, Class<? extends T> retType)
127        {
128            T res = null;
129            try
130            {
131                res = retType.newInstance();
132            }
133            catch (Exception e)
134            {
135                // unpossible
136            }
137    
138            if (refs == null)
139            {
140                return res;
141            }
142            for (String ref : ((List<String>)refs))
143            {
144                res.add(VersionParser.parseVersionReference(ref));
145            }
146            return res;
147        }
148        /**
149         * @return
150         */
151        public String getChildModCountString()
152        {
153            return String.format("%d child mod%s", childMods.size(), childMods.size() != 1 ? "s" : "");
154        }
155    
156        public String getAuthorList()
157        {
158            return Joiner.on(", ").join(authorList);
159        }
160    
161        /**
162         * @return
163         */
164        public String getChildModList()
165        {
166            return Joiner.on(", ").join(Lists.transform(childMods, new ModNameFunction()));
167        }
168    
169        public String printableSortingRules()
170        {
171            return "";
172        }
173    }