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.repeater.data; 018 019import java.util.Iterator; 020 021import org.apache.wicket.markup.html.navigation.paging.IPageable; 022import org.apache.wicket.markup.repeater.AbstractPageableView; 023import org.apache.wicket.markup.repeater.RefreshingView; 024import org.apache.wicket.model.IModel; 025import org.apache.wicket.util.lang.Args; 026 027 028/** 029 * Base class for data views. 030 * 031 * Data views aim to make it very simple to populate your repeating view from a database by 032 * utilizing {@link IDataProvider} to act as an interface between the database and the dataview. 033 * 034 * @see IDataProvider 035 * @see DataView 036 * @see IPageable 037 * @see RefreshingView 038 * 039 * @author Igor Vaynberg (ivaynberg) 040 * 041 * @param <T> 042 * Model object type 043 */ 044public abstract class DataViewBase<T> extends AbstractPageableView<T> 045{ 046 private static final long serialVersionUID = 1L; 047 private final IDataProvider<T> dataProvider; 048 049 /** 050 * @param id 051 * component id 052 * @param dataProvider 053 * data provider 054 */ 055 public DataViewBase(String id, IDataProvider<T> dataProvider) 056 { 057 super(id); 058 059 this.dataProvider = Args.notNull(dataProvider, "dataProvider"); 060 } 061 062 /** 063 * @return data provider associated with this view 064 */ 065 protected final IDataProvider<T> internalGetDataProvider() 066 { 067 return dataProvider; 068 } 069 070 071 @Override 072 protected final Iterator<IModel<T>> getItemModels(long offset, long count) 073 { 074 return new ModelIterator<T>(internalGetDataProvider(), offset, count); 075 } 076 077 /** 078 * Helper class that converts input from IDataProvider to an iterator over view items. 079 * 080 * @author Igor Vaynberg (ivaynberg) 081 * 082 * @param <T> 083 * Model object type 084 */ 085 private static final class ModelIterator<T> implements Iterator<IModel<T>> 086 { 087 private final Iterator<? extends T> items; 088 private final IDataProvider<T> dataProvider; 089 private final long max; 090 private long index; 091 092 /** 093 * Constructor 094 * 095 * @param dataProvider 096 * data provider 097 * @param offset 098 * index of first item 099 * @param count 100 * max number of items to return 101 */ 102 public ModelIterator(IDataProvider<T> dataProvider, long offset, long count) 103 { 104 this.dataProvider = dataProvider; 105 max = count; 106 107 items = count > 0 ? dataProvider.iterator(offset, count) : null; 108 } 109 110 /** 111 * @see java.util.Iterator#remove() 112 */ 113 @Override 114 public void remove() 115 { 116 throw new UnsupportedOperationException(); 117 } 118 119 /** 120 * @see java.util.Iterator#hasNext() 121 */ 122 @Override 123 public boolean hasNext() 124 { 125 return items != null && items.hasNext() && (index < max); 126 } 127 128 /** 129 * @see java.util.Iterator#next() 130 */ 131 @Override 132 public IModel<T> next() 133 { 134 index++; 135 return dataProvider.model(items.next()); 136 } 137 } 138 139 @Override 140 protected final long internalGetItemCount() 141 { 142 return internalGetDataProvider().size(); 143 } 144 145 /** 146 * @see org.apache.wicket.markup.repeater.AbstractPageableView#onDetach() 147 */ 148 @Override 149 protected void onDetach() 150 { 151 dataProvider.detach(); 152 super.onDetach(); 153 } 154}