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 }