KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonbeller > jpivot > xmla > XMLA_SOAP


1 /*
2  * ====================================================================
3  * This software is subject to the terms of the Common Public License
4  * Agreement, available at the following URL:
5  * http://www.opensource.org/licenses/cpl.html .
6  * Copyright (C) 2003-2004 TONBELLER AG.
7  * All Rights Reserved.
8  * You must accept the terms of that agreement to use this software.
9  * ====================================================================
10  *
11  *
12  */

13 package com.tonbeller.jpivot.xmla;
14
15 import java.io.StringWriter JavaDoc;
16 import java.io.Writer JavaDoc;
17 import java.net.MalformedURLException JavaDoc;
18 import java.net.URL JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import javax.xml.soap.Detail JavaDoc;
26 import javax.xml.soap.DetailEntry JavaDoc;
27 import javax.xml.soap.MessageFactory JavaDoc;
28 import javax.xml.soap.MimeHeaders JavaDoc;
29 import javax.xml.soap.Name JavaDoc;
30 import javax.xml.soap.Node JavaDoc;
31 import javax.xml.soap.SOAPBody JavaDoc;
32 import javax.xml.soap.SOAPConnection JavaDoc;
33 import javax.xml.soap.SOAPConnectionFactory JavaDoc;
34 import javax.xml.soap.SOAPElement JavaDoc;
35 import javax.xml.soap.SOAPEnvelope JavaDoc;
36 import javax.xml.soap.SOAPException JavaDoc;
37 import javax.xml.soap.SOAPFault JavaDoc;
38 import javax.xml.soap.SOAPMessage JavaDoc;
39 import javax.xml.soap.SOAPPart JavaDoc;
40 import javax.xml.transform.Source JavaDoc;
41 import javax.xml.transform.Transformer JavaDoc;
42 import javax.xml.transform.TransformerFactory JavaDoc;
43 import javax.xml.transform.stream.StreamResult JavaDoc;
44
45 import org.apache.log4j.Logger;
46
47 import com.tonbeller.jpivot.olap.model.OlapDiscoverer;
48 import com.tonbeller.jpivot.olap.model.OlapException;
49 import com.tonbeller.jpivot.olap.model.OlapItem;
50 import com.tonbeller.jpivot.olap.model.QueryResultHandler;
51
52 /**
53  * Handling XMLA SOAP calls
54  */

55 public class XMLA_SOAP implements OlapDiscoverer {
56
57   static final String JavaDoc MDD_URI = "urn:schemas-microsoft-com:xml-analysis:mddataset";
58   static final String JavaDoc ROWS_URI = "urn:schemas-microsoft-com:xml-analysis:rowset";
59   static final String JavaDoc XMLA_URI = "urn:schemas-microsoft-com:xml-analysis";
60   static final String JavaDoc XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
61
62   static Logger logger = Logger.getLogger(XMLA_SOAP.class);
63
64   private SOAPConnectionFactory JavaDoc scf = null;
65   private MessageFactory JavaDoc mf = null;
66
67   private int provider = 0;
68
69   private String JavaDoc uri;
70   private URL JavaDoc url;
71   private String JavaDoc dataSource;
72
73   private String JavaDoc user;
74   private String JavaDoc password;
75
76   interface Rowhandler {
77     void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope);
78   }
79
80   /**
81    * c'tor
82    * set URI, password, user and create URL
83    * no datasource, no provider, will be determined by discover datasource
84    * @param uri
85    * @param user
86    * @param password
87    */

88   public XMLA_SOAP(String JavaDoc uri, String JavaDoc user, String JavaDoc password) throws OlapException {
89     logger.debug("Constructor: straight DiscoverDS");
90     init(uri, user, password);
91
92     setProviderAndDataSource(this.discoverDS());
93   }
94
95   /**
96    * c'tor
97    * set URI, password, user and create URL
98    * datasource given, provider will be determined from datasource
99    * @param uri
100    * @param user
101    * @param password
102    * @param dataSource
103    */

104   public XMLA_SOAP(String JavaDoc uri, String JavaDoc user, String JavaDoc password, String JavaDoc dataSource)
105       throws OlapException {
106     logger.debug("Constructor: given dataSource= " + dataSource);
107     init(uri, user, password);
108
109     this.dataSource = dataSource;
110     provider = determineProvider(dataSource);
111     
112   }
113
114   /**
115    * c'tor
116    * set URI, password, user and create URL
117    * provider given, datasource will be determined by discover datasource
118    * @param uri
119    * @param user
120    * @param password
121    * @param provider
122    */

123   public XMLA_SOAP(String JavaDoc uri, String JavaDoc user, String JavaDoc password, int newProvider) throws OlapException {
124     logger.debug("Constructor: given provider= " + newProvider);
125     init(uri, user, password);
126     provider = newProvider;
127     setProviderAndDataSource(discoverDS());
128   }
129
130   /*
131    * init
132    */

133   private void init(String JavaDoc uri, String JavaDoc user, String JavaDoc password) throws OlapException {
134     try {
135       scf = SOAPConnectionFactory.newInstance();
136       mf = MessageFactory.newInstance();
137     } catch (UnsupportedOperationException JavaDoc e) {
138       throw new OlapException(e);
139     } catch (SOAPException JavaDoc e) {
140       throw new OlapException(e);
141     }
142
143     this.uri = uri;
144     this.user = user;
145     this.password = password;
146     try {
147       url = new URL JavaDoc(uri);
148     } catch (MalformedURLException JavaDoc e1) {
149       throw new OlapException(e1);
150     }
151
152     if (user != null && user.length() > 0) {
153       String JavaDoc newUri = url.getProtocol() + "://" + user;
154       if (password != null && password.length() > 0) {
155         newUri += ":" + password;
156       }
157       newUri += "@" + url.getHost() + ":" + url.getPort() + url.getPath();
158
159       try {
160         url = new URL JavaDoc(newUri);
161       } catch (MalformedURLException JavaDoc e2) {
162         throw new OlapException(e2);
163       }
164     }
165   }
166
167   /**
168    * retrieve catalogs in data source
169    * @return List of OlapItems for the catalogs
170    * @see DataSourceBrowser
171    */

172   public List JavaDoc discoverCat() throws OlapException {
173     final List JavaDoc cats = new ArrayList JavaDoc();
174
175     // restrictions
176
HashMap JavaDoc rHash = new HashMap JavaDoc(); // empty
177

178     // properties
179
HashMap JavaDoc pHash = new HashMap JavaDoc();
180     pHash.put("DataSourceInfo", dataSource);
181     pHash.put("Content", "SchemaData");
182
183     Rowhandler rh = new Rowhandler() {
184       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
185
186         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_CATALOG);
187         cats.add(oi);
188         Iterator JavaDoc it = eRow.getChildElements();
189         while (it.hasNext()) {
190           Object JavaDoc o = it.next();
191           if (!(o instanceof SOAPElement JavaDoc))
192             continue;
193           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
194           String JavaDoc lname = e.getElementName().getLocalName();
195           if (lname.equals("CATALOG_NAME"))
196             oi.setName(e.getValue());
197           else
198             oi.setProperty(lname, e.getValue());
199         }
200       }
201     };
202
203     discover("DBSCHEMA_CATALOGS", url, rHash, pHash, rh);
204     logger.debug("DBSCHEMA_CATALOGS: found " + cats.size());
205
206     return cats;
207   }
208
209   /**
210    * retrieve datasource properties
211    * @return List of OlapItems for the datasource properties
212    * @see DataSourceBrowser
213    */

214   public List JavaDoc discoverDSProps() throws OlapException {
215     final List JavaDoc props = new ArrayList JavaDoc();
216
217     // restrictions
218
HashMap JavaDoc rHash = new HashMap JavaDoc(); // empty
219

220     // properties
221
HashMap JavaDoc pHash = new HashMap JavaDoc();
222     pHash.put("DataSourceInfo", dataSource);
223     pHash.put("Content", "SchemaData");
224
225     Rowhandler rh = new Rowhandler() {
226       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
227
228         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_PROPERTY);
229         props.add(oi);
230         Iterator JavaDoc it = eRow.getChildElements();
231         while (it.hasNext()) {
232           Object JavaDoc o = it.next();
233           if (!(o instanceof SOAPElement JavaDoc))
234             continue;
235           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
236           String JavaDoc lname = e.getElementName().getLocalName();
237           if ( lname.equals("PropertyName") )
238             oi.setName( e.getValue());
239           oi.setProperty(lname, e.getValue());
240         }
241       }
242     };
243
244     discover("DISCOVER_PROPERTIES", url, rHash, pHash, rh);
245     logger.debug("DISCOVER_PROPERTIES: found " + props.size());
246
247     return props;
248   }
249
250   /**
251    * retrieve cubes in data source
252    * @return List of OlapItems for the cubes
253    * @see DataSourceBrowser
254    */

