/*******************************************************************************
* 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.scplugin.ui.session.basic;
// JDK
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Iterator;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileSystemView;
import org.eclipse.persistence.tools.workbench.framework.context.WorkbenchContextHolder;
import org.eclipse.persistence.tools.workbench.framework.ui.view.AbstractSubjectPanel;
import org.eclipse.persistence.tools.workbench.framework.uitools.GridLayout;
import org.eclipse.persistence.tools.workbench.framework.uitools.SwingComponentFactory;
import org.eclipse.persistence.tools.workbench.scplugin.model.adapter.DatabaseSessionAdapter;
import org.eclipse.persistence.tools.workbench.scplugin.model.adapter.ProjectAdapter;
import org.eclipse.persistence.tools.workbench.scplugin.model.adapter.ProjectXMLAdapter;
import org.eclipse.persistence.tools.workbench.uitools.app.CollectionAspectAdapter;
import org.eclipse.persistence.tools.workbench.uitools.app.CollectionValueModel;
import org.eclipse.persistence.tools.workbench.uitools.app.SortedListValueModelAdapter;
import org.eclipse.persistence.tools.workbench.uitools.app.ValueModel;
import org.eclipse.persistence.tools.workbench.uitools.app.swing.ListModelAdapter;
import org.eclipse.persistence.tools.workbench.uitools.app.swing.ObjectListSelectionModel;
import org.eclipse.persistence.tools.workbench.uitools.cell.AbstractCellRendererAdapter;
import org.eclipse.persistence.tools.workbench.uitools.cell.AdaptableListCellRenderer;
// Mapping Workbench
/**
* This pane shows the multiple projects contained by a
* {@link DatabaseSessionAdapter}. The {@link SessionProjectPane} shows only one
* entry which represents the primary project, this pane has to be activated
* by the check box located in the project pane.
* <p>
* Here the layout of this pane:
* <pre>
* _____________________________________________________
* | ________________________________ ________________ |
* | | myPackage.MyClass |^| | Add... | |
* | | C:/location/myFile.xml | | ---------------- |
* | | ... ||| ________________ |
* | | ||| | Remove | |
* | | ||| ---------------- |
* | | ||| |
* | | | | |
* | | |v| |
* | -------------------------------- |
* -----------------------------------------------------</pre>
*
* @see DatabaseSessionAdapter
*
* @version 10.1.3
* @author Pascal Filion
*/
abstract class AbstractSessionMultipleProjectsPane extends AbstractSubjectPanel
{
/**
* The model responsible to keep track of the selected items.
*/
private ObjectListSelectionModel selectionModel;
/**
* Creates a new <code>AbstractSessionMultipleProjectsPane</code>.
*
* @param subjectHolder The holder of {@link DatabaseSessionAdapter}
* @param context The context to be used by this pane
*/
AbstractSessionMultipleProjectsPane(ValueModel subjectHolder,
WorkbenchContextHolder contextHolder)
{
super(subjectHolder, contextHolder);
}
/**
* Prompts to add an additional project (Class or XML).
*
* @param selectionModel The selection model used by the list
*/
protected abstract void addProject(ObjectListSelectionModel selectionModel);
/**
* Creates a new <code>ActionListener</code> that adds a new project to the
* list.
*
* @return A new <code>ActionListener</code>
*/
private ActionListener buildAddAction()
{
return new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
addProject(AbstractSessionMultipleProjectsPane.this.selectionModel);
}
};
}
/**
* Creates the <code>CollectionValueModel</code> containing all the items to
* be shown in the Additional Projects list.
*
* @return A new <code>CollectionValueModel</code>
*/
private CollectionValueModel buildAddionalProjectsCollectionHolder()
{
return new CollectionAspectAdapter(getSubjectHolder(), DatabaseSessionAdapter.ADDITIONAL_PROJECTS_COLLECTION)
{
protected Iterator getValueFromSubject()
{
DatabaseSessionAdapter session = (DatabaseSessionAdapter) subject;
return session.additionalProjects();
}
};
}
/**
* Creates the <code>ListModel</code> containing all the items to be shown in
* the list.
*
* @return A new <code>ListModel</code>
*/
private ListModel buildAddionalProjectsListAdapter()
{
return new ListModelAdapter
(
new SortedListValueModelAdapter
(
buildAddionalProjectsCollectionHolder()
)
);
}
/**
* Creates a new <code>ListCellRenderer</code> that will render either a
* class name or an xml file.
*
* @return A new <code>ListCellRenderer</code>
*/
private ListCellRenderer buildAddiontalProjectsCellRenderer()
{
return new AdaptableListCellRenderer
(
new CellRendererAdapter()
);
}
/**
* Creates the <code>ActionListener</code> responsible to remove the selected
* items from the list.
*
* @return A new <code>ActionListener</code>
*/
private ActionListener buildRemoveAction()
{
return new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Object[] selectedValues = AbstractSessionMultipleProjectsPane.this.selectionModel.getSelectedValues();
DatabaseSessionAdapter session = (DatabaseSessionAdapter) subject();
for (int index = 0; index < selectedValues.length; index++)
{
session.removeProject((ProjectAdapter) selectedValues[index]);
}
}
};
}
/**
* Keeps the enable state of the given button in sync with the list selection.
*
* @param The button that has its enable state kept in sync based on the new
* selection
*/
private void buildRemoveButtonEnabler(final JButton removeButton)
{
this.selectionModel.addListSelectionListener(new ListSelectionListener()
{
public void valueChanged(ListSelectionEvent e)
{
if (e.getValueIsAdjusting())
return;
removeButton.setEnabled(AbstractSessionMultipleProjectsPane.this.selectionModel.getSelectedValues().length > 0);
}
});
}
/**
* Initializes the layout of this pane.
*
* @return The container with all its widgets
*/
protected void initializeLayout()
{
GridBagConstraints constraints = new GridBagConstraints();
// List label
JLabel additionalProjectsLabel = buildLabel("SESSION_MULTIPLE_PROJECTS_LIST");
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.weightx = 0;
constraints.weighty = 0;
constraints.fill = GridBagConstraints.NONE;
constraints.anchor = GridBagConstraints.LINE_START;
constraints.insets = new Insets(0, 0, 0, 0);
add(additionalProjectsLabel, constraints);
// Additional Projects list
JList additionalProjectsList = SwingComponentFactory.buildList(buildAddionalProjectsListAdapter());
additionalProjectsList.setCellRenderer(buildAddiontalProjectsCellRenderer());
this.selectionModel = new ObjectListSelectionModel(additionalProjectsList.getModel());
additionalProjectsList.setSelectionModel(this.selectionModel);
constraints.gridx = 0;
constraints.gridy = 1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.weightx = 1;
constraints.weighty = 0;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.anchor = GridBagConstraints.LINE_START;
constraints.insets = new Insets(1, 0, 0, 0);
add(new JScrollPane(additionalProjectsList), constraints);
additionalProjectsLabel.setLabelFor(additionalProjectsList);
// Button panel
JPanel buttonPanel = new JPanel(new GridLayout(2, 1, 0, 5));
constraints.gridx = 1;
constraints.gridy = 1;
constraints.gridwidth = 1;
constraints.gridheight = 1;
constraints.weightx = 0;
constraints.weighty = 1;
constraints.fill = GridBagConstraints.NONE;
constraints.anchor = GridBagConstraints.PAGE_START;
constraints.insets = new Insets(1, 5, 0, 0);
add(buttonPanel, constraints);
// Add button
JButton addButton = buildButton("SESSION_MULTIPLE_PROJECTS_ADD_BUTTON");
addButton.addActionListener(buildAddAction());
buttonPanel.add(addButton);
// Remove button
JButton removeButton = buildButton("SESSION_MULTIPLE_PROJECTS_REMOVE_BUTTON");
removeButton.setEnabled(false);
removeButton.addActionListener(buildRemoveAction());
buildRemoveButtonEnabler(removeButton);
buttonPanel.add(removeButton);
}
/**
* This <code>LabelDecorator</code> takes care to show on screen the path
* based on the system the MW is ran. In the file, the file separator is
* always '/' since a sessions.xml created on Windows with '\' as the file
* separator will not work on a Unix system.
*/
private class CellRendererAdapter extends AbstractCellRendererAdapter
{
public Icon buildFileIcon(String path)
{
File file = new File(path);
return resourceRepository().getIcon(file.exists() ? (file.isDirectory() ? "folder" : "file") : "file");
}
public Icon buildIcon(Object value)
{
if (value instanceof ProjectXMLAdapter)
return buildFileIcon(((ProjectXMLAdapter) value).getName());
return resourceRepository().getIcon("class.public");
}
public String buildText(Object value)
{
String name = ((ProjectAdapter) value).getName();
return name.replace('/', File.separatorChar);
}
}
}