| /* |
| * Copyright 2013 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.cfg; |
| |
| import com.google.gwt.core.ext.BadPropertyValueException; |
| import com.google.gwt.core.ext.ConfigurationProperty; |
| import com.google.gwt.core.ext.DefaultConfigurationProperty; |
| import com.google.gwt.core.ext.DefaultSelectionProperty; |
| import com.google.gwt.core.ext.PropertyOracle; |
| import com.google.gwt.core.ext.SelectionProperty; |
| import com.google.gwt.core.ext.TreeLogger; |
| import com.google.gwt.thirdparty.guava.common.collect.Maps; |
| import com.google.gwt.thirdparty.guava.common.collect.Sets; |
| |
| import java.util.Arrays; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.SortedSet; |
| |
| /** |
| * An implementation of {@link PropertyOracle} that helps discover the property values associated |
| * with specific rebind results for generators.<br /> |
| * |
| * It does so by recording the properties that are queried, providing a first legal answer for |
| * properties not previously queried and allowing an external driver to prescribe values for |
| * properties that have been discovered as dependencies. |
| */ |
| // TODO(stalcup): get rid of foo.ConfigurationProperty and bar.ConfigurationProperty class name |
| // collisions. |
| public class DynamicPropertyOracle implements PropertyOracle { |
| |
| private static SelectionProperty createSelectionProperty( |
| String value, BindingProperty bindingProperty) { |
| SortedSet<String> possibleValues = |
| Sets.newTreeSet(Arrays.asList(bindingProperty.getDefinedValues())); |
| return new DefaultSelectionProperty(value, bindingProperty.getFallback(), |
| bindingProperty.getName(), possibleValues, bindingProperty.getFallbackValuesMap()); |
| } |
| |
| private final Set<BindingProperty> accessedProperties = Sets.newHashSet(); |
| private boolean accessedPropertiesChanged; |
| private final Map<String, String> prescribedPropertyValuesByName = Maps.newHashMap(); |
| private final Properties properties; |
| |
| public DynamicPropertyOracle(Properties properties) { |
| this.properties = properties; |
| } |
| |
| public boolean haveAccessedPropertiesChanged() { |
| return accessedPropertiesChanged; |
| } |
| |
| public Set<BindingProperty> getAccessedProperties() { |
| return accessedProperties; |
| } |
| |
| @Override |
| public ConfigurationProperty getConfigurationProperty(String propertyName) |
| throws BadPropertyValueException { |
| com.google.gwt.dev.cfg.ConfigurationProperty prop = properties.findConfigProp(propertyName); |
| if (prop != null) { |
| return new DefaultConfigurationProperty(prop.getName(), prop.getValues()); |
| } |
| throw new BadPropertyValueException(propertyName); |
| } |
| |
| /** |
| * Returns the mapping from property names to its currently prescribed value. The internal mapping |
| * changes between runs so the returned value is a stable copy. |
| */ |
| public Map<String, String> getPrescribedPropertyValuesByName() { |
| return Maps.newHashMap(prescribedPropertyValuesByName); |
| } |
| |
| @Override |
| public SelectionProperty getSelectionProperty(TreeLogger logger, String propertyName) |
| throws BadPropertyValueException { |
| BindingProperty bindingProperty = getBindingProperty(propertyName); |
| accessedPropertiesChanged |= accessedProperties.add(bindingProperty); |
| |
| String propertyValue = prescribedPropertyValuesByName.isEmpty() |
| ? bindingProperty.getFirstGeneratedValue() : prescribedPropertyValuesByName.get(propertyName); |
| return createSelectionProperty(propertyValue, bindingProperty); |
| } |
| |
| public void prescribePropertyValue(String propertyName, String propertyValue) { |
| prescribedPropertyValuesByName.put(propertyName, propertyValue); |
| } |
| |
| /** |
| * Clears state in preparation for another round of rebind analysis on the same generator. Since |
| * some per generator state is not cleared it is necessary to create a new instance per generator. |
| */ |
| public void reset() { |
| accessedPropertiesChanged = false; |
| prescribedPropertyValuesByName.clear(); |
| } |
| |
| private BindingProperty getBindingProperty(String propertyName) throws BadPropertyValueException { |
| BindingProperty property = properties.findBindingProp(propertyName); |
| if (property != null) { |
| return property; |
| } |
| throw new BadPropertyValueException(propertyName); |
| } |
| } |