1 8 9 15 package jfun.yan; 16 17 import jfun.yan.factory.Pool; 18 19 29 final class StagedComponent<T> extends Component<T> { 30 private final Component<T> c1; 31 private final ComponentBinder<T,?> next; 32 public boolean isConcrete(){ 33 return c1.isConcrete(); 34 } 35 StagedComponent(final Component<T> cc, final ComponentBinder<T,?> next){ 36 this.c1 =cc; 37 this.next = next; 38 } 39 private Creator<?> bindNext(T obj){ 40 try{ 41 return next.bind(obj); 42 } 43 catch(Error e){ 44 throw e; 45 } 46 catch(YanException e){ 47 throw e; 48 } 49 catch(Throwable e){ 50 throw new ComponentInstantiationException(e); 51 } 52 } 53 public Class <T> getType(){return c1.getType();} 54 public T create(Dependency dep){ 55 final T obj = c1.create(dep); 56 bindNext(obj).create(dep); 57 return obj; 58 } 59 public Class verify(Dependency dep){ 60 final Class r = c1.verify(dep); 61 next.verify(r).verify(dep); 62 return r; 63 } 64 public final Component<T> singleton(){ 65 return new DelegatingComponent(c1){ 67 private transient T v = null; 68 private transient Class type = null; 69 private transient boolean cached = false; 70 public synchronized Class getType(){ 71 if(v!=null) 72 return v.getClass(); 73 else if(type!=null) 74 return type; 75 else 76 return super.getType(); 77 } 78 public synchronized boolean isConcrete(){ 79 return cached; 80 } 81 public synchronized Object create(Dependency dep) { 82 if(cached) return this.v; 83 this.v = (T)super.create(dep); 84 cached = true; 85 boolean ok = false; 86 try{ 87 bindNext(v).create(dep); 88 ok = true; 89 } 90 finally{ 91 if(!ok){ 92 this.v = null; 93 this.cached = false; 94 } 95 else if(this.v!=null){ 96 this.type = this.v.getClass(); 97 } 98 } 99 return this.v; 100 } 101 public synchronized Class verify(Dependency dep) { 102 if(type != null) return type; 103 this.type = super.verify(dep); 104 next.verify(this.type).verify(dep); 105 return type; 106 } 107 public Component singleton(){return this;} 108 public Component guard(){return this;} 109 public boolean isSingleton(){ 110 return true; 111 } 112 public String toString(){ 113 return "singleton " + super.toString(); 114 } 115 }; 116 } 117 private static class StagedSingletonComponent 118 extends DelegatingComponent implements Mutation{ 119 private final ComponentBinder next; 120 private transient Object v = null; 121 private transient Class type = null; 122 private transient boolean cached = false; 123 private final Component staged; 124 StagedSingletonComponent(Component c1, ComponentBinder next, Pool pool){ 125 super(c1); 126 this.staged = new PooledComponent( 127 new StagedComponent(c1.mutate(this), next), pool); 128 this.next = next; 129 } 130 public synchronized Class getType(){ 131 if(type!=null) 132 return type; 133 return super.getType(); 134 } 135 public void mutate(Object obj){ 136 this.v = obj; 137 this.cached = true; 138 } 139 public synchronized Object create(final Dependency dep) { 140 if(cached) return v; 141 try{ 142 return staged.create(dep); 143 } 144 finally{ 145 if(this.v!=null){ 146 this.type = this.v.getClass(); 147 } 148 this.v = null; 149 this.cached = false; 150 } 151 } 152 public synchronized Class verify(Dependency dep) { 153 if(type != null) return type; 154 this.type = super.verify(dep); 155 next.verify(this.type).verify(dep); 156 return type; 157 } 158 159 public Component guard(){return this;} 160 public String toString(){ 161 return getDelegateTarget().toString(); 162 } 163 } 164 public final Component<T> singleton(final Pool scope){ 165 return new StagedSingletonComponent(c1, next, scope); 167 } 168 public final Component<T> guard(){ 169 return new GuardedComponent<T>(this){ 170 public Component singleton(){ 171 return getDelegateTarget().singleton(); 174 } 175 public Component singleton(Pool scope){ 176 return getDelegateTarget().singleton(scope); 177 } 178 }; 179 } 180 public String toString(){ 181 return c1.toString(); 182 } 183 184 public boolean equals(Object obj) { 185 if(obj instanceof StagedComponent){ 186 final StagedComponent other = (StagedComponent)obj; 187 return c1.equals(other.c1) && next.equals(other.next); 188 } 189 else return false; 190 } 191 public int hashCode() { 192 return c1.hashCode()*31+next.hashCode(); 193 } 194 public boolean isSingleton(){ 195 return false; 196 } 197 } 198 | Popular Tags |