001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.markup.html.form;
018
019import org.danekja.java.util.function.serializable.SerializableFunction;
020
021/**
022 * Renders one choice. Separates the 'id' values used for internal representation from 'display
023 * values' which are the values shown to the user of components that use this renderer.
024 * <p>
025 * Usage:
026 *
027 * <pre>
028 * new DropDownChoice&lt;User&gt;(&quot;users&quot;, new Model&lt;User&gt;(selectedUser), listOfUsers,
029 *      new LambdaChoiceRenderer&lt;User&gt;(User::getName))
030 * </pre>
031 * <p>
032 * creates a DropDownChoice of users and the display value will be looked up by function
033 * (User::getName) and the id the index of the object in the ListOfUsers
034 * </p>
035 * <p>
036 *
037 * <pre>
038 * new DropDownChoice&lt;User&gt;(&quot;users&quot;, new Model&lt;User&gt;(selectedUser), listOfUsers,
039 *      new LambdaChoiceRenderer&lt;User&gt;(User::getName, User::getId))
040 * </pre>
041 * <p>
042 * creates a DropDownChoice of users and the display value will be looked up by function
043 * (User::getName) and the id will be looked up by the function (User::getId)
044 * </p>
045 *
046 * @param <T> The model object type
047 */
048public class LambdaChoiceRenderer<T> implements IChoiceRenderer<T> {
049    private static final long serialVersionUID = 1L;
050
051    /**
052     * function for getting the display value.
053     */
054    private final SerializableFunction<T, ?> displayExpression;
055
056    /**
057     * function for getting the id.
058     */
059    private final SerializableFunction<T, ?> idExpression;
060
061    /**
062     * Constructor.
063     * <p>
064     * When you use this constructor, the display value will be determined by calling
065     * toString() on the list object, and the id will be based on the list index. the id value will
066     * be the index
067     */
068    public LambdaChoiceRenderer() {
069        this(null);
070    }
071
072    /**
073     * Constructor.
074     * <p>
075     * When you use this constructor, the display value will be determined by executing
076     * the given function on the list object, and the id will be based on the list index.
077     * The display value will be calculated by the given function
078     *
079     * @param displayExpression A function to get the display value
080     */
081    public LambdaChoiceRenderer(SerializableFunction<T, ?> displayExpression) {
082        this(displayExpression, null);
083    }
084
085    /**
086     * Constructor.
087     * <p>
088     * When you use this constructor, both the id and the display value will be
089     * determined by executing the given functions on the list object.
090     *
091     * @param displayExpression A function to get the display value
092     * @param idExpression      A function to get the id value
093     */
094    public LambdaChoiceRenderer(SerializableFunction<T, ?> displayExpression, SerializableFunction<T, ?> idExpression) {
095        this.displayExpression = displayExpression;
096        this.idExpression = idExpression;
097    }
098
099    @Override
100    public Object getDisplayValue(T object) {
101        Object returnValue = object;
102        if ((displayExpression != null) && (object != null)) {
103            returnValue = displayExpression.apply(object);
104        }
105
106        if (returnValue == null) {
107            return "";
108        }
109
110        return returnValue;
111    }
112
113    @Override
114    public String getIdValue(T object, int index) {
115        if (idExpression == null) {
116            return Integer.toString(index);
117        }
118
119        if (object == null) {
120            return "";
121        }
122
123        Object returnValue = idExpression.apply(object);
124        if (returnValue == null) {
125            return "";
126        }
127
128        return returnValue.toString();
129    }
130}