255   public List JavaDoc discoverCube(String JavaDoc cat) throws OlapException {
256     final List JavaDoc cubes = new ArrayList JavaDoc();
257     // restrictions
258
HashMap JavaDoc rHash = new HashMap JavaDoc();
259     rHash.put("CATALOG_NAME", cat);
260
261     // properties
262
HashMap JavaDoc pHash = new HashMap JavaDoc();
263     pHash.put("DataSourceInfo", dataSource);
264     pHash.put("Content", "SchemaData");
265     pHash.put("Catalog", cat); // needed, or else can only discover first catalog's cubes
266

267     Rowhandler rh = new Rowhandler() {
268       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
269
270         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_CUBE);
271         cubes.add(oi);
272
273         Iterator JavaDoc it = eRow.getChildElements();
274         while (it.hasNext()) {
275           Object JavaDoc o = it.next();
276           if (!(o instanceof SOAPElement JavaDoc))
277             continue;
278           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
279           String JavaDoc lname = e.getElementName().getLocalName();
280           if (lname.equals("CUBE_NAME"))
281             oi.setName(e.getValue());
282           else
283             oi.setProperty(lname, e.getValue());
284         }
285       }
286
287     };
288     discover("MDSCHEMA_CUBES", url, rHash, pHash, rh);
289     logger.debug("MDSCHEMA_CUBES: found " + cubes.size());
290     return cubes;
291   }
292
293   /**
294    * retrieve dimensions in data source
295    * @return List of OlapItems for the dimensions
296    * @see DataSourceBrowser
297    */

298   public List JavaDoc discoverDim(String JavaDoc cat, String JavaDoc cube) throws OlapException {
299     final List JavaDoc dims = new ArrayList JavaDoc();
300     // restrictions
301
HashMap JavaDoc rHash = new HashMap JavaDoc();
302     rHash.put("CATALOG_NAME", cat);
303     rHash.put("CUBE_NAME", cube);
304
305     // properties
306
HashMap JavaDoc pHash = new HashMap JavaDoc();
307     pHash.put("DataSourceInfo", dataSource);
308     pHash.put("Catalog", cat); // neccessary ???
309
pHash.put("Content", "SchemaData");
310
311     Rowhandler rh = new Rowhandler() {
312       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
313         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_DIMENSION);
314         dims.add(oi);
315
316         Iterator JavaDoc it = eRow.getChildElements();
317         while (it.hasNext()) {
318           Object JavaDoc o = it.next();
319           if (!(o instanceof SOAPElement JavaDoc))
320             continue;
321           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
322
323           String JavaDoc lname = e.getElementName().getLocalName();
324           if (lname.equals("DIMENSION_UNIQUE_NAME")) {
325             oi.setUniqueName(e.getValue());
326           } else if (lname.equals("DIMENSION_CAPTION")) {
327             oi.setCaption(e.getValue());
328           } else if (lname.equals("DIMENSION_NAME")) {
329             oi.setName(e.getValue());
330           } else {
331             oi.setProperty(lname, e.getValue());
332           }
333
334         }
335       }
336
337     };
338
339     discover("MDSCHEMA_DIMENSIONS", url, rHash, pHash, rh);
340     logger.debug("MDSCHEMA_DIMENSIONS: found " + dims.size());
341     if (dims.size() == 0) {
342         throw new OlapException("No metadata schema dimensions for catalog: " + cat + " and cube: " + cube);
343     }
344     return dims;
345   }
346
347   /**
348    * retrieve hierarchies in data source
349    * @return List of OlapItems for the hierarchies
350    * @see DataSourceBrowser
351    */

352   public List JavaDoc discoverHier(String JavaDoc cat, String JavaDoc cube, String JavaDoc dimension) throws OlapException {
353     final List JavaDoc hiers = new ArrayList JavaDoc();
354
355     // restrictions
356
HashMap JavaDoc rHash = new HashMap JavaDoc();
357     rHash.put("CATALOG_NAME", cat);
358     rHash.put("CUBE_NAME", cube);
359     if (dimension != null)
360       rHash.put("DIMENSION_UNIQUE_NAME", dimension);
361
362     // properties
363
HashMap JavaDoc pHash = new HashMap JavaDoc();
364     pHash.put("DataSourceInfo", dataSource);
365     pHash.put("Catalog", cat); // neccessary ???
366
pHash.put("Content", "SchemaData");
367
368     Rowhandler rh = new Rowhandler() {
369       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
370         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_HIERARCHY);
371         hiers.add(oi);
372
373         Iterator JavaDoc it = eRow.getChildElements();
374         while (it.hasNext()) {
375           Object JavaDoc o = it.next();
376           if (!(o instanceof SOAPElement JavaDoc))
377             continue;
378           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
379           String JavaDoc lname = e.getElementName().getLocalName();
380           if (lname.equals("HIERARCHY_UNIQUE_NAME")) {
381             oi.setUniqueName(e.getValue());
382           } else if (lname.equals("HIERARCHY_CAPTION")) {
383             oi.setCaption(e.getValue());
384           } else if (lname.equals("HIERARCHY_NAME")) {
385             oi.setName(e.getValue());
386           } else {
387             oi.setProperty(lname, e.getValue());
388           }
389         }
390       }
391
392     };
393
394     discover("MDSCHEMA_HIERARCHIES", url, rHash, pHash, rh);
395     logger.debug("MDSCHEMA_HIERARCHIES: found " + hiers.size());
396     if (hiers.size() == 0) {
397         throw new OlapException("No metadata schema hierarchies for catalog: " + cat + " and cube: " + cube);
398     }
399     return hiers;
400   }
401
402   /**
403    * retrieve levels in data source
404    * @return List of OlapItems for the levels
405    * @see DataSourceBrowser
406    */

407   public List JavaDoc discoverLev(String JavaDoc cat, String JavaDoc cube, String JavaDoc dimension, String JavaDoc hier)
408       throws OlapException {
409
410     final List JavaDoc levels = new ArrayList JavaDoc();
411
412     // restrictions
413
HashMap JavaDoc rHash = new HashMap JavaDoc();
414     rHash.put("CATALOG_NAME", cat);
415     rHash.put("CUBE_NAME", cube);
416     if (dimension != null)
417       rHash.put("DIMENSION_UNIQUE_NAME", dimension);
418     if (hier != null)
419       rHash.put("HIERARCHY_UNIQUE_NAME", dimension);
420
421     // properties
422
HashMap JavaDoc pHash = new HashMap JavaDoc();
423     pHash.put("DataSourceInfo", dataSource);
424     pHash.put("Catalog", cat); // neccessary ???
425
pHash.put("Content", "SchemaData");
426
427     Rowhandler rh = new Rowhandler() {
428       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
429
430         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_LEVEL);
431         levels.add(oi);
432
433         Iterator JavaDoc it = eRow.getChildElements();
434         while (it.hasNext()) {
435           Object JavaDoc o = it.next();
436           if (!(o instanceof SOAPElement JavaDoc))
437             continue;
438           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
439
440           String JavaDoc lname = e.getElementName().getLocalName();
441           if (lname.equals("LEVEL_UNIQUE_NAME")) {
442             oi.setUniqueName(e.getValue());
443           } else if (lname.equals("LEVEL_CAPTION")) {
444             oi.setCaption(e.getValue());
445           } else if (lname.equals("LEVEL_NAME")) {
446             oi.setName(e.getValue());
447           } else {
448             oi.setProperty(lname, e.getValue());
449           }
450         }
451       }
452
453     };
454
455     discover("MDSCHEMA_LEVELS", url, rHash, pHash, rh);
456     logger.debug("MDSCHEMA_LEVELS: found " + levels.size());
457     if (levels.size() == 0) {
458         throw new OlapException("No metadata schema levels for catalog: " + cat + " and cube: " + cube);
459     }
460     return levels;
461   }
462
463   /**
464    * retrieve members in data source
465    * @return List of OlapItems for the members
466    * @see DataSourceBrowser
467    */

