/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.mappingsplugin.ui.query.relational; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import org.eclipse.persistence.tools.workbench.framework.context.WorkbenchContext; import org.eclipse.persistence.tools.workbench.framework.ui.dialog.AbstractDialog; import org.eclipse.persistence.tools.workbench.framework.uitools.DoubleClickMouseListener; import org.eclipse.persistence.tools.workbench.framework.uitools.SwingComponentFactory; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWMappingDescriptor; import org.eclipse.persistence.tools.workbench.mappingsmodel.query.MWQuery; import org.eclipse.persistence.tools.workbench.mappingsmodel.query.MWQueryable; import org.eclipse.persistence.tools.workbench.mappingsmodel.query.relational.MWAttributeItem; import org.eclipse.persistence.tools.workbench.mappingsmodel.query.relational.MWQueryableArgumentElement; import org.eclipse.persistence.tools.workbench.utility.filters.Filter; abstract class AttributeItemDialog extends AbstractDialog { private MWQuery query; private MWAttributeItem attributeItem; private QueryableTree queryableTree; private Filter traversableFilter; private Filter chooseableFilter; AttributeItemDialog(MWQuery query, MWAttributeItem attributeItem, Filter traversableFilter, Filter chooseableFilter, WorkbenchContext context) { super(context); this.query = query; this.attributeItem = attributeItem; this.traversableFilter = traversableFilter; this.chooseableFilter = chooseableFilter; getOKAction().setEnabled(false); } AttributeItemDialog(MWQuery query, MWAttributeItem attributeItem, WorkbenchContext context) { this(query, attributeItem, null, null, context); this.traversableFilter = buildTraversableFilter(); this.chooseableFilter = buildChooseableFilter(); } protected Filter buildTraversableFilter() { return Filter.NULL_INSTANCE; } protected Filter buildChooseableFilter() { return Filter.NULL_INSTANCE; } protected abstract String titleKey(); protected abstract String editTitleKey(); private MWMappingDescriptor getDescriptor() { return this.query.getOwningDescriptor(); } protected MWQuery getQuery() { return this.query; } protected MWAttributeItem getAttributeItem() { return this.attributeItem; } protected QueryableTree getQueryableTree() { return this.queryableTree; } protected void initializeContentPane() { super.initializeContentPane(); if (this.attributeItem != null) { initializeEditMode(this.attributeItem ); setTitle(resourceRepository().getString(editTitleKey())); } else { setTitle(resourceRepository().getString(titleKey())); } } protected Component buildMainPanel() { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints constraints = new GridBagConstraints(); JScrollPane scrollPane = new JScrollPane(this.buildQueryableTree()); constraints.gridx = 0; constraints.gridy = 0; constraints.gridwidth = 2; constraints.gridheight = 1; constraints.weightx = 1; constraints.weighty = 1; constraints.fill = GridBagConstraints.BOTH; constraints.anchor = GridBagConstraints.CENTER; constraints.insets = new Insets(5, 5, 5, 5); panel.add(scrollPane, constraints); return panel; } protected QueryableTree buildQueryableTree() { this.queryableTree = new QueryableTree(buildQueryableTreeModel(), getWorkbenchContext()); this.queryableTree.addTreeSelectionListener(buildTreeSelectionHandler()); SwingComponentFactory.addDoubleClickMouseListener(queryableTree, new DoubleClickMouseListener() { public void mouseDoubleClicked(MouseEvent e) { TreePath path = queryableTree.getPathForLocation(e.getX(), e.getY()); if (path != null) { clickOK(); } } }); return this.queryableTree; } protected QueryableTreeModel buildQueryableTreeModel() { return new QueryableTreeModel(new DefaultMutableTreeNode(getDescriptor()), this.traversableFilter); } protected void initializeEditMode(MWAttributeItem attributeItem) { MWQueryableArgumentElement element = attributeItem.getQueryableArgument().getQueryableArgumentElement(); if ( element.getQueryable() != null && this.chooseableFilter.accept(element.getQueryable())) { this.queryableTree.setSelectedQueryableArgumentElement(attributeItem.getQueryableArgument().getQueryableArgumentElement()); } setTitle(resourceRepository().getString(titleKey())); } /** * Invoked each time a node is selected or unselected. */ private TreeSelectionListener buildTreeSelectionHandler() { return new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { treeSelectionChanged(e); } }; } protected void treeSelectionChanged(TreeSelectionEvent e) { updateOKButton(); } protected void updateOKButton() { boolean selected = this.queryableTree.getSelectionCount() > 0; if (selected) { QueryableTreeNode selectedNode = (QueryableTreeNode) this.queryableTree.getSelectionPath().getLastPathComponent(); getOKAction().setEnabled(this.chooseableFilter.accept(selectedNode.getQueryable())); } else { getOKAction().setEnabled(false); } } protected void cancelPressed() { ((DefaultMutableTreeNode) this.queryableTree.getModel().getRoot()).removeAllChildren(); super.cancelPressed(); } protected boolean preConfirm() { TreePath selectionPath = this.queryableTree.getSelectionPath(); List queryablePath = new ArrayList(); List allowsNull = new ArrayList(); QueryableTreeNode selectedNode = (QueryableTreeNode) selectionPath.getLastPathComponent(); allowsNull.add(Boolean.valueOf(selectedNode.isAllowsNull())); MWQueryable queryableObject = selectedNode.getQueryable(); queryablePath.add(queryableObject); selectionPath = selectionPath.getParentPath(); while (selectionPath.getPathCount() > 1) {//first path component is always a descriptor, we want to quit before reaching it selectedNode = (QueryableTreeNode) selectionPath.getLastPathComponent(); allowsNull.add(new Boolean(selectedNode.isAllowsNull())); MWQueryable joinedQueryable = selectedNode.getQueryable(); queryablePath.add(joinedQueryable); selectionPath = selectionPath.getParentPath(); } int index = attributeItemsSize(); if (this.attributeItem != null) { index = indexOfAttributeItem(this.attributeItem); removeAttributeItem(index); } addAttributeItem(index, queryablePath.iterator(), allowsNull.iterator()); ((DefaultMutableTreeNode) this.queryableTree.getModel().getRoot()).removeAllChildren(); return super.preConfirm(); } protected abstract int attributeItemsSize(); protected abstract int indexOfAttributeItem(MWAttributeItem attributeItem); protected abstract void removeAttributeItem(int index); protected abstract void addAttributeItem(int index, Iterator queryables, Iterator allowsNulls); }