/** * 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.HashMap; import java.util.Map; import java.util.TreeMap; 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.custom.ScrolledComposite; import org.eclipse.swt.custom.TableEditor; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; /** * Used to added aggregates and modifiers to the user selected tokens. This * alters the underlying query in Logic Service friendly format so that the * query can later be easily parsed by the Logic Service. */ public class ModifierPage extends DataSetWizardPage { private static final String DEFAULT_DATASTYLE = "mostrecent"; private static final String DATASTYLE = "DATASTYLE"; private static final String TOKENS = "TOKENS"; // @jve:decl-index=0: private static final String TOKENTAG = "TOKENTAG"; private static final String FILTER = "FILTER"; private Logger log = Logger.getLogger(ModifierPage.class.getName()); // @jve:decl-index=0: private static String FILTER_MESSAGE = "First select a filter."; private transient Composite composite, m_columnComp; // private transient List m_chosenColumnList; private java.util.List selectedColumns; // @jve:decl-index=0: private Table table = null; private Composite modifierComposite, instructionsComposite, modifierLabelComposite, aggregateComposite = null; //private ScrolledComposite scrolledComposite; private List tokenList = null; private TableEditor editor; private Label modifierLabel; private Combo aggregateCombo, valueCombo = null; private String[] modifiers = { "GT", "LT", "EQ", "NE", "BEFORE", "AFTER" }; private String[] values = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }; private String[] aggregates = { "FIRST", "LAST", "MAX", "MIN" }; private String selectedToken = null; private Map aggregateRows; // @jve:decl-index=0: // stores the modifiers for those tokens that are selected private Map selectedTokenModifiers; /** * Constructor. * * @param pageName the page name */ public ModifierPage(String pageName) { super(pageName); setTitle(pageName); setMessage(FILTER_MESSAGE); setPageComplete(false); } /** * Constructor. * * @param pageName the page name * @param title the title * @param titleImage the title image */ public ModifierPage(String pageName, String title, ImageDescriptor titleImage) { super(pageName, title, titleImage); setMessage(FILTER_MESSAGE); setPageComplete(false); } /** * @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); if (InformationHolder.hasDestroyed()) InformationHolder.start(this.getInitializationDesign()); 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.BORDER); 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); */ selectedColumns = new java.util.ArrayList(); log.info("Getting selected columns"); if (InformationHolder.getPropertyValue(TOKENS) != null) { log.info("Not null"); selectedColumns = new java.util.ArrayList(); for (String t : QueryBuilder .getTokenNamesFromStorage(InformationHolder .getPropertyValue(TOKENS))) { log.info("Got " + t); selectedColumns.add(t); } } log.info("Done getting selected columns"); setupSelectedTokensList(); setupModifierContents(); setMessage("Select Aggregates and Modifiers for Tokens"); return composite; } /** * Loads the rows of tokens and their stored aggregate information. */ public void loadAggregateRows() { aggregateRows.size(); for (String token : selectedColumns) { String aggregateNameForThisToken = Utils .getAggregateNameForTokenFromTokenProperty(token, InformationHolder.getPropertyValue("TOKENS")); String aggregateValueForThisToken = Utils .getAggregateValueForTokenFromTokenProperty(token, InformationHolder.getPropertyValue("TOKENS")); Combo aggregateCombo = aggregateRows.get(token).getAggregateCombo(); int aggregateIndex = aggregateCombo .indexOf(aggregateNameForThisToken); aggregateCombo.select(aggregateIndex); Combo valueCombo = aggregateRows.get(token).getValueCombo(); int valueIndex = valueCombo.indexOf(aggregateValueForThisToken); valueCombo.select(valueIndex); //disable the aggregate selections if the most recent data style has been chosen if(InformationHolder.getPropertyValue("DATASTYLE").equals("mostrecent")) { aggregateCombo.setEnabled(false); valueCombo.setEnabled(false); } } } /** * Sets up the List of selected tokens for the user to toggle between and * add the desired aggregates and modifiers. */ private void setupSelectedTokensList() { /* instructionsComposite = new Composite(composite, SWT.NONE); Label instructionsLabel = new Label(instructionsComposite, SWT.BORDER | SWT.WRAP); GridData instructionsLabelData = new GridData(SWT.LEFT, 1, true, true); instructionsLabel.setLayoutData(instructionsLabelData); GridLayout instructionsLayout = new GridLayout(); instructionsLayout.numColumns = 1; instructionsComposite.setLayout(instructionsLayout); instructionsLabel.setText("INSTRUCTIONS: Change the aggregate for each token if desired. You must change the data style to stacked or flat to change aggregate settings (default data style is most recent). Click the token name and use the bottom modifier table to apply modifiers to the token. Check the box to the left of the desired modifier and provide appropriate values. Use the arrows to the left of the modifier table to move the modifiers up and down to specify precedence"); */ /* scrolledComposite = new ScrolledComposite(composite, SWT.V_SCROLL | SWT.BORDER); GridData scrolledData = new GridData(); scrolledData.horizontalAlignment = GridData.FILL; scrolledData.grabExcessHorizontalSpace = true; scrolledComposite.setLayoutData(scrolledData); */ aggregateComposite = new Composite(composite, SWT.NONE); GridLayout aggregateLayout = new GridLayout(); aggregateLayout.makeColumnsEqualWidth = false; aggregateLayout.numColumns = 3; aggregateComposite.setLayout(aggregateLayout); GridData aggregateData = new GridData(); aggregateData.verticalAlignment = GridData.FILL; aggregateData.horizontalAlignment = GridData.FILL; aggregateData.horizontalIndent = 0; aggregateData.grabExcessHorizontalSpace = true; aggregateComposite.setLayoutData(aggregateData); GridData aggregateLabelData = new GridData(); aggregateLabelData.horizontalAlignment = GridData.CENTER; aggregateLabelData.verticalAlignment = GridData.CENTER; GridData tokenLabelData = new GridData(); tokenLabelData.horizontalAlignment = GridData.CENTER; tokenLabelData.verticalAlignment = GridData.CENTER; GridData valueLabelData = new GridData(); valueLabelData.horizontalAlignment = GridData.CENTER; valueLabelData.verticalAlignment = GridData.CENTER; // composite.setSize(new Point(290, 306)); aggregateRows = new HashMap(); GridData labelData = new GridData(); labelData.verticalAlignment = GridData.FILL; labelData.horizontalIndent = 0; labelData.grabExcessHorizontalSpace = true; labelData.heightHint = 1; labelData.horizontalAlignment = GridData.FILL; Label aggregateLabel = new Label(aggregateComposite, SWT.NONE); // aggregateLabel.setLayoutData(labelData); aggregateLabel.setText("Aggregate"); aggregateLabel.setLayoutData(aggregateLabelData); Label valueLabel = new Label(aggregateComposite, SWT.CENTER); valueLabel.setText("Value"); valueLabel.setLayoutData(valueLabelData); Label tokenLabel = new Label(aggregateComposite, SWT.CENTER); tokenLabel.setText("Token"); tokenLabel.setLayoutData(tokenLabelData); for (String token : selectedColumns) { log.info("Loading row: " + token); GridData tokenData = new GridData(); tokenData.verticalAlignment = GridData.FILL; tokenData.horizontalIndent = 0; tokenData.grabExcessHorizontalSpace = true; tokenData.heightHint = 1; tokenData.horizontalAlignment = GridData.FILL; createAggregateCombo(); createValueCombo(); tokenList = new List(aggregateComposite, SWT.SINGLE | SWT.BORDER); tokenList.setLayoutData(tokenData); tokenList.add(token); aggregateRows.put(token, new AggregateRow(token, tokenList, aggregateCombo, valueCombo, aggregateRows, this)); } /* scrolledComposite.setContent(aggregateComposite); scrolledComposite.setMinSize(50, 50); scrolledComposite.setExpandHorizontal(true); scrolledComposite.setExpandVertical(true); */ } /** * Creates a combo for selecting aggregates * */ private void createAggregateCombo() { GridData gridData8 = new GridData(); gridData8.horizontalAlignment = GridData.FILL; gridData8.verticalAlignment = GridData.CENTER; aggregateCombo = new Combo(aggregateComposite, SWT.NONE | SWT.READ_ONLY); aggregateCombo.setLayoutData(gridData8); for (int i = 0; i < aggregates.length; i++) { aggregateCombo.add(aggregates[i]); } } /** * Creates a combo for selecting aggregate values * */ private void createValueCombo() { GridData gridData5 = new GridData(); gridData5.widthHint = 20; gridData5.verticalAlignment = GridData.CENTER; gridData5.horizontalAlignment = GridData.CENTER; valueCombo = new Combo(aggregateComposite, SWT.NONE | SWT.READ_ONLY); valueCombo.setLayoutData(gridData5); for (int i = 0; i < values.length; i++) { valueCombo.add(values[i]); } } /** * Called when a token is selected and loads the modifier table * appropriately based on any past modifier selections. * * @param token the token that the user selected from the list */ public void loadModifierTable(String token) { modifierLabel.setText("Token Modifiers - Selected Token: " + token); // redraw the label modifierLabelComposite.layout(); table.addMouseListener(getModifierTextInputListener()); table.setEnabled(true); log.info("Selected Token: " + token); this.selectedToken = token; table.removeAll(); table.setEnabled(true); Modifiers modifiers = selectedTokenModifiers.get(token); // load up the modifier table based on what has been input for the // selected column for (int i = 0; i < modifiers.getSize(); i++) { // Create the row final TableItem item = new TableItem(table, SWT.NONE); item.setText(0, modifiers.getModifierAtLocation(i)); item.setChecked(modifiers.isEnabled(modifiers .getModifierAtLocation(i))); // load the arguments item.setText(1, modifiers.getModifierArguments(modifiers .getModifierAtLocation(i))); } } /** * Orchestrates the creation of the modifier interface which consists of a * table of modifiers where the first column are check boxes to indicate * whether or not to use a certain modifier, the second column is the name * of the modifier, and the third column is the value to use with the * modifier. There are up and down arrows to the left of this modifier table * to allow the user to move the modifiers up and down to indicate * precedence. */ private void setupModifierContents() { modifierLabelComposite = new Composite(composite, SWT.NONE); modifierLabelComposite.setLayout(new GridLayout(1, false)); GridData gridLabelData = new GridData(SWT.FILL, SWT.FILL, true, false); gridLabelData.horizontalSpan = 2; modifierLabelComposite.setLayoutData(gridLabelData); modifierLabel = new Label(modifierLabelComposite, SWT.NONE); GridData columnLabelData = new GridData(SWT.LEFT, 1, true, false); modifierLabel.setLayoutData(columnLabelData); modifierLabel.setText("Token Modifiers - Selected Token: "); // holds all of the modifier interface modifierComposite = new Composite(composite, SWT.NONE); modifierComposite.setLayout(new GridLayout(2, false)); GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); gridData.horizontalSpan = 2; modifierComposite.setLayoutData(gridData); // setup the up/down arrows setupModifierArrows(); setupModifierTable(); } /** * Responsible for creating and returning the ControlAdapter that * dynamically resizes the modifier table based on the changing size of the * parent composite. * * @return the modifier resize listener */ private ControlAdapter getModifierResizeListener() { return new ControlAdapter() { @Override public void controlResized(ControlEvent e) { Rectangle area = modifierComposite.getClientArea(); Point preferredSize = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); int width = area.width - 2 * table.getBorderWidth(); if (preferredSize.y > area.height + table.getHeaderHeight()) { // Subtract the scrollbar width from the total column width // if a vertical scrollbar will be required Point vBarSize = table.getVerticalBar().getSize(); width -= vBarSize.x; } Point oldSize = table.getSize(); if (oldSize.x > area.width) { // table is getting smaller so make the columns // smaller first and then resize the table to // match the client area width table.getColumn(0).setWidth(width / 4); table.getColumn(1).setWidth( width - table.getColumn(0).getWidth()); table.setSize(area.width, area.height); } else { // table is getting bigger so make the table // bigger first and then make the columns wider // to match the client area width table.setSize(area.width, area.height); table.getColumn(0).setWidth(width / 4); table.getColumn(1).setWidth( width - table.getColumn(0).getWidth()); } } }; } /** * Modifier table consisting of three columns: 1) Check box to indicate the * desired use of a modifier, 2) the name of the modifier, and 3) any * arguments to pass to the modifier. A TableEditor is to used to record * every character entered in the 3rd column and constantly updates the * InformationHolder TOKENS property as the user inputs text. */ private void setupModifierTable() { // Create the table table = new Table(modifierComposite, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION | SWT.CHECK | SWT.V_SCROLL | SWT.H_SCROLL); GridData modifierTable = new GridData(SWT.FILL, SWT.FILL, true, true); table.setLayoutData(modifierTable); table.setEnabled(false); table.setSize(50, 50); table.pack(); table.setHeaderVisible(true); table.setLinesVisible(true); // create the two columns and their headers TableColumn modifierColumn = new TableColumn(table, SWT.CENTER); modifierColumn.setText("Modifier"); modifierColumn.pack(); TableColumn argumentColumn = new TableColumn(table, SWT.LEFT); argumentColumn.setText("Value"); argumentColumn.pack(); // create all the modifier rows with the appropriate labels for (int i = 0; i < modifiers.length; i++) { // Create the row final TableItem item = new TableItem(table, SWT.NONE); item.setText(modifiers[i]); } // this piece dynamically resizes the columns as the table size changes modifierComposite.addControlListener(getModifierResizeListener()); // Create an editor object to use for text editing editor = new TableEditor(table); editor.horizontalAlignment = SWT.LEFT; editor.grabHorizontal = true; // setup the listener for text input into the table table.addMouseListener(getModifierTextInputListener()); table.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { TableItem temp = (TableItem) event.item; if (event.detail == SWT.CHECK) { if (temp.getChecked()) { log.info(temp.getText() + " checked"); selectedTokenModifiers.get(selectedToken).setEnabled( temp.getText()); InformationHolder.setPropertyValue(TOKENS, Utils .tokenModifiersToPropertyStorageString( selectedTokenModifiers, InformationHolder .getPropertyValue(TOKENS))); } // disable the editor if it's not checked else { selectedTokenModifiers.get(selectedToken).setDisabled( temp.getText()); InformationHolder.setPropertyValue(TOKENS, Utils .tokenModifiersToPropertyStorageString( selectedTokenModifiers, InformationHolder .getPropertyValue(TOKENS))); } } } }); } /** * Responsible for listening to the user's input in the modifier table. * * @return the modifier text input listener */ private MouseAdapter getModifierTextInputListener() { return new MouseAdapter() { @Override public void mouseDown(MouseEvent event) { // Dispose any existing editor Control old = editor.getEditor(); if (old != null) old.dispose(); // Determine where the mouse was clicked Point pt = new Point(event.x, event.y); // Determine which row was selected final TableItem item = table.getItem(pt); if (item != null) { // Determine which column was selected int column = -1; for (int i = 0, n = table.getColumnCount(); i < n; i++) { Rectangle rect = item.getBounds(i); if (rect.contains(pt)) { // This is the selected column column = i; break; } } // we don't want the first column to be editable if (column > 0) { // Create the Text object for our editor final Text text = new Text(table, SWT.NONE); text.setForeground(item.getForeground()); // Transfer any text from the cell to the Text control, // set the color to match this row, select the text, // and set focus to the control // System.out.println(item.getText(0)); text.setText(item.getText(column)); text.setForeground(item.getForeground()); text.selectAll(); text.setFocus(); // text.setEnabled(false); // Recalculate the minimum width for the editor editor.minimumWidth = text.getBounds().width; // Set the control into the editor editor.setEditor(text, item, column); // Add a handler to transfer the text back to the cell // any time it's modified final int col = column; text.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { // Set the text of the editor's control back // into the cell item.setText(col, text.getText()); log.info("User input - " + item.getText(0) + " - " + text.getText()); // record the modifier text selectedTokenModifiers.get(selectedToken) .setModifierArguments(item.getText(0), text.getText()); InformationHolder .setPropertyValue( TOKENS, Utils .tokenModifiersToPropertyStorageString( selectedTokenModifiers, InformationHolder .getPropertyValue(TOKENS))); } }); } } } }; } /** * Sets up the modifier arrows to the left of the modifier table. This * allows the user to move their modifiers up and down in the table to * indicate precedence. */ private void setupModifierArrows() { final Composite m_ArrowSelectComp = new Composite(modifierComposite, SWT.NONE); m_ArrowSelectComp.setLayout(new GridLayout(1, false)); GridData columnButtonCompData = new GridData(SWT.FILL, SWT.FILL, false, true); m_ArrowSelectComp.setLayoutData(columnButtonCompData); Button m_upButton = new Button(m_ArrowSelectComp, SWT.ARROW | SWT.UP); GridData rightData = new GridData(SWT.FILL, SWT.FILL, false, true); m_upButton.setLayoutData(rightData); m_upButton.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { // make sure that a row is selected if (table.getSelection().length > 0) { // get the modifier name and value String modifierText = table.getSelection()[0].getText(0); String modifierValue = table.getSelection()[0].getText(1); // see if it is checked boolean checked = table.getSelection()[0].getChecked(); int newIndex = -1; // check if we are the top row if (table.getSelectionIndex() == 0) { // keep the row where it is at if the row is at the top newIndex = table.getSelectionIndex(); } else { selectedTokenModifiers.get(selectedToken) .moveModifierUp(modifierText); InformationHolder.setPropertyValue(TOKENS, Utils .tokenModifiersToPropertyStorageString( selectedTokenModifiers, InformationHolder .getPropertyValue(TOKENS))); newIndex = table.getSelectionIndex() - 1; } // remove the row because we are going to add it back in the // new position table.getSelection()[0].dispose(); TableItem item = new TableItem(table, SWT.NONE, newIndex); item.setText(new String[] { modifierText, modifierValue }); item.setChecked(checked); table.setSelection(newIndex); } } public void widgetDefaultSelected(SelectionEvent e) { } }); Button m_downButton = new Button(m_ArrowSelectComp, SWT.ARROW | SWT.DOWN); GridData leftData = new GridData(SWT.FILL, SWT.FILL, false, true); m_downButton.setLayoutData(leftData); m_downButton.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { // make sure that a row is selected if (table.getSelection().length > 0) { // get the modifier name and value String modifierText = table.getSelection()[0].getText(0); String modifierValue = table.getSelection()[0].getText(1); // see if it is checked boolean checked = table.getSelection()[0].getChecked(); int newIndex = -1; // check if we are on the bottom row if (table.getSelectionIndex() == (table.getItemCount() - 1)) { // keep the row where it is at if the row is at the // bottom newIndex = table.getSelectionIndex(); } else { // otherwise, move a row down newIndex = table.getSelectionIndex() + 1; selectedTokenModifiers.get(selectedToken) .moveModifierDown(modifierText); InformationHolder.setPropertyValue(TOKENS, Utils .tokenModifiersToPropertyStorageString( selectedTokenModifiers, InformationHolder .getPropertyValue(TOKENS))); } // System.out.println("Selected row: " + modifierText); // remove the row because we are going to add it back in the // new position table.getSelection()[0].dispose(); TableItem item = new TableItem(table, SWT.NONE, newIndex); item.setText(new String[] { modifierText, modifierValue }); item.setChecked(checked); // keep the item selected table.setSelection(newIndex); } } public void widgetDefaultSelected(SelectionEvent e) { } }); } /* * private String getFullPath(java.util.Properties connProps) { String path = * connProps.getProperty("PATH"); // Make sure there is a slash at the end * of the path if (!path.endsWith("/")) path += "/"; * * return path + "moduleServlet/logicws/api/"; } */ /** * 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("Entering initializeControl() for ModifierPage"); // Restores the last saved data set design DataSetDesign dataSetDesign = this.getInitializationDesign(); if (dataSetDesign == null) return; // nothing to initialize if (InformationHolder.hasDestroyed()) InformationHolder.start(dataSetDesign); // setup the default data type if its not set if (InformationHolder.getPropertyValue(DATASTYLE) == null) { InformationHolder.setPropertyValue(DATASTYLE, DEFAULT_DATASTYLE); } if (InformationHolder.getPropertyValue(TOKENS) != null) { log.info("Here I am!"); selectedColumns = new java.util.ArrayList(); for (String t : QueryBuilder .getTokenNamesFromStorage(InformationHolder .getPropertyValue(TOKENS))) { selectedColumns.add(t); } } loadAggregateRows(); // initialize control validateData(); loadSelectedColumns(); composite.layout(); // composite.getParent().layout(); /* * To optionally honor the request for an editable or read-only design * session, use isSessionEditable(); */ } /** * Load the selected tokens in the list. */ private void loadSelectedColumns() { // m_chosenColumnList.removeAll(); try { if (selectedColumns != null) { String tokensAndModifiers = InformationHolder .getPropertyValue(TOKENS); for (String s : selectedColumns) { log.info("Loading " + s); // m_chosenColumnList.add(s); // create a new token/modifier map if it is null if (selectedTokenModifiers == null) { selectedTokenModifiers = new TreeMap(); } // create a new Modifiers object for the token selectedTokenModifiers.put(s, (new Modifiers(modifiers))); String modifierAndArguments = null; // load any appropriate modifiers for the token if ((modifierAndArguments = Utils .getModifierInfoForTokenFromTokenProperty(s, tokensAndModifiers)) != null) { log.info("Loading arguments: " + modifierAndArguments); selectedTokenModifiers.get(s).loadModifierURLformat( modifierAndArguments); } } // m_chosenColumnList.setEnabled(true); } else { selectedColumns = null; } } catch (Exception e) { // Something has changed, so deselect everything selectedColumns = null; // m_chosenColumnList.removeAll(); } } /** * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#collectDataSetDesign(org.eclipse.datatools.connectivity.oda.design.DataSetDesign) */ @Override protected DataSetDesign collectDataSetDesign(DataSetDesign design) { if (!hasValidData()) return 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(); } /** * Validates the user-defined value in the page control exists and not a * blank text. Set page message accordingly. */ private void validateData() { // setMessage(DONE_MESSAGE); setPageComplete(true); } /** * Indicates whether the custom page has valid data to proceed with defining * a data set. * * @return true, if checks for valid data */ private boolean hasValidData() { validateData(); return canLeave(); } /** * 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; } /** * 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; } /** * 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("Saving modifier page"); 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); 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 modifier 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(); } /** * Reload the modifier table in the case that the user has made changes in * the other data set pages that can effect the contents of this page (i.e. * adding or removing tokens). */ protected void refresh() { selectedColumns = new java.util.ArrayList(); log.info(InformationHolder.getPropertyValue(TOKENS)); if (InformationHolder.getPropertyValue(TOKENS) != null) { selectedColumns = new java.util.ArrayList(); for (String t : QueryBuilder .getTokenNamesFromStorage(InformationHolder .getPropertyValue(TOKENS))) { log.info("Adding column: " + t); selectedColumns.add(t); } } //instructionsComposite.dispose(); aggregateComposite.dispose(); modifierComposite.dispose(); modifierLabelComposite.dispose(); //scrolledComposite.dispose(); log.info(selectedColumns.toString()); setupSelectedTokensList(); setupModifierContents(); loadAggregateRows(); loadSelectedColumns(); table.removeAll(); table.setEnabled(false); log.info(selectedColumns.toString()); // deselect everything for (String token : selectedColumns) { aggregateRows.get(token).getList().deselectAll(); } modifierLabel.setText("Token Modifiers - Selected Token: "); composite.layout(); // composite.getParent().layout(); } /* * @see org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage#cleanup() */ @Override protected void cleanup() { InformationHolder.destroy(); } }