001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package samples.common;
021:
022: import org.apache.axiom.om.OMAbstractFactory;
023: import org.apache.axiom.om.OMElement;
024: import org.apache.axiom.om.OMFactory;
025: import org.apache.axiom.om.OMNamespace;
026: import org.apache.axiom.om.xpath.AXIOMXPath;
027:
028: import javax.xml.namespace.QName;
029: import java.util.Random;
030: import java.util.List;
031: import java.util.Iterator;
032:
033: /**
034: * A class that can create messages to, and parse replies from our sample StockQuote service
035: */
036: public class StockQuoteHandler {
037:
038: private static final Random RANDOM = new Random();
039:
040: /**
041: * Create a new custom quote request with a body as follows
042: * <m0:CheckPriceRequest xmlns:m0="http://services.samples/xsd">
043: * <m0:Code>symbol</m0:Code>
044: * </m0:CheckPriceRequest>
045: * @param symbol the stock symbol
046: * @return OMElement for SOAP body
047: */
048: public static OMElement createCustomQuoteRequest(String symbol) {
049: OMFactory factory = OMAbstractFactory.getOMFactory();
050: OMNamespace ns = factory.createOMNamespace(
051: "http://services.samples/xsd", "m0");
052: OMElement chkPrice = factory.createOMElement(
053: "CheckPriceRequest", ns);
054: OMElement code = factory.createOMElement("Code", ns);
055: chkPrice.addChild(code);
056: code.setText(symbol);
057: return chkPrice;
058: }
059:
060: /**
061: * Create a new quote request with a body as follows
062: * <m:GetQuote xmlns:m="http://services.samples/xsd">
063: * <m:request>
064: * <m:symbol>IBM</m:symbol>
065: * </m:request>
066: * </m:GetQuote>
067: * @param symbol the stock symbol
068: * @return OMElement for SOAP body
069: */
070: public static OMElement createStandardQuoteRequest(String symbol,
071: int itrCount) {
072: OMFactory factory = OMAbstractFactory.getOMFactory();
073: OMNamespace ns = factory.createOMNamespace(
074: "http://services.samples/xsd", "m0");
075: OMElement getQuote = factory.createOMElement("getQuote", ns);
076: for (int i = 0; i < itrCount; i++) {
077: OMElement request = factory.createOMElement("request", ns);
078: OMElement symb = factory.createOMElement("symbol", ns);
079: request.addChild(symb);
080: getQuote.addChild(request);
081: symb.setText(symbol);
082: }
083: return getQuote;
084: }
085:
086: /**
087: * Create a new full quote request with a body as follows
088: * <m:GetFullQuote xmlns:m="http://services.samples/xsd">
089: * <m:request>
090: * <m:symbol>IBM</m:symbol>
091: * </m:request>
092: * </m:GetFullQuote>
093: * @param symbol the stock symbol
094: * @return OMElement for SOAP body
095: */
096: public static OMElement createFullQuoteRequest(String symbol) {
097: OMFactory factory = OMAbstractFactory.getOMFactory();
098: OMNamespace ns = factory.createOMNamespace(
099: "http://services.samples/xsd", "m0");
100: OMElement getQuote = factory
101: .createOMElement("getFullQuote", ns);
102: OMElement request = factory.createOMElement("request", ns);
103: OMElement symb = factory.createOMElement("symbol", ns);
104: request.addChild(symb);
105: getQuote.addChild(request);
106: symb.setText(symbol);
107: return getQuote;
108: }
109:
110: /**
111: * Create a new market activity request with a body as follows
112: * <m:getMarketActivity xmlns:m="http://services.samples/xsd">
113: * <m:request>
114: * <m:symbol>IBM</m:symbol>
115: * ...
116: * <m:symbol>MSFT</m:symbol>
117: * </m:request>
118: * </m:getMarketActivity>
119: * @return OMElement for SOAP body
120: */
121: public static OMElement createMarketActivityRequest() {
122: OMFactory factory = OMAbstractFactory.getOMFactory();
123: OMNamespace ns = factory.createOMNamespace(
124: "http://services.samples/xsd", "m0");
125: OMElement getQuote = factory.createOMElement(
126: "getMarketActivity", ns);
127: OMElement request = factory.createOMElement("request", ns);
128:
129: OMElement symb = null;
130: for (int i = 0; i < 100; i++) {
131: symb = factory.createOMElement("symbols", ns);
132: symb.setText(randomString(3));
133: request.addChild(symb);
134: }
135:
136: getQuote.addChild(request);
137: return getQuote;
138: }
139:
140: /**
141: * Create a new order for a quantiry of a stock at a given price
142: * <m:placeOrder xmlns:m="http://services.samples/xsd">
143: * <m:order>
144: * <m:price>3.141593E0</m:price>
145: * <m:quantity>4</m:quantity>
146: * <m:symbol>IBM</m:symbol>
147: * </m:order>
148: * </m:placeOrder>
149: *
150: * @param purchPrice the purchase price
151: * @param qty the quantiry
152: * @param symbol the stock
153: * @return an OMElement payload for the order
154: */
155: public static OMElement createPlaceOrderRequest(double purchPrice,
156: int qty, String symbol) {
157: OMFactory factory = OMAbstractFactory.getOMFactory();
158: OMNamespace ns = factory.createOMNamespace(
159: "http://services.samples/xsd", "m0");
160: OMElement placeOrder = factory
161: .createOMElement("placeOrder", ns);
162: OMElement order = factory.createOMElement("order", ns);
163: OMElement price = factory.createOMElement("price", ns);
164: OMElement quantity = factory.createOMElement("quantity", ns);
165: OMElement symb = factory.createOMElement("symbol", ns);
166: price.setText(Double.toString(purchPrice));
167: quantity.setText(Integer.toString(qty));
168: symb.setText(symbol);
169: order.addChild(price);
170: order.addChild(quantity);
171: order.addChild(symb);
172: placeOrder.addChild(order);
173: return placeOrder;
174: }
175:
176: /**
177: * Digests the standard StockQuote response and extracts the last trade price
178: * @param result
179: * @return
180: * @throws javax.xml.stream.XMLStreamException
181: *
182: * <ns:getQuoteResponse xmlns:ns="http://services.samples/xsd">
183: * <ns:return>
184: * <ns:change>-2.3238706829151026</ns:change>
185: * ...
186: * <ns:symbol>IBM</ns:symbol>
187: * <ns:volume>17949</ns:volume>
188: * </ns:return>
189: * </ns:getQuoteResponse>
190: */
191: public static String parseStandardQuoteResponse(OMElement result)
192: throws Exception {
193:
194: AXIOMXPath xPath = new AXIOMXPath("//ns:last");
195: xPath.addNamespace("ns", "http://services.samples/xsd");
196: OMElement last = (OMElement) xPath.selectSingleNode(result);
197: if (last != null) {
198: return last.getText();
199: } else {
200: throw new Exception("Unexpected response : " + result);
201: }
202: }
203:
204: /**
205: * <ns:getFullQuoteResponse xmlns:ns="http://services.samples/xsd">
206: <ns:return>
207: <tradeHistory xmlns="http://services.samples/xsd">
208: <day>0</day>
209: <quote>
210: <change>-2.367492989603466</change>
211: <earnings>13.14956711287784</earnings>
212: <high>-155.58844623078153</high>
213: <last>157.47582716569198</last>
214: <lastTradeTimestamp>Mon Apr 16 23:29:58 LKT 2007</lastTradeTimestamp>
215: <low>-155.31924118819015</low>
216: <marketCap>6373750.467022192</marketCap>
217: <name>IBM Company</name>
218: <open>-154.84071720443495</open>
219: <peRatio>-17.353258031353164</peRatio>
220: <percentageChange>-1.3910235348298898</percentageChange>
221: <prevClose>170.1979104108393</prevClose>
222: <symbol>IBM</symbol>
223: <volume>8935</volume>
224: </quote>
225: </tradeHistory>
226: <tradeHistory xmlns="http://services.samples/xsd">
227: <day>1</day>
228: <quote>
229: <change>3.794122022240518</change>
230: <earnings>-8.656536789776045</earnings>
231: <high>176.77136802352928</high>
232: <last>170.28677783945102</last>
233: <lastTradeTimestamp>Mon Apr 16 23:29:58 LKT 2007</lastTradeTimestamp>
234: <low>-166.64126635049223</low>
235: <marketCap>-6112014.916847887</marketCap>
236: <name>IBM Company</name>
237: <open>-168.30884678174925</open>
238: <peRatio>-18.644628475049693</peRatio>
239: <percentageChange>-2.29678289479374</percentageChange>
240: <prevClose>-165.19288918603885</prevClose>
241: <symbol>IBM</symbol>
242: <volume>5825</volume>
243: </quote>
244: </tradeHistory>
245: ...
246: </ns:return>
247: </ns:getFullQuoteResponse>
248: *
249: * @param result
250: * @return
251: * @throws Exception
252: */
253: public static String parseFullQuoteResponse(OMElement result)
254: throws Exception {
255:
256: AXIOMXPath xPath = new AXIOMXPath("//ns:last");
257: xPath.addNamespace("ns", "http://services.samples/xsd");
258: List lastNodes = xPath.selectNodes(result);
259:
260: if (lastNodes == null) {
261: throw new Exception("Unexpected response : " + result);
262: }
263:
264: double total = 0;
265: int count = 0;
266:
267: Iterator iter = lastNodes.iterator();
268: while (iter.hasNext()) {
269: OMElement last = (OMElement) iter.next();
270: total += Double.parseDouble(last.getText());
271: count++;
272: }
273:
274: return Double.toString(total / count);
275: }
276:
277: /**
278: * <ns:getMarketActivityResponse xmlns:ns="http://services.samples/xsd">
279: <ns:return>
280: <quotes xmlns="http://services.samples/xsd">
281: <change>4.183958555301184</change>
282: <earnings>-8.585281368244686</earnings>
283: <high>-158.70528805517333</high>
284: <last>160.83784480071603</last>
285: <lastTradeTimestamp>Tue Apr 17 02:21:30 LKT 2007</lastTradeTimestamp>
286: <low>-157.4950051860593</low>
287: <marketCap>5.9907588733164035E7</marketCap>
288: <name>EHM Company</name>
289: <open>-160.18368223376558</open>
290: <peRatio>24.0926205053427</peRatio>
291: <percentageChange>-2.6141745708181374</percentageChange>
292: <prevClose>-160.04893483420904</prevClose>
293: <symbol>EHM</symbol>
294: <volume>6319</volume>
295: </quotes>
296: <quotes xmlns="http://services.samples/xsd">
297: ....
298: <volume>7613</volume>
299: </quotes>
300: ...
301: </ns:return>
302: <ns:getMarketActivityResponse>
303: * @param result
304: * @return the average last price for each stock symbol
305: * @throws Exception
306: */
307: public static String parseMarketActivityResponse(OMElement result)
308: throws Exception {
309:
310: AXIOMXPath xPath = new AXIOMXPath("//ns:last");
311: xPath.addNamespace("ns", "http://services.samples/xsd");
312: List lastNodes = xPath.selectNodes(result);
313:
314: if (lastNodes == null) {
315: throw new Exception("Unexpected response : " + result);
316: }
317:
318: double total = 0;
319: int count = 0;
320:
321: Iterator iter = lastNodes.iterator();
322: while (iter.hasNext()) {
323: OMElement last = (OMElement) iter.next();
324: total += Double.parseDouble(last.getText());
325: count++;
326: }
327:
328: return Double.toString(total / count);
329: }
330:
331: /**
332: * Digests the custom quote response and extracts the last trade price
333: * @param result
334: * @return
335: * @throws javax.xml.stream.XMLStreamException
336: *
337: * <CheckPriceResponse xmlns="http://ws.invesbot.com/" >
338: * <Code>IBM</Code>
339: * <Price>82.90</Price>
340: * </CheckPriceResponse>
341: */
342: public static String parseCustomQuoteResponse(OMElement result)
343: throws Exception {
344:
345: AXIOMXPath xPath = new AXIOMXPath("//ns:Price");
346: xPath.addNamespace("ns", "http://services.samples/xsd");
347: OMElement price = (OMElement) xPath.selectSingleNode(result);
348: if (price != null) {
349: return price.getText();
350: } else {
351: throw new Exception("Unexpected response : " + result);
352: }
353: }
354:
355: /**
356: * Return a random String of letters
357: * @param count number of letters
358: * @return the random string
359: */
360: public static String randomString(int count) {
361: int end = 'Z' + 1;
362: int start = 'A';
363:
364: StringBuffer buffer = new StringBuffer();
365: int gap = end - start;
366:
367: while (count-- != 0) {
368: char ch;
369: ch = (char) (RANDOM.nextInt(gap) + start);
370: if (Character.isLetter(ch)) {
371: buffer.append(ch);
372: } else {
373: count++;
374: }
375: }
376: return buffer.toString();
377: }
378:
379: }
|