5 import mir.entity.adapter.*;
10 public class EntityBatchingProducerNode implements ProducerNode {
13 private String batchInfoKey;
14 private String batchDataKey;
15 private EntityAdapterModel model;
16 private String definition;
17 private String whereClause;
18 private String orderByClause;
19 private String nrEntitiesToSkipExpression;
20 private String nrEntitiesPerBatchExpression;
21 private String minNrEntitiesInFirstBatchExpression;
22 private String defaultNrBatchesToProcessExpression;
23 private ProducerNode batchSubNode;
24 private ProducerNode batchListSubNode;
26 public EntityBatchingProducerNode(
29 EntityAdapterModel aModel,
32 String anOrderByClause,
33 int anrEntitiesPerBatchExpression,
34 int aminNrEntitiesInFirstBatchExpression,
35 int anrEntitiesToSkipExpression,
36 ProducerNode aBatchSubNode) {
37 this(aBatchDataKey, aBatchInfoKey, aModel, aDefinition, aWhereClause,
38 anOrderByClause, anrEntitiesPerBatchExpression, aminNrEntitiesInFirstBatchExpression, anrEntitiesToSkipExpression,
42 public EntityBatchingProducerNode(
45 EntityAdapterModel aModel,
48 String anOrderByClause,
49 int aNrEntitiesPerBatch,
50 int aMinNrEntitiesInFirstBatch,
51 int aNrEntitiesToSkip,
52 ProducerNode aBatchSubNode,
53 ProducerNode aBatchListSubNode) {
55 this(aBatchDataKey, aBatchInfoKey, aModel, aDefinition,
56 aWhereClause, anOrderByClause,
57 Integer.toString(aNrEntitiesPerBatch),
58 Integer.toString(aMinNrEntitiesInFirstBatch),
59 Integer.toString(aNrEntitiesToSkip),
61 aBatchSubNode, aBatchListSubNode);
65 public EntityBatchingProducerNode(
68 EntityAdapterModel aModel,
71 String anOrderByClause,
72 String anrEntitiesPerBatchExpression,
73 String aminNrEntitiesInFirstBatchExpression,
74 String anrEntitiesToSkipExpression,
75 String aDefaultNrBatchesToProcessExpression,
76 ProducerNode aBatchSubNode,
77 ProducerNode aBatchListSubNode) {
79 batchSubNode = aBatchSubNode;
80 batchListSubNode = aBatchListSubNode;
82 verbs = new HashMap();
84 batchDataKey = aBatchDataKey;
85 batchInfoKey = aBatchInfoKey;
87 definition = aDefinition;
88 whereClause = aWhereClause;
89 orderByClause = anOrderByClause;
90 nrEntitiesToSkipExpression = anrEntitiesToSkipExpression;
91 nrEntitiesPerBatchExpression = anrEntitiesPerBatchExpression;
92 minNrEntitiesInFirstBatchExpression = aminNrEntitiesInFirstBatchExpression;
93 defaultNrBatchesToProcessExpression = aDefaultNrBatchesToProcessExpression;
96 public void produce(Map aValueMap, String aVerb, PrintWriter aLogger) throws ProducerFailure {
99 int nrBatchesAfterFirst;
100 int nrEntitiesInFirstBatch;
101 int nrBatchesToProcess;
106 String expandedWhereClause;
107 String expandedOrderByClause;
108 EntityBatchingProducerNodeVerb verb = (EntityBatchingProducerNodeVerb) verbs.get(aVerb);
111 BatchLocation location;
113 int nrEntitiesToSkip;
114 int nrEntitiesPerBatch;
115 int minNrEntitiesInFirstBatch;
117 // ML: The order by clause should lead to a result set in _reverse order_: the first row will be
118 // the last entity presented on the last page
123 nrBatchesToProcess = ParameterExpander.evaluateIntegerExpressionWithDefault( aValueMap, defaultNrBatchesToProcessExpression, -1 );
126 nrBatchesToProcess=verb.nrBatchesToProcess;
129 expandedWhereClause = ParameterExpander.expandExpression( aValueMap, whereClause );
130 expandedOrderByClause = ParameterExpander.expandExpression( aValueMap, orderByClause );
132 nrEntitiesToSkip = ParameterExpander.evaluateIntegerExpression( aValueMap, nrEntitiesToSkipExpression);
133 nrEntitiesPerBatch = ParameterExpander.evaluateIntegerExpression( aValueMap, nrEntitiesPerBatchExpression);
134 minNrEntitiesInFirstBatch = ParameterExpander.evaluateIntegerExpression( aValueMap, minNrEntitiesInFirstBatchExpression);
136 batchesData = new Vector();
137 batchLocations = new Vector();
139 nrEntities = model.getMappingForName(definition).getStorage().getSize(expandedWhereClause)-nrEntitiesToSkip;
140 nrEntitiesInFirstBatch = nrEntities % nrEntitiesPerBatch;
141 while (nrEntitiesInFirstBatch<minNrEntitiesInFirstBatch && nrEntities-nrEntitiesInFirstBatch>=nrEntitiesPerBatch)
142 nrEntitiesInFirstBatch = nrEntitiesInFirstBatch + nrEntitiesPerBatch;
143 nrBatchesAfterFirst = (nrEntities-nrEntitiesInFirstBatch)/nrEntitiesPerBatch;
145 batchLocations.add(new BatchLocation(nrBatchesAfterFirst*nrEntitiesPerBatch, nrEntitiesInFirstBatch));
146 batchData = new HashMap();
147 batchData.put("identifier", "");
148 batchData.put("index", new Integer(nrBatchesAfterFirst+1));
149 batchData.put("size", new Integer(nrEntitiesInFirstBatch));
150 batchesData.add(batchData);
152 for (i=0; i<nrBatchesAfterFirst; i++) {
153 batchLocations.add(1, new BatchLocation(i*nrEntitiesPerBatch, nrEntitiesPerBatch));
154 batchData = new HashMap();
155 batchData.put("identifier", new Integer(i));
156 batchData.put("index", new Integer(i+1));
157 batchData.put("size", new Integer(nrEntitiesPerBatch));
158 batchesData.add(1, batchData);
161 batchData = new HashMap();
162 ParameterExpander.setValueForKey(aValueMap, batchInfoKey, batchData);
163 batchData.put("all", batchesData);
164 batchData.put("first", batchesData.get(0));
165 batchData.put("last", batchesData.get(batchesData.size()-1));
166 batchData.put("count", new Integer(batchesData.size()));
168 if (batchListSubNode!=null) {
169 batchListSubNode.produce(aValueMap, aVerb, aLogger);
172 if (nrBatchesToProcess<0 || nrBatchesToProcess>nrBatchesAfterFirst+1) {
173 nrBatchesToProcess = nrBatchesAfterFirst+1;
176 if (batchSubNode!=null) {
177 for (i=0; i<nrBatchesToProcess; i++) {
178 location = (BatchLocation) batchLocations.get(i);
180 batchData.put("current", batchesData.get(i));
182 batchData.put("previous", batchesData.get(i-1));
184 batchData.put("previous", null);
186 if (i<batchesData.size()-1)
187 batchData.put("next", batchesData.get(i+1));
189 batchData.put("next", null);
191 Iterator j = new EntityIteratorAdapter(expandedWhereClause, expandedOrderByClause,
192 location.nrEntities, model, definition, location.nrEntities, location.firstEntity);
193 List entities = new Vector();
196 entities.add(0, j.next());
198 ParameterExpander.setValueForKey(aValueMap, batchDataKey, entities );
200 batchSubNode.produce(aValueMap, aVerb, aLogger);
204 catch (Throwable t) {
205 throw new ProducerFailure(t.getMessage(), t);
209 private class BatchLocation {
213 public BatchLocation(int aFirstEntity, int aNrEntities) {
214 firstEntity = aFirstEntity;
215 nrEntities = aNrEntities;
219 public Set buildVerbSet() {
220 return verbs.keySet();
223 public void addVerb(String aVerb, int aNrPagesToGenerate) {
224 verbs.put(aVerb, new EntityBatchingProducerNodeVerb(aNrPagesToGenerate));
227 private class EntityBatchingProducerNodeVerb {
228 int nrBatchesToProcess;
230 EntityBatchingProducerNodeVerb(int aNrBatchesToProcess) {
231 nrBatchesToProcess = aNrBatchesToProcess;