Did entertain myself with the idea and tried to implement it. Attached is a roughly tested patch.

I changed the name of IPrimaryKeyProvider to IPrimaryKeyDataProvider.

I also did replace the Map in DataView.onRender() with an array.

Christian

On Wed, 10 Aug 2005 14:35:45 -0700, Igor Vaynberg <[EMAIL PROTECTED]> wrote:

Alrite, without spending too much more time on this, entartain this idea:
Move primarykey to IPrimaryKeyProvider { String primaryKey() }

The dataview can do an instanceof check on the impl of IDataProvider, if it
implements iprimarykeyprovider use that otherwise use a generic counter.


-Igor

Index: DataView.java
===================================================================
RCS file: 
/cvsroot/wicket-stuff/wicket-contrib-dataview/src/wicket/contrib/dataview/DataView.java,v
retrieving revision 1.8
diff -u -r1.8 DataView.java
--- DataView.java       10 Aug 2005 04:55:09 -0000      1.8
+++ DataView.java       11 Aug 2005 00:51:48 -0000
@@ -57,6 +57,11 @@
        private int cachedItemCount = -1;
 
        /**
+        * A counter which will be used to generate generic ids for DataItem
+        */
+       private long _idGenerationCounter = 0; //TODO: check if this holds 
enough numbers for unchecked upcount.
+
+       /**
         * @see wicket.Component#Component(String)
         */
        public DataView(final String id)
@@ -208,9 +213,74 @@
        /**
         * @see wicket.MarkupContainer#internalOnBeginRequest()
         */
-       protected void internalOnBeginRequest()
-       {
+       protected void internalOnBeginRequest(){
                final IDataProvider dataProvider = getDataProvider();
+               if (dataProvider instanceof IPrimaryKeyDataProvider) {
+                       IPrimaryKeyDataProvider pkp = 
(IPrimaryKeyDataProvider)dataProvider;
+                       internalOnBeginRequestPrimaryKey(pkp);
+               }else{
+                       internalOnBeginRequestIModel(dataProvider);
+               }
+       }
+
+       private void internalOnBeginRequestIModel(IDataProvider dataProvider)
+       {
+               // Get number of items to be displayed
+               final int size = getViewSize();
+
+               if (size > 0)
+               {
+                       Iterator it = null;
+
+                       Map existingDataItems = new HashMap(size());
+                       it = iterator();
+                       while (it.hasNext())
+                       {
+                               final DataItem child = (DataItem)it.next();
+                               existingDataItems.put(child.getModel(),child);
+                       }
+
+                       it = dataProvider.iterator(firstIndex, size);
+
+                       // render all items not already present
+                       int index = 0;
+                       while (it.hasNext()&&index<size)
+                       {
+                               final Object object = it.next();
+                               final String id = 
"DataViewUniqueName"+_idGenerationCounter++;
+                               final IModel newModel = 
dataProvider.model(object);
+
+                               DataItem item = 
(DataItem)existingDataItems.get(newModel); 
+                               if (item == null)
+                               {
+                                       item = newItem(id, index, newModel);
+                                       add(item);
+                                       populateItem(item);
+                               }
+                               else
+                               {
+                                       item.setIndex(index);
+                                       existingDataItems.remove(newModel);
+                               }
+                               index++;
+                       }
+
+                       // remove dataitems no longer present in the view
+                       it = existingDataItems.values().iterator();
+                       while (it.hasNext())
+                       {
+                               DataItem item = (DataItem)it.next();
+                               remove(item.getId());
+                       }
+               }
+               else
+               {
+                       removeAll();
+               }
+       }
+
+       private void internalOnBeginRequestPrimaryKey(final 
IPrimaryKeyDataProvider dataProvider)
+       {
 
                // Get number of items to be displayed
                final int size = getViewSize();
@@ -290,23 +360,31 @@
 
                // maybe keep a map like this always updated as a field? what 
about
                // versioning?
-               Map itemsByIndex = new HashMap();
+               // just a proposal: (Christian)
+               final int size = getViewSize();
+               DataItem[] itemsByIndex = new DataItem[size];
                Iterator it = iterator();
                while (it.hasNext())
                {
                        final DataItem item = (DataItem)it.next();
-                       itemsByIndex.put(new Integer(item.getIndex()), item);
+                       int index = item.getIndex();
+                       try{
+                               itemsByIndex[index] = item;
+                       }catch(IndexOutOfBoundsException e){
+                               throw new WicketRuntimeException("DataItem with 
index [" + index
+                                               + "] is out of viewSize [" + 
size + "]");
+                               
+                       }
                }
 
                // Get number of items to be displayed
-               final int size = getViewSize();
                if (size > 0)
                {
                        // Loop through the markup in this container for each 
item
                        for (int i = 0; i < size; i++)
                        {
                                // If this component does not already exist, 
populate it
-                               DataItem item = (DataItem)itemsByIndex.get(new 
Integer(i));
+                               DataItem item = itemsByIndex[i];
 
                                if (item == null)
                                {
Index: IDataProvider.java
===================================================================
RCS file: 
/cvsroot/wicket-stuff/wicket-contrib-dataview/src/wicket/contrib/dataview/IDataProvider.java,v
retrieving revision 1.3
diff -u -r1.3 IDataProvider.java
--- IDataProvider.java  2 Aug 2005 16:48:26 -0000       1.3
+++ IDataProvider.java  11 Aug 2005 00:51:48 -0000
@@ -63,12 +63,4 @@
         */
        IModel model(Object object);
 
-       /**
-        * return stringized primary key for the current object
-        * 
-        * @param object
-        *            object whose primary key will be returned
-        * @return object's primary key
-        */
-       String primaryKey(Object object);
 }
Index: IPrimaryKeyDataProvider.java
===================================================================
RCS file: IPrimaryKeyDataProvider.java
diff -N IPrimaryKeyDataProvider.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ IPrimaryKeyDataProvider.java        1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,20 @@
+package wicket.contrib.dataview;
+
+/**
+ * An IDataProvider which also provides a primaryKey for optimized itemremoval 
based on
+ * the primary key.
+ * @author Igor Vaynberg ( ivaynberg )
+ *
+ */
+public interface IPrimaryKeyDataProvider extends IDataProvider
+{
+       /**
+        * return stringized primary key for the current object 
+        * 
+        * @param object
+        *            object whose primary key will be returned
+        * @return object's primary key
+        */
+       String primaryKey(Object object);
+
+}

Reply via email to