/* * Copyright (c) 2007-2009, Osmorc Development Team * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * Neither the name of 'Osmorc Development Team' nor the names of its contributors may be * used to endorse or promote products derived from this software without specific * prior written permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.osmorc.run.ui; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.libraries.Library; import com.intellij.ui.DocumentAdapter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.osmorc.facet.OsmorcFacet; import org.osmorc.frameworkintegration.CachingBundleInfoProvider; import org.osmorc.frameworkintegration.FrameworkInstanceDefinition; import org.osmorc.frameworkintegration.LibraryHandler; import org.osmorc.i18n.OsmorcBundle; import org.osmorc.make.BundleCompiler; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.event.*; import java.util.*; /** * Dialog for selecting a bundle to be deployed. * * @author <a href="mailto:janthomae@janthomae.de">Jan Thomä</a> * @version $Id$ */ public class BundleSelector extends JDialog { private JPanel contentPane; private JButton buttonOK; private JButton buttonCancel; private JList bundlesList; private JTextField searchField; private FrameworkInstanceDefinition usedFramework; private List<SelectedBundle> hideBundles = new ArrayList<SelectedBundle>(); private final Project project; private ArrayList<SelectedBundle> selectedBundles = new ArrayList<SelectedBundle>(); private final ArrayList<SelectedBundle> allAvailableBundles = new ArrayList<SelectedBundle>(); public BundleSelector(Project project) { this.project = project; setContentPane(contentPane); setModal(true); setTitle(OsmorcBundle.getTranslation("bundleselector.title")); getRootPane().setDefaultButton(buttonOK); bundlesList.setCellRenderer(new SelectedBundleListCellRenderer()); buttonOK.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { onOK(); } }); buttonCancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { onCancel(); } }); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { onCancel(); } }); searchField.getDocument().addDocumentListener(new DocumentAdapter() { protected void textChanged(DocumentEvent event) { updateList(); } }); contentPane.registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent e) { onCancel(); } }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); bundlesList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { buttonOK.setEnabled(bundlesList.getSelectedIndex() != -1); } }); setSize(400, 300); } public void show(JComponent owner) { setLocationRelativeTo(owner); setVisible(true); } private void createList() { allAvailableBundles.clear(); HashSet<SelectedBundle> hs = new HashSet<SelectedBundle>(); // add all the modules Module[] modules = ModuleManager.getInstance(project).getModules(); for (Module module : modules) { if (OsmorcFacet.hasOsmorcFacet(module)) { SelectedBundle selectedBundle = new SelectedBundle(module.getName(), null, SelectedBundle.BundleType.Module); // treeset produced weird results here... so i gotta take the slow approach. hs.add(selectedBundle); } } // add all framework bundles, if there are some. if (usedFramework != null) { LibraryHandler libraryHandler = ServiceManager.getService(LibraryHandler.class); List<Library> libs = libraryHandler.getLibraries(usedFramework.getName()); for (Library lib : libs) { String[] urls = lib.getUrls(OrderRootType.CLASSES); for (String url : urls) { url = BundleCompiler.convertJarUrlToFileUrl(url); url = BundleCompiler.fixFileURL(url); String bundleName = CachingBundleInfoProvider.getBundleSymbolicName(url); if (bundleName != null) { String bundleVersion = CachingBundleInfoProvider.getBundleVersions(url); SelectedBundle b = new SelectedBundle(bundleName + " - " + bundleVersion, url, SelectedBundle.BundleType.FrameworkBundle); hs.add(b); } } } // all the libraries that are bundles already (doesnt make much sense to start bundlified libs as they have no activator). final String[] urls = OrderEnumerator.orderEntries(project).withoutSdk().withoutModuleSourceEntries() .satisfying(BundleCompiler.NOT_FRAMEWORK_LIBRARY_CONDITION).classes().getUrls(); for (String url : urls) { url = BundleCompiler.convertJarUrlToFileUrl(url); url = BundleCompiler.fixFileURL(url); String displayName = CachingBundleInfoProvider.getBundleSymbolicName(url); if (displayName != null) { // okay its a startable library SelectedBundle selectedBundle = new SelectedBundle(displayName, url, SelectedBundle.BundleType.StartableLibrary); hs.add(selectedBundle); } } } hs.removeAll(hideBundles); allAvailableBundles.addAll(hs); Collections.sort(allAvailableBundles, new TypeComparator()); } private void updateList() { ArrayList<SelectedBundle> theList = new ArrayList<SelectedBundle>(allAvailableBundles); // now filter String filterText = searchField.getText().toLowerCase(); DefaultListModel newModel = new DefaultListModel(); for (SelectedBundle selectedBundle : theList) { boolean needsFiltering = filterText.length() > 0; if (needsFiltering && !selectedBundle.getName().toLowerCase().contains(filterText)) { continue; } newModel.addElement(selectedBundle); } bundlesList.setModel(newModel); } private void onOK() { Object[] selectedValues = bundlesList.getSelectedValues(); selectedBundles = new ArrayList<SelectedBundle>(); for (Object selectedValue : selectedValues) { selectedBundles.add((SelectedBundle) selectedValue); } dispose(); } private void onCancel() { selectedBundles = null; dispose(); } public void setUp(@Nullable FrameworkInstanceDefinition usedFramework, @NotNull List<SelectedBundle> hideBundles) { this.usedFramework = usedFramework; this.hideBundles = hideBundles; createList(); updateList(); } @Nullable public List<SelectedBundle> getSelectedBundles() { return selectedBundles; } /** * Comparator for sorting bundles by their type. * * @author <a href="mailto:janthomae@janthomae.de">Jan Thomä</a> * @version $Id:$ */ public static class TypeComparator implements Comparator<SelectedBundle> { public int compare(SelectedBundle selectedBundle, SelectedBundle selectedBundle2) { return selectedBundle.getBundleType().ordinal() - selectedBundle2.getBundleType().ordinal(); } } }