/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.eclipse.datatools.connectivity.oda.openmrs.ui.impl; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.datatools.connectivity.oda.IConnection; import org.eclipse.datatools.connectivity.oda.IParameterMetaData; import org.eclipse.datatools.connectivity.oda.IQuery; import org.eclipse.datatools.connectivity.oda.IResultSetMetaData; import org.eclipse.datatools.connectivity.oda.OdaException; import org.eclipse.datatools.connectivity.oda.design.DataSetDesign; import org.eclipse.datatools.connectivity.oda.design.DesignFactory; import org.eclipse.datatools.connectivity.oda.design.ResultSetColumns; import org.eclipse.datatools.connectivity.oda.design.ResultSetDefinition; import org.eclipse.datatools.connectivity.oda.design.ui.designsession.DesignSessionUtil; import org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage; import org.eclipse.datatools.connectivity.oda.design.util.DesignUtil; import org.eclipse.datatools.connectivity.oda.openmrs.impl.QueryBuilder; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; /** * This page shows the user the query that will actually be sent over the line * to the Logic Web Service. Right now, this is also the page where the user * chooses between the 3 available data styles. */ public class ViewQueryPage extends DataSetWizardPage { private static final String TOKENTAG = "TOKENTAG"; private static final String FILTER = "FILTER"; private static final String TOKENS = "TOKENS"; private static final String DEFAULT_DATASTYLE = "Most Recent"; private static final String FLAT = "flat"; private static final String STACKED = "stacked"; private static final String MOSTRECENT = "mostrecent"; private static final String DATASTYLE = "DATASTYLE"; private Logger log = Logger.getLogger(ViewQueryPage.class.getName()); private static String QUERY_VIEW_MESSAGE = "OpenMRS Query to be Sent to Logic Service"; private Label filterLabel; private Button[] radios; private transient Composite composite; /** * Constructor. * * @param pageName the page name */ public ViewQueryPage(String pageName) { super(pageName); setTitle(pageName); setMessage(QUERY_VIEW_MESSAGE); setPageComplete(true); } /** * Constructor. * * @param pageName the page name * @param title the title * @param titleImage the title image */ public ViewQueryPage(String pageName, String title, ImageDescriptor titleImage) { super(pageName, title, titleImage); setMessage(QUERY_VIEW_MESSAGE); setPageComplete(true); } /** * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#createPageCustomControl(org.eclipse.swt.widgets.Composite) */ @Override public void createPageCustomControl(Composite parent) { log.setLevel(Level.INFO); setControl(createPageControl(parent)); initializeControl(); } /** * Creates custom control for user-defined query text. * * @param parent the parent * * @return the control */ private Control createPageControl(Composite parent) { composite = new Composite(parent, SWT.NONE); composite.setSize(400, 400); composite.setLayout(new GridLayout(2, false)); GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, false); gridData.heightHint = 400; gridData.widthHint = 400; composite.setLayoutData(gridData); /* * parent.setSize(405, 405); GridData parentData = new * GridData(SWT.FILL, SWT.FILL, false, false); parentData.heightHint = * 405; parentData.widthHint = 405; parent.setLayoutData(parentData); */ setupQueryViewGUI(); setupDataStyleSelection(); return composite; } /** * Sets up the Label that displays the Logic Web Service query. */ private void setupQueryViewGUI() { filterLabel = new Label(composite, SWT.BORDER | SWT.WRAP); GridData gridData = new GridData(SWT.LEFT, 1, true, true); gridData.horizontalSpan = 2; gridData.heightHint = 200; filterLabel.setLayoutData(gridData); if (getQueryText() != null) filterLabel.setText(getQueryText()); } /* * private String prettyPrint(String query) { String answer = ""; // extract * the SELECT field String select = query.substring(query.indexOf("SELECT") + * 7, query .indexOf("FROM") - 1); String[] toks = select.split("|"); for * (int i = 0; i < toks.length; i++) { answer += toks[i] + "|" + "\n"; } * * String filter = "FROM " + QueryBuilder.getFilter(query) + "\n"; String * datastyle = "datastyle=" + QueryBuilder.getDataStyle(query) + "\n"; * * return "SELECT " + answer + filter + datastyle; } */ /** * Sets up the three radio buttons for the user to choose between the three * different available data styles. */ private void setupDataStyleSelection() { Composite dataStyleComposite = new Composite(composite, SWT.BORDER); dataStyleComposite.setLayout(new GridLayout(1, false)); GridData styleData = new GridData(SWT.FILL, 1, true, true); dataStyleComposite.setLayoutData(styleData); Label dataStyleLabel = new Label(dataStyleComposite, SWT.NONE); dataStyleLabel.setText("Select the Style of Data to Generate:"); radios = new Button[3]; radios[0] = new Button(dataStyleComposite, SWT.RADIO | SWT.TOP); radios[0].setText(DEFAULT_DATASTYLE); radios[0].addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { InformationHolder.setPropertyValue(DATASTYLE, MOSTRECENT); if (getQueryText() != null) { filterLabel.setText(getQueryText()); composite.layout(); } } public void widgetDefaultSelected(SelectionEvent e) { } }); radios[1] = new Button(dataStyleComposite, SWT.RADIO | SWT.TOP); radios[1].setText("Stacked"); radios[1].addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { InformationHolder.setPropertyValue(DATASTYLE, STACKED); if (getQueryText() != null) { filterLabel.setText(getQueryText()); composite.layout(); } } public void widgetDefaultSelected(SelectionEvent e) { } }); radios[2] = new Button(dataStyleComposite, SWT.RADIO | SWT.TOP); radios[2].setText("Flat"); radios[2].addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { InformationHolder.setPropertyValue(DATASTYLE, FLAT); if (getQueryText() != null) { filterLabel.setText(getQueryText()); composite.layout(); } } public void widgetDefaultSelected(SelectionEvent e) { } }); } /** * Initializes the page control with the last edited data set design. */ private void initializeControl() { /* * To optionally restore the designer state of the previous design * session, use getInitializationDesignerState(); */ log.info("Initializing filter page"); // Restores the last saved data set design DataSetDesign dataSetDesign = getInitializationDesign(); if (InformationHolder.hasDestroyed()) InformationHolder.start(dataSetDesign); // setup the default data type if its not set if (InformationHolder.getPropertyValue(DATASTYLE) == null) { InformationHolder.setPropertyValue(DATASTYLE, MOSTRECENT); } else if (InformationHolder.getPropertyValue(DATASTYLE).equals( MOSTRECENT)) { radios[0].setSelection(true); } else if (InformationHolder.getPropertyValue(DATASTYLE) .equals(STACKED)) { radios[1].setSelection(true); } else if (InformationHolder.getPropertyValue(DATASTYLE).equals(FLAT)) { radios[2].setSelection(true); } if (dataSetDesign == null) return; // nothing to initialize composite.layout(); // composite.getParent().layout(); } /** * Obtains the user-defined query text of this data set from page control. * * @return query text */ private String getQueryText() { String queryText = QueryBuilder.getQuery(InformationHolder .getPropertyValue(TOKENS), InformationHolder .getPropertyValue(FILTER), InformationHolder .getPropertyValue(DATASTYLE)); log.info(queryText); return queryText; } /** * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#collectDataSetDesign(org.eclipse.datatools.connectivity.oda.design.DataSetDesign) */ @Override protected DataSetDesign collectDataSetDesign(DataSetDesign design) { savePage(design); return design; } /** * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#collectResponseState() */ @Override protected void collectResponseState() { super.collectResponseState(); /* * To optionally assign a custom response state, for inclusion in the * ODA design session response, use setResponseSessionStatus( * SessionStatus status ); setResponseDesignerState( DesignerState * customState ); */ } /** * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#canLeave() */ @Override protected boolean canLeave() { return isPageComplete(); } /** * Gets the blank page properties. * * @return the blank page properties */ private static java.util.Properties getBlankPageProperties() { java.util.Properties prop = new java.util.Properties(); prop.setProperty(FILTER, ""); prop.setProperty(TOKENTAG, ""); prop.setProperty(TOKENS, ""); prop.setProperty(DATASTYLE, ""); return prop; } /** * Saves the user-defined value in this page, and updates the specified * dataSetDesign with the latest design definition. * * @param dataSetDesign the data set design */ private void savePage(DataSetDesign dataSetDesign) { // save user-defined query text if (InformationHolder.hasDestroyed()) InformationHolder.start(dataSetDesign); String queryText = getQueryText(); dataSetDesign.setQueryText(queryText); log.info(queryText); if (dataSetDesign.getPublicProperties() == null) { try { dataSetDesign.setPublicProperties(DesignSessionUtil .createDataSetPublicProperties(dataSetDesign .getOdaExtensionDataSourceId(), dataSetDesign .getOdaExtensionDataSetId(), getBlankPageProperties())); } catch (OdaException e) { // TODO need some logging here e.printStackTrace(); } } if (dataSetDesign.getPublicProperties() != null) { if (dataSetDesign.getPublicProperties().findProperty(FILTER) != null) dataSetDesign.getPublicProperties().findProperty(FILTER) .setNameValue(FILTER, InformationHolder.getPropertyValue(FILTER)); if (dataSetDesign.getPublicProperties().findProperty(TOKENTAG) != null) dataSetDesign.getPublicProperties().findProperty(TOKENTAG) .setNameValue(TOKENTAG, InformationHolder.getPropertyValue(TOKENTAG)); if (dataSetDesign.getPublicProperties().findProperty(TOKENS) != null) dataSetDesign.getPublicProperties().findProperty(TOKENS) .setNameValue(TOKENS, InformationHolder.getPropertyValue(TOKENS)); if (dataSetDesign.getPublicProperties().findProperty(DATASTYLE) != null) dataSetDesign.getPublicProperties().findProperty(DATASTYLE) .setNameValue(DATASTYLE, InformationHolder.getPropertyValue(DATASTYLE)); } // obtain query's current runtime metadata, and maps it to the // dataSetDesign IConnection conn = null; try { // obtain and open a live connection conn = new org.eclipse.datatools.connectivity.oda.openmrs.impl.Driver() .getConnection(null); java.util.Properties connProps = DesignUtil .convertDataSourceProperties(getInitializationDesign() .getDataSourceDesign()); conn.open(connProps); // update the data set design with the query's current runtime // metadata updateDesign(dataSetDesign, conn, queryText); } catch (OdaException e) { // not able to get current metadata, reset previous derived metadata dataSetDesign.setResultSets(null); dataSetDesign.setParameters(null); e.printStackTrace(); } finally { closeConnection(conn); } log.info("Done saving filter page"); } /** * Updates the given dataSetDesign with the queryText and its derived * metadata obtained from the ODA runtime connection. * * @param dataSetDesign the data set design * @param conn the conn * @param queryText the query text * * @throws OdaException the oda exception */ private void updateDesign(DataSetDesign dataSetDesign, IConnection conn, String queryText) throws OdaException { IQuery query = conn.newQuery(null); query.prepare(queryText); try { IResultSetMetaData md = query.getMetaData(); updateResultSetDesign(md, dataSetDesign); } catch (OdaException e) { // no result set definition available, reset previous derived // metadata dataSetDesign.setResultSets(null); e.printStackTrace(); } // proceed to get parameter design definition try { IParameterMetaData paramMd = query.getParameterMetaData(); updateParameterDesign(paramMd, dataSetDesign); } catch (OdaException ex) { // no parameter definition available, reset previous derived // metadata dataSetDesign.setParameters(null); ex.printStackTrace(); } /* * See DesignSessionUtil for more convenience methods to define a data * set design instance. */ } /** * Updates the specified data set design's result set definition based on * the specified runtime metadata. * * @param md runtime result set metadata instance * @param dataSetDesign data set design instance to update * * @throws OdaException the oda exception */ private void updateResultSetDesign(IResultSetMetaData md, DataSetDesign dataSetDesign) throws OdaException { ResultSetColumns columns = DesignSessionUtil .toResultSetColumnsDesign(md); ResultSetDefinition resultSetDefn = DesignFactory.eINSTANCE .createResultSetDefinition(); // resultSetDefn.setName( value ); // result set name resultSetDefn.setResultSetColumns(columns); // no exception in conversion; go ahead and assign to specified // dataSetDesign dataSetDesign.setPrimaryResultSet(resultSetDefn); dataSetDesign.getResultSets().setDerivedMetaData(true); } /** * Updates the specified data set design's parameter definition based on the * specified runtime metadata. Unimplemented, as parameters are unsupported. * * @param paramMd the param md * @param dataSetDesign the data set design * * @throws OdaException the oda exception */ private void updateParameterDesign(IParameterMetaData paramMd, DataSetDesign dataSetDesign) throws OdaException { } /** * Attempts to close given ODA connection. * * @param conn the conn */ private void closeConnection(IConnection conn) { try { if (conn != null && conn.isOpen()) conn.close(); } catch (OdaException e) { // TODO need some logging here e.printStackTrace(); } } /** * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#refresh(org.eclipse.datatools.connectivity.oda.design.DataSetDesign) */ @Override protected void refresh(DataSetDesign dataSetDesign) { if (InformationHolder.hasDestroyed()) InformationHolder.start(dataSetDesign); refresh(); } /** * Refreshes the screen so the latest Logic Web Service query is displayed * as the user makes changes using the other data set wizard pages. */ protected void refresh() { // setup the default data type if its not set if (InformationHolder.getPropertyValue(DATASTYLE) == null) { InformationHolder.setPropertyValue(DATASTYLE, MOSTRECENT); } else if (InformationHolder.getPropertyValue(DATASTYLE).equals( MOSTRECENT)) { radios[0].setSelection(true); } else if (InformationHolder.getPropertyValue(DATASTYLE) .equals(STACKED)) { radios[1].setSelection(true); } else if (InformationHolder.getPropertyValue(DATASTYLE).equals(FLAT)) { radios[2].setSelection(true); } if (getQueryText() != null) filterLabel.setText(getQueryText()); composite.layout(); // composite.getParent().layout(); } /* * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#cleanup() */ @Override protected void cleanup() { InformationHolder.destroy(); } }