Source code: com/sample/addressbook/controller/components/search/SearchController.java
1 /*
2 * SearchController.java
3 *
4 * Copyright (c) 2001, 2002 Aendvari, Ltd. All Rights Reserved.
5 *
6 * See the file LICENSE for terms of use.
7 *
8 */
9
10 package com.sample.addressbook.controller.components.search;
11
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.TreeSet;
15 import java.util.Iterator;
16
17 import javax.servlet.*;
18 import javax.servlet.http.*;
19
20 import com.aendvari.satyr.servlet.*;
21 import com.aendvari.satyr.servlet.gateway.tethys.*;
22
23 import com.aendvari.griffin.util.XmlUtil;
24 import com.aendvari.griffin.bean.transform.BeanTransformer;
25
26 import com.aendvari.common.model.*;
27 import com.aendvari.common.osm.*;
28 import com.aendvari.common.util.ConversionUtil;
29
30 import com.aendvari.tethys.context.*;
31 import com.aendvari.tethys.context.model.*;
32
33 import com.aendvari.tethys.tag.context.*;
34 import com.aendvari.tethys.tag.model.*;
35
36 import com.aendvari.cerberus.component.descriptor.ComponentDescriptor;
37
38 import com.aendvari.cerberus.component.assembly.AssembledComponent;
39 import com.aendvari.cerberus.component.assembly.AssemblyContext;
40
41 import com.aendvari.hermes.broker.*;
42 import com.aendvari.hermes.broker.http.*;
43
44
45 /**
46 * <p>Manages search request.</p>
47 *
48 * <p>
49 * When an item is "selected", this component sets the id of the selected value
50 * into the sending message under the name "itemId". To extract that id while in the
51 * listening component of the send message, use the following code:
52 * </p>
53 *
54 * <code>
55 * String itemId = message.getProperties().getString("itemId");
56 * </code>
57 *
58 * <p>
59 * The message sent to respond to the "selected" action, is determined in the configuration
60 * of this search component. See the message "select" in SearchController.xml
61 * </p>
62 *
63 * @author Scott Milne
64 *
65 */
66
67 public class SearchController implements AssembledComponent
68 {
69 protected ComponentDescriptor descriptor;
70 protected String model;
71 protected String pageNumber;
72 protected int entriesPerPage;
73
74
75 /* Constructors. */
76
77
78 /**
79 * Constructs a <code>SearchController</code> instance.
80 *
81 */
82
83 public SearchController()
84 {
85 }
86
87 /**
88 * Creates the component based on the provided descriptor.
89 *
90 * The {@link AssemblyContext} object is transient and should not be retained
91 * by the component.
92 *
93 * The {@link ComponentDescriptor} may be retained by the component.
94 *
95 * @param context The {@link AssemblyContext} for this component.
96 * @param descriptor The {@link ComponentDescriptor} for this component.
97 *
98 */
99
100 public void createComponent(AssemblyContext context, ComponentDescriptor descriptor)
101 {
102 MessageBrokerConnection connection = context.getMessageBroker().createConnection();
103
104 // subscribe to the topic associated with the "submit" message
105 connection.subscribe(descriptor.getMessage("submit").getTopic(), new SubmitListener());
106
107 // subscribe to the topic associated with the "page" message
108 connection.subscribe(descriptor.getMessage("page").getTopic(), new PageListener());
109
110 // subscribe to the topic associated with the "select" message
111 connection.subscribe(descriptor.getMessage("item").getTopic(), new ItemListener());
112
113 // store descriptor
114 this.descriptor = descriptor;
115
116 // retrieve information
117 model = descriptor.getAttribute("model").getValue();
118 pageNumber = descriptor.getAttribute("pageNumber").getValue();
119 entriesPerPage = ConversionUtil.stringToInt(descriptor.getAttribute("entriesPerPage").getValue());
120 }
121
122 class SubmitListener implements MessageListener
123 {
124 public void onMessage(Message message)
125 {
126 // retrieve web objects
127 HttpServletRequest request = HttpMessageBrokerContext.getRequest(message.getContext());
128 HttpServletResponse response = HttpMessageBrokerContext.getResponse(message.getContext());
129 HttpSession session = HttpMessageBrokerContext.getSession(message.getContext());
130
131 // get view model
132 ModelTree modelTree = ServletModelUtil.getModelTree(session);
133 ModelNode modelNode = modelTree.getNode(modelTree.getRootNode(), model);
134
135 // get the page number from the updated node
136 ModelNode pageNumberNode = modelTree.getNode(modelTree.getRootNode(), pageNumber);
137
138 // reset the page back to 1
139 pageNumberNode.setNodeValue("1");
140
141 // set the page data
142 setPageData(message);
143 }
144 }
145
146 class PageListener implements MessageListener
147 {
148 public void onMessage(Message message)
149 {
150 // retrieve web objects
151 HttpServletRequest request = HttpMessageBrokerContext.getRequest(message.getContext());
152 HttpServletResponse response = HttpMessageBrokerContext.getResponse(message.getContext());
153 HttpSession session = HttpMessageBrokerContext.getSession(message.getContext());
154
155 // get view model
156 ModelTree modelTree = ServletModelUtil.getModelTree(session);
157 ModelNode modelNode = modelTree.getNode(modelTree.getRootNode(), model);
158
159 // extract the OSM (form) data into the DOM node
160 ModelUtil.osmToModel(message.getProperties(), null, modelNode, false);
161
162 // set the page data
163 setPageData(message);
164 }
165 }
166
167 private void setPageData(Message message)
168 {
169 // retrieve web objects
170 HttpServletRequest request = HttpMessageBrokerContext.getRequest(message.getContext());
171 HttpServletResponse response = HttpMessageBrokerContext.getResponse(message.getContext());
172 HttpSession session = HttpMessageBrokerContext.getSession(message.getContext());
173
174 // get view model
175 ModelTree modelTree = ServletModelUtil.getModelTree(session);
176 ModelNode modelNode = modelTree.getNode(modelTree.getRootNode(), model);
177
178 // get the page number from the node
179 ModelNode pageNumberNode = modelTree.getNode(modelTree.getRootNode(), pageNumber);
180 int nPageNumber = ConversionUtil.stringToInt(pageNumberNode.getNodeValue());
181
182 // ok we're done preparing, so send the message for display
183 MessageBrokerConnection connection = message.getContext().createConnection();
184
185 // get the query message
186 MessageTopic query = connection.getTopic(
187 descriptor.getMessage("query").getTopic()
188 );
189
190 // prepare the message requestor
191 MessageRequestor requestor = new MessageRequestor(connection, query);
192
193 // send the "query" message and wait for it to respond
194 Message queryResponse = requestor.request(message);
195
196 // get the collection of results back from the message
197 ArrayList queryResult =
198 (ArrayList)queryResponse.getProperties().getObject("searchResults");
199
200 // create paged search
201 PagedSearch pagedSearch = new PagedSearch( entriesPerPage, nPageNumber );
202
203 // create the filter
204 SearchFilter filter = pagedSearch.getFilter();
205
206 // place results into a collection
207 ArrayList searchResults = new ArrayList();
208
209 int totalCount = 0;
210 Iterator resultIterator = queryResult.iterator();
211
212 while (resultIterator.hasNext())
213 {
214 // retrieve each record in result
215 Object entry = resultIterator.next();
216
217 // ignore filtered records
218 if (filter.isRetained(totalCount))
219 {
220 searchResults.add(entry);
221 }
222
223 totalCount++;
224 }
225
226 // create a paged search result for the view
227 PagedSearchResult pagedSearchResult = new PagedSearchResult(
228 pagedSearch,
229 searchResults,
230 totalCount,
231 nPageNumber
232 );
233
234 // extract the pagedSearchResult into the DOM
235 try
236 {
237 BeanTransformer.beanToModel( pagedSearchResult, modelNode, true );
238 }
239 catch( Exception exception )
240 {
241 exception.printStackTrace();
242 }
243
244 // ok we're done preparing, so send the message for display
245 // get the "display" topic so we can return to the same page again
246 String display = descriptor.getMessage("display").getTopic();
247
248 // create the success message and send it
249 Message displayMessage = connection.createMessage();
250 MessageTopic topic = connection.getTopic(display);
251 connection.publish(topic, displayMessage);
252 }
253
254 class ItemListener implements MessageListener
255 {
256 public void onMessage(Message message)
257 {
258 // retrieve web objects
259 HttpServletRequest request = HttpMessageBrokerContext.getRequest(message.getContext());
260 HttpServletResponse response = HttpMessageBrokerContext.getResponse(message.getContext());
261 HttpSession session = HttpMessageBrokerContext.getSession(message.getContext());
262
263 // get view model
264 ModelTree modelTree = ServletModelUtil.getModelTree(session);
265 ModelNode modelNode = modelTree.getNode(modelTree.getRootNode(), model);
266
267 // get the item id out of the form
268 OsmNode node = QueryOsmPath.selectNode(message.getProperties(), "itemId.*");
269 String itemId = node.getNodeValue().toString();
270
271 // ok we're done preparing, so send the message for display
272 // get the "display" topic so we can return to the same page again
273 String select = descriptor.getMessage("select").getTopic();
274
275 // create the success message and send it
276 MessageBrokerConnection connection = message.getContext().createConnection();
277 Message selectedMessage = connection.createMessage();
278
279 // set the item id into the message
280 selectedMessage.getProperties().setString("itemId", itemId);
281
282 // create the topic and send the message
283 MessageTopic topic = connection.getTopic(select);
284 connection.publish(topic, selectedMessage);
285 }
286 }
287 }
288