blob: a0d363f3ed7c64bdfa1154e131056753151fe4f1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.j2ee.persistence.util;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JSeparator;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.libraries.LibrariesCustomizer;
import org.netbeans.modules.j2ee.persistence.dd.common.Persistence;
import org.netbeans.modules.j2ee.persistence.provider.DefaultProvider;
import org.netbeans.modules.j2ee.persistence.provider.Provider;
import org.netbeans.modules.j2ee.persistence.provider.ProviderUtil;
import org.netbeans.modules.j2ee.persistence.spi.provider.PersistenceProviderSupplier;
import org.netbeans.modules.j2ee.persistence.wizard.Util;
import org.netbeans.modules.j2ee.persistence.wizard.library.PersistenceLibraryCustomizer;
import org.netbeans.modules.j2ee.persistence.wizard.library.PersistenceLibrarySupport;
import org.openide.util.NbBundle;
import org.openide.util.Parameters;
/**
* A helper class for populating combo box with persistence providers.
* Providers may be provided (no pun intended) by server in a container
* managed environment or they might come from libraries.
*
* @author Libor Kotouc
* @author Erno Mononen
*/
public final class PersistenceProviderComboboxHelper {
private final static String SEPARATOR = "PersistenceProviderComboboxHelper.SEPARATOR";
private final static String EMPTY = "PersistenceProviderComboboxHelper.EMPTY";
private final static Provider preferredProvider = ProviderUtil.ECLIPSELINK_PROVIDER;
private final PersistenceProviderSupplier providerSupplier;
private final Project project;
/**
* Creates a new PersistenceProviderComboboxHelper.
* @param project the current project. Must have an implementation of
* the PersistenceProviderSupplier in its lookup.
* @throws IllegalArgumentException if the project did not have an implementation of
* the PersistenceProviderSupplier in its lookup.
*/
public PersistenceProviderComboboxHelper(Project project) {
Parameters.notNull("project", project);
PersistenceProviderSupplier aProviderSupplier =project.getLookup().lookup(PersistenceProviderSupplier.class);
if (aProviderSupplier == null){
// a java se project
aProviderSupplier = new DefaultPersistenceProviderSupplier();
}
this.project = project;
this.providerSupplier = aProviderSupplier;
}
/**
* Populates the given <code>providerCombo</code> with persistence providers. Supported
* providers from the project's server (if it had one) are also added. If the project
* doesn't have a server, only providers from libraries
* are added. Items for adding and managing libraries are always included.
* @param providerCombo the combo box to be populated.
*/
public void connect(final JComboBox providerCombo) {
providerCombo.setEditable(false);
initCombo(providerCombo);
// handling of <ENTER> key event
providerCombo.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (KeyEvent.VK_ENTER == keyCode) {
Object selectedItem = providerCombo.getSelectedItem();
if (selectedItem instanceof LibraryItem) {
providerCombo.hidePopup();
((LibraryItem) selectedItem).performAction();
e.consume();
initCombo(providerCombo);
}
}
}
});
providerCombo.addActionListener(new ActionListener() {
Object currentItem = providerCombo.getSelectedItem();
int currentIndex = providerCombo.getSelectedIndex();
public void actionPerformed(ActionEvent e) {
Object selectedItem = providerCombo.getSelectedItem();
// skipping of separator
if (SEPARATOR.equals(selectedItem)) {
int selectedIndex = providerCombo.getSelectedIndex();
if (selectedIndex > currentIndex) {
currentIndex = selectedIndex + 1;
currentItem = providerCombo.getItemAt(currentIndex);
} else {
currentIndex = selectedIndex - 1;
currentItem = providerCombo.getItemAt(currentIndex);
}
providerCombo.setSelectedItem(currentItem);
// handling mouse click, see KeyEvent.getKeyModifiersText(e.getModifiers())
} else if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
if (selectedItem instanceof LibraryItem) {
providerCombo.setPopupVisible(false);
((LibraryItem) selectedItem).performAction();
initCombo(providerCombo);
}
} else {
currentItem = selectedItem;
currentIndex = providerCombo.getSelectedIndex();
}
}
});
}
private void initCombo(JComboBox providerCombo) {
DefaultComboBoxModel providers = new DefaultComboBoxModel();
for(Provider each : providerSupplier.getSupportedProviders()){
providers.addElement(each);
}
if (providers.getSize() == 0 && providerSupplier.supportsDefaultProvider()){
providers.addElement(ProviderUtil.DEFAULT_PROVIDER);
}
if (providers.getSize() == 0){
providers.addElement(EMPTY);
}
providerCombo.setModel(providers);
providerCombo.addItem(SEPARATOR);
providerCombo.addItem(new NewPersistenceLibraryItem());
providerCombo.addItem(new ManageLibrariesItem());
providerCombo.setRenderer(new PersistenceProviderCellRenderer(getDefaultProvider(providers)));
//select either default or first or preferred provider depending on project details
int selectIndex = 0;
if(providers.getSize()>1 && providers.getElementAt(0) instanceof Provider){
String defProviderVersion = ProviderUtil.getVersion((Provider) providers.getElementAt(0));
boolean specialCase = (Util.isJPAVersionSupported(project, Persistence.VERSION_2_0) || Util.isJPAVersionSupported(project, Persistence.VERSION_2_1)) && (defProviderVersion == null || defProviderVersion.equals(Persistence.VERSION_1_0));//jpa 2.0 is supported by default (or first) is jpa1.0 or udefined version provider
if(specialCase){
for (int i = 1; i<providers.getSize() ; i++){
if(preferredProvider.equals(providers.getElementAt(i))){
selectIndex = i;
break;
}
}
}
}
providerCombo.setSelectedIndex(selectIndex);
}
/**
* Gets the provider representing the default provider from
* the given <code>providers</code>.
* @param providers the providers. if the default provider is supported,
* it has to be the first element in the model.
* @return the default provider or null if is not supported.
*/
private Provider getDefaultProvider(ComboBoxModel providers){
if (!providerSupplier.supportsDefaultProvider()){
return null;
}
if (providers.getElementAt(0) instanceof Provider){
return (Provider) providers.getElementAt(0);
}
return null;
}
public static interface LibraryItem {
String getText();
void performAction();
}
private static class NewPersistenceLibraryItem implements LibraryItem {
public String getText() {
return NbBundle.getMessage(PersistenceProviderComboboxHelper.class, "LBL_NewPersistenceLibrary");
}
public void performAction() {
PersistenceLibraryCustomizer.showCustomizer();
}
}
private static class ManageLibrariesItem implements LibraryItem {
public String getText() {
return NbBundle.getMessage(PersistenceProviderComboboxHelper.class, "LBL_ManageLibraries");
}
public void performAction() {
LibrariesCustomizer.showCustomizer(null);
}
}
private static class PersistenceProviderCellRenderer extends DefaultListCellRenderer {
Provider defaultProvider;
PersistenceProviderCellRenderer(Provider defaultProvider) {
this.defaultProvider = defaultProvider;
}
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (isSelected) {
setBackground(list.getSelectionBackground());
setForeground(list.getSelectionForeground());
} else {
setBackground(list.getBackground());
setForeground(list.getForeground());
}
if (value instanceof Provider) {
Provider provider = (Provider)value;
String text = provider.getDisplayName();
if (value.equals(defaultProvider) && (!(value instanceof DefaultProvider))) {
text += NbBundle.getMessage(PersistenceProviderComboboxHelper.class, "LBL_DEFAULT_PROVIDER");
}
setText(text);
} else if (SEPARATOR.equals(value)) {
JSeparator s = new JSeparator();
s.setPreferredSize(new Dimension(s.getWidth(), 1));
s.setForeground(Color.BLACK);
return s;
} else if (EMPTY.equals(value)) {
setText(" ");
} else if (value instanceof LibraryItem) {
setText(((LibraryItem) value).getText());
} else {
setText(value != null ? value.toString() : ""); // NOI18N
}
return this;
}
}
/**
* An implementation of the PersistenceProviderSupplier that returns an empty list for supported
* providers and doesn't support a default provider. Used when an implementation of
* the PersistenceProviderSupplier can't be found in the project lookup (as is the case
* for instance for Java SE projects).
*/
private static class DefaultPersistenceProviderSupplier implements PersistenceProviderSupplier{
@Override
public List<Provider> getSupportedProviders() {
ArrayList<Provider> providers = new ArrayList<Provider>();
for (Provider each : PersistenceLibrarySupport.getProvidersFromLibraries()){
boolean found = false;
for (int i = 0; i < providers.size(); i++) {
Object elem = providers.get(i);
if (elem instanceof Provider && each.equals(elem)){
found = true;
break;
}
}
if (!found){
providers.add(each);
}
}
return providers;
}
public boolean supportsDefaultProvider() {
return false;
}
}
}