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.discovery;
014
015import java.util.List;
016import java.util.Map;
017import java.util.Set;
018
019import com.google.common.base.Predicate;
020import com.google.common.collect.HashMultimap;
021import com.google.common.collect.ImmutableMap;
022import com.google.common.collect.ImmutableSetMultimap;
023import com.google.common.collect.Lists;
024import com.google.common.collect.Multimap;
025import com.google.common.collect.Multimaps;
026import com.google.common.collect.SetMultimap;
027
028import cpw.mods.fml.common.ModContainer;
029
030public class ASMDataTable
031{
032    public static class ASMData
033    {
034        private ModCandidate candidate;
035        private String annotationName;
036        private String className;
037        private String objectName;
038        private Map<String,Object> annotationInfo;
039        public ASMData(ModCandidate candidate, String annotationName, String className, String objectName, Map<String,Object> info)
040        {
041            this.candidate = candidate;
042            this.annotationName = annotationName;
043            this.className = className;
044            this.objectName = objectName;
045            this.annotationInfo = info;
046        }
047        public ModCandidate getCandidate()
048        {
049            return candidate;
050        }
051        public String getAnnotationName()
052        {
053            return annotationName;
054        }
055        public String getClassName()
056        {
057            return className;
058        }
059        public String getObjectName()
060        {
061            return objectName;
062        }
063        public Map<String, Object> getAnnotationInfo()
064        {
065            return annotationInfo;
066        }
067    }
068
069    private static class ModContainerPredicate implements Predicate<ASMData>
070    {
071        private ModContainer container;
072        public ModContainerPredicate(ModContainer container)
073        {
074            this.container = container;
075        }
076        public boolean apply(ASMData data)
077        {
078            return container.getSource().equals(data.candidate.getModContainer());
079        }
080    }
081    private SetMultimap<String, ASMData> globalAnnotationData = HashMultimap.create();
082    private Map<ModContainer, SetMultimap<String,ASMData>> containerAnnotationData;
083
084    private List<ModContainer> containers = Lists.newArrayList();
085
086    public SetMultimap<String,ASMData> getAnnotationsFor(ModContainer container)
087    {
088        if (containerAnnotationData == null)
089        {
090            ImmutableMap.Builder<ModContainer, SetMultimap<String, ASMData>> mapBuilder = ImmutableMap.<ModContainer, SetMultimap<String,ASMData>>builder();
091            for (ModContainer cont : containers)
092            {
093                Multimap<String, ASMData> values = Multimaps.filterValues(globalAnnotationData, new ModContainerPredicate(cont));
094                mapBuilder.put(cont, ImmutableSetMultimap.copyOf(values));
095            }
096            containerAnnotationData = mapBuilder.build();
097        }
098        return containerAnnotationData.get(container);
099    }
100
101    public Set<ASMData> getAll(String annotation)
102    {
103        return globalAnnotationData.get(annotation);
104    }
105
106    public void addASMData(ModCandidate candidate, String annotation, String className, String objectName, Map<String,Object> annotationInfo)
107    {
108        globalAnnotationData.put(annotation, new ASMData(candidate, annotation, className, objectName, annotationInfo));
109    }
110
111    public void addContainer(ModContainer container)
112    {
113        this.containers.add(container);
114    }
115}