| /* |
| * Copyright 2014 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.dev; |
| |
| import com.google.gwt.thirdparty.guava.common.collect.ArrayListMultimap; |
| import com.google.gwt.thirdparty.guava.common.collect.Maps; |
| import com.google.gwt.thirdparty.guava.common.collect.Multimap; |
| import com.google.gwt.thirdparty.guava.common.collect.SortedSetMultimap; |
| import com.google.gwt.thirdparty.guava.common.collect.TreeMultimap; |
| |
| import java.io.Serializable; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.SortedMap; |
| |
| /** |
| * Contains mappings for property names to property values and from request types (GWT.create) to |
| * rebound types. |
| * <p> |
| * Each info object typically contains the information for one (soft) permutation. |
| */ |
| public class PropertyAndBindingInfo implements Serializable { |
| private final SortedMap<String, String> reboundTypeByGwtCreateType; |
| private final SortedMap<String, String> propertyValueByPropertyName; |
| |
| public PropertyAndBindingInfo() { |
| reboundTypeByGwtCreateType = Maps.newTreeMap(); |
| propertyValueByPropertyName = Maps.newTreeMap(); |
| } |
| |
| private PropertyAndBindingInfo( |
| SortedMap<String, String> reboundTypeByGwtCreateType, |
| SortedMap<String, String> propertyValueByPropertyName) { |
| this.reboundTypeByGwtCreateType = reboundTypeByGwtCreateType; |
| this.propertyValueByPropertyName = propertyValueByPropertyName; |
| } |
| |
| /** |
| * Returns the property value for a propertyname. |
| */ |
| public String getPropertyValue(String key) { |
| return propertyValueByPropertyName.get(key); |
| } |
| |
| /** |
| * Returns the Java class that a GWT.create() call will construct. |
| * |
| * @param key the GWT.create() argument (source type name) |
| * @return a source type name |
| */ |
| public String getReboundType(String key) { |
| return reboundTypeByGwtCreateType.get(key); |
| } |
| |
| /** |
| * Adds a property value. |
| */ |
| public void putPropertyValue(String propertyName, String propertyValue) { |
| propertyValueByPropertyName.put(propertyName, propertyValue); |
| } |
| |
| /** |
| * Sets the Java class that a GWT.create() call will construct. |
| * |
| * @param key a source type name |
| * @param value a source type name |
| */ |
| void putReboundType(String key, String value) { |
| reboundTypeByGwtCreateType.put(key, value); |
| } |
| |
| /** |
| * Returns true if the map contains a answer for the given GWT.create() argument. |
| */ |
| public boolean containsProperty(String key) { |
| return propertyValueByPropertyName.containsKey(key); |
| } |
| |
| /** |
| * Returns true if the map contains a answer for the given GWT.create() argument. |
| */ |
| public boolean containsType(String key) { |
| return reboundTypeByGwtCreateType.containsKey(key); |
| } |
| |
| /** |
| * Asserts that two maps contain the same answers for the given GWT.create() arguments. |
| */ |
| void assertRebindsEqual(PropertyAndBindingInfo other, Iterable<String> keysToCheck) { |
| for (String key : keysToCheck) { |
| assert reboundTypeByGwtCreateType.get(key).equals(other.reboundTypeByGwtCreateType.get(key)); |
| } |
| } |
| |
| /** |
| * Returns the answers that are the same in every permutation. |
| */ |
| public static PropertyAndBindingInfo getCommonAnswers(Iterable<PropertyAndBindingInfo> maps) { |
| Iterator<PropertyAndBindingInfo> it = maps.iterator(); |
| |
| // Start with an arbitrary copy |
| PropertyAndBindingInfo first = it.next(); |
| SortedMap<String, String> commonTypesByGwtCreateType = |
| Maps.newTreeMap(first.reboundTypeByGwtCreateType); |
| SortedMap<String, String> commonPropertiesValuesByPropertyNames = |
| Maps.newTreeMap(first.propertyValueByPropertyName); |
| |
| while (it.hasNext()) { |
| PropertyAndBindingInfo next = it.next(); |
| // Only keep key/value pairs present in both maps. |
| commonTypesByGwtCreateType.entrySet().retainAll(next.reboundTypeByGwtCreateType.entrySet()); |
| commonPropertiesValuesByPropertyNames.entrySet() |
| .retainAll(next.propertyValueByPropertyName.entrySet()); |
| } |
| |
| return new PropertyAndBindingInfo(commonTypesByGwtCreateType, |
| commonPropertiesValuesByPropertyNames); |
| } |
| |
| /** |
| * Returns the Java classes that GWT.create() might return in at least one permutation. |
| * |
| * @param requestTypes the GWT.create() arguments to include (source type names). |
| */ |
| public static SortedSetMultimap<String, String> getPossibleReboundTypesByRequestType( |
| Iterable<PropertyAndBindingInfo> permutationPropertyAndBindingInfoList, |
| Set<String> requestTypes) { |
| |
| SortedSetMultimap<String, String> result = TreeMultimap.create(); |
| |
| for (PropertyAndBindingInfo map : permutationPropertyAndBindingInfoList) { |
| for (Map.Entry<String, String> entry : map.reboundTypeByGwtCreateType.entrySet()) { |
| if (!requestTypes.contains(entry.getKey())) { |
| continue; |
| } |
| result.put(entry.getKey(), entry.getValue()); |
| } |
| } |
| |
| return result; |
| } |
| |
| /** |
| * Given an argument to GWT.create(), returns a map containing each possible return type and the |
| * permutations that would create it. |
| * |
| * @return a map from a Java class (source type name) to a list of indexes into the maps list. |
| */ |
| public static Multimap<String, Integer> getPermutationIdsByRequestTypes( |
| List<PropertyAndBindingInfo> maps, String key) { |
| |
| Multimap<String, Integer> result = ArrayListMultimap.create(); |
| |
| int permutationCount = maps.size(); |
| for (int i = 0; i < permutationCount; i++) { |
| String answerType = maps.get(i).getReboundType(key); |
| result.put(answerType, i); |
| } |
| return result; |
| } |
| |
| /** |
| * Given a property name, returns a map containing each possible return value and the |
| * permutations that would create it. |
| * |
| * @return a map from a Java class (source type name) to a list of indexes into the maps list. |
| */ |
| public static Multimap<String, Integer> getPermutationIdsByPropertyName( |
| List<PropertyAndBindingInfo> maps, String key) { |
| |
| Multimap<String, Integer> result = ArrayListMultimap.create(); |
| |
| int permutationCount = maps.size(); |
| for (int i = 0; i < permutationCount; i++) { |
| String answerType = maps.get(i).getPropertyValue(key); |
| result.put(answerType, i); |
| } |
| return result; |
| } |
| } |