468   public List JavaDoc discoverMem(String JavaDoc cat, String JavaDoc cube, String JavaDoc dimension, String JavaDoc hierarchy, String JavaDoc level)
469       throws OlapException {
470     final List JavaDoc mems = new ArrayList JavaDoc();
471
472     // restrictions
473
HashMap JavaDoc rHash = new HashMap JavaDoc();
474     rHash.put("CATALOG_NAME", cat);
475     rHash.put("CUBE_NAME", cube);
476     if (dimension != null)
477       rHash.put("DIMENSION_UNIQUE_NAME", dimension);
478     if (hierarchy != null)
479       rHash.put("HIERARCHY_UNIQUE_NAME", hierarchy);
480     if (level != null)
481       rHash.put("LEVEL_UNIQUE_NAME", level);
482
483     // properties
484
HashMap JavaDoc pHash = new HashMap JavaDoc();
485     pHash.put("DataSourceInfo", dataSource);
486     pHash.put("Catalog", cat); // neccessary ???
487
pHash.put("Content", "SchemaData");
488
489     Rowhandler rh = new Rowhandler() {
490
491       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
492
493         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_MEMBER);
494         mems.add(oi);
495
496         Iterator JavaDoc it = eRow.getChildElements();
497         while (it.hasNext()) {
498           Object JavaDoc o = it.next();
499           if (!(o instanceof SOAPElement JavaDoc))
500             continue;
501           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
502
503           String JavaDoc lname = e.getElementName().getLocalName();
504           if (lname.equals("MEMBER_UNIQUE_NAME")) {
505             oi.setUniqueName(e.getValue());
506           } else if (lname.equals("MEMBER_CAPTION")) {
507             oi.setCaption(e.getValue());
508           } else if (lname.equals("MEMBER_NAME")) {
509             oi.setName(e.getValue());
510           } else {
511             oi.setProperty(lname, e.getValue());
512           }
513         }
514       }
515
516     };
517
518     discover("MDSCHEMA_MEMBERS", url, rHash, pHash, rh);
519     logger.debug("MDSCHEMA_MEMBERS: found " + mems.size());
520     if (mems.size() == 0) {
521         logger.error("No metadata schema members for catalog: " + cat + " and cube: " + cube);
522     }
523
524     return mems;
525   }
526
527   /**
528    * retrieve member tree in data source for given catalog, cube, member
529    * @param cat name of catalog
530    * @param cube name of cube
531    * @param member unique name of member
532    * @param treeop bit combination according to TREEOP specification
533    * MDTREEOP_CHILDREN = 1
534    * MDTREEOP_SIBLINGS = 2
535    * MDTREEOP_PARENT = 4
536    * MDTREEOP_SELF = 8
537    * MDTREEOP_DESCENDANTS = 16
538    * MDTREEOP_ANCESTORS = 32
539    * @return List of OlapItems for the members
540    * @throws OlapException
541    * @see com.tonbeller.jpivot.olap.model.OlapDiscoverer#discoverMemTree
542    */

543
544   public List JavaDoc discoverMemTree(String JavaDoc cat, String JavaDoc cube, String JavaDoc member, int treeop)
545       throws OlapException {
546     final List JavaDoc mems = new ArrayList JavaDoc();
547
548     // restrictions
549
HashMap JavaDoc rHash = new HashMap JavaDoc();
550     rHash.put("CATALOG_NAME", cat);
551     rHash.put("CUBE_NAME", cube);
552     rHash.put("MEMBER_UNIQUE_NAME", member);
553     rHash.put("TREE_OP", String.valueOf(treeop));
554
555     // properties
556
HashMap JavaDoc pHash = new HashMap JavaDoc();
557     pHash.put("DataSourceInfo", dataSource);
558     pHash.put("Catalog", cat); // neccessary ???
559
pHash.put("Content", "SchemaData");
560
561     Rowhandler rh = new Rowhandler() {
562
563       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
564
565         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_MEMBER);
566         mems.add(oi);
567
568         Iterator JavaDoc it = eRow.getChildElements();
569         while (it.hasNext()) {
570           Object JavaDoc o = it.next();
571           if (!(o instanceof SOAPElement JavaDoc))
572             continue;
573           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
574
575           String JavaDoc lname = e.getElementName().getLocalName();
576           if (lname.equals("MEMBER_UNIQUE_NAME")) {
577             oi.setUniqueName(e.getValue());
578           } else if (lname.equals("MEMBER_CAPTION")) {
579             oi.setCaption(e.getValue());
580           } else if (lname.equals("MEMBER_NAME")) {
581             oi.setName(e.getValue());
582           } else {
583             oi.setProperty(lname, e.getValue());
584           }
585         }
586       }
587
588     };
589
590     discover("MDSCHEMA_MEMBERS", url, rHash, pHash, rh);
591     logger.debug("MDSCHEMA_MEMBERS Tree: found " + mems.size());
592     if (mems.size() == 0) {
593         logger.error("No metadata schema members tree for catalog: " + cat + " and cube: " + cube +
594                 ", member unique name: " + member + ", tree operation: " + String.valueOf(treeop));
595     }
596     return mems;
597   }
598
599   /**
600    * retrieve data source properties
601    * @return Map of key/value strings
602    * @see DataSourceBrowser
603    */

604   public Map JavaDoc discoverDS() throws OlapException {
605     // Microsoft wants restrictions
606
HashMap JavaDoc rHash = new HashMap JavaDoc();
607
608     HashMap JavaDoc pHash = new HashMap JavaDoc();
609     pHash.put("Content", "Data");
610     final Map JavaDoc resultMap = new HashMap JavaDoc();
611     Rowhandler rh = new Rowhandler() {
612
613       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
614
615         /*
616          <row><DataSourceName>SAP_BW</DataSourceName>
617          <DataSourceDescription>SAP BW Release 3.0A XML f. Analysis Service</DataSourceDescription>
618          <URL>http://155.56.49.46:83/SAP/BW/XML/SOAP/XMLA</URL>
619          <DataSourceInfo>default</DataSourceInfo>
620          <ProviderName>SAP BW</ProviderName>
621          <ProviderType>MDP</ProviderType>
622          <AuthenticationMode>Integrated</AuthenticationMode></row>
623          */

624         Iterator JavaDoc it = eRow.getChildElements();
625         while (it.hasNext()) {
626           Object JavaDoc o = it.next();
627           if (!(o instanceof SOAPElement JavaDoc))
628             continue; //bypass text nodes
629
SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
630           String JavaDoc name = e.getElementName().getLocalName();
631           String JavaDoc value = e.getValue();
632           resultMap.put(name, value);
633         }
634       }
635     };
636
637     discover("DISCOVER_DATASOURCES", url, rHash, pHash, rh);
638     logger.debug("DISCOVER_DATASOURCES: found " + resultMap.size());
639     return resultMap;
640
641   }
642
643   /**
644    * retrieve member properties in data source for given catalog, cube, dimension, hierarchy, level
645    * @param cat name of catalog
646    * @param cube name of cube
647    * @param dimension unique name of dimension
648    * @param hierarchy unique name of hierarchy
649    * @param level unique name of level
650    * @return List of OlapItems for the members
651    * @throws OlapException
652    * @see com.tonbeller.jpivot.olap.model.OlapDiscoverer#discoverProp
653    */

654   public List JavaDoc discoverProp(String JavaDoc cat, String JavaDoc cube, String JavaDoc dimension, String JavaDoc hierarchy, String JavaDoc level)
655       throws OlapException {
656     final List JavaDoc props = new ArrayList JavaDoc();
657
658     // restrictions
659
HashMap JavaDoc rHash = new HashMap JavaDoc();
660     rHash.put("CATALOG_NAME", cat);
661     rHash.put("CUBE_NAME", cube);
662     if (dimension != null)
663       rHash.put("DIMENSION_UNIQUE_NAME", dimension);
664     if (hierarchy != null)
665       rHash.put("HIERARCHY_UNIQUE_NAME", hierarchy);
666     if (level != null)
667       rHash.put("LEVEL_UNIQUE_NAME", level);
668
669     // properties
670
HashMap JavaDoc pHash = new HashMap JavaDoc();
671     pHash.put("DataSourceInfo", dataSource);
672     pHash.put("Catalog", cat); // neccessary ???
673
pHash.put("Content", "SchemaData");
674
675     Rowhandler rh = new Rowhandler() {
676
677       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
678         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_PROPERTY);
679         props.add(oi);
680
681         Iterator JavaDoc it = eRow.getChildElements();
682         while (it.hasNext()) {
683           Object JavaDoc o = it.next();
684           if (!(o instanceof SOAPElement JavaDoc))
685             continue;
686           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
687
688           String JavaDoc lname = e.getElementName().getLocalName();
689           if (lname.equals("PROPERTY_NAME")) {
690             oi.setName(e.getValue());
691           } else if (lname.equals("PROPERTY_CAPTION")) {
692             oi.setCaption(e.getValue());
693           } else {
694             oi.setProperty(lname, e.getValue());
695           }
696         }
697
698       }
699     };
700
701     discover("MDSCHEMA_PROPERTIES", url, rHash, pHash, rh);
702     logger.debug("MDSCHEMA_PROPERTIES: found " + props.size());
703
704     return props;
705   }
706
707   /**
708    * retrieve SAP variables for given catalog, cube
709    * @param cat name of catalog
710    * @param cube name of cube
711    * @return List of OlapItems for the members
712    * @throws OlapException
713    * @see com.tonbeller.jpivot.olap.model.OlapDiscoverer#discoverProp
714    */

