Changeset 6772


Ignore:
Timestamp:
Mar 16, 2015, 12:52:48 PM (7 years ago)
Author:
Nicklas Nordborg
Message:

References #1325: Lists of items

Added functionality for keeping track of the sync status of a single SyncFilter. Each time a synchronization is made, an MD5 value is calculated from the ID:s of items matching a filter. If the number of ID and their MD5 value doesn't change the filter is assumed to be in sync. Note that parent/child relationships are not taken into account so the even if a filter appears to be in sync it may result in a different child/parent list.

It could also be a performance hog to load this information every time on the view page, so it may have to be changed to lazy-loading in the future.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/net/sf/basedb/core/ItemList.java

    r6771 r6772  
    2929import java.util.Map;
    3030import java.util.Set;
     31import java.util.SortedSet;
     32import java.util.TreeSet;
    3133
    3234import org.apache.commons.collections.CollectionUtils;
     
    930932    sfData.setSourceItemType(getMemberType().getValue());
    931933    sfData.setSourceItemTransform(SourceItemTransform.NONE.ordinal());
     934    sfData.setMatching(-1);
    932935   
    933936    getData().getSyncFilters().add(sfData);
     
    960963
    961964      // Load all matching items and save their id:s
    962       Set<Integer> matching = new HashSet<Integer>(query.idList(dc));
     965      SortedSet<Integer> matching = new TreeSet<Integer>(query.idList(dc));
    963966      sf.setMatching(matching.size());
     967      sf.setMd5(SyncFilter.toMd5(matching));
    964968     
    965969      // For now, ignore parent/child transforms
  • trunk/src/core/net/sf/basedb/core/SyncFilter.java

    r6770 r6772  
    2222package net.sf.basedb.core;
    2323
     24import java.security.MessageDigest;
    2425import java.util.ArrayList;
    2526import java.util.Collection;
    2627import java.util.List;
    2728import java.util.Map;
     29import java.util.SortedSet;
     30import java.util.TreeSet;
    2831
    2932import net.sf.basedb.core.data.ItemListSyncFilterData;
     
    3235import net.sf.basedb.core.query.Hql;
    3336import net.sf.basedb.core.query.Restrictions;
     37import net.sf.basedb.util.MD5;
    3438import net.sf.basedb.util.listable.ListableUtil;
    3539
     
    97101  private List<PropertyFilter> filters;
    98102  private int numFilterRows;
     103  private SortedSet<Integer> matching;
    99104 
    100105 
     
    234239    synchronization. See {@link ItemList#getSyncDate()}.
    235240  */
    236   public int getMatchingItems()
     241  public int getLastSyncMatching()
    237242  {
    238243    return getData().getMatching();
     244  }
     245 
     246  /**
     247    Get the number of items that is currently matching this filter.
     248    The method will cause a query to be executed against the database,
     249    but the result is cached and re-used if called multiple times.
     250  */
     251  public int getCurrentMatching(DbControl dc)
     252  {
     253    return getMatching(dc).size();
     254  }
     255
     256  /**
     257    Checks if the items that are currently matching this filter are
     258    the same as the items that matched it during the last sync. The
     259    check is done by comparing the MD5 sum of the concatenated
     260    ID values.
     261  */
     262  public boolean isInSync(DbControl dc)
     263  {
     264    SortedSet<Integer> tmp = getMatching(dc);
     265    if (tmp.size() != getLastSyncMatching()) return false;
     266    String md5 = toMd5(tmp);
     267    return md5.equals(getData().getMd5());
    239268  }
    240269 
     
    290319  }
    291320 
     321  private SortedSet<Integer> getMatching(DbControl dc)
     322  {
     323    if (matching == null)
     324    {
     325      Item sourceItemType = getSourceItemType();
     326      ItemQuery<? extends BasicItem> query = sourceItemType.getQuery();
     327      ItemContext syncContext = new ItemContext(getSourceItemType(), getData());
     328      syncContext.configureQuery(dc, query, true);
     329      matching = new TreeSet<Integer>(query.idList(dc));
     330    }
     331    return matching;
     332  }
     333 
     334  /**
     335    Calculate the MD5 sum of all all ID values in the collection.
     336    Each ID is converted to a 4-byte array and added to the
     337    MD5 by {@link MessageDigest#update(byte[])}
     338    The list is assumed to be sorted in ID order so that
     339    if two collections contain the same ID values, they
     340    should produce the same MD5.
     341  */
     342  static String toMd5(SortedSet<Integer> listOfIds)
     343  {
     344    MessageDigest md5 = MD5.newInstance();
     345    byte[] bytes = new byte[4];
     346    for (int id : listOfIds)
     347    {
     348      bytes[0] = (byte)(id >> 24);
     349      bytes[1] = (byte)(id >> 16);
     350      bytes[2] = (byte)(id >> 8);
     351      bytes[3] = (byte)(id >> 0);
     352      md5.update(bytes);
     353    }
     354   
     355    return MD5.getHashString(md5);
     356  }
     357 
    292358  public enum SourceItemTransform
    293359  {
  • trunk/src/core/net/sf/basedb/core/data/ItemListSyncFilterData.java

    r6770 r6772  
    126126  }
    127127
     128  private String md5;
     129  /**
     130    Get the MD5 hash of the concatenated ID values. It is always returned as a string
     131    with 32 hexadecimal characters.
     132    @hibernate.property column="`md5`" type="string" length="32" not-null="false"
     133  */
     134  public String getMd5()
     135  {
     136    return md5;
     137  }
     138  public void setMd5(String md5)
     139  {
     140    this.md5 = md5;
     141  }
     142 
    128143  private int include;
    129144  /**
  • trunk/www/views/itemlists/view_list.jsp

    r6771 r6772  
    316316            title="Name"
    317317          />
     318          <tbl:columndef
     319            id="inSync"
     320            title="In sync"
     321          />
    318322          <tbl:columndef
    319323            id="sourceItems"
     
    326330          <tbl:columndef
    327331            id="matching"
    328             title="Matching items"
     332            title="Items matching"
    329333          />
    330334          <tbl:columndef
     
    388392                sb.append(Values.getString(sf.getPropertyFilters(filterRow), "\n   AND ", true, filterFormatter));
    389393              }
     394              boolean inSync = sf.isInSync(dc);
     395              int lastSyncMatching = sf.getLastSyncMatching();
    390396              %>
    391397              <tbl:row>
     
    426432                </tbl:cell>
    427433                <tbl:cell column="filter"><pre><%=HTML.encodeTags(sb.toString())%></pre></tbl:cell>
    428                 <tbl:cell column="matching"><%=sf.getMatchingItems()%></tbl:cell>
     434                <tbl:cell column="inSync">
     435                  <base:icon
     436                    image="<%=inSync ? "ok.png" : "notify.png" %>" style="padding-right: 4px;"
     437                  /><%=inSync ? (transform == SourceItemTransform.NONE ? "Yes" : "Yes¹") : "No"%>
     438                </tbl:cell>
     439                <tbl:cell column="matching">
     440                  <%=lastSyncMatching == -1 ? "?" : lastSyncMatching%>
     441                  <%
     442                  if (!inSync)
     443                  {
     444                    %>
     445                    › <%=sf.getCurrentMatching(dc)%>
     446                    <%
     447                  }
     448                  %>
     449                </tbl:cell>
    429450                <tbl:cell column="description"><%=HTML.niceFormat(sf.getDescription())%></tbl:cell>
    430451              </tbl:row>
     
    443464          </tbl:data>
    444465        </tbl:table>
    445      
     466        <%
     467        if (syncFilters.size() > 0)
     468        {
     469          %>
     470          ¹ Changes in parent/child relationship are not checked!
     471          <%
     472        }
     473        %>
    446474      </base:section>
    447475
Note: See TracChangeset for help on using the changeset viewer.