EMMA Coverage Report (generated Thu Jan 20 11:39:44 EST 2011)
[all classes][com.hammurapi.common.concurrent]

COVERAGE SUMMARY FOR SOURCE FILE [AbstractPropertySet.java]

nameclass, %method, %block, %line, %
AbstractPropertySet.java75%  (3/4)55%  (38/69)63%  (1035/1654)62%  (201.2/326)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractPropertySet$1$10%   (0/1)0%   (0/2)0%   (0/20)0%   (0/3)
AbstractPropertySet$1$1 (AbstractPropertySet$1, PropertySet, Object): void 0%   (0/1)0%   (0/8)0%   (0/2)
buildPath (Object, Object): Object 0%   (0/1)0%   (0/12)0%   (0/1)
     
class AbstractPropertySet$1100% (1/1)11%  (3/28)22%  (54/249)20%  (10.3/52)
access$0 (AbstractPropertySet$1): AbstractPropertySet 0%   (0/1)0%   (0/3)0%   (0/1)
cancel (Object): void 0%   (0/1)0%   (0/4)0%   (0/1)
cancelAll (): void 0%   (0/1)0%   (0/4)0%   (0/1)
clear (): void 0%   (0/1)0%   (0/4)0%   (0/1)
cook (Object, Callable): void 0%   (0/1)0%   (0/4)0%   (0/1)
cook (Object, Callable, long, TimeUnit): void 0%   (0/1)0%   (0/4)0%   (0/1)
cooking (Object, Future): void 0%   (0/1)0%   (0/4)0%   (0/1)
get (Object, Class): Object 0%   (0/1)0%   (0/31)0%   (0/6)
get (Object, Class, Object): Object 0%   (0/1)0%   (0/31)0%   (0/6)
get (Object, Object): Object 0%   (0/1)0%   (0/30)0%   (0/6)
getAdapter (Class, Context): Object 0%   (0/1)0%   (0/4)0%   (0/1)
invoke (Object, Object []): Object 0%   (0/1)0%   (0/4)0%   (0/1)
lazy (Object, Callable): void 0%   (0/1)0%   (0/4)0%   (0/1)
mount (Object, PropertySet): void 0%   (0/1)0%   (0/4)0%   (0/1)
remove (Object): void 0%   (0/1)0%   (0/4)0%   (0/1)
set (Object, Object): void 0%   (0/1)0%   (0/4)0%   (0/1)
setAll (PropertySet): void 0%   (0/1)0%   (0/4)0%   (0/1)
setInvocable (Object, Invocable): void 0%   (0/1)0%   (0/4)0%   (0/1)
shadowGet (Object): Object 0%   (0/1)0%   (0/4)0%   (0/1)
shadowGet (Object, Class): Object 0%   (0/1)0%   (0/4)0%   (0/1)
shadowGet (Object, Class, Object): Object 0%   (0/1)0%   (0/4)0%   (0/1)
shadowGet (Object, Object): Object 0%   (0/1)0%   (0/4)0%   (0/1)
shadowInvoke (Object, Object []): Object 0%   (0/1)0%   (0/4)0%   (0/1)
subset (Object): PropertySet 0%   (0/1)0%   (0/7)0%   (0/1)
unmount (Object): void 0%   (0/1)0%   (0/4)0%   (0/1)
keySet (): Set 100% (1/1)61%  (19/31)54%  (2.7/5)
get (Object): Object 100% (1/1)97%  (29/30)99%  (6/6)
AbstractPropertySet$1 (AbstractPropertySet): void 100% (1/1)100% (6/6)100% (2/2)
     