715   public List JavaDoc discoverSapVar(String JavaDoc cat, String JavaDoc cube) throws OlapException {
716     final List JavaDoc props = new ArrayList JavaDoc();
717
718     // restrictions
719
HashMap JavaDoc rHash = new HashMap JavaDoc();
720     rHash.put("CATALOG_NAME", cat);
721     rHash.put("CUBE_NAME", cube);
722
723     // properties
724
HashMap JavaDoc pHash = new HashMap JavaDoc();
725     pHash.put("DataSourceInfo", dataSource);
726     pHash.put("Catalog", cat); // neccessary ???
727
pHash.put("Content", "SchemaData");
728
729     Rowhandler rh = new Rowhandler() {
730
731       public void handleRow(SOAPElement JavaDoc eRow, SOAPEnvelope JavaDoc envelope) {
732         XMLA_OlapItem oi = new XMLA_OlapItem(OlapItem.TYPE_PROPERTY);
733         props.add(oi);
734
735         Iterator JavaDoc it = eRow.getChildElements();
736         while (it.hasNext()) {
737           Object JavaDoc o = it.next();
738           if (!(o instanceof SOAPElement JavaDoc))
739             continue;
740           SOAPElement JavaDoc e = (SOAPElement JavaDoc) o;
741
742           String JavaDoc lname = e.getElementName().getLocalName();
743           if (lname.equals("VARIABLE_NAME")) {
744             // ??? probably not supported
745
oi.setName(e.getValue());
746           } else if (lname.equals("VARIABLE_CAPTION")) { // ?? probably not supported
747
oi.setCaption(e.getValue());
748           } else {
749             oi.setProperty(lname, e.getValue());
750           }
751         }
752
753       }
754     };
755
756     discover("SAP_VARIABLES", url, rHash, pHash, rh);
757
758     return props;
759   }
760
761   /**
762    * Execute query
763    * @param query - MDX to be executed
764    * @param catalog
765    * @param handler Callback handler
766    * @throws OlapException
767    */

