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.grid; 018 019import java.util.List; 020 021import org.apache.wicket.WicketRuntimeException; 022import org.apache.wicket.markup.repeater.Item; 023import org.apache.wicket.markup.repeater.RefreshingView; 024import org.apache.wicket.markup.repeater.RepeatingView; 025import org.apache.wicket.markup.repeater.data.DataViewBase; 026import org.apache.wicket.markup.repeater.data.IDataProvider; 027import org.apache.wicket.model.IModel; 028import org.apache.wicket.model.Model; 029 030 031/** 032 * Acts as a base for data-grid views. Unlike a data view a data-grid view populates both rows and 033 * columns. The columns are populated by an array of provided ICellPopulator objects. 034 * 035 * @see DataGridView 036 * 037 * @author Igor Vaynberg (ivaynberg) 038 * 039 * @param <T> 040 * Model object type 041 */ 042public abstract class AbstractDataGridView<T> extends DataViewBase<T> 043{ 044 private static final long serialVersionUID = 1L; 045 046 private static final String CELL_REPEATER_ID = "cells"; 047 private static final String CELL_ITEM_ID = "cell"; 048 049 private final List<? extends ICellPopulator<T>> populators; 050 051 /** 052 * Constructor 053 * 054 * @param id 055 * component id 056 * @param populators 057 * array of ICellPopulator objects that will be used to populate cell items 058 * @param dataProvider 059 * data provider 060 */ 061 public AbstractDataGridView(final String id, 062 final List<? extends ICellPopulator<T>> populators, final IDataProvider<T> dataProvider) 063 { 064 super(id, dataProvider); 065 066 this.populators = populators; 067 } 068 069 protected final List<? extends ICellPopulator<T>> internalGetPopulators() 070 { 071 return populators; 072 } 073 074 075 /** 076 * Factory method for Item container that represents a cell. 077 * 078 * @see Item 079 * @see RefreshingView#newItem(String, int, IModel) 080 * 081 * @param id 082 * component id for the new data item 083 * @param index 084 * the index of the new data item 085 * @param model 086 * the model for the new data item 087 * 088 * @return DataItem created DataItem 089 */ 090 protected Item<ICellPopulator<T>> newCellItem(final String id, final int index, 091 final IModel<ICellPopulator<T>> model) 092 { 093 return new Item<>(id, index, model); 094 } 095 096 @Override 097 protected final Item<T> newItem(final String id, final int index, final IModel<T> model) 098 { 099 return newRowItem(id, index, model); 100 } 101 102 /** 103 * Factory method for Item container that represents a row. 104 * 105 * @see Item 106 * @see RefreshingView#newItem(String, int, IModel) 107 * 108 * @param id 109 * component id for the new data item 110 * @param index 111 * the index of the new data item 112 * @param model 113 * the model for the new data item. 114 * 115 * @return DataItem created DataItem 116 */ 117 protected Item<T> newRowItem(final String id, final int index, final IModel<T> model) 118 { 119 return new Item<>(id, index, model); 120 } 121 122 123 /** 124 * @see org.apache.wicket.markup.repeater.data.DataViewBase#onDetach() 125 */ 126 @Override 127 protected void onDetach() 128 { 129 super.onDetach(); 130 if (populators != null) 131 { 132 for (ICellPopulator<T> populator : populators) 133 { 134 populator.detach(); 135 } 136 } 137 } 138 139 /** 140 * @see org.apache.wicket.markup.repeater.RefreshingView#populateItem(org.apache.wicket.markup.repeater.Item) 141 */ 142 @Override 143 protected final void populateItem(final Item<T> item) 144 { 145 RepeatingView cells = new RepeatingView(CELL_REPEATER_ID); 146 item.add(cells); 147 148 int populatorsNumber = populators.size(); 149 for (int i = 0; i < populatorsNumber; i++) 150 { 151 ICellPopulator<T> populator = populators.get(i); 152 IModel<ICellPopulator<T>> populatorModel = new Model<>(populator); 153 Item<ICellPopulator<T>> cellItem = newCellItem(cells.newChildId(), i, populatorModel); 154 cells.add(cellItem); 155 156 populator.populateItem(cellItem, CELL_ITEM_ID, item.getModel()); 157 158 if (cellItem.get("cell") == null) 159 { 160 throw new WicketRuntimeException( 161 populator.getClass().getName() + 162 ".populateItem() failed to add a component with id [" + 163 CELL_ITEM_ID + 164 "] to the provided [cellItem] object. Make sure you call add() on cellItem and make sure you gave the added component passed in 'componentId' id. ( *cellItem*.add(new MyComponent(*componentId*, rowModel) )"); 165 } 166 } 167 168 } 169}