001package io.ebean.bean; 002 003import java.lang.ref.WeakReference; 004import java.util.LinkedHashSet; 005import java.util.Set; 006 007/** 008 * Collects profile information for a bean (or reference/proxy bean) at a given node. 009 * <p> 010 * The node identifies the location of the bean in the object graph. 011 * </p> 012 * <p> 013 * It has to use a weak reference so as to ensure that it does not stop the 014 * associated bean from being garbage collected. 015 * </p> 016 */ 017public final class NodeUsageCollector { 018 019 /** 020 * The point in the object graph for a specific query and call stack point. 021 */ 022 private final ObjectGraphNode node; 023 024 /** 025 * Weak to allow garbage collection. 026 */ 027 private final WeakReference<NodeUsageListener> managerRef; 028 029 /** 030 * The properties used at this profile point. 031 */ 032 private final Set<String> used = new LinkedHashSet<>(); 033 034 /** 035 * set to true if the bean is modified (setter called) 036 */ 037 private boolean modified; 038 039 /** 040 * The property that cause a reference to lazy load. 041 */ 042 private String loadProperty; 043 044 public NodeUsageCollector(ObjectGraphNode node, WeakReference<NodeUsageListener> managerRef) { 045 this.node = node; 046 // weak to allow garbage collection. 047 this.managerRef = managerRef; 048 } 049 050 /** 051 * The bean has been modified by a setter method. 052 */ 053 public void setModified() { 054 modified = true; 055 } 056 057 /** 058 * Add the name of a property that has been used. 059 */ 060 public void addUsed(String property) { 061 used.add(property); 062 } 063 064 /** 065 * The property that invoked a lazy load. 066 */ 067 public void setLoadProperty(String loadProperty) { 068 this.loadProperty = loadProperty; 069 } 070 071 /** 072 * Publish the usage info to the manager. 073 */ 074 private void publishUsageInfo() { 075 NodeUsageListener manager = managerRef.get(); 076 if (manager != null) { 077 manager.collectNodeUsage(this); 078 } 079 } 080 081 /** 082 * publish the collected usage information when garbage collection occurs. 083 */ 084 @Override 085 protected void finalize() throws Throwable { 086 publishUsageInfo(); 087 super.finalize(); 088 } 089 090 /** 091 * Return the associated node which identifies the location in the object 092 * graph of the bean/reference. 093 */ 094 public ObjectGraphNode getNode() { 095 return node; 096 } 097 098 /** 099 * Return true if no properties where used. 100 */ 101 public boolean isEmpty() { 102 return used.isEmpty(); 103 } 104 105 /** 106 * Return the set of used properties. 107 */ 108 public Set<String> getUsed() { 109 return used; 110 } 111 112 /** 113 * Return true if the bean was modified by a setter. 114 */ 115 public boolean isModified() { 116 return modified; 117 } 118 119 public String getLoadProperty() { 120 return loadProperty; 121 } 122 123 @Override 124 public String toString() { 125 return node + " read:" + used + " modified:" + modified; 126 } 127}