001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028: package net.sf.jasperreports.olap.xmla;
029:
030: import java.net.MalformedURLException;
031: import java.net.URL;
032: import java.util.HashMap;
033: import java.util.Iterator;
034: import java.util.Map;
035: import java.util.regex.Matcher;
036: import java.util.regex.Pattern;
037:
038: import javax.xml.soap.MessageFactory;
039: import javax.xml.soap.MimeHeaders;
040: import javax.xml.soap.Name;
041: import javax.xml.soap.SOAPBody;
042: import javax.xml.soap.SOAPConnection;
043: import javax.xml.soap.SOAPConnectionFactory;
044: import javax.xml.soap.SOAPElement;
045: import javax.xml.soap.SOAPEnvelope;
046: import javax.xml.soap.SOAPException;
047: import javax.xml.soap.SOAPFactory;
048: import javax.xml.soap.SOAPFault;
049: import javax.xml.soap.SOAPMessage;
050: import javax.xml.soap.SOAPPart;
051:
052: import net.sf.jasperreports.engine.JRDataSource;
053: import net.sf.jasperreports.engine.JRDataset;
054: import net.sf.jasperreports.engine.JRException;
055: import net.sf.jasperreports.engine.JRRuntimeException;
056: import net.sf.jasperreports.engine.query.JRAbstractQueryExecuter;
057: import net.sf.jasperreports.olap.JROlapDataSource;
058:
059: import org.apache.commons.logging.Log;
060: import org.apache.commons.logging.LogFactory;
061:
062: /**
063: * @author Michael Günther (m.guenther at users.sourceforge.net)
064: * @version $Id: JRXmlaQueryExecuter.java 1575 2007-02-08 16:53:46Z lucianc $
065: */
066: public class JRXmlaQueryExecuter extends JRAbstractQueryExecuter {
067:
068: private static final Log log = LogFactory
069: .getLog(JRXmlaQueryExecuter.class);
070:
071: private static final String SLICER_AXIS_NAME = "SlicerAxis";
072: private static final String MDD_URI = "urn:schemas-microsoft-com:xml-analysis:mddataset";
073: private static final String XMLA_URI = "urn:schemas-microsoft-com:xml-analysis";
074:
075: private static final Pattern LEVEL_UNIQUE_NAME_PATTERN = Pattern
076: .compile("\\[[^\\]]+\\]\\.\\[([^\\]]+)\\]");
077: private static final int LEVEL_UNIQUE_NAME_PATTERN_NAME_GROUP = 1;
078:
079: private SOAPFactory sf;
080: private SOAPConnection connection;
081: private JRXmlaResult xmlaResult;
082:
083: public JRXmlaQueryExecuter(JRDataset dataset, Map parametersMap) {
084: super (dataset, parametersMap);
085:
086: parseQuery();
087: }
088:
089: protected String getParameterReplacement(String parameterName) {
090: return String.valueOf(getParameterValue(parameterName));
091: }
092:
093: public JRDataSource createDatasource() throws JRException {
094: try {
095: this .sf = SOAPFactory.newInstance();
096: this .connection = createSOAPConnection();
097: SOAPMessage queryMessage = createQueryMessage();
098:
099: URL soapURL = new URL(getSoapUrl());
100: SOAPMessage resultMessage = executeQuery(queryMessage,
101: soapURL);
102:
103: xmlaResult = new JRXmlaResult();
104: parseResult(resultMessage);
105: } catch (MalformedURLException e) {
106: log.error(e);
107: throw new JRRuntimeException(e);
108: } catch (SOAPException e) {
109: log.error(e);
110: throw new JRRuntimeException(e);
111: }
112:
113: JROlapDataSource olapDS = new JROlapDataSource(dataset,
114: xmlaResult);
115: return olapDS;
116: }
117:
118: protected String getSoapUrl() throws MalformedURLException {
119: String soapUrl;
120: String xmlaUrl = (String) getParameterValue(JRXmlaQueryExecuterFactory.PARAMETER_XMLA_URL);
121: String user = (String) getParameterValue(
122: JRXmlaQueryExecuterFactory.PARAMETER_XMLA_USER, true);
123: if (user == null || user.length() == 0) {
124: soapUrl = xmlaUrl;
125: } else {
126: URL url = new URL(xmlaUrl);
127: soapUrl = url.getProtocol() + "://" + user;
128:
129: String password = (String) getParameterValue(
130: JRXmlaQueryExecuterFactory.PARAMETER_XMLA_PASSWORD,
131: true);
132: if (password != null && password.length() > 0) {
133: soapUrl += ":" + password;
134: }
135:
136: soapUrl += "@" + url.getHost() + ":" + url.getPort()
137: + url.getPath();
138: }
139: return soapUrl;
140: }
141:
142: public boolean cancelQuery() throws JRException {
143: return false;
144: }
145:
146: public void close() {
147: if (connection != null) {
148: try {
149: connection.close();
150: } catch (SOAPException e) {
151: log.error(e);
152: throw new JRRuntimeException(e);
153: }
154: connection = null;
155: }
156: }
157:
158: protected SOAPConnection createSOAPConnection() {
159: try {
160: SOAPConnectionFactory scf = SOAPConnectionFactory
161: .newInstance();
162: SOAPConnection soapConnection = scf.createConnection();
163: return soapConnection;
164: } catch (UnsupportedOperationException e) {
165: log.error(e);
166: throw new JRRuntimeException(e);
167: } catch (SOAPException e) {
168: log.error(e);
169: throw new JRRuntimeException(e);
170: }
171: }
172:
173: protected SOAPMessage createQueryMessage() {
174: String queryStr = getQueryString();
175:
176: if (log.isDebugEnabled()) {
177: log.debug("MDX query: " + queryStr);
178: }
179:
180: try {
181: MessageFactory mf = MessageFactory.newInstance();
182: SOAPMessage message = mf.createMessage();
183:
184: MimeHeaders mh = message.getMimeHeaders();
185: mh
186: .setHeader("SOAPAction",
187: "\"urn:schemas-microsoft-com:xml-analysis:Execute\"");
188:
189: SOAPPart soapPart = message.getSOAPPart();
190: SOAPEnvelope envelope = soapPart.getEnvelope();
191: SOAPBody body = envelope.getBody();
192: Name nEx = envelope.createName("Execute", "", XMLA_URI);
193:
194: SOAPElement eEx = body.addChildElement(nEx);
195:
196: // add the parameters
197:
198: // COMMAND parameter
199: // <Command>
200: // <Statement>queryStr</Statement>
201: // </Command>
202: Name nCom = envelope.createName("Command", "", XMLA_URI);
203: SOAPElement eCommand = eEx.addChildElement(nCom);
204: Name nSta = envelope.createName("Statement", "", XMLA_URI);
205: SOAPElement eStatement = eCommand.addChildElement(nSta);
206: eStatement.addTextNode(queryStr);
207:
208: // <Properties>
209: // <PropertyList>
210: // <DataSourceInfo>dataSource</DataSourceInfo>
211: // <Catalog>catalog</Catalog>
212: // <Format>Multidimensional</Format>
213: // <AxisFormat>TupleFormat</AxisFormat>
214: // </PropertyList>
215: // </Properties>
216: Map paraList = new HashMap();
217: String datasource = (String) getParameterValue(JRXmlaQueryExecuterFactory.PARAMETER_XMLA_DATASOURCE);
218: paraList.put("DataSourceInfo", datasource);
219: String catalog = (String) getParameterValue(JRXmlaQueryExecuterFactory.PARAMETER_XMLA_CATALOG);
220: paraList.put("Catalog", catalog);
221: paraList.put("Format", "Multidimensional");
222: paraList.put("AxisFormat", "TupleFormat");
223: addParameterList(envelope, eEx, "Properties",
224: "PropertyList", paraList);
225: message.saveChanges();
226:
227: if (log.isDebugEnabled()) {
228: log.debug("XML/A query message: " + message.toString());
229: }
230:
231: return message;
232: } catch (SOAPException e) {
233: log.error(e);
234: throw new JRRuntimeException(e);
235: }
236: }
237:
238: protected void addParameterList(SOAPEnvelope envelope,
239: SOAPElement eParent, String typeName, String listName,
240: Map params) throws SOAPException {
241: Name nPara = envelope.createName(typeName, "", XMLA_URI);
242: SOAPElement eType = eParent.addChildElement(nPara);
243: nPara = envelope.createName(listName, "", XMLA_URI);
244: SOAPElement eList = eType.addChildElement(nPara);
245: if (params == null)
246: return;
247:
248: Iterator it = params.keySet().iterator();
249: while (it.hasNext()) {
250: String tag = (String) it.next();
251: String value = (String) params.get(tag);
252: nPara = envelope.createName(tag, "", XMLA_URI);
253: SOAPElement eTag = eList.addChildElement(nPara);
254: eTag.addTextNode(value);
255: }
256: }
257:
258: /**
259: * Sends the SOAP Message over the connection and returns the
260: * Result-SOAP-Message
261: *
262: * @return Reply-Message
263: */
264: protected SOAPMessage executeQuery(SOAPMessage message, URL url) {
265: try {
266: SOAPMessage soapResult = connection.call(message, url);
267: return soapResult;
268: } catch (SOAPException e) {
269: log.error("Message-Call failed.", e);
270: throw new JRRuntimeException(e);
271: }
272: }
273:
274: /**
275: * Parses the result-Message into this class's structure
276: *
277: * @param reply
278: * The reply-Message from the Server
279: */
280: protected void parseResult(SOAPMessage reply) throws SOAPException {
281: SOAPPart soapPart = reply.getSOAPPart();
282: SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
283: SOAPBody soapBody = soapEnvelope.getBody();
284: SOAPElement eElement = null;
285:
286: if (log.isDebugEnabled()) {
287: log.debug("XML/A result envelope: "
288: + soapEnvelope.toString());
289: }
290:
291: SOAPFault fault = soapBody.getFault();
292: if (fault != null) {
293: handleResultFault(fault);
294: }
295:
296: Name eName = soapEnvelope.createName("ExecuteResponse", "",
297: XMLA_URI);
298:
299: // Get the ExecuteResponse-Node
300: Iterator responseElements = soapBody.getChildElements(eName);
301: if (responseElements.hasNext()) {
302: Object eObj = responseElements.next();
303: if (eObj == null) {
304: log.error("ExecuteResponse Element is null.");
305: throw new JRRuntimeException(
306: "ExecuteResponse Element is null.");
307: }
308: eElement = (SOAPElement) eObj;
309: } else {
310: log.error("Could not retrieve ExecuteResponse Element.");
311: throw new JRRuntimeException(
312: "Could not retrieve ExecuteResponse Element.");
313: }
314:
315: // Get the return-Node
316: Name rName = soapEnvelope.createName("return", "", XMLA_URI);
317: Iterator returnElements = eElement.getChildElements(rName);
318: SOAPElement returnElement = null;
319: if (returnElements.hasNext()) {
320: Object eObj = returnElements.next();
321: if (eObj == null) {
322: log.error("return Element is null.");
323: throw new JRRuntimeException("return Element is null.");
324: }
325: returnElement = (SOAPElement) eObj;
326: } else {
327: // Should be old-Microsoft XMLA-SDK. Try without m-prefix
328: Name rName2 = soapEnvelope.createName("return", "", "");
329: returnElements = eElement.getChildElements(rName2);
330: if (returnElements.hasNext()) {
331: Object eObj = returnElements.next();
332: if (eObj == null) {
333: log.error("return Element is null.");
334: throw new JRRuntimeException(
335: "return Element is null.");
336: }
337: returnElement = (SOAPElement) eObj;
338: } else {
339: log.error("Could not retrieve return Element.");
340: throw new JRRuntimeException(
341: "Could not retrieve return Element.");
342: }
343: }
344:
345: // Get the root-Node
346: Name rootName = soapEnvelope.createName("root", "", MDD_URI);
347: SOAPElement rootElement = null;
348: Iterator rootElements = returnElement
349: .getChildElements(rootName);
350: if (rootElements.hasNext()) {
351: Object eObj = rootElements.next();
352: if (eObj == null) {
353: log.error("root Element is null.");
354: throw new JRRuntimeException("root Element is null.");
355: }
356: rootElement = (SOAPElement) eObj;
357: } else {
358: log.error("Could not retrieve root Element.");
359: throw new JRRuntimeException(
360: "Could not retrieve root Element.");
361: }
362: // Get the OlapInfo-Node
363: Name olapInfoName = soapEnvelope.createName("OlapInfo", "",
364: MDD_URI);
365: SOAPElement olapInfoElement = null;
366: Iterator olapInfoElements = rootElement
367: .getChildElements(olapInfoName);
368: if (olapInfoElements.hasNext()) {
369: Object eObj = olapInfoElements.next();
370: if (eObj == null) {
371: log.error("OlapInfo Element is null.");
372: throw new JRRuntimeException(
373: "OlapInfo Element is null.");
374: }
375: olapInfoElement = (SOAPElement) eObj;
376: } else {
377: log.error("Could not retrieve OlapInfo Element.");
378: throw new JRRuntimeException(
379: "Could not retrieve OlapInfo Element.");
380: }
381:
382: parseOLAPInfoElement(olapInfoElement);
383:
384: // Get the Axes Element
385: Name axesName = soapEnvelope.createName("Axes", "", MDD_URI);
386: SOAPElement axesElement = null;
387: Iterator axesElements = rootElement.getChildElements(axesName);
388: if (axesElements.hasNext()) {
389: Object eObj = axesElements.next();
390: if (eObj == null) {
391: log.error("Axes Element is null");
392: throw new JRRuntimeException("Axes Element is null");
393: }
394: axesElement = (SOAPElement) eObj;
395: } else {
396: log.error("Could not retrieve Axes Element.");
397: throw new JRRuntimeException(
398: "Could not retrieve Axes Element.");
399: }
400:
401: parseAxesElement(axesElement);
402:
403: // Get the CellData Element
404: Name cellDataName = soapEnvelope.createName("CellData", "",
405: MDD_URI);
406: SOAPElement cellDataElement = null;
407: Iterator cellDataElements = rootElement
408: .getChildElements(cellDataName);
409: if (cellDataElements.hasNext()) {
410: Object eObj = cellDataElements.next();
411: if (eObj == null) {
412: log.error("CellData element is null");
413: throw new JRRuntimeException("CellData element is null");
414: }
415: cellDataElement = (SOAPElement) eObj;
416: } else {
417: log.error("Could not retrieve CellData Element.");
418: throw new JRRuntimeException(
419: "Could not retrieve CellData Element.");
420: }
421: parseCellDataElement(cellDataElement);
422: }
423:
424: protected void handleResultFault(SOAPFault fault) {
425: StringBuffer errorMsg = new StringBuffer();
426: errorMsg.append("XML/A fault: ");
427:
428: String faultString = fault.getFaultString();
429: if (faultString != null) {
430: errorMsg.append(faultString);
431: errorMsg.append("; ");
432: }
433:
434: String faultActor = fault.getFaultActor();
435: if (faultActor != null) {
436: errorMsg.append("Actor: ");
437: errorMsg.append(faultActor);
438: errorMsg.append("; ");
439: }
440:
441: String faultCode = fault.getFaultCode();
442: if (faultCode != null) {
443: errorMsg.append("Code: ");
444: errorMsg.append(faultCode);
445: errorMsg.append("; ");
446: }
447:
448: throw new JRRuntimeException(errorMsg.toString());
449: }
450:
451: protected void parseOLAPInfoElement(SOAPElement olapInfoElement)
452: throws SOAPException {
453: // CubeInfo-Element is not needed
454:
455: // Get the AxesInfo-Node
456: Name axesInfoName = sf.createName("AxesInfo", "", MDD_URI);
457: SOAPElement axesElement = null;
458: Iterator axesInfoElements = olapInfoElement
459: .getChildElements(axesInfoName);
460: if (axesInfoElements.hasNext()) {
461: Object axesObj = axesInfoElements.next();
462: if (axesObj == null) {
463: log.error("AxisInfo Element is null.");
464: throw new JRRuntimeException(
465: "AxisInfo Element is null.");
466: }
467: axesElement = (SOAPElement) axesObj;
468: } else {
469: log.error("Could not retrieve AxesInfo Element.");
470: throw new JRRuntimeException(
471: "Could not retrieve AxesInfo Element.");
472: }
473:
474: parseAxesInfoElement(axesElement);
475:
476: // CellInfo is not needed
477: }
478:
479: protected void parseAxesInfoElement(SOAPElement axesInfoElement)
480: throws SOAPException {
481: // Cycle over AxisInfo-Elements
482: Name axisInfoName = sf.createName("AxisInfo", "", MDD_URI);
483: Iterator itAxis = axesInfoElement
484: .getChildElements(axisInfoName);
485: while (itAxis.hasNext()) {
486: SOAPElement axisElement = (SOAPElement) itAxis.next();
487: Name name = sf.createName("name");
488: String axisName = axisElement.getAttributeValue(name);
489: if (axisName.equals(SLICER_AXIS_NAME)) {
490: continue;
491: }
492:
493: JRXmlaResultAxis axis = new JRXmlaResultAxis(axisName);
494: xmlaResult.addAxis(axis);
495:
496: // retrieve the hierarchies by <HierarchyInfo>
497: name = sf.createName("HierarchyInfo", "", MDD_URI);
498: Iterator itHierInfo = axisElement.getChildElements(name);
499: while (itHierInfo.hasNext()) {
500: SOAPElement eHierInfo = (SOAPElement) itHierInfo.next();
501: handleHierInfo(axis, eHierInfo);
502: }
503: }
504: }
505:
506: protected void parseAxesElement(SOAPElement axesElement)
507: throws SOAPException {
508: // Cycle over Axis-Elements
509: Name aName = sf.createName("Axis", "", MDD_URI);
510: Iterator itAxis = axesElement.getChildElements(aName);
511: while (itAxis.hasNext()) {
512: SOAPElement axisElement = (SOAPElement) itAxis.next();
513: Name name = sf.createName("name");
514: String axisName = axisElement.getAttributeValue(name);
515:
516: if (axisName.equals(SLICER_AXIS_NAME)) {
517: continue;
518: }
519:
520: // LookUp for the Axis
521: JRXmlaResultAxis axis = xmlaResult.getAxisByName(axisName);
522:
523: // retrieve the tuples by <Tuples>
524: name = sf.createName("Tuples", "", MDD_URI);
525: Iterator itTuples = axisElement.getChildElements(name);
526: if (itTuples.hasNext()) {
527: SOAPElement eTuples = (SOAPElement) itTuples.next();
528: handleTuplesElement(axis, eTuples);
529: }
530: }
531: }
532:
533: protected void parseCellDataElement(SOAPElement cellDataElement)
534: throws SOAPException {
535: Name name = sf.createName("Cell", "", MDD_URI);
536: Iterator itCells = cellDataElement.getChildElements(name);
537: while (itCells.hasNext()) {
538: SOAPElement cellElement = (SOAPElement) itCells.next();
539:
540: Name errorName = sf.createName("Error", "", MDD_URI);
541: Iterator errorElems = cellElement
542: .getChildElements(errorName);
543: if (errorElems.hasNext()) {
544: handleCellErrors(errorElems);
545: }
546:
547: Name ordinalName = sf.createName("CellOrdinal");
548: String cellOrdinal = cellElement
549: .getAttributeValue(ordinalName);
550:
551: Object value = null;
552: Iterator valueElements = cellElement.getChildElements(sf
553: .createName("Value", "", MDD_URI));
554: if (valueElements.hasNext()) {
555: SOAPElement valueElement = (SOAPElement) valueElements
556: .next();
557: String valueType = valueElement
558: .getAttribute("xsi:type");
559: if (valueType.equals("xsd:int"))
560: value = new Long(valueElement.getValue());
561: else if (valueType.equals("xsd:double"))
562: value = new Double(valueElement.getValue());
563: else if (valueType.equals("xsd:decimal"))
564: value = new Double(valueElement.getValue());
565: else
566: value = valueElement.getValue();
567: }
568:
569: String fmtValue = "";
570: Iterator fmtValueElements = cellElement.getChildElements(sf
571: .createName("FmtValue", "", MDD_URI));
572: if (fmtValueElements.hasNext()) {
573: SOAPElement fmtValueElement = ((SOAPElement) fmtValueElements
574: .next());
575: fmtValue = fmtValueElement.getValue();
576: }
577:
578: int pos = Integer.parseInt(cellOrdinal);
579: JRXmlaCell cell = new JRXmlaCell(value, fmtValue);
580: xmlaResult.setCell(cell, pos);
581: }
582: }
583:
584: protected void handleCellErrors(Iterator errorElems)
585: throws SOAPException {
586: SOAPElement errorElem = (SOAPElement) errorElems.next();
587:
588: StringBuffer errorMsg = new StringBuffer();
589: errorMsg.append("Cell error: ");
590:
591: Iterator descriptionElems = errorElem.getChildElements(sf
592: .createName("Description", "", MDD_URI));
593: if (descriptionElems.hasNext()) {
594: SOAPElement descrElem = (SOAPElement) descriptionElems
595: .next();
596: errorMsg.append(descrElem.getValue());
597: errorMsg.append("; ");
598: }
599:
600: Iterator sourceElems = errorElem.getChildElements(sf
601: .createName("Source", "", MDD_URI));
602: if (sourceElems.hasNext()) {
603: SOAPElement sourceElem = (SOAPElement) sourceElems.next();
604: errorMsg.append("Source: ");
605: errorMsg.append(sourceElem.getValue());
606: errorMsg.append("; ");
607: }
608:
609: Iterator codeElems = errorElem.getChildElements(sf.createName(
610: "ErrorCode", "", MDD_URI));
611: if (codeElems.hasNext()) {
612: SOAPElement codeElem = (SOAPElement) codeElems.next();
613: errorMsg.append("Code: ");
614: errorMsg.append(codeElem.getValue());
615: errorMsg.append("; ");
616: }
617:
618: throw new JRRuntimeException(errorMsg.toString());
619: }
620:
621: protected void handleHierInfo(JRXmlaResultAxis axis,
622: SOAPElement hierInfoElement) throws SOAPException {
623: Name name = sf.createName("name");
624: String dimName = hierInfoElement.getAttributeValue(name); // Get the Dimension Name
625:
626: JRXmlaHierarchy hier = new JRXmlaHierarchy(dimName);
627: axis.addHierarchy(hier);
628: }
629:
630: protected void handleTuplesElement(JRXmlaResultAxis axis,
631: SOAPElement tuplesElement) throws SOAPException {
632: Name tName = sf.createName("Tuple", "", MDD_URI);
633: for (Iterator itTuple = tuplesElement.getChildElements(tName); itTuple
634: .hasNext();) {
635: SOAPElement eTuple = (SOAPElement) itTuple.next();
636: handleTupleElement(axis, eTuple);
637: }
638: }
639:
640: protected void handleTupleElement(JRXmlaResultAxis axis,
641: SOAPElement tupleElement) throws SOAPException {
642: JRXmlaMemberTuple tuple = new JRXmlaMemberTuple(axis
643: .getHierarchiesOnAxis().length);
644:
645: Name memName = sf.createName("Member", "", MDD_URI);
646: Iterator itMember = tupleElement.getChildElements(memName);
647: int memNum = 0;
648: while (itMember.hasNext()) {
649: SOAPElement memElement = (SOAPElement) itMember.next();
650:
651: Name name = sf.createName("Hierarchy", "", "");
652: String hierName = memElement.getAttributeValue(name);
653:
654: String uName = "";
655: Iterator uNameElements = memElement.getChildElements(sf
656: .createName("UName", "", MDD_URI));
657: if (uNameElements.hasNext())
658: uName = ((SOAPElement) uNameElements.next()).getValue();
659:
660: String caption = "";
661: Iterator captionElements = memElement.getChildElements(sf
662: .createName("Caption", "", MDD_URI));
663: if (captionElements.hasNext())
664: caption = ((SOAPElement) captionElements.next())
665: .getValue();
666:
667: String lName = "";
668: Iterator lNameElements = memElement.getChildElements(sf
669: .createName("LName", "", MDD_URI));
670: if (lNameElements.hasNext()) {
671: String levelUniqueName = ((SOAPElement) lNameElements
672: .next()).getValue();
673: Matcher matcher = LEVEL_UNIQUE_NAME_PATTERN
674: .matcher(levelUniqueName);
675: if (matcher.matches()) {
676: lName = matcher
677: .group(LEVEL_UNIQUE_NAME_PATTERN_NAME_GROUP);
678: }
679: }
680:
681: int lNum = 0;
682: Iterator lNumElements = memElement.getChildElements(sf
683: .createName("LNum", "", MDD_URI));
684: if (lNumElements.hasNext())
685: lNum = Integer.parseInt(((SOAPElement) lNumElements
686: .next()).getValue());
687:
688: JRXmlaMember member = new JRXmlaMember(caption, uName,
689: hierName, lName, lNum);
690: tuple.setMember(memNum++, member);
691: }
692:
693: axis.addTuple(tuple);
694: }
695: }
|