/******************************************************************************* * Copyright (c) 2014-2016 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.boot.properties.editor.metadata; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.core.runtime.Platform; import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty; import org.springframework.boot.configurationmetadata.ConfigurationMetadataSource; import org.springframework.boot.configurationmetadata.Deprecation; import org.springframework.boot.configurationmetadata.ValueHint; import org.springframework.boot.configurationmetadata.ValueProvider; import org.springframework.ide.eclipse.boot.properties.editor.metadata.ValueProviderRegistry.ValueProviderStrategy; import org.springframework.ide.eclipse.boot.properties.editor.util.Type; import org.springframework.ide.eclipse.boot.properties.editor.util.TypeParser; import org.springframework.ide.eclipse.boot.properties.editor.util.TypeUtil; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; /** * Information about a spring property, basically, this is the same as * * {@link ConfigurationMetadataProperty} but augmented with information * about {@link ConfigurationMetadataSource}s that declare the property. * * @author Kris De Volder */ public class PropertyInfo { // private static final boolean DEBUG = (""+Platform.getLocation()).contains("kdvolder"); // // private static void debug(String string) { // if (DEBUG) // System.out.println(string); // } /** * Identifies a 'Source'. This is essentially the sames as {@link ConfigurationMetadataSource}. * We could use {@link ConfigurationMetadataSource} directly, but this only contains * the info that we actually use so takes less memory. */ public static class PropertySource { private final String sourceType; private final String sourceMethod; public PropertySource(ConfigurationMetadataSource source) { String st = source.getSourceType(); this.sourceType = st!=null?st:source.getType(); this.sourceMethod = source.getSourceMethod(); } @Override public String toString() { return sourceType+"::"+sourceMethod; } public String getSourceType() { return sourceType; } public String getSourceMethod() { return sourceMethod; } } final private String id; private String type; final private String name; final private Object defaultValue; final private String description; private List<PropertySource> sources; private Deprecation deprecation; private ImmutableList<ValueHint> valueHints; private ImmutableList<ValueHint> keyHints; private ValueProviderStrategy valueProvider; private ValueProviderStrategy keyProvider; public PropertyInfo(String id, String type, String name, Object defaultValue, String description, Deprecation deprecation, List<ValueHint> valueHints, List<ValueHint> keyHints, ValueProviderStrategy valueProvider, ValueProviderStrategy keyProvider, List<PropertySource> sources) { super(); this.id = id; this.type = type; this.name = name; this.defaultValue = defaultValue; this.description = description; this.deprecation = deprecation; this.valueHints = valueHints==null?null:ImmutableList.copyOf(valueHints); this.keyHints = keyHints==null?null:ImmutableList.copyOf(keyHints); this.valueProvider = valueProvider; this.keyProvider = keyProvider; this.sources = sources; } public PropertyInfo(ValueProviderRegistry valueProviders, ConfigurationMetadataProperty prop) { this( prop.getId(), prop.getType(), prop.getName(), prop.getDefaultValue(), prop.getDescription(), prop.getDeprecation(), prop.getHints().getValueHints(), prop.getHints().getKeyHints(), valueProviders.resolve(prop.getHints().getValueProviders()), valueProviders.resolve(prop.getHints().getKeyProviders()), null ); for (ValueProvider h : prop.getHints().getValueProviders()) { if (h.getName().equals("handle-as")) { handleAs(h.getParameters().get("target")); } } } private void handleAs(Object targetObject) { // debug("handle-as "+this.getId()+" -> "+targetObject); if (targetObject instanceof String) { this.type = (String)targetObject; } } public String getId() { return id; } public String getType() { return type; } public String getName() { return name; } public Object getDefaultValue() { return defaultValue; } public String getDescription() { return description; } public HintProvider getHints(TypeUtil typeUtil, boolean dimensionAware) { Type type = TypeParser.parse(this.type); if (TypeUtil.isMap(type)) { return HintProviders.forMap(keyHints(typeUtil), valueHints(typeUtil), TypeUtil.getDomainType(type), dimensionAware); } else if (TypeUtil.isSequencable(type)) { if (dimensionAware) { if (TypeUtil.isSequencable(type)) { return HintProviders.forDomainAt(valueHints(typeUtil), TypeUtil.getDimensionality(type)); } else { return HintProviders.forHere(valueHints(typeUtil)); } } else { return HintProviders.forAllValueContexts(valueHints(typeUtil)); } } else { return HintProviders.forHere(valueHints(typeUtil)); } } private HintProvider keyHints(TypeUtil typeUtil) { return HintProviders.basic(typeUtil.getJavaProject(), keyHints, keyProvider); } private HintProvider valueHints(TypeUtil typeUtil) { return HintProviders.basic(typeUtil.getJavaProject(), valueHints, valueProvider); } public List<PropertySource> getSources() { if (sources!=null) { return sources; } return Collections.emptyList(); } @Override public String toString() { return "PropertyInfo("+getId()+")"; } public void addSource(ConfigurationMetadataSource source) { if (sources==null) { sources = new ArrayList<PropertySource>(); } sources.add(new PropertySource(source)); } public PropertyInfo withId(String alias) { if (alias.equals(id)) { return this; } return new PropertyInfo(alias, type, name, defaultValue, description, deprecation, valueHints, keyHints, valueProvider, keyProvider, sources); } public void setDeprecation(Deprecation d) { this.deprecation = d; } public boolean isDeprecated() { return deprecation!=null; } public String getDeprecationReason() { return deprecation == null ? null : deprecation.getReason(); } public String getDeprecationReplacement() { return deprecation == null ? null : deprecation.getReplacement(); } public void addValueHints(List<ValueHint> hints) { Builder<ValueHint> builder = ImmutableList.builder(); builder.addAll(valueHints); builder.addAll(hints); valueHints = builder.build(); } public void addKeyHints(List<ValueHint> hints) { Builder<ValueHint> builder = ImmutableList.builder(); builder.addAll(keyHints); builder.addAll(hints); keyHints = builder.build(); } }