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.extensions.markup.html.repeater.data.table; 018 019import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; 020import org.apache.wicket.extensions.markup.html.repeater.data.table.export.IExportableColumn; 021import org.apache.wicket.markup.html.basic.Label; 022import org.apache.wicket.markup.repeater.Item; 023import org.apache.wicket.model.IModel; 024import org.apache.wicket.util.lang.Args; 025import org.danekja.java.util.function.serializable.SerializableFunction; 026 027/** 028 * An implementation of column that adds a label to the cell whose model is determined by the 029 * provided {@code SerializableFunction} that is evaluated against the current row's model object 030 * <p> 031 * Example for a table of {@code Contact}s: 032 * 033 * <pre> 034 * columns[0] = new LambdaColumn(new Model<String>("First Name"), Contact::getFirstName); 035 * </pre> 036 * 037 * The above will attach a label to the cell which calls {@code #getFirstName()} for each displayed 038 * contact. 039 * 040 * @param <T> 041 * The Model object type 042 * @param <S> 043 * the type of the sort property 044 */ 045public class LambdaColumn<T, S> extends AbstractColumn<T, S> implements IExportableColumn<T, S> 046{ 047 private static final long serialVersionUID = 1L; 048 049 private final SerializableFunction<T, ?> function; 050 051 /** 052 * Creates a column that is not sortable. 053 * 054 * @param displayModel 055 * display model 056 * @param function 057 * Wicket function to be applied to each row 058 */ 059 public LambdaColumn(final IModel<String> displayModel, 060 final SerializableFunction<T, ?> function) 061 { 062 this(displayModel, null, function); 063 } 064 065 /** 066 * Creates a property column that is also sortable. 067 * 068 * @param displayModel 069 * display model 070 * @param sortProperty 071 * sort property 072 * @param function 073 * Wicket function to be applied to each row 074 */ 075 public LambdaColumn(final IModel<String> displayModel, final S sortProperty, 076 final SerializableFunction<T, ?> function) 077 { 078 super(displayModel, sortProperty); 079 080 this.function = Args.notNull(function, "function"); 081 } 082 083 @Override 084 public void populateItem(Item<ICellPopulator<T>> item, String componentId, IModel<T> rowModel) 085 { 086 item.add(new Label(componentId, getDataModel(rowModel))); 087 } 088 089 /** 090 * Factory method for generating a model that will generated the displayed value. 091 * 092 * @param rowModel 093 * @return model 094 */ 095 @Override 096 public IModel<?> getDataModel(IModel<T> rowModel) 097 { 098 IModel<Object> dataModel = new IModel<Object>() 099 { 100 private static final long serialVersionUID = 1L; 101 102 @Override 103 public Object getObject() 104 { 105 T before = rowModel.getObject(); 106 107 if (before == null) { 108 return null; 109 } else { 110 return function.apply(before); 111 } 112 } 113 114 @Override 115 public void detach() 116 { 117 rowModel.detach(); 118 } 119 }; 120 return dataModel; 121 } 122}