768   public void executeQuery(String JavaDoc query, String JavaDoc catalog, QueryResultHandler handler)
769       throws OlapException {
770
771     SOAPConnection JavaDoc connection = null;
772     SOAPMessage JavaDoc reply = null;
773
774     try {
775       connection = scf.createConnection();
776       SOAPMessage JavaDoc msg = mf.createMessage();
777
778       MimeHeaders JavaDoc mh = msg.getMimeHeaders();
779       mh.setHeader("SOAPAction", "\"urn:schemas-microsoft-com:xml-analysis:Execute\"");
780
781       SOAPPart JavaDoc soapPart = msg.getSOAPPart();
782       SOAPEnvelope JavaDoc envelope = soapPart.getEnvelope();
783       SOAPBody JavaDoc body = envelope.getBody();
784       Name JavaDoc nEx = envelope.createName("Execute", "", XMLA_URI);
785
786       SOAPElement JavaDoc eEx = body.addChildElement(nEx);
787
788       // add the parameters
789

790       // COMMAND parameter
791
// <Command>
792
// <Statement>select [Measures].members on Columns from Sales</Statement>
793
// </Command>
794
Name JavaDoc nCom = envelope.createName("Command", "", XMLA_URI);
795       SOAPElement JavaDoc eCommand = eEx.addChildElement(nCom);
796       Name JavaDoc nSta = envelope.createName("Statement", "", XMLA_URI);
797       SOAPElement JavaDoc eStatement = eCommand.addChildElement(nSta);
798       eStatement.addTextNode(query);
799
800       // <Properties>
801
// <PropertyList>
802
// <DataSourceInfo>Provider=MSOLAP;Data Source=local</DataSourceInfo>
803
// <Catalog>Foodmart 2000</Catalog>
804
// <Format>Multidimensional</Format>
805
// <AxisFormat>TupleFormat</AxisFormat> oder "ClusterFormat"
806
// </PropertyList>
807
// </Properties>
808
Map JavaDoc paraList = new HashMap JavaDoc();
809       paraList.put("DataSourceInfo", dataSource);
810       paraList.put("Catalog", catalog);
811       paraList.put("Format", "Multidimensional");
812       paraList.put("AxisFormat", "TupleFormat");
813       addParameterList(envelope, eEx, "Properties", "PropertyList", paraList);
814       msg.saveChanges();
815
816       // run the call
817
reply = connection.call(msg, url);
818       if (logger.isDebugEnabled()) {
819         logger.debug("Reply from Execute");
820         //reply.getSOAPPart().getContent().
821
logSoapMsg(reply);
822       }
823
824       // error check
825
errorCheck(reply);
826       // process the reply
827

828       SOAPElement JavaDoc eRoot = findExecRoot(reply);
829
830       // determine axes from <OlapInfo><AxesInfo><AxisInfo>
831
Name JavaDoc name = envelope.createName("OlapInfo", "", MDD_URI);
832       SOAPElement JavaDoc eOlapInfo = selectSingleNode(eRoot, name);
833       if (eOlapInfo == null)
834         throw new OlapException("Excecute result has no eOlapInfo element");
835
836       name = envelope.createName("AxesInfo", "", MDD_URI);
837       SOAPElement JavaDoc eAxesInfo = selectSingleNode(eOlapInfo, name);
838       if (eAxesInfo == null)
839         throw new OlapException("Excecute result has no AxesInfo element");
840
841       name = envelope.createName("AxisInfo", "", MDD_URI);
842       Iterator JavaDoc itAxisInfo = eAxesInfo.getChildElements(name);
843
844       int iOrdinal = 0;
845       AxisInfoLoop: while (itAxisInfo.hasNext()) {
846         SOAPElement JavaDoc eAxisInfo = (SOAPElement JavaDoc) itAxisInfo.next();
847
848         name = envelope.createName("name");
849         String JavaDoc axisName = eAxisInfo.getAttributeValue(name);
850         int axisOrdinal;
851         if (axisName.equals("SlicerAxis"))
852           axisOrdinal = -1;
853         else
854           axisOrdinal = iOrdinal++;
855
856         handler.handleAxisInfo(axisName, axisOrdinal);
857
858         // retrieve the hierarchies by <HierarchyInfo>
859
name = envelope.createName("HierarchyInfo", "", MDD_URI);
860         Iterator JavaDoc itHierInfo = eAxisInfo.getChildElements(name);
861
862         int hierNumber = 0;
863         HierInfoLoop: while (itHierInfo.hasNext()) {
864           SOAPElement JavaDoc eHierInfo = (SOAPElement JavaDoc) itHierInfo.next();
865           name = envelope.createName("name");
866           String JavaDoc hierName = eHierInfo.getAttributeValue(name);
867           handler.handleHierInfo(hierName, axisOrdinal, hierNumber++);
868         } // HierInfoLoop
869

870       } // AxisInfoLoop
871

872       // for each axis, get the positions (tuples)
873
name = envelope.createName("Axes", "", MDD_URI);
874       SOAPElement JavaDoc eAxes = selectSingleNode(eRoot, name);
875       if (eAxes == null)
876         throw new OlapException("Excecute result has no Axes element");
877
878       name = envelope.createName("Axis", "", MDD_URI);
879       Iterator JavaDoc itAxis = eAxes.getChildElements(name);
880
881       AxisLoop: for (iOrdinal = 0; itAxis.hasNext();) {
882         SOAPElement JavaDoc eAxis = (SOAPElement JavaDoc) itAxis.next();
883         name = envelope.createName("name");
884         String JavaDoc axisName = eAxis.getAttributeValue(name);
885         int axisOrdinal;
886         if (axisName.equals("SlicerAxis"))
887           axisOrdinal = -1;
888         else
889           axisOrdinal = iOrdinal++;
890
891         handler.handleAxis(axisName, axisOrdinal);
892
893         name = envelope.createName("Tuples", "", MDD_URI);
894         SOAPElement JavaDoc eTuples = selectSingleNode(eAxis, name);
895         if (eTuples == null)
896           continue AxisLoop; // what else?
897

898         name = envelope.createName("Tuple", "", MDD_URI);
899         Iterator JavaDoc itTuple = eTuples.getChildElements(name);
900
901         // loop over tuples
902
int positionOrdinal = 0;
903         TupleLoop: while (itTuple.hasNext()) {
904           SOAPElement JavaDoc eTuple = (SOAPElement JavaDoc) itTuple.next();
905           handler.handleTuple(axisOrdinal, positionOrdinal);
906
907           // loop over members
908
//XMLA_Member[] posMembers = new XMLA_Member[axis.getNHier()];
909

910           int index = 0;
911           name = envelope.createName("Member", "", MDD_URI);
912           Iterator JavaDoc itMember = eTuple.getChildElements(name);
913           MemberLoop: while (itMember.hasNext()) {
914             SOAPElement JavaDoc eMem = (SOAPElement JavaDoc) itMember.next();
915             // loop over children nodes
916
String JavaDoc uName = null;
917             String JavaDoc caption = null;
918             String JavaDoc levUname = null;
919             String JavaDoc displayInfo = null;
920             Iterator JavaDoc it = eMem.getChildElements();
921             Map JavaDoc otherProps = new HashMap JavaDoc();
922             InnerLoop: while (it.hasNext()) {
923               Node JavaDoc n = (Node JavaDoc) it.next();
924               if (!(n instanceof SOAPElement JavaDoc))
925                 continue InnerLoop;
926               SOAPElement JavaDoc el = (SOAPElement JavaDoc) n;
927               String JavaDoc enam = el.getElementName().getLocalName();
928               if (enam.equals("UName"))
929                 uName = el.getValue();
930               else if (enam.equals("Caption"))
931                 caption = el.getValue();
932               else if (enam.equals("LName"))
933                 levUname = el.getValue();
934               else if (enam.equals("DisplayInfo"))
935                 displayInfo = el.getValue();
936               else
937                 otherProps.put(enam, el.getValue());
938             }
939             handler.handleMember(uName, caption, levUname, displayInfo, otherProps, axisOrdinal,
940                 positionOrdinal, index);
941             ++index;
942           } //MemberLoop
943

944           ++positionOrdinal;
945         } // TupleLoop
946
} // AxisLoop
947

948       // loop over cells in result set
949
name = envelope.createName("CellData", "", MDD_URI);
950       SOAPElement JavaDoc eCellData = selectSingleNode(eRoot, name);
951       handler.handleCellData(); // start cell loop
952
name = envelope.createName("Cell", "", MDD_URI);
953       Iterator JavaDoc itSoapCell = eCellData.getChildElements(name);
954       CellLoop: while (itSoapCell.hasNext()) {
955         SOAPElement JavaDoc eCell = (SOAPElement JavaDoc) itSoapCell.next();
956         name = envelope.createName("CellOrdinal", "", "");
957         String JavaDoc cellOrdinal = eCell.getAttributeValue(name);
958         int ordinal = Integer.parseInt(cellOrdinal);
959         name = envelope.createName("Value", "", MDD_URI);
960         SOAPElement JavaDoc eValue = selectSingleNode(eCell, name);
961         Object JavaDoc value = null;
962         if (eValue != null) {
963           name = envelope.createName("type", "xsi", XSI_URI);
964           String JavaDoc type = eValue.getAttributeValue(name);
965           /*
966            if ( type == null) {
967            // probably Error
968            String eCode = "unknown";
969            String eDescription = "unknown";
970            name = envelope.createName("Error", "", MDD_URI);
971            SOAPElement eError = selectSingleNode(eValue, name);
972            if (eError != null) {
973            name = envelope.createName("ErrorCode", "", MDD_URI);
974            SOAPElement eErrorCode = selectSingleNode(eError, name);
975            if (eErrorCode != null) {
976            eCode = eErrorCode.getValue();
977            }
978            name = envelope.createName("Description", "", MDD_URI);
979            SOAPElement eErrorDesc = selectSingleNode(eError, name);
980            if (eErrorDesc != null) {
981            eDescription = eErrorDesc.getValue();
982            }
983            }
984            throw new OlapException("Error reading Cell: Error Code = " + eCode +
985            " Description = " + eDescription);
986            }
987            */

988           if ("xsd:int".equals(type)) {
989             // value = new Integer(eValue.getValue()); //EGO crash too long
990
value = new Long JavaDoc(eValue.getValue());
991           } else if ("xsd:double".equals(type)) {
992             value = new Double JavaDoc(eValue.getValue());
993           } else if("xsd:decimal".equals(type)) {
994               value=new Double JavaDoc(eValue.getValue());
995           } else {
996             value = eValue.getValue();
997           }
998         }
999         name = envelope.createName("FmtValue", "", MDD_URI);
1000        SOAPElement JavaDoc eFmtValue = selectSingleNode(eCell, name);
1001        String JavaDoc fmtValue;
1002        if (eFmtValue != null)
1003          fmtValue = eFmtValue.getValue();
1004        else
1005          fmtValue = "";
1006
1007        name = envelope.createName("FontSize", "", MDD_URI);
1008        SOAPElement JavaDoc eFontSize = selectSingleNode(eCell, name);
1009        String JavaDoc fontSize = null;
1010        if (eFontSize != null)
1011          fontSize = eFontSize.getValue();
1012
1013        handler.handleCell(ordinal, value, fmtValue, fontSize);
1014
1015      } // CellLoop
1016

1017    } catch (SOAPException JavaDoc se) {
1018      throw new OlapException(se);
1019    } finally {
1020      if (connection != null)
1021        try {
1022          connection.close();
1023        } catch (SOAPException JavaDoc e) {
1024          // log and ignore
1025
logger.error("?", e);
1026        }
1027    }
1028
1029  }
1030
1031  // dsf
1032
public void executeDrillQuery(String JavaDoc query, String JavaDoc catalog, QueryResultHandler handler)
1033  throws OlapException {
1034
1035  SOAPConnection JavaDoc connection = null;
1036  SOAPMessage JavaDoc reply = null;
1037
1038  try {
1039    connection = scf.createConnection();
1040    SOAPMessage JavaDoc msg = mf.createMessage();
1041
1042    MimeHeaders JavaDoc mh = msg.getMimeHeaders();
1043    mh.setHeader("SOAPAction", "\"urn:schemas-microsoft-com:xml-analysis:Execute\"");
1044
1045    SOAPPart JavaDoc soapPart = msg.getSOAPPart();
1046    SOAPEnvelope JavaDoc envelope = soapPart.getEnvelope();
1047    SOAPBody JavaDoc body = envelope.getBody();
1048    Name JavaDoc nEx = envelope.createName("Execute", "", XMLA_URI);
1049
1050    SOAPElement JavaDoc eEx = body.addChildElement(nEx);
1051
1052    // add the parameters
1053

1054    // COMMAND parameter
1055
// <Command>
1056
// <Statement>select [Measures].members on Columns from Sales</Statement>
1057
// </Command>
1058
Name JavaDoc nCom = envelope.createName("Command");
1059    SOAPElement JavaDoc eCommand = eEx.addChildElement(nCom);
1060    Name JavaDoc nSta = envelope.createName("Statement");
1061    SOAPElement JavaDoc eStatement = eCommand.addChildElement(nSta);
1062    eStatement.addTextNode(query);
1063
1064    Map JavaDoc paraList = new HashMap JavaDoc();
1065    paraList.put("DataSourceInfo", dataSource);
1066    paraList.put("Catalog", catalog);
1067    //dsf : Note the use of tabular format instead of multidimensional. This is crucial
1068
// otherwise the drillthrough will fail
1069
paraList.put("Format", "Tabular");
1070    addParameterList(envelope, eEx, "Properties", "PropertyList", paraList);
1071    msg.saveChanges();
1072  
1073    reply = connection.call(msg, url);
1074    if (logger.isDebugEnabled()) {
1075      logger.debug("Reply from Execute");
1076      //reply.getSOAPPart().getContent().
1077
logSoapMsg(reply);
1078    }
1079
1080    // error check
1081
errorCheck(reply);
1082    // process the reply
1083

1084    SOAPElement JavaDoc eRoot = findDrillExecRoot(reply);
1085   
1086    // first the column headers
1087
// Note the use of Hashmap for the column names. This is because
1088
// the reponse message can return variable number of data columns depending on whether
1089
// the column data value is null. The hash map is used to store the column name and the
1090
// column position so that when we do the rendering we can map the data to its appropriate column header.
1091

1092    Name JavaDoc name = envelope.createName("row", "", ROWS_URI);
1093    SOAPElement JavaDoc columnHeader = selectSingleNode(eRoot, name);
1094    if (columnHeader == null)
1095      throw new OlapException("Excecute result has no rows element");
1096    
1097    Map JavaDoc colNames = new HashMap JavaDoc();
1098    Iterator JavaDoc columnHeaderIt = columnHeader.getChildElements();
1099    int colIdx = 0;
1100    RowHeadLoop : while (columnHeaderIt.hasNext()) {
1101        Object JavaDoc columnHeaderObj = columnHeaderIt.next();
1102        if (columnHeaderObj instanceof SOAPElement JavaDoc) {
1103            String JavaDoc colName = ((SOAPElement JavaDoc)columnHeaderObj).getElementName().getLocalName();
1104            colNames.put(colName,new Integer JavaDoc(colIdx));
1105            colIdx++;
1106        }
1107    }
1108
1109// handler.setDrillHeader(colNames);
1110

1111
1112    // extract the data for each row
1113

1114    ArrayList JavaDoc drillRows = new ArrayList JavaDoc();
1115    name = envelope.createName("row", "", ROWS_URI);
1116    Iterator JavaDoc rowIt = eRoot.getChildElements(name);
1117    while (rowIt.hasNext()) {
1118        SOAPElement JavaDoc rowElement = (SOAPElement JavaDoc) rowIt.next();
1119
1120        // process the column in each row
1121
Iterator JavaDoc rowDataIt = rowElement.getChildElements();
1122        javax.xml.soap.Text JavaDoc child = (javax.xml.soap.Text JavaDoc)rowDataIt.next();
1123        SOAPElement JavaDoc columnElement = child.getParentElement();
1124        Iterator JavaDoc columnIterator = columnElement.getChildElements();
1125
1126        Map JavaDoc dataRow = new HashMap JavaDoc();
1127        while (columnIterator.hasNext()) {
1128        Object JavaDoc colObject = columnIterator.next();
1129        if (colObject instanceof SOAPElement JavaDoc) {
1130            String JavaDoc colName = ((SOAPElement JavaDoc)colObject).getElementName().getLocalName();
1131            if (!colNames.containsKey(colName)) {
1132                colNames.put(colName,new Integer JavaDoc(colIdx));
1133                colIdx++;
1134            }
1135            String JavaDoc colValue = ((SOAPElement JavaDoc)colObject).getValue();
1136            dataRow.put(colName, colValue );
1137        }
1138        }
1139        drillRows.add(dataRow);
1140    }
1141
1142    handler.setDrillHeader(colNames);
1143    handler.setDrillRows(drillRows);
1144
1145  
1146  } catch (SOAPException JavaDoc se) {
1147    throw new OlapException(se);
1148  } finally {
1149    if (connection != null)
1150      try {
1151        connection.close();
1152      } catch (SOAPException JavaDoc e) {
1153        // log and ignore
1154
logger.error("?", e);
1155      }
1156  }
1157
1158}
1159  
1160  
1161  /**
1162   * @return provider (Microsoft/SAP/Mondrian)
1163   */

1164  public int getProvider() {
1165    return provider;
1166  }
1167  
1168  /**
1169   * Get provider id from String
1170   *
1171   * @param dataSourceString
1172   * @return provider id from OlapDiscoverer
1173   * @throws OlapException
1174   */

1175  private int determineProvider(String JavaDoc dataSourceString) throws OlapException {
1176    logger.debug("determineProvider from dataSourceString: " + dataSourceString);
1177    if (dataSourceString == null) {
1178      throw new OlapException("No data source given for determining XML/A OLAP provider");
1179    }
1180
1181    String JavaDoc upperDSString = dataSourceString.toUpperCase();
1182    if (!upperDSString.startsWith("PROVIDER=")) {
1183        throw new OlapException("Malformed data source given for determining XML/A provider");
1184    }
1185    
1186    if (upperDSString.startsWith("PROVIDER=SAP")) {
1187      logger.debug("Provider is SAP");
1188      return OlapDiscoverer.PROVIDER_SAP;
1189    } else if (upperDSString.startsWith("PROVIDER=MONDRIAN")) {
1190      logger.debug("Provider is Mondrian");
1191      return OlapDiscoverer.PROVIDER_MONDRIAN;
1192    } else if (upperDSString.startsWith("PROVIDER=MS")) {//not sure if this is needed?
1193
logger.debug("Provider is Microsoft");
1194      return OlapDiscoverer.PROVIDER_MICROSOFT;
1195    } else if (upperDSString.startsWith("PROVIDER=MICROSOFT")) {// return value from MSAS: "Microsoft XML for Analysis"
1196
logger.debug("Provider is Microsoft");
1197        return OlapDiscoverer.PROVIDER_MICROSOFT; //
1198
} else {
1199      logger.error("Error determining provider from: " + dataSourceString);
1200      throw new OlapException("Unexpected data source determining XML/A provider");
1201    }
1202
1203  }
1204
1205  /** Set provider and dataSource from result of discoverDS
1206   *
1207   * @param resMap
1208   * @throws OlapException
1209   */

1210  private void setProviderAndDataSource(Map JavaDoc resMap) throws OlapException {
1211    if (resMap == null || resMap.size() == 0) {
1212      logger.error("No resource map from Discover Datasource");
1213      throw new OlapException("No resource map from Discover Datasource");
1214    }
1215    
1216    String JavaDoc pstr = (String JavaDoc) resMap.get("ProviderName");
1217      
1218    //if (provider == 0) {
1219
//logger.debug("Provider was 0");
1220
// Check other providers
1221
if (pstr == null)
1222        throw new OlapException("No ProviderName from Discover Datasource");
1223      
1224      provider = determineProvider("Provider=" + pstr);
1225    //}
1226

1227    logger.debug("Provider ID: " + provider);
1228
1229    if (provider == OlapDiscoverer.PROVIDER_SAP) {
1230        String JavaDoc dstr = (String JavaDoc) resMap.get("DataSourceDescription");
1231        if (dstr == null) {
1232          throw new OlapException("No DataSourceDescription from Discover Datasource");
1233        }
1234        dataSource = "Provider=" + pstr + ";DataSource=" + dstr;
1235    } else {
1236        logger.debug("DataSourceName: " + String.valueOf(resMap.get("DataSourceName")));
1237        logger.debug("DataSourceInfo: " + String.valueOf(resMap.get("DataSourceInfo")));
1238
1239        // sql2000 (type1 - unsure which versions): DataSourceName=Local Analysis Server, DataSourceInfo=Provider=MSOLAP...
1240
// sql2000 (others): DataSourceName=Local Analysis Server, DataSourceInfo=Local Analysis Server
1241
// sql2005 (some versions): DataSourceName=instancename, DataSourceInfo=NULL
1242
dataSource = (String JavaDoc) resMap.get("DataSourceInfo");
1243
1244        if (dataSource == null || dataSource.length() < 1) {
1245            dataSource = (String JavaDoc) resMap.get("DataSourceName");
1246        }
1247
1248        if (dataSource == null) {
1249          throw new OlapException("No DataSourceName from Discover Datasource");
1250        }
1251    }
1252    logger.debug("Discover Datasource set: " + dataSource);
1253
1254  }
1255  
1256  /**
1257   * Find the Provider type in the DiscoverResponse
1258   *
1259   * @param n
1260   * @return
1261   * @throws OlapException
1262 * @throws SOAPException
1263   */

1264  private int getProviderFromDiscoverResponse(SOAPEnvelope JavaDoc envelope, SOAPElement JavaDoc e) throws OlapException, SOAPException JavaDoc {
1265      Name JavaDoc name = ((SOAPElement JavaDoc) e).getElementName();
1266      if (!name.getLocalName().equals("DiscoverResponse")) {
1267          throw new OlapException("Not a DiscoverResponse element. Was: " + name.getLocalName());
1268      }
1269      
1270      // Look for return/root/row/ProviderName
1271

1272      SOAPElement JavaDoc walker = getDiscoverReturn(envelope, e);
1273      
1274      if (walker == null) {
1275          throw new OlapException("Discover result has no DiscoverResponse/return element");
1276      }
1277      
1278      walker = getDiscoverRoot(envelope, walker);
1279      
1280      if (walker == null) {
1281          throw new OlapException("Discover result has no DiscoverResponse/return/root element");
1282      }
1283      
1284      walker = getDiscoverRow(envelope, walker);
1285      
1286      if (walker == null) {
1287          throw new OlapException("Discover result has no DiscoverResponse/return/root/row element");
1288      }
1289
1290/* Name nProviderName = envelope.createName("ProviderName", "", ROWS_URI);
1291      SOAPElement eProviderName = selectSingleNode(e, nProviderName);
1292      
1293      if (eProviderName == null) {
1294          throw new OlapException("Discover result has no DiscoverResponse/return/root/row/ProviderName element");
1295      }
1296      value = eProviderName.getValue();
1297*/

1298      String JavaDoc value = null;
1299      Iterator JavaDoc it = walker.getChildElements();
1300      while (it.hasNext()) {
1301        Object JavaDoc o = it.next();
1302        if (!(o instanceof SOAPElement JavaDoc))
1303          continue; //bypass text nodes
1304
SOAPElement JavaDoc e2 = (SOAPElement JavaDoc) o;
1305        String JavaDoc nameString = e2.getElementName().getLocalName();
1306        if (nameString.equals("ProviderName")) {
1307            value = e2.getValue();
1308            logger.debug("Found ProviderName with value: " + value);
1309            break;
1310        }
1311      }
1312      
1313      if (value == null || value.trim().length() == 0) {
1314          throw new OlapException("Discover result has empty DiscoverResponse/return/root/row/ProviderName element");
1315      }
1316
1317      return determineProvider("Provider=" + value);
1318  }
1319  
1320  private SOAPElement JavaDoc getDiscoverReturn(SOAPEnvelope JavaDoc envelope, SOAPElement JavaDoc e) throws OlapException, SOAPException JavaDoc {
1321
1322      Name JavaDoc nReturn;
1323      if (provider == PROVIDER_MICROSOFT) {
1324        nReturn = envelope.createName("return", "m", XMLA_URI); // Microsoft
1325
} else {
1326        nReturn = envelope.createName("return", "", XMLA_URI); // SAP or Mondrian
1327
}
1328      SOAPElement JavaDoc eReturn = selectSingleNode(e, nReturn);
1329      if (eReturn == null) {
1330        // old Microsoft XMLA SDK 1.0 does not have "m" prefix - try
1331
nReturn = envelope.createName("return", "", ""); // old Microsoft
1332
eReturn = selectSingleNode(e, nReturn);
1333        if (eReturn == null)
1334          throw new OlapException("Discover result has no return element");
1335      }
1336      return eReturn;
1337  }
1338  
1339  private SOAPElement JavaDoc getDiscoverRoot(SOAPEnvelope JavaDoc envelope, SOAPElement JavaDoc e) throws OlapException, SOAPException JavaDoc {
1340
1341      Name JavaDoc nRoot = envelope.createName("root", "", ROWS_URI);
1342      SOAPElement JavaDoc eRoot = selectSingleNode(e, nRoot);
1343      if (eRoot == null) { throw new OlapException("Discover result has no root element"); }
1344      return eRoot;
1345
1346  }
1347  
1348  private SOAPElement JavaDoc getDiscoverRow(SOAPEnvelope JavaDoc envelope, SOAPElement JavaDoc e) throws OlapException, SOAPException JavaDoc {
1349
1350      Name JavaDoc nRow = envelope.createName("row", "", ROWS_URI);
1351      SOAPElement JavaDoc eRow = selectSingleNode(e, nRow);
1352      if (eRow == null) { throw new OlapException("Discover result has no row element"); }
1353      return eRow;
1354
1355  }
1356  
1357  /**
1358   * discover
1359   * @param request
1360   * @param url
1361   * @param restrictions
1362   * @param properties
1363   * @param rh
1364   * @throws OlapException
1365   */

1366  private void discover(String JavaDoc request, URL JavaDoc url, Map JavaDoc restrictions, Map JavaDoc properties, Rowhandler rh)
1367      throws OlapException {
1368
1369    try {
1370      SOAPConnection JavaDoc connection = scf.createConnection();
1371
1372      SOAPMessage JavaDoc msg = mf.createMessage();
1373
1374      MimeHeaders JavaDoc mh = msg.getMimeHeaders();
1375      mh.setHeader("SOAPAction", "\"urn:schemas-microsoft-com:xml-analysis:Discover\"");
1376
1377      SOAPPart JavaDoc soapPart = msg.getSOAPPart();
1378      SOAPEnvelope JavaDoc envelope = soapPart.getEnvelope();
1379      SOAPBody JavaDoc body = envelope.getBody();
1380      Name JavaDoc nDiscover = envelope
1381          .createName("Discover", "", XMLA_URI);
1382
1383      SOAPElement JavaDoc eDiscover = body.addChildElement(nDiscover);
1384
1385      Name JavaDoc nPara = envelope.createName("RequestType", "", XMLA_URI);
1386      SOAPElement JavaDoc eRequestType = eDiscover.addChildElement(nPara);
1387      eRequestType.addTextNode(request);
1388
1389      // add the parameters
1390
if (restrictions != null)
1391        addParameterList(envelope, eDiscover, "Restrictions", "RestrictionList", restrictions);
1392      addParameterList(envelope, eDiscover, "Properties", "PropertyList", properties);
1393
1394      msg.saveChanges();
1395
1396      if (logger.isDebugEnabled()) {
1397        logger.debug("Discover Request for " + request);
1398        logSoapMsg(msg);
1399      }
1400
1401      // run the call
1402
SOAPMessage JavaDoc reply = connection.call(msg, url);
1403
1404      if (logger.isDebugEnabled()) {
1405        logger.debug("Discover Response for " + request);
1406        logSoapMsg(reply);
1407      }
1408
1409      errorCheck(reply);
1410
1411      SOAPElement JavaDoc eRoot = findDiscoverRoot(reply);
1412
1413      Name JavaDoc nRow = envelope.createName("row", "", ROWS_URI); // SAP
1414
Iterator JavaDoc itRow = eRoot.getChildElements(nRow);
1415      RowLoop: while (itRow.hasNext()) {
1416
1417        SOAPElement JavaDoc eRow = (SOAPElement JavaDoc) itRow.next();
1418        rh.handleRow(eRow, envelope);
1419
1420      } // RowLoop
1421

1422      connection.close();
1423    } catch (UnsupportedOperationException JavaDoc e) {
1424      throw new OlapException(e);
1425    } catch (SOAPException JavaDoc e) {
1426      throw new OlapException(e);
1427    }
1428
1429  }
1430
1431  /**
1432   * add a list of Restrictions/Properties ...
1433   */

1434  private void addParameterList(SOAPEnvelope JavaDoc envelope, SOAPElement JavaDoc eParent, String JavaDoc typeName,
1435      String JavaDoc listName, Map JavaDoc params) throws SOAPException JavaDoc {
1436    Name JavaDoc nPara = envelope.createName(typeName, "", XMLA_URI);
1437    SOAPElement JavaDoc eType = eParent.addChildElement(nPara);
1438    nPara = envelope.createName(listName, "", XMLA_URI);
1439    SOAPElement JavaDoc eList = eType.addChildElement(nPara);
1440    if (params == null)
1441      return;
1442    Iterator JavaDoc it = params.keySet().iterator();
1443    while (it.hasNext()) {
1444      String JavaDoc tag = (String JavaDoc) it.next();
1445      String JavaDoc value = (String JavaDoc) params.get(tag);
1446      nPara = envelope.createName(tag, "", XMLA_URI);
1447      SOAPElement JavaDoc eTag = eList.addChildElement(nPara);
1448      eTag.addTextNode(value);
1449    }
1450  }
1451
1452  // error check
1453
private void errorCheck(SOAPMessage JavaDoc reply) throws SOAPException JavaDoc, OlapException {
1454    String JavaDoc[] strings = new String JavaDoc[4];
1455    if (soapFault(reply, strings)) {
1456      String JavaDoc faultString = "Soap Fault code=" + strings[0] + " fault string=" + strings[1]
1457          + " fault actor=" + strings[2];
1458      if (strings[3] != null)
1459        faultString += "\ndetail:" + strings[3];
1460      throw new OlapException(faultString);
1461    }
1462  }
1463
1464  /**
1465   * @param contextNode
1466   * @param childPath
1467   * @return
1468   */

1469  private SOAPElement JavaDoc selectSingleNode(SOAPElement JavaDoc contextNode, Name JavaDoc childName) {
1470
1471    Iterator JavaDoc it = contextNode.getChildElements(childName);
1472    if (it.hasNext())
1473      return (SOAPElement JavaDoc) it.next();
1474    else
1475      return null;
1476  }
1477
1478  /**
1479   * locate "root" in DisoverResponse
1480   */

1481  private SOAPElement JavaDoc findDiscoverRoot(SOAPMessage JavaDoc reply) throws SOAPException JavaDoc, OlapException {
1482
1483    SOAPPart JavaDoc sp = reply.getSOAPPart();
1484    SOAPEnvelope JavaDoc envelope = sp.getEnvelope();
1485    SOAPBody JavaDoc body = envelope.getBody();
1486    Name JavaDoc childName;
1487    SOAPElement JavaDoc eResponse = null;
1488    if (provider == 0) {
1489      // unknown provider - recognize by prefix of DiscoverResponse
1490
Iterator JavaDoc itBody = body.getChildElements();
1491      while (itBody.hasNext()) {
1492        Node JavaDoc n = (Node JavaDoc) itBody.next();
1493        if (!(n instanceof SOAPElement JavaDoc))
1494          continue;
1495        Name JavaDoc name = ((SOAPElement JavaDoc) n).getElementName();
1496        if (name.getLocalName().equals("DiscoverResponse")) {
1497          eResponse = (SOAPElement JavaDoc) n;
1498          provider = getProviderFromDiscoverResponse(envelope, eResponse);
1499/* if ("m".equals(name.getPrefix()))
1500            provider = PROVIDER_MICROSOFT;
1501          // Microsoft has prefix "m"
1502          else
1503            provider = PROVIDER_SAP; // SAP has no prefix
1504*/
break;
1505        }
1506      }
1507      if (eResponse == null) {
1508          throw new OlapException("Discover result has no DiscoverResponse element");
1509      }
1510
1511    } else {
1512      if (provider == PROVIDER_MICROSOFT) {
1513        // Microsoft
1514
childName = envelope.createName("DiscoverResponse", "m", XMLA_URI);
1515      } else if (provider == PROVIDER_SAP || provider == PROVIDER_MONDRIAN) {
1516          // SAP or Mondrian
1517
childName = envelope.createName("DiscoverResponse", "", XMLA_URI);
1518      } else {
1519          throw new IllegalArgumentException JavaDoc("no a valid provider specification");
1520      }
1521      eResponse = selectSingleNode(body, childName);
1522      if (eResponse == null) {
1523          throw new OlapException("Discover result has no DiscoverResponse element");
1524      }
1525    }
1526
1527    SOAPElement JavaDoc eReturn = getDiscoverReturn(envelope, eResponse);
1528    if (eReturn == null)
1529      throw new OlapException("Discover result has no return element");
1530
1531    SOAPElement JavaDoc eRoot = getDiscoverRoot(envelope, eReturn);
1532    if (eRoot == null)
1533      throw new OlapException("Discover result has no root element");
1534    return eRoot;
1535  }
1536
1537  /**
1538   * log the reply message
1539   */

1540  private void logSoapMsg(SOAPMessage JavaDoc msg) {
1541
1542    /*
1543     OutputStream os = null;
1544     try {
1545     os = new FileOutputStream("c:\\x\\SoapReturn.txt", true);
1546     } catch (FileNotFoundException e1) {
1547     e1.printStackTrace();
1548     }
1549     try {
1550     msg.writeTo(os);
1551     } catch (SOAPException e2) {
1552     e2.printStackTrace();
1553     } catch (IOException e2) {
1554     e2.printStackTrace();
1555     }
1556     */

1557    // Document source, do a transform.
1558
try {
1559      Writer JavaDoc writer = new StringWriter JavaDoc();
1560      TransformerFactory JavaDoc tFact = TransformerFactory.newInstance();
1561      Transformer JavaDoc transformer = tFact.newTransformer();
1562      Source JavaDoc src = msg.getSOAPPart().getContent();
1563      StreamResult JavaDoc result = new StreamResult JavaDoc(writer);
1564      transformer.transform(src, result);
1565      logger.debug(writer.toString());
1566    } catch (Exception JavaDoc e) {
1567      // no big problen - just for debugging
1568
logger.error("?", e);
1569    }
1570  }
1571
1572  /**
1573   * check SOAP reply for Error, return fault Code
1574   * @param reply the message to check
1575   * @param aReturn ArrayList containing faultcode,faultstring,faultactor
1576   */

1577  private boolean soapFault(SOAPMessage JavaDoc reply, String JavaDoc[] faults) throws SOAPException JavaDoc {
1578    SOAPPart JavaDoc sp = reply.getSOAPPart();
1579    SOAPEnvelope JavaDoc envelope = sp.getEnvelope();
1580    SOAPBody JavaDoc body = envelope.getBody();
1581    if (!body.hasFault())
1582      return false;
1583    SOAPFault JavaDoc fault = body.getFault();
1584
1585    faults[0] = fault.getFaultCode();
1586    faults[1] = fault.getFaultString();
1587    faults[2] = fault.getFaultActor();
1588
1589    //probably not neccessary with Microsoft;
1590
Detail JavaDoc detail = fault.getDetail();
1591    if (detail == null)
1592      return true;
1593    String JavaDoc detailMsg = "";
1594    Iterator JavaDoc it = detail.getDetailEntries();
1595    for (; it.hasNext();) {
1596      DetailEntry JavaDoc det = (DetailEntry JavaDoc) it.next();
1597      Iterator JavaDoc ita = det.getAllAttributes();
1598      for (boolean cont = false; ita.hasNext(); cont = true) {
1599        Name JavaDoc name = (Name JavaDoc) ita.next();
1600        if (cont)
1601          detailMsg += "; ";
1602        detailMsg += name.getLocalName();
1603        detailMsg += " = ";
1604        detailMsg += det.getAttributeValue(name);
1605      }
1606    }
1607    faults[3] = detailMsg;
1608
1609    return true;
1610  }
1611
1612  /**
1613   * locate "root" in ExecuteResponse
1614   */

1615  private SOAPElement JavaDoc findExecRoot(SOAPMessage JavaDoc reply) throws SOAPException JavaDoc, OlapException {
1616    SOAPPart JavaDoc sp = reply.getSOAPPart();
1617    SOAPEnvelope JavaDoc envelope = sp.getEnvelope();
1618    SOAPBody JavaDoc body = envelope.getBody();
1619
1620    Name JavaDoc name;
1621    if (provider == PROVIDER_SAP) {
1622      name = envelope.createName("ExecuteResponse", "", XMLA_URI);
1623      // SAP
1624
} else {
1625      name = envelope.createName("ExecuteResponse", "m", XMLA_URI);
1626      // Microsoft
1627
}
1628    SOAPElement JavaDoc eResponse = selectSingleNode(body, name);
1629    if (eResponse == null)
1630      throw new OlapException("Excecute result has no ExecuteResponse element");
1631
1632    if (provider == PROVIDER_SAP) {
1633      name = envelope.createName("return", "", XMLA_URI);
1634      // SAP
1635
} else {
1636      // Microsoft
1637
// name = envelope.createName("return", "", ""); // old
1638
name = envelope.createName("return", "m", XMLA_URI);
1639    }
1640    SOAPElement JavaDoc eReturn = selectSingleNode(eResponse, name);
1641    if (eReturn == null) {
1642      // old Microsoft XMLA SDK 1.0 does not have "m" prefix - try
1643
name = envelope.createName("return", "", ""); // old Microsoft
1644
eReturn = selectSingleNode(eResponse, name);
1645      if (eReturn == null)
1646        throw new OlapException("Excecute result has no ExecuteResponse element");
1647    }
1648
1649    name = envelope.createName("root", "", MDD_URI);
1650    SOAPElement JavaDoc eRoot = selectSingleNode(eReturn, name);
1651    if (eRoot == null) { throw new OlapException("Excecute result has no root element"); }
1652    return eRoot;
1653  }
1654
1655  // dsf
1656
private SOAPElement JavaDoc findDrillExecRoot(SOAPMessage JavaDoc reply) throws SOAPException JavaDoc, OlapException {
1657    // the root for drillthrough is ROWS_URI
1658
SOAPPart JavaDoc sp = reply.getSOAPPart();
1659    SOAPEnvelope JavaDoc envelope = sp.getEnvelope();
1660    SOAPBody JavaDoc body = envelope.getBody();
1661
1662    Name JavaDoc name;
1663    if (provider == PROVIDER_SAP) {
1664      name = envelope.createName("ExecuteResponse", "", XMLA_URI);
1665      // SAP
1666
} else {
1667      name = envelope.createName("ExecuteResponse", "m", XMLA_URI);
1668      // Microsoft
1669
}
1670    SOAPElement JavaDoc eResponse = selectSingleNode(body, name);
1671    if (eResponse == null) {
1672      throw new OlapException("Excecute result has no ExecuteResponse element");
1673    }
1674
1675    if (provider == PROVIDER_SAP) {
1676      name = envelope.createName("return", "", XMLA_URI);
1677      // SAP
1678
} else {
1679      // Microsoft
1680
// name = envelope.createName("return", "", ""); // old
1681
name = envelope.createName("return", "m", XMLA_URI);
1682    }
1683    SOAPElement JavaDoc eReturn = selectSingleNode(eResponse, name);
1684    if (eReturn == null) {
1685      throw new OlapException("Excecute result has no return element");
1686    }
1687
1688    name = envelope.createName("root", "", ROWS_URI);
1689    SOAPElement JavaDoc eRoot = selectSingleNode(eReturn, name);
1690    if (eRoot == null) {
1691      throw new OlapException("Excecute result has no root element");
1692    }
1693    return eRoot;
1694  }
1695  
1696} // End XMLA_SOAP
1697
Popular Tags