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