1 | package com.hammurapi.eventbus.local; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.Arrays; |
5 | import java.util.List; |
6 | |
7 | import com.hammurapi.eventbus.AbstractEventBus; |
8 | import com.hammurapi.eventbus.AbstractEventBus.Handle; |
9 | import com.hammurapi.eventbus.Derivation; |
10 | import com.hammurapi.eventbus.EventHandler; |
11 | import com.hammurapi.eventbus.EventStore; |
12 | import com.hammurapi.eventbus.InferenceContext; |
13 | import com.hammurapi.store.local.LocalHandle.HandleStrength; |
14 | |
15 | class DerivationImpl<E, P extends Comparable<P>, C, S extends EventStore<E, P, C, AbstractEventBus.Handle<E, P, C, Long>, S>> implements Derivation<E,P,C>, AbstractEventBus.DerivationEx<Long>, Comparable<DerivationImpl<E,P,C,S>> { |
16 | |
17 | final Long handlerId; |
18 | final EventHandler<E, P, C, ?, ?> handler; |
19 | final FacadeHandle<E,P,C,S>[] handles; |
20 | final long timestamp = System.currentTimeMillis(); |
21 | final List<E> events = new ArrayList<E>(); |
22 | |
23 | public DerivationImpl(Long handlerId, EventHandler<E, P, C, ?, ?> handler, AbstractEventBus.Handle<E,P,C,Long>[] inputs) { |
24 | this.handlerId = handlerId; |
25 | this.handler = handler; |
26 | this.handles = new FacadeHandle[inputs.length]; |
27 | for (int i=0; i<handles.length; ++i) { |
28 | if (inputs[i] instanceof FacadeHandle) { |
29 | handles[i] = (FacadeHandle<E, P, C, S>) inputs[i]; |
30 | } else { |
31 | handles[i]= new FacadeHandle<E,P,C,S>((MasterHandle<E, P, C, S>) inputs[i], HandleStrength.STRONG); |
32 | } |
33 | } |
34 | |
35 | for (int i=0; i<handles.length; ++i) { |
36 | handles[i].addDerivative(this); |
37 | this.events.add(inputs[i].getEvent()); |
38 | } |
39 | } |
40 | |
41 | @Override |
42 | public EventHandler<E, P, C, ?, ?> getHandler() { |
43 | return handler; |
44 | } |
45 | |
46 | @Override |
47 | public List<E> getInputs() { |
48 | return events; |
49 | } |
50 | |
51 | @Override |
52 | public boolean isDerivedFrom(E sourceEvent) { |
53 | for (Handle<E,P,C,Long> h: handles) { |
54 | if (h.isValid()) { |
55 | if (sourceEvent.equals(h.getEvent())) { |
56 | return true; |
57 | } |
58 | if (h.isDerivedFrom(sourceEvent)) { |
59 | return true; |
60 | } |
61 | } |
62 | } |
63 | return false; |
64 | } |
65 | |
66 | @Override |
67 | public long timestamp() { |
68 | return timestamp; |
69 | } |
70 | |
71 | @Override |
72 | public String toString() { |
73 | return "DerivationImpl [handlerId=" + handlerId + ", handler=" |
74 | + handler + ", handles=" + Arrays.toString(handles) |
75 | + ", inputs=" + events + ", timestamp=" + timestamp + "]"; |
76 | } |
77 | |
78 | @Override |
79 | public Long getHandlerId() { |
80 | return handlerId; |
81 | } |
82 | |
83 | @Override |
84 | public List<Long> getInputIds() { |
85 | List<Long> ret = new ArrayList<Long>(handles.length); |
86 | for (Handle<E,P,C,Long> h: handles) { |
87 | ret.add(h.getId()); |
88 | } |
89 | return ret; |
90 | } |
91 | |
92 | @Override |
93 | public int hashCode() { |
94 | final int prime = 31; |
95 | int result = 1; |
96 | result = prime * result |
97 | + ((handlerId == null) ? 0 : handlerId.hashCode()); |
98 | result = prime * result + ((events == null) ? 0 : events.hashCode()); |
99 | return result; |
100 | } |
101 | |
102 | @Override |
103 | public boolean equals(Object obj) { |
104 | if (this == obj) |
105 | return true; |
106 | if (obj == null) |
107 | return false; |
108 | if (getClass() != obj.getClass()) |
109 | return false; |
110 | DerivationImpl other = (DerivationImpl) obj; |
111 | if (handlerId == null) { |
112 | if (other.handlerId != null) |
113 | return false; |
114 | } else if (!handlerId.equals(other.handlerId)) |
115 | return false; |
116 | if (events == null) { |
117 | if (other.events != null) |
118 | return false; |
119 | } else if (!events.equals(other.events)) |
120 | return false; |
121 | return true; |
122 | } |
123 | |
124 | private MasterHandle<E,P,C,?> masterHandle; |
125 | |
126 | @Override |
127 | public void invalidate(InferenceContext<E,P,C,?,?,?> inferenceContext) { |
128 | if (masterHandle!=null) { |
129 | masterHandle.removeDerivation(this, (InferenceContext) inferenceContext); |
130 | } |
131 | } |
132 | |
133 | void setMasterHandle(MasterHandle<E, P, C, S> masterHandle) { |
134 | this.masterHandle = masterHandle; |
135 | } |
136 | |
137 | // In order to be able to put to concurrent skip list |
138 | @Override |
139 | public int compareTo(DerivationImpl<E, P, C, S> o) { |
140 | if (o==this) { |
141 | return 0; |
142 | } |
143 | long hDelta = handlerId - o.handlerId; |
144 | if (hDelta>0) { |
145 | return 1; |
146 | } |
147 | if (hDelta<0) { |
148 | return -1; |
149 | } |
150 | |
151 | for (int i=0; i<handles.length; ++i) { |
152 | long d = handles[i].getId()-o.handles[i].getId(); |
153 | if (d>0) { |
154 | return 1; |
155 | } |
156 | if (d<0) { |
157 | return -1; |
158 | } |
159 | } |
160 | |
161 | return 0; |
162 | } |
163 | |
164 | } |