class AbstractPropertySet100% (1/1)89%  (32/36)70%  (927/1331)68%  (177.3/259)
shadowGet (Object, Class): Object 0%   (0/1)0%   (0/6)0%   (0/1)
shadowGet (Object, Class, Object): Object 0%   (0/1)0%   (0/7)0%   (0/1)
shadowGet (Object, Object): Object 0%   (0/1)0%   (0/6)0%   (0/1)
shadowInvoke (Object, Object []): Object 0%   (0/1)0%   (0/7)0%   (0/1)
mount (Object [], int, PropertySet): void 100% (1/1)34%  (16/47)38%  (3/8)
cancel (Object [], int): void 100% (1/1)38%  (21/55)45%  (5/11)
cook (Object [], int, Callable, long, TimeUnit): void 100% (1/1)48%  (49/103)50%  (8/16)
unmount (Object [], int): void 100% (1/1)48%  (15/31)50%  (3/6)
get (Object, Class, Object): Object 100% (1/1)51%  (31/61)69%  (9/13)
subset (Object [], int, boolean): PropertySet 100% (1/1)62%  (44/71)64%  (9/14)
invoke (PropertySet, Object, Object []): Object 100% (1/1)64%  (89/138)75%  (15.8/21)
cancel (Object): void 100% (1/1)70%  (14/20)57%  (3.4/6)
remove (Object): void 100% (1/1)70%  (14/20)57%  (3.4/6)
unmount (Object): void 100% (1/1)70%  (14/20)57%  (3.4/6)
cancelAll (): void 100% (1/1)71%  (44/62)56%  (6.7/12)
mount (Object, PropertySet): void 100% (1/1)71%  (15/21)57%  (3.4/6)
set (Object, Object): void 100% (1/1)71%  (15/21)57%  (3.4/6)
subset (Object): PropertySet 100% (1/1)73%  (16/22)54%  (2.7/5)
clear (): void 100% (1/1)74%  (51/69)59%  (7.7/13)
cook (Object, Callable, long, TimeUnit): void 100% (1/1)74%  (17/23)57%  (3.4/6)
keySet (): Set 100% (1/1)74%  (93/125)69%  (11.1/16)
setAll (PropertySet): void 100% (1/1)81%  (26/32)63%  (4.4/7)
remove (Object [], int): void 100% (1/1)82%  (41/50)89%  (8/9)
get (Object): Object 100% (1/1)83%  (30/36)73%  (6.5/9)
get (Object [], int, Object []): Object 100% (1/1)95%  (118/124)93%  (25/27)
AbstractPropertySet (ExecutorService, Converter, Context, PropertySet []): void 100% (1/1)100% (25/25)100% (7/7)
buildPath (Object []): Object 100% (1/1)100% (5/5)100% (1/1)
cook (Object, Callable): void 100% (1/1)100% (7/7)100% (2/2)
cooking (Object, Future): void 100% (1/1)100% (9/9)100% (2/2)
get (Object, Class): Object 100% (1/1)100% (6/6)100% (1/1)
get (Object, Object): Object 100% (1/1)100% (10/10)100% (2/2)
invoke (Object, Object []): Object 100% (1/1)100% (6/6)100% (1/1)
lazy (Object, Callable): void 100% (1/1)100% (9/9)100% (2/2)
set (Object [], int, Object): void 100% (1/1)100% (67/67)100% (11/11)
setInvocable (Object, Invocable): void 100% (1/1)100% (5/5)100% (2/2)
shadowGet (Object): Object 100% (1/1)100% (5/5)100% (1/1)
     
class AbstractPropertySet$CookEntry100% (1/1)100% (3/3)100% (54/54)100% (15/15)
AbstractPropertySet$CookEntry (Future, Callable): void 100% (1/1)100% (9/9)100% (4/4)
cancel (): void 100% (1/1)100% (19/19)100% (4/4)
get (): Object 100% (1/1)100% (26/26)100% (7/7)

