/* * Copyright 2016 Stormpath, 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.stormpath.sdk.convert; import com.stormpath.sdk.lang.Assert; import java.util.LinkedHashMap; import java.util.Map; /** * A Conversion represents directives that indicate how to convert one object (or collection) into another. * * @since 1.3.0 */ public class Conversion { private boolean enabled; private String name; private ConversionStrategyName strategy; private Map<String, Conversion> fields; private String field; private ElementsConversion elements; /** * Default constructor that enables the following settings: * <ul> * <li>{@link #isEnabled() enabled} = true</li> * <li>{@link #setStrategy(String) strategy} = {@link ConversionStrategyName#SCALARS SCALARS}</li> * </ul> */ public Conversion() { this.enabled = true; this.strategy = ConversionStrategyName.SCALARS; this.fields = java.util.Collections.emptyMap(); } /** * Returns {@code true} if this conversion is enabled and will result in a converted value, or {@code false} if * no conversion will occur and the input field or object will be skipped/removed entirely. Unless overridden, * the default value is {@code true}, meaning a discovered input field/object should be converted by default. * * @return {@code true} if this conversion is enabled and will result in a converted value, or {@code false} if * no conversion will occur and the input field or object will be skipped/removed entirely. */ public boolean isEnabled() { return enabled; } /** * Sets whether or not the conversion is enabled and will result in a converted value. If {@code false}, no * conversion will take place and the input object will not be represented at all. Unless overridden, the default * value is {@code true}, meaning a discovered input field/object should be converted by default. * * @param enabled whether or not the conversion is enabled and will result in a converted value. * @return this object for method chaining. */ public Conversion setEnabled(boolean enabled) { this.enabled = enabled; return this; } /** * Returns the field/property name to represent the converted output object. If unspecified, the name will be * the same name as discovered on the input object. * * @return the field/property name to represent the converted output object. */ public String getName() { return name; } /** * Sets the field/property name to represent the converted output object. If unspecified, the name will be * the same name as discovered on the input object. * * @param name the field/property name to represent the converted output object. * @return this object for method chaining. */ public Conversion setName(String name) { this.name = name; return this; } /** * Returns the conversion strategy to use when converting an input object to an output object. Unless overridden, * the default strategy is {@link ConversionStrategyName#SCALARS SCALARS}. * * @return the conversion strategy to use whne converting the input object to an output object. */ public ConversionStrategyName getStrategy() { return strategy; } /** * Sets the strategy to use when converting an input object to an output object. Unless overridden, the * default strategy is {@link ConversionStrategyName#SCALARS SCALARS}. * * @param strategy the strategy to use when converting the input object. * @return this object for method chaining. * @see ConversionStrategyName */ public Conversion setStrategy(ConversionStrategyName strategy) { Assert.notNull(strategy, "strategy argument cannot be null."); this.strategy = strategy; return this; } /** * Sets the strategy to use when converting the input object. This is a convenience method that * {@link ConversionStrategyName#fromName(String) looks up} the {@link ConversionStrategyName} instance using the * method argument. * <p>Unless overridden, the default strategy is {@link ConversionStrategyName#SCALARS SCALARS}.</p> * * @param strategy the strategy to use when converting the input object. * @return this object for method chaining. * @see #setStrategy(ConversionStrategyName) * @see ConversionStrategyName */ public Conversion setStrategy(String strategy) { return setStrategy(ConversionStrategyName.fromName(strategy)); } /** * Returns the name of the field on the input object to use as the only output value. This property is only used * with the {@link ConversionStrategyName#SINGLE SINGLE} strategy - it is ignored otherwise. * * @return the name of the field on the input object to use as the only output value. * @see ConversionStrategyName#SINGLE */ public String getField() { return field; } /** * Sets the name of the field on the input object to use as the only output value. This property is only used with * the {@link ConversionStrategyName#SINGLE SINGLE} strategy - it is ignored otherwise. * * @param field the name of the field on the input object to use as the only output value. * @return this object for method chaining. * @see ConversionStrategyName#SINGLE */ public Conversion setField(String field) { this.field = field; return this; } /** * Returns the Conversion directives for any specifically named fields encountered on an input object. The * Map's String key is the name of a field on the object to convert. The Map value for that key is the Conversion * that indicates how to convert the corresponding field's value. * <p>Because Conversion instances can contain fields (Maps of named Conversion instances), and so on, a * Conversion can reflect how to convert an entire object graph if desired.</p> * * @return the Conversion directives for any specifically named fields encountered on an input object. */ public Map<String, Conversion> getFields() { return fields; } /** * Sets the Conversion directives for any specifically named fields encountered on an input object. The * Map's String key is the name of a field on the object to convert. The Map value for that key is the Conversion * that indicates how to convert the corresponding field's value. * <p>Because Conversion instances can contain fields (Maps of named Conversion instances), and so on, a * Conversion can reflect how to convert an entire object graph if desired.</p> * * @param fields the conversions to apply when encountering named field values * @return this Conversion object for method chaining. */ public Conversion setFields(Map<String, Conversion> fields) { if (fields == null) { fields = java.util.Collections.emptyMap(); } this.fields = fields; return this; } private Map<String, Conversion> ensureFields() { Map<String, Conversion> fields = this.fields; if (fields == null || fields == java.util.Collections.EMPTY_MAP) { this.fields = fields = new LinkedHashMap<>(); } return fields; } /** * A convenience builder method that will add the specified {@code conversion} argument to the * {@link #getFields() fields} map under the specified {@code fieldName} key. * * @param fieldName the name of the field on the input object to be converted * @param conversion the conversion to apply when encountering the named field on the input object * @return this object for method chaining. */ public Conversion withField(String fieldName, Conversion conversion) { Assert.hasText(fieldName, "fieldName argument cannot be null or empty."); Assert.notNull(conversion, "fieldConfig argument cannot be null."); ensureFields().put(fieldName, conversion); return this; } /** * Returns the {@link ElementsConversion} that indicates how to convert a collection's elements. This property is * only used if the input object is a collection resource - it is ignored otherwise. * * @return the {@link ElementsConversion} that indicates how to convert a collection's elements. */ public ElementsConversion getElements() { return elements; } /** * Sets the {@link ElementsConversion} that indicates how to convert a collection's elements. This property is * only used if the input object is a collection resource - it is ignored otherwise. * * @param elements the {@code ElementsConversion} that indicates how to convert a collection's elements. * @return this object for method chaining. */ public Conversion setElements(ElementsConversion elements) { this.elements = elements; return this; } }