1 20 package org.openi.olap.drillthrough; 21 22 import com.tonbeller.jpivot.core.ModelChangeEvent; 23 import com.tonbeller.jpivot.core.ModelChangeListener; 24 import com.tonbeller.jpivot.olap.model.Axis; 25 import com.tonbeller.jpivot.olap.model.Cell; 26 import com.tonbeller.jpivot.olap.model.Member; 27 import com.tonbeller.jpivot.olap.model.OlapException; 28 import com.tonbeller.jpivot.olap.model.OlapModel; 29 import com.tonbeller.jpivot.olap.navi.DrillThrough; 30 import com.tonbeller.jpivot.table.CellBuilder; 31 import com.tonbeller.jpivot.table.CellBuilderDecorator; 32 import com.tonbeller.jpivot.table.TableComponent; 33 import com.tonbeller.jpivot.table.TableComponentExtensionSupport; 34 import com.tonbeller.jpivot.xmla.*; 35 import com.tonbeller.wcf.component.RendererParameters; 36 import com.tonbeller.wcf.controller.Dispatcher; 37 import com.tonbeller.wcf.controller.DispatcherSupport; 38 import com.tonbeller.wcf.controller.RequestContext; 39 import com.tonbeller.wcf.controller.RequestListener; 40 import com.tonbeller.wcf.table.EmptyTableModel; 41 import com.tonbeller.wcf.table.ITableComponent; 42 import com.tonbeller.wcf.table.TableModel; 43 import com.tonbeller.wcf.table.TableModelDecorator; 44 import com.tonbeller.wcf.utils.DomUtils; 45 import org.apache.log4j.Logger; 46 import org.w3c.dom.Element ; 47 import java.io.OutputStream ; 48 import java.net.MalformedURLException ; 49 import java.net.URL ; 50 import java.text.DateFormat ; 51 import java.text.SimpleDateFormat ; 52 import java.util.ArrayList ; 53 import java.util.Calendar ; 54 import java.util.Date ; 55 import java.util.HashMap ; 56 import java.util.Iterator ; 57 import java.util.List ; 58 import java.util.Map ; 59 import javax.servlet.http.HttpSession ; 60 import javax.xml.soap.MessageFactory ; 61 import javax.xml.soap.MimeHeaders ; 62 import javax.xml.soap.Name ; 63 import javax.xml.soap.SOAPBody ; 64 import javax.xml.soap.SOAPConnectionFactory ; 65 import javax.xml.soap.SOAPElement ; 66 import javax.xml.soap.SOAPEnvelope ; 67 import javax.xml.soap.SOAPException ; 68 import javax.xml.soap.SOAPMessage ; 69 import javax.xml.soap.SOAPPart ; 70 71 72 public class CustomDrillthroughUI extends TableComponentExtensionSupport 73 implements ModelChangeListener { 74 private static Logger logger = Logger.getLogger(CustomDrillthroughUI.class); 75 public static final String ID = "drillThrough"; 76 boolean available; 77 boolean renderActions; 78 Dispatcher dispatcher = new DispatcherSupport(); 79 DrillThrough extension; 80 TableModelDecorator tableModel = new TableModelDecorator(EmptyTableModel 81 .instance()); 82 OlapModel model = null; 83 84 public String getId() { 85 return ID; 86 } 87 88 public void initialize(RequestContext context, TableComponent table) 89 throws Exception { 90 super.initialize(context, table); 91 table.getOlapModel().addModelChangeListener(this); 92 model = table.getOlapModel(); 93 94 if (!initializeExtension()) { 96 available = false; 97 98 return; 99 } 100 101 available = true; 102 103 table.getDispatcher().addRequestListener(null, null, dispatcher); 105 106 CellBuilder cb = table.getCellBuilder(); 108 DomDecorator cr = new DomDecorator(table.getCellBuilder()); 109 table.setCellBuilder(cr); 110 } 111 112 public void startBuild(RequestContext context) { 113 super.startBuild(context); 114 renderActions = RendererParameters.isRenderActions(context); 115 116 if (renderActions) { 117 dispatcher.clear(); 118 } 119 } 120 121 122 protected boolean initializeExtension() { 123 OlapModel om = table.getOlapModel(); 124 extension = (DrillThrough) om.getExtension(DrillThrough.ID); 125 126 return extension != null; 127 } 128 129 protected boolean canDrillThrough(Cell cell) { 130 return extension.canDrillThrough((Cell) cell.getRootDecoree()); 131 } 132 133 138 protected TableModel drillThrough(Cell cell) { 139 return extension.drillThrough((Cell) cell.getRootDecoree()); 140 } 141 142 public boolean isAvailable() { 143 return available; 144 } 145 146 public void modelChanged(ModelChangeEvent e) { 147 } 148 149 public void structureChanged(ModelChangeEvent e) { 150 initializeExtension(); 151 dispatcher.clear(); 152 } 153 154 public TableModel getTableModel() { 155 return tableModel; 156 } 157 158 class DomDecorator extends CellBuilderDecorator { 159 DomDecorator(CellBuilder delegate) { 160 super(delegate); 161 } 162 163 public Element build(Cell cell, boolean even) { 164 Element parent = super.build(cell, even); 165 166 if (!enabled || !renderActions || (extension == null)) { 167 return parent; 168 } 169 170 String id = DomUtils.randomId(); 171 172 if (canDrillThrough(cell) && (!cell.isNull())) { 173 Element elem = table.insert("drill-through", parent); 175 elem.setAttribute("id", id); 176 elem.setAttribute("title", "Show source data"); 177 dispatcher.addRequestListener(id, null, 178 new DrillThroughHandler(cell)); 179 } else { 180 } 182 183 return parent; 184 } 185 } 186 187 class DrillThroughHandler implements RequestListener { 188 Cell cell; 189 190 DrillThroughHandler(Cell cell) { 191 this.cell = cell; 192 } 193 194 public void request(RequestContext context) 195 throws Exception { 196 if (canDrillThrough(cell)) { 197 HttpSession session = context.getSession(); 198 final String drillTableRef = table.getOlapModel().getID() 199 + ".drillthroughtable"; 200 ITableComponent tc = (ITableComponent) session.getAttribute(drillTableRef); 201 202 TableModel tm = drillThrough(cell); 204 XMLA_DrillThroughTableModel dmodel = (XMLA_DrillThroughTableModel) tm; 205 String mdx = buildDrillThroughMdx(dmodel, 206 (XMLA_Result) table.getOlapModel().getResult()); 207 logger.debug("Got DT Request. MDX : " + mdx); 208 executeDrillQuery(context, (XMLA_Model) dmodel.getModel(), mdx); 209 } 210 } 211 212 private void executeDrillQuery(RequestContext context, XMLA_Model model, String query) 213 throws Exception { 214 try { 215 217 context.getResponse() 222 .setContentType("text/plain"); 223 context.getResponse() 224 .setHeader("Pragma", "no-cache"); 225 context.getResponse() 226 .setHeader("Content-Disposition", 227 "attachment; filename=\"drillthrough.txt\""); 228 229 OutputStream responseStream; 230 responseStream = context.getResponse().getOutputStream(); 231 232 URL url = constructUrl(model.getUri(), model.getUser(), model.getPassword()); 233 try { 234 235 String datasource = model.getDataSource(); 236 if(datasource == null || datasource.equals("")) { 237 logger.debug("Datasource is not available in model.So discovering default one"); 238 XMLA_SOAP soap = new XMLA_SOAP(model.getUri(), model.getUser(), 239 model.getPassword()); 240 Map ds = soap.discoverDS(); 241 if(ds!=null) { 242 datasource = (String )ds.get("DataSourceName"); 243 } 244 } 245 246 if(datasource == null || datasource.equals("")) { 247 logger.error("Datasource is not found"); 248 return; 249 } 250 SOAPMessage message = DrillthroughHelper 251 .constructDrillthroughSoapMessage(query, datasource, 252 model.getCatalog()); 253 logger.debug("executing drillthrough request"); 254 DrillthroughHelper.executeDrillthrough(url, 255 message, responseStream); 256 } catch (Exception ex) { 257 logger.error(ex); 258 RequestContext.instance().setResponseComplete(true); 259 try { 260 if (responseStream != null) { 261 responseStream.write(ex.getMessage().getBytes()); 262 } 263 } catch (Exception exx) { 264 logger.warn( 265 "Response OutputStream error/r/n root cause:/r/n" 266 + exx.getMessage()); 267 } 268 } 269 270 RequestContext.instance().setResponseComplete(true); 271 } catch (Exception se) { 272 throw se; 273 } 274 } 275 276 277 278 private URL constructUrl(String uri, String user, String password) 279 throws MalformedURLException { 280 URL url = null; 281 282 try { 283 url = new URL (uri); 284 } catch (MalformedURLException e1) { 285 throw e1; 286 } 287 288 if ((user != null) && (user.length() > 0)) { 289 String newUri = url.getProtocol() + "://" + user; 290 291 if ((password != null) && (password.length() > 0)) { 292 newUri += (":" + password); 293 } 294 295 newUri += ("@" + url.getHost() + ":" + url.getPort() 296 + url.getPath()); 297 298 try { 299 url = new URL (newUri); 300 } catch (MalformedURLException e2) { 301 throw e2; 302 } 303 } 304 305 return url; 306 } 307 308 private String buildDrillThroughMdx( 309 XMLA_DrillThroughTableModel tmodel, XMLA_Result res) { 310 Axis[] axes = res.getAxes(); 311 StringBuffer mdxBuf = new StringBuffer (" Drillthrough Select "); 312 int nXPositions = axes[0].getPositions().size(); 313 int posIdx = 0; 314 315 for (int i = 0; i < axes.length; i++) { 316 if (i == 0) { 319 posIdx = tmodel.getCellOrdinal() 320 - ((tmodel.getCellOrdinal() / nXPositions) * nXPositions); 321 } else { 322 posIdx = tmodel.getCellOrdinal() / nXPositions; 323 } 324 325 XMLA_Position position = (XMLA_Position) axes[i].getPositions() 326 .get(posIdx); 327 Member[] positionMembers = position.getMembers(); 328 329 if (i == 1) { 330 mdxBuf.append(","); 331 } 332 333 mdxBuf.append("{("); 334 335 for (int j = 0; j < positionMembers.length; j++) { 336 XMLA_Member member = (XMLA_Member) positionMembers[j]; 337 338 if (j > 0) { 339 mdxBuf.append(","); 340 } 341 342 mdxBuf.append(member.getUniqueName()); 343 } 344 345 mdxBuf.append(")}"); 346 347 if (i == 0) { 348 mdxBuf.append(" on Columns"); 349 } else { 350 mdxBuf.append(" on Rows"); 351 } 352 } 353 354 mdxBuf.append(" from [" 355 + ((XMLA_Model) tmodel.getModel()).getCube() + "]"); 356 357 Axis slicer = res.getSlicer(); 358 359 List slicerList = slicer.getPositions(); 361 XMLA_Position slicerPosition = (XMLA_Position) slicerList.get(0); 362 Member[] slicerMembers = slicerPosition.getMembers(); 363 364 for (int j = 0; j < slicerMembers.length; j++) { 365 XMLA_Member member = (XMLA_Member) slicerMembers[j]; 366 367 if (j == 0) { 368 mdxBuf.append(" Where ( "); 369 } else if (j > 0) { 370 mdxBuf.append(" , "); 371 } 372 373 mdxBuf.append(member.getUniqueName()); 374 } 375 376 if (slicerMembers.length > 0) { 377 mdxBuf.append(")"); 378 } 379 380 return mdxBuf.toString(); 381 } 382 } 383 } 384 | Popular Tags |