1package com.hammurapi.common.concurrent;
2 
3import java.util.Arrays;
4import java.util.HashSet;
5import java.util.Map;
6import java.util.Set;
7import java.util.concurrent.Callable;
8import java.util.concurrent.ExecutorService;
9import java.util.concurrent.Future;
10import java.util.concurrent.ScheduledExecutorService;
11import java.util.concurrent.TimeUnit;
12import java.util.concurrent.locks.ReadWriteLock;
13 
14import com.hammurapi.common.Context;
15import com.hammurapi.convert.Converter;
16import com.hammurapi.convert.ConvertingService;
17 
18/**
19 * 
20 * @author Pavel Vlasov
21 *
22 * @param <KP> Key path
23 * @param <KE> Key path element
24 */
25public abstract class AbstractPropertySet<KP,KE> implements PropertySet<KP>, ReadWriteLock {
26        
27        protected Converter converter;
28        protected ExecutorService executorService;
29        protected PropertySet<KP>[] shadows;
30//        protected ClassLoader classLoader;
31        protected Context context;
32        
33        private PropertySet<KP> shadowPropertySet = new PropertySet<KP>() {
34 
35                @Override
36                public <T> T getAdapter(Class<T> type, Context context) {
37                        throw new UnsupportedOperationException(); // Maybe implement.
38                }
39 
40                @Override
41                public Set<KP> keySet() {
42                        HashSet<KP> ret = new HashSet<KP>();
43                        
44                        for (PropertySet<KP> ch: shadows) {
45                                if (ch!=null) {
46                                        ret.addAll(ch.keySet());
47                                }
48                        }
49                        return ret;
50                }
51 
52                @Override
53                public PropertySet<KP> subset(KP prefix) {
54                        return new AbstractSubSet<KP>(this, prefix) {
55 
56                                @Override
57                                protected KP buildPath(KP prefix, KP key) {
58                                        return AbstractPropertySet.this.buildPath(prefix, key);
59                                }
60                                
61                        };
62                }
63 
64                @Override
65                public void remove(KP key) {
66                        throw new UnsupportedOperationException();
67                }
68 
69                @Override
70                public void clear() {
71                        throw new UnsupportedOperationException();
72                }
73 
74                @Override
75                public void mount(KP prefix, PropertySet<KP> source) {
76                        throw new UnsupportedOperationException();
77                }
78 
79                @Override
80                public void unmount(KP prefix) {
81                        throw new UnsupportedOperationException();
82                }
83 
84                @Override
85                public void setAll(PropertySet<KP> source) {
86                        throw new UnsupportedOperationException();
87                }
88 
89                @Override
90                public Object get(KP key) {
91                        for (PropertySet<KP> ch: shadows) {
92                                if (ch!=null) {
93                                        Object ret = ch.get(key);
94                                        if (ret!=null) {
95                                                return ret;
96                                        }
97                                }
98                        }
99                        return null;
100                }
101 
102                @Override
103                public Object get(KP key, Object defaultValue) {
104                        for (PropertySet<KP> ch: shadows) {
105                                if (ch!=null) {
106                                        Object ret = ch.get(key);
107                                        if (ret!=null) {
108                                                return ret;
109                                        }
110                                }
111                        }
112                        return defaultValue;
113                }
114 
115                @Override
116                public <T> T get(KP key, Class<T> type) {
117                        for (PropertySet<KP> ch: shadows) {
118                                if (ch!=null) {
119                                        T ret = ch.get(key, type);
120                                        if (ret!=null) {
121                                                return ret;
122                                        }
123                                }
124                        }
125                        return null;
126                }
127 
128                @Override
129                public <T> T get(KP key, Class<T> type, T defaultValue) {
130                        for (PropertySet<KP> ch: shadows) {
131                                if (ch!=null) {
132                                        T ret = ch.get(key, type);
133                                        if (ret!=null) {
134                                                return ret;
135                                        }
136                                }
137                        }
138                        return defaultValue;
139                }
140 
141                @Override
142                public void set(KP key, Object value) {
143                        throw new UnsupportedOperationException();
144                        
145                }
146 
147                @Override
148                public void setInvocable(KP key, Invocable<PropertySet<KP>, ?, KP> invocable) {
149                        throw new UnsupportedOperationException();
150                }
151 
152                @Override
153                public void cook(KP key, Callable<?> callable) {
154                        throw new UnsupportedOperationException();
155                }
156 
157                @Override
158                public void cook(KP key, Callable<?> callable, long delay, TimeUnit timeUnit) {
159                        throw new UnsupportedOperationException();
160                }
161 
162                @Override
163                public void cooking(KP key, Future<?> future) {
164                        throw new UnsupportedOperationException();
165                }
166 
167                @Override
168                public void lazy(KP key, Callable<?> callable) {
169                        throw new UnsupportedOperationException();
170                }
171 
172                @Override
173                public void cancel(KP key) {
174                        throw new UnsupportedOperationException();
175                }
176 
177                @Override
178                public void cancelAll() {
179                        throw new UnsupportedOperationException();
180                }
181 
182                @Override
183                public Object invoke(KP key, Object... args) {
184                        throw new UnsupportedOperationException();
185                }
186 
187                @Override
188                public Object shadowInvoke(KP key, Object... args) {
189                        throw new UnsupportedOperationException();
190                }
191 
192                @Override
193                public Object shadowGet(KP key) {
194                        throw new UnsupportedOperationException();
195                }
196 
197                @Override
198                public Object shadowGet(KP key, Object defaultValue) {
199                        throw new UnsupportedOperationException();
200                }
201 
202                @Override
203                public <T> T shadowGet(KP key, Class<T> type) {
204                        throw new UnsupportedOperationException();
205                }
206 
207                @Override
208                public <T> T shadowGet(KP key, Class<T> type, T defaultValue) {
209                        throw new UnsupportedOperationException();
210                }
211                
212        };
213        
214        /**
215         * @return Store for values.
216         */
217        protected abstract Map<KE, Object> getValueStore();
218        
219        /**
220         * 
221         * @return
222         */
223        protected abstract Map<KE, AbstractPropertySet<KP,KE>> getSubSetStore();
224        
225        /**
226         * Creates a property set which shares lock and chain with this one.
227         * @return
228         */
229        protected abstract AbstractPropertySet<KP,KE> newInstance(KE key);
230        
231        protected abstract Map<KE, PropertySet<KP>> getMounts();
232        
233        protected AbstractPropertySet(
234                        ExecutorService executorService, 
235                        Converter converter,
236//                        ClassLoader classLoader,
237                        Context context,
238                        PropertySet<KP>... shadows) {
239                this.executorService = executorService;
240                this.converter = converter==null ? ConvertingService.CONVERTER : converter;
241//                this.classLoader = classLoader==null ? getClass().getClassLoader() : classLoader;
242                this.context = context;
243                this.shadows = shadows;                
244        }
245        
246        protected abstract KP buildPath(int startIdx, Object... elements);
247 
248        protected KP buildPath(Object... elements) {
249                return buildPath(0, elements);
250        }
251        
252        protected abstract KP buildPath(KP prefix, Object... elements);
253        
254        protected abstract KP buildPath(KE prefix, KP suffix);
255        
256        protected abstract KE[] tokenize(KP path);
257        
258        /**
259         * Versions object for forward-only change propagation purposes.
260         * @param <T>
261         * @param source
262         * @return
263         */
264        protected abstract <T> T version(T source);
265        
266        @Override
267        public Set<KP> keySet() {
268                readLock().lock();
269                HashSet<KP> ret = new HashSet<KP>();
270                try {
271                        for (KE key: getValueStore().keySet()) {
272                                ret.add(buildPath(key));
273                        }
274                        
275                        for (Map.Entry<KE, PropertySet<KP>> entry: getMounts().entrySet()) {
276                                for (KP path: entry.getValue().keySet()) {
277                                        ret.add(buildPath(entry.getKey(), path));
278                                }
279                        }
280                        
281                        for (Map.Entry<KE, AbstractPropertySet<KP, KE>> entry: getSubSetStore().entrySet()) {
282                                if (!getMounts().containsKey(entry.getKey())) { // If not shadowed
283                                        for (KP path: entry.getValue().keySet()) {
284                                                ret.add(buildPath(entry.getKey(), path));
285                                        }
286                                }
287                        }                        
288                } finally {
289                        readLock().unlock();
290                }
291                
292                ret.addAll(shadowPropertySet.keySet());
293                return ret;
294        }
295 
296        @Override
297        public PropertySet<KP> subset(KP prefix) {
298                writeLock().lock();
299                try {
300                        return subset(tokenize(prefix),0,true);
301                } finally {
302                        writeLock().unlock();
303                }
304        }
305 
306        protected PropertySet<KP> subset(KE[] prefix, int idx, boolean create) {
307                PropertySet<KP> mount = getMounts().get(prefix[idx]);
308                if (mount!=null) {
309                        if (prefix.length==idx+1) {
310                                return mount;
311                        }
312                        
313                        return mount.subset(buildPath(idx+1, prefix));
314                }
315                
316                AbstractPropertySet<KP, KE> ret = getSubSetStore().get(prefix[idx]);
317                if (ret==null) {
318                        if (!create) {
319                                return null;
320                        }
321                        ret = newInstance(prefix[idx]);
322                        getSubSetStore().put(prefix[idx], ret);
323                }
324                
325                if (prefix.length==idx+1) {
326                        return ret;
327                }
328                
329                return ret.subset(prefix, idx+1, create);
330        }
331        
332        @Override
333        public void remove(KP key) {
334                writeLock().lock();
335                try {
336                        remove(tokenize(key), 0);
337                } finally {
338                        writeLock().unlock();
339                }
340        }
341 
342        protected void remove(KE[] path, int idx) {
343                if (path.length==idx+1) {
344                        getValueStore().remove(path[idx]);
345                } else {                        
346                        PropertySet<KP> mount = getMounts().get(path[idx]);
347                        if (mount!=null) {
348                                mount.remove(buildPath(idx+1, path));
349                        } else {                        
350                                AbstractPropertySet<KP, KE> ss = getSubSetStore().get(path[idx]);
351                                if (ss!=null) {
352                                        ss.remove(path, idx+1);
353                                }
354                        }
355                }
356        }
357        
358        @Override
359        public void clear() {
360                writeLock().lock();
361                try {
362                        getValueStore().clear();
363                        for (PropertySet<KP> m: getMounts().values()) {
364                                m.clear();
365                        }
366                        for (Map.Entry<KE, AbstractPropertySet<KP, KE>> e: getSubSetStore().entrySet()) {
367                                if (!getMounts().containsKey(e.getKey())) {
368                                        e.getValue().clear();
369                                }
370                        }
371                        for (int i=0; i<shadows.length; ++i) {
372                                shadows[i]=null;
373                        }
374                } finally {
375                        writeLock().unlock();
376                }
377        }
378 
379        @Override
380        public void mount(KP prefix, PropertySet<KP> source) {
381                writeLock().lock();
382                try {
383                        mount(tokenize(prefix), 0, source);
384                } finally {
385                        writeLock().unlock();
386                }
387        }
388 
389        protected void mount(KE[] path, int idx, PropertySet<KP> source) {
390                if (path.length==idx+1) {
391                        getMounts().put(path[idx], source);
392                } else {                        
393                        AbstractPropertySet<KP, KE> ss = getSubSetStore().get(path[idx]);
394                        if (ss==null) {
395                                ss = newInstance(path[idx]);
396                                getSubSetStore().put(path[idx], ss);
397                        }
398                        
399                        ss.mount(path, idx+1, source);
400                }
401        }
402        
403        @Override
404        public void unmount(KP prefix) {
405                writeLock().lock();
406                try {
407                        unmount(tokenize(prefix), 0);
408                } finally {
409                        writeLock().unlock();
410                }
411        }
412        
413        protected void unmount(KE[] path, int idx) {
414                if (path.length==idx+1) {
415                        getMounts().remove(path[idx]);
416                } else {                        
417                        AbstractPropertySet<KP, KE> ss = getSubSetStore().get(path[idx]);
418                        if (ss!=null) {
419                                ss.unmount(path, idx+1);
420                        }
421                }
422        }
423        
424        @Override
425        public void setAll(PropertySet<KP> source) {
426                writeLock().lock();
427                try {
428                        for (KP path: source.keySet()) {
429                                set(path, source.get(path));
430                        }
431                } finally {
432                        writeLock().unlock();
433                }
434        }
435 
436        @Override
437        public Object get(KP key) {
438                Object ret;
439                Object[] va = {null};
440                readLock().lock();
441                try {
442                        ret = get(tokenize(key), 0, va);
443                } finally {
444                        readLock().unlock();
445                }
446                
447                // Chained version
448                if (va[0]!=null) {
449                        set(key, va[0]);
450                }
451                
452                return ret;
453        }
454        
455        private static class CookEntry {
456                
457                CookEntry(Future<?> future, Callable<?> callable) {
458                        this.future = future;
459                        this.callable = callable;
460                }
461                
462                Future<?> future;
463                Callable<?> callable;
464                Object value;
465                
466                synchronized Object get() throws Exception {
467                        if (future!=null) {
468                                value = future.get();        
469                                future = null;
470                        } else if (callable!=null) {
471                                value = callable.call();
472                                callable = null;
473                        }
474                        return value;
475                }
476                
477                void cancel() {
478                        if (future!=null && callable!=null && !future.isDone()) {
479                                future.cancel(false);
480                                future = null;                                
481                        }
482                }
483                
484        }
485 
486        protected Object get(KE[] path, int idx, Object[] va) {
487                if (path.length==idx+1) {
488                        if (getValueStore().containsKey(path[idx])) {
489                                Object ret = getValueStore().get(path[idx]);
490                                
491                                if (ret instanceof Invocable) {
492                                        Invocable<PropertySet<KP>,?, KP> i = (Invocable<PropertySet<KP>,?, KP>) ret;
493                                        if (i.getParameterTypes()==null || i.getParameterTypes().length==0) {
494                                                InvocationImpl<KP> invocation = new InvocationImpl<KP>();
495                                                invocation.setPropertySet(this);
496                                                return i.invoke(this, invocation, executorService);
497                                        }
498                                        return i;
499                                }
500                                
501                                if (ret instanceof CookEntry) {
502                                        try {
503                                                ret = ((CookEntry) ret).get();
504                                                va[0] = ret; // To replace cook entry with value
505                                                return ret;
506                                        } catch (Exception e) {
507                                                throw new PropertySetException(e);
508                                        }
509                                }
510                                                        
511                                return ret;
512                        }
513                } else {                
514                        PropertySet<KP> mount = getMounts().get(path[idx]);
515                        if (mount!=null) {
516                                return mount.get(buildPath(idx+1, path));
517                        }
518                        
519                        AbstractPropertySet<KP, KE> ss = getSubSetStore().get(path[idx]);
520                        if (ss!=null) {
521                                Object ret = ss.get(path, idx+1, va);
522                                if (ret!=null) {
523                                        return ret;
524                                }
525                        }
526                }
527                
528                va[0] = shadowGet(buildPath(idx, path));
529                return va[0];
530        }
531        
532        @Override
533        public Object get(KP key, Object defaultValue) {
534                Object ret = get(key);
535                return ret == null ? defaultValue : ret;
536        }
537 
538        @Override
539        public <T> T get(KP key, Class<T> type) {
540                return get(key, type, null);
541        }
542 
543        @Override
544        public <T> T get(KP key, Class<T> type, T defaultValue) {
545                Object ret = get(key);
546                if (ret==null) {
547                        if (type!=null && type.isInterface()) {
548                                PropertySet<KP> toWrap = subset(tokenize(key), 0, false);
549                                if (toWrap!=null) {
550                                        return toWrap.getAdapter(type, null);
551                                }
552                        }
553                        return defaultValue;
554                }
555                if (type.isInstance(ret)) {
556                        return (T) ret;
557                }
558                T converted = converter.convert(ret, type, context);
559                if (converted==null) {
560                        throw new PropertySetException("Cannot convert "+ ret +" to "+type);
561                }
562                return converted;
563        }
564 
565        @Override
566        public void set(KP key, Object value) {
567                writeLock().lock();
568                try {
569                        set(tokenize(key), 0, value);
570                } finally {
571                        writeLock().unlock();
572                }
573        }
574 
575        protected void set(KE[] path, int idx, Object value) {
576                if (path.length==idx+1) {
577                        getValueStore().put(path[idx], value);
578                } else {
579                        PropertySet<KP> mount = getMounts().get(path[idx]);
580                        if (mount!=null) {
581                                mount.set(buildPath(idx+1, path), value);
582                        } else {                                
583                                AbstractPropertySet<KP, KE> ret = getSubSetStore().get(path[idx]);
584                                if (ret==null) {
585                                        ret = newInstance(path[idx]);
586                                        getSubSetStore().put(path[idx], ret);
587                                }
588                                
589                                ret.set(path, idx+1, value);
590                        }
591                }
592        }
593        
594        @Override
595        public void setInvocable(KP key, Invocable<PropertySet<KP>, ?, KP> invocable) {
596                set(key, invocable);
597        }
598 
599        @Override
600        public void cook(KP key, Callable<?> callable) {
601                cook(key, callable, 0, null);
602        }
603 
604        protected void cook(KE[] path, int idx, Callable<?> callable, long delay, TimeUnit timeUnit) {
605                if (path.length==idx+1) {
606                        Future<?> future = null;
607                        if (delay>0 && timeUnit!=null && executorService instanceof ScheduledExecutorService) {
608                                future = ((ScheduledExecutorService) executorService).schedule(callable, delay, timeUnit);
609                        } else if (executorService!=null) {
610                                future = executorService.submit(callable);
611                        }
612                        getValueStore().put(path[idx], new CookEntry(future, callable));
613                } else {
614                        PropertySet<KP> mount = getMounts().get(path[idx]);
615                        if (mount!=null) {
616                                mount.cook(buildPath(idx+1, path), callable, delay, timeUnit);
617                        }
618                        
619                        AbstractPropertySet<KP, KE> ret = getSubSetStore().get(path[idx]);
620                        if (ret==null) {
621                                ret = newInstance(path[idx]);
622                                getSubSetStore().put(path[idx], ret);
623                        }
624                        
625                        ret.cook(path, idx+1, callable, delay, timeUnit);
626                }
627        }
628 
629        @Override
630        public void cook(KP key, Callable<?> callable, long delay, TimeUnit timeUnit) {
631                writeLock().lock();
632                try {
633                        cook(tokenize(key), 0, callable, delay, timeUnit);
634                } finally {
635                        writeLock().unlock();
636                }
637        }
638 
639        @Override
640        public void cooking(KP key, Future<?> future) {
641                set(key, new CookEntry(future, null));
642        }
643 
644        @Override
645        public void lazy(KP key, Callable<?> callable) {
646                set(key, new CookEntry(null, callable));
647        }
648 
649        @Override
650        public void cancel(KP key) {
651                readLock().lock();
652                try {
653                        cancel(tokenize(key),0);
654                } finally {
655                        readLock().unlock();
656                }
657        }
658 
659        protected void cancel(KE[] path, int idx) {
660                if (path.length==idx+1) {
661                        Object v = getValueStore().get(path[idx]);
662                        if (v instanceof CookEntry) {
663                                ((CookEntry) v).cancel();
664                        }
665                } else {
666                        PropertySet<KP> mount = getMounts().get(path[idx]);
667                        if (mount!=null) {
668                                mount.cancel(buildPath(idx+1, path));
669                        }
670                        
671                        AbstractPropertySet<KP, KE> ret = getSubSetStore().get(path[idx]);
672                        if (ret!=null) {
673                                ret.cancel(path, idx+1);
674                        }
675                }
676        }
677        
678        @Override
679        public void cancelAll() {
680                readLock().lock();
681                try {
682                        for (PropertySet<KP> mount: getMounts().values()) {
683                                mount.cancelAll();
684                        }
685                        for (PropertySet<KP> ss: getSubSetStore().values()) {
686                                ss.cancelAll();
687                        }
688                        for (Object v: getValueStore().values()) {
689                                if (v instanceof CookEntry) {
690                                        ((CookEntry) v).cancel();
691                                }                                
692                        }
693                } finally {
694                        readLock().unlock();
695                }
696        }
697 
698        @Override
699        public Object invoke(KP key, Object... args) {
700                return invoke(this, key, args);
701        }
702        
703        private Object invoke(PropertySet<KP> contextPropertySet, KP key, Object... args) {
704                writeLock().lock(); // To avoid deadlocks if invocable has side effects.
705                try {
706                        Object i = contextPropertySet.get(key);
707                        if (i instanceof Invocable) {
708                                Invocable invocable = (Invocable) i;
709                                Class[] parameterTypes = invocable.getParameterTypes();
710                                if (args!=null && parameterTypes!=null) {
711                                        if (parameterTypes.length!=args.length) {
712                                                throw new PropertySetException("Cannot invoke "+key+" - invalid number of arguments");
713                                        }
714                                        args = Arrays.copyOf(args, args.length);
715                                        for (int j=0; j<args.length; ++j) {
716                                                if (args[j]!=null && !parameterTypes[j].isInstance(args[j])) {
717                                                        Object newVal = converter.convert(args[j], parameterTypes[j], context);
718                                                        if (args[j]==null) {
719                                                                throw new PropertySetException("Cannot covert "+args[j]+" to "+parameterTypes[j]);
720                                                        }
721                                                        args[j] = newVal;
722                                                }
723                                        }
724                                }
725                                InvocationImpl invocation = new InvocationImpl(args, contextPropertySet, null);
726                                return invocable.invoke(contextPropertySet, invocation, executorService);
727                        }
728                        
729                        throw new PropertySetException("Not invocable: "+i);
730                } finally {
731                        writeLock().unlock();
732                }
733        }
734 
735        @Override
736        public Object shadowInvoke(KP key, Object... args) {
737                return invoke(shadowPropertySet, key, args);
738        }
739 
740        @Override
741        public Object shadowGet(KP key) {
742                return shadowPropertySet.get(key);
743        }
744 
745        @Override
746        public Object shadowGet(KP key, Object defaultValue) {
747                return shadowPropertySet.get(key, defaultValue);
748        }
749 
750        @Override
751        public <T> T shadowGet(KP key, Class<T> type) {
752                return shadowPropertySet.get(key, type);
753        }
754 
755        @Override
756        public <T> T shadowGet(KP key, Class<T> type, T defaultValue) {
757                return shadowPropertySet.get(key, type, defaultValue);
758        }
759        
760        
761}

[all classes][com.hammurapi.common.concurrent]
EMMA 2.0.5312 EclEmma Fix 2 (C) Vladimir Roubtsov