1 20 package org.openi.olap.drillthrough; 21 22 import org.xml.sax.Attributes ; 23 import org.xml.sax.SAXException ; 24 25 import org.xml.sax.helpers.DefaultHandler ; 26 import sun.misc.BASE64Encoder; 27 28 import java.io.BufferedInputStream ; 29 import java.io.ByteArrayInputStream ; 30 import java.io.ByteArrayOutputStream ; 31 import java.io.IOException ; 32 import java.io.InputStream ; 33 import java.io.OutputStream ; 34 35 import java.net.MalformedURLException ; 36 import java.net.URL ; 37 import java.util.ArrayList ; 38 import java.util.HashMap ; 39 import java.util.Iterator ; 40 import java.util.List ; 41 import java.util.Map ; 42 import java.util.StringTokenizer ; 43 44 import javax.xml.parsers.SAXParser ; 45 import javax.xml.parsers.SAXParserFactory ; 46 import javax.xml.soap.MessageFactory ; 47 import javax.xml.soap.MimeHeader ; 48 import javax.xml.soap.MimeHeaders ; 49 import javax.xml.soap.Name ; 50 import javax.xml.soap.SOAPBody ; 51 import javax.xml.soap.SOAPElement ; 52 import javax.xml.soap.SOAPEnvelope ; 53 import javax.xml.soap.SOAPException ; 54 import javax.xml.soap.SOAPMessage ; 55 import javax.xml.soap.SOAPPart ; 56 57 import org.apache.commons.httpclient.Header; 58 import org.apache.commons.httpclient.HttpClient; 59 import org.apache.commons.httpclient.HttpStatus; 60 import org.apache.commons.httpclient.methods.InputStreamRequestEntity; 61 import org.apache.commons.httpclient.methods.PostMethod; 62 import org.apache.log4j.Logger; 63 64 68 public class DrillthroughHelper { 69 private static Logger logger = Logger.getLogger(DrillthroughHelper.class); 70 71 public static int BUFFER_SIZE = 4048; 72 73 80 public static void executeDrillthrough(URL url, SOAPMessage request, 81 OutputStream outstream) throws Exception { 82 try { 83 84 logger.info("Executing SOAP Request"); 85 86 InputStream instream = executeSOAP(request, url.toString()); 87 88 logger.debug("Parsing results"); 89 parseAndWriteCSV(new BufferedInputStream (instream, 1024), outstream); 90 instream.close(); 91 logger.debug("Done"); 92 93 } catch (Exception ex) { 94 ex.printStackTrace(); 95 throw ex; 96 } 97 } 98 99 107 public static void executeDrillthrough(URL url, String mdxQuery, 108 String datasource, String catalog, OutputStream outstream) 109 throws Exception { 110 SOAPMessage message = constructDrillthroughSoapMessage(mdxQuery, 111 datasource, catalog); 112 InputStream instream = executeSOAP(message, url.toString()); 113 readAndWriteStream(instream, outstream); 114 try { 115 instream.close(); 116 } catch (Exception ex) { 117 logger.warn("Exception occured while closing input stream", ex); 118 } 119 120 } 121 122 129 private static void readAndWriteStream(InputStream in, OutputStream out) 130 throws IOException { 131 byte array[] = new byte[BUFFER_SIZE]; 136 int count; 137 while ((count = in.read(array, 0, BUFFER_SIZE)) != -1) { 138 out.write(array, 0, count); 139 } 140 141 } 142 143 155 public static SOAPMessage constructDrillthroughSoapMessage(String mdxQuery, 156 String datasource, String catalog) throws SOAPException { 157 158 logger.debug("Creating SOAP Envelope"); 159 MessageFactory mf = MessageFactory.newInstance(); 160 SOAPMessage msg = mf.createMessage(); 161 MimeHeaders mh = msg.getMimeHeaders(); 162 mh.setHeader("SOAPAction", 163 "\"urn:schemas-microsoft-com:xml-analysis:Execute\""); 164 165 SOAPPart soapPart = msg.getSOAPPart(); 166 SOAPEnvelope envelope = soapPart.getEnvelope(); 167 SOAPBody body = envelope.getBody(); 168 Name nEx = envelope.createName("Execute", "", 169 "urn:schemas-microsoft-com:xml-analysis"); 170 SOAPElement eEx = body.addChildElement(nEx); 171 172 Name nCom = envelope.createName("Command"); 179 SOAPElement eCommand = eEx.addChildElement(nCom); 180 Name nSta = envelope.createName("Statement"); 181 SOAPElement eStatement = eCommand.addChildElement(nSta); 182 eStatement.addTextNode(mdxQuery); 183 184 Map paraList = new HashMap (); 185 logger.debug("DT MDX :" + mdxQuery); 186 logger.debug("Datasource :" + datasource); 187 logger.debug("Catalog :" + catalog); 188 paraList.put("DataSourceInfo", datasource); 189 paraList.put("Catalog", catalog); 190 191 paraList.put("Format", "Tabular"); 195 addParameterList(envelope, eEx, "Properties", "PropertyList", paraList); 196 msg.saveChanges(); 197 198 return msg; 199 } 200 201 209 public static InputStream executeSOAP(SOAPMessage message, String endUrl) 210 throws SOAPException { 211 212 URL url = null; 213 214 try { 215 url = new URL (endUrl); 216 } catch (MalformedURLException ex) { 217 ex.printStackTrace(); 218 throw new SOAPException ("Mailformed url", ex); 219 } 220 221 PostMethod post = new PostMethod(url.toString()); 222 HttpClient client = new HttpClient(); 223 224 MimeHeaders headers = message.getMimeHeaders(); 225 Iterator it = headers.getAllHeaders(); 226 227 boolean hasAuth = false; boolean isFailure = false; 229 while (it.hasNext()) { 230 MimeHeader header = (MimeHeader ) it.next(); 231 232 String [] values = headers.getHeader(header.getName()); 233 234 if (values.length == 1) 235 post.setRequestHeader(header.getName(), header.getValue()); 236 else { 237 StringBuffer concat = new StringBuffer (); 238 int i = 0; 239 while (i < values.length) { 240 if (i != 0) 241 concat.append(','); 242 concat.append(values[i]); 243 i++; 244 } 245 246 post.setRequestHeader(header.getName(), concat.toString()); 247 } 248 249 if ("Authorization".equals(header.getName())) 250 hasAuth = true; 251 } 252 253 if (!hasAuth && url.getUserInfo() != null) { 254 post.setRequestHeader("Authorization", "Basic " 255 + new BASE64Encoder().encode(url.getUserInfo().getBytes())); 256 } 257 258 try { 259 ByteArrayOutputStream outstream = new ByteArrayOutputStream (); 260 message.writeTo(outstream); 261 ByteArrayInputStream instream = new ByteArrayInputStream (outstream 262 .toByteArray()); 263 264 post.setRequestEntity(new InputStreamRequestEntity(instream, 265 outstream.size())); 266 267 client.executeMethod(post); 268 if (post.getStatusCode() == HttpStatus.SC_INTERNAL_SERVER_ERROR) { 269 isFailure = true; 270 } else if ((post.getStatusCode() / 100) != 2) { 271 throw new SOAPException ("Bad response: " 272 + post.getStatusLine().toString()); 273 } 274 275 headers = new MimeHeaders (); 276 String key, value; 277 278 Header [] responseHeaders = post.getResponseHeaders(); 279 for (int i = 0; i < responseHeaders.length; i++) { 280 281 key = responseHeaders[i].getName(); 282 value = responseHeaders[i].getValue(); 283 284 if (key == null && value == null) 285 break; 286 287 if (key != null) { 288 StringTokenizer values = new StringTokenizer (value, ","); 289 while (values.hasMoreTokens()) 290 headers.addHeader(key, values.nextToken().trim()); 291 } 292 } 293 if (isFailure) { 294 String msg = "SOAP Request Error\r\n" 295 + post.getResponseBodyAsString(); 296 post.releaseConnection(); 297 throw new SOAPException (msg); 298 } 299 300 return post.getResponseBodyAsStream(); 301 302 } catch (SOAPException ex) { 303 ex.printStackTrace(); 304 throw ex; 305 } catch (Exception ex) { 306 ex.printStackTrace(); 307 throw new SOAPException (ex); 308 } 309 310 } 311 312 private static void addParameterList(SOAPEnvelope envelope, 314 SOAPElement eParent, String typeName, String listName, Map params) 315 throws SOAPException { 316 Name nPara = envelope.createName(typeName, "", 317 "urn:schemas-microsoft-com:xml-analysis"); 318 SOAPElement eType = eParent.addChildElement(nPara); 319 nPara = envelope.createName(listName, "", 320 "urn:schemas-microsoft-com:xml-analysis"); 321 322 SOAPElement eList = eType.addChildElement(nPara); 323 324 if (params == null) { 325 return; 326 } 327 328 Iterator it = params.keySet().iterator(); 329 330 while (it.hasNext()) { 331 String tag = (String ) it.next(); 332 String value = (String ) params.get(tag); 333 nPara = envelope.createName(tag, "", 334 "urn:schemas-microsoft-com:xml-analysis"); 335 336 SOAPElement eTag = eList.addChildElement(nPara); 337 eTag.addTextNode(value); 338 } 339 } 340 341 private static void parseAndWriteCSV(InputStream in, OutputStream out) 344 throws Exception { 345 final OutputStream writer = out; 346 DefaultHandler rowHandler = new DefaultHandler () { 347 boolean rowStarted = false; 349 350 boolean inRowItemElement = false; 351 352 boolean isFirstRow = true; 353 354 List stringList = new ArrayList (); 357 358 List colNames = new ArrayList (); 362 363 public void startElement(String namespaceURI, String localName, 365 String qName, Attributes atts) throws SAXException { 366 if ("row".equals(localName)) { 373 rowStarted = true; 374 } else if (rowStarted) { 375 inRowItemElement = true; 376 377 if (isFirstRow) { 378 colNames.add(localName); 379 } 380 } else { 381 rowStarted = false; 382 inRowItemElement = false; 383 } 384 } 385 386 public void characters(char[] ch, int start, int length) 387 throws SAXException { 388 if (inRowItemElement) { 390 String value = new String (ch, start, length); 391 stringList.add(value); 392 } 393 } 394 395 public void endElement(String namespaceURI, String localName, 396 String qName) throws SAXException { 397 try { 398 if (inRowItemElement) { 399 inRowItemElement = false; 401 } else if (rowStarted && !inRowItemElement) { 402 rowStarted = false; 404 405 if (isFirstRow) { 406 isFirstRow = false; 408 writeRow(colNames); 409 } 410 411 writeRow(stringList); 413 stringList.clear(); 414 } 415 } catch (Exception ex) { 416 throw new SAXException (ex); 417 } 418 } 419 420 public void writeRow(List stringList) throws IOException { 423 424 for (int i = 0; i < stringList.size(); i++) { 425 writer.write(stringList.get(i).toString().getBytes()); 426 427 if (i == (stringList.size() - 1)) { 428 writer.write("\n".getBytes()); 429 } else { 430 writer.write(",".getBytes()); 431 } 432 } 433 434 writer.flush(); 435 } 436 }; 437 438 try { 439 SAXParserFactory factory = SAXParserFactory.newInstance(); 440 factory.setNamespaceAware(true); 441 factory.setValidating(true); 442 443 SAXParser saxParser = factory.newSAXParser(); 444 saxParser.parse(in, rowHandler); 445 saxParser = null; 446 rowHandler = null; 447 in.close(); 448 in = null; 449 } catch (Exception ex) { 450 throw new SAXException ( 451 "An error occured while parsing drillthrough results", ex); 452 } 453 } 454 } 455 | Popular Tags |