package org.openslx.dozmod.gui.window; import java.awt.Color; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.RowFilter; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.apache.log4j.Logger; import org.apache.thrift.TException; import org.openslx.bwlp.thrift.iface.ImageSummaryRead; import org.openslx.bwlp.thrift.iface.Organization; import org.openslx.bwlp.thrift.iface.UserInfo; import org.openslx.dozmod.Branding; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.MainWindow; import org.openslx.dozmod.gui.control.table.ListTable.ListModel; import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.gui.helper.TextChangeListener; import org.openslx.dozmod.gui.helper.UiFeedback; import org.openslx.dozmod.gui.window.layout.ImagePublishedWindowLayout; import org.openslx.dozmod.thrift.ImagePublishedDetailsActions; import org.openslx.dozmod.thrift.Session; import org.openslx.dozmod.thrift.ThriftActions; import org.openslx.dozmod.thrift.ThriftActions.DownloadCallback; import org.openslx.dozmod.thrift.ThriftError; import org.openslx.dozmod.thrift.cache.ImagePublishedCache; import org.openslx.dozmod.thrift.cache.OrganizationCache; import org.openslx.dozmod.thrift.cache.UserCache; import org.openslx.sat.thrift.version.Feature; import org.openslx.thrifthelper.TConst; import org.openslx.thrifthelper.ThriftManager; import org.openslx.util.QuickTimer; import org.openslx.util.QuickTimer.Task; @SuppressWarnings("serial") public class ImagePublishedWindow extends ImagePublishedWindowLayout implements UiFeedback, DownloadCallback { private final static Logger LOGGER = Logger.getLogger(ImagePublishedWindow.class); private final ImagePublishedWindow me = this; // Filtering: matches against image's name, user's first/last name or email and organisation name of the owner private Pattern searchFieldPattern = null; private final RowFilter, Integer> filterSearchTerm = new RowFilter, Integer>() { public boolean include(Entry, ? extends Integer> entry) { // match against image names first ImageSummaryRead image = imagePublishedTable.getModelRow(entry.getIdentifier()); if (searchFieldPattern.matcher(image.imageName).find()) return true; // match against users UserInfo user = UserCache.find(image.ownerId); if (user == null) return false; if (searchFieldPattern.matcher(user.firstName).find()) return true; if (searchFieldPattern.matcher(user.lastName).find()) return true; if (searchFieldPattern.matcher(user.eMail).find()) return true; // match against organizations Organization org = OrganizationCache.find(user); if (org == null) return false; if (searchFieldPattern.matcher(org.displayName).find()) return true; return false; } }; public ImagePublishedWindow(Frame modalParent) { super(modalParent); // Hook when user presses X (top right) setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { dispose(); } }); btnClose.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dispose(); } }); btnSatDownload.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ImageSummaryRead item = imagePublishedTable.getSelectedItem(); if (item == null) return; String transferToken = null; try { transferToken = ThriftManager.getSatClient() .requestImageReplication(Session.getSatelliteToken(), item.latestVersionId); } catch (TException ex) { ThriftError.showMessage(me, LOGGER, ex, "Could not start download"); return; } MainWindow.addPassiveTransfer(transferToken, item.imageName, false); Gui.showMessageBox(ImagePublishedWindow.this, "Die Übertragung läuft direkt zwischen Satellitenserver und" + " dem " + Branding.getServiceName() + " Zentral-Server.\n" + "Wenn Sie die " + Branding.getApplicationName() + " schließen, wird der Transfer trotzdem" + "weiterlaufen.", MessageType.INFO, null, null); } }); btnDownload.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final ImageSummaryRead item = imagePublishedTable.getSelectedItem(); if (item == null) return; btnDownload.setEnabled(false); ThriftActions.initDownload((JFrame) SwingUtilities.getWindowAncestor(me), item.latestVersionId, item.imageName, item.virtId, item.osId, item.fileSize, null); } }); txtSearch.getDocument().addDocumentListener(new TextChangeListener() { @Override public void changed() { String str = txtSearch.getText(); if (str == null || str.isEmpty()) { searchFieldPattern = null; } else { try { searchFieldPattern = Pattern.compile(str, Pattern.CASE_INSENSITIVE); txtSearch.setForeground(UIManager.getColor("TextField.foreground")); } catch (PatternSyntaxException ex) { txtSearch.setForeground(Color.RED); } } applyFilterOnTable(); } }); imagePublishedTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { ImageSummaryRead item = imagePublishedTable.getSelectedItem(); updateAvailableOptions(item); } }); imagePublishedTable.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) { ImageSummaryRead item = imagePublishedTable.getSelectedItem(); if (item == null || item.getImageBaseId() == null) return; ImageDetailsWindow.open(JOptionPane.getFrameForComponent(ImagePublishedWindow.this), item.getImageBaseId(), null, new ImagePublishedDetailsActions( JOptionPane.getFrameForComponent(ImagePublishedWindow.this))); } processClick(e); } @Override public void mousePressed(MouseEvent e) { processClick(e); } @Override public void mouseReleased(MouseEvent e) { processClick(e); } private void processClick(MouseEvent e) { // TODO popup menu? } }); // init buttons state btnSatDownload.setVisible(Session.isImagePublishSupported()); updateAvailableOptions(null); // init data refreshList(true, 0); } private void updateAvailableOptions(ImageSummaryRead item) { btnDownload.setEnabled(item != null); if (Session.isImagePublishSupported()) btnSatDownload.setEnabled(item != null); } /** * Called when a change occurs in the filter search field */ private void applyFilterOnTable() { // List for filters List, Integer>> filters = new ArrayList<>(); // string for text in filter text field if (searchFieldPattern != null) { filters.add(filterSearchTerm); } // for using multiple filters if we need it one day RowFilter, Integer> andFilters = RowFilter.andFilter(filters); imagePublishedTable.getRowSorter().setRowFilter(andFilters); } /** * Callback when download initialized * * @param success * true if downloading, false otherwise */ @Override public void downloadInitialized(boolean success) { if (!success) { Gui.asyncExec(new Runnable() { @Override public void run() { btnDownload.setEnabled(true); } }); } } /** * Refreshes the image list in the table * * @param forceRefresh * true to force a refresh, false to use the cached list */ public void refreshList(final boolean forceRefresh, int delay) { QuickTimer.scheduleOnce(new Task() { @Override public void fire() { final List imagePublishedList = ImagePublishedCache.get(forceRefresh); if (imagePublishedList == null) return; // 04.2018: Safety check to hide the non-vmware images from the list // in case they somehow manage to get published. Remove this when we // support publishing images from other hypervisors. if (Session.hasFeature(Feature.MULTIPLE_HYPERVISORS)) { for (Iterator iter = imagePublishedList.listIterator(); iter .hasNext();) { ImageSummaryRead current = iter.next(); if (current != null && !current.virtId.equals(TConst.VIRT_VMWARE)) { iter.remove(); } } } Gui.asyncExec(new Runnable() { @Override public void run() { imagePublishedTable.setData(imagePublishedList, true); } }); } }, delay); } /** * Opens a new ImageDetailsWindow showing the details of the image with ID = * imageBaseId * * @param modalParent * parent of this window * @param imageBaseId * id of the image to set the details of */ public static void open(Frame modalParent) { ImagePublishedWindow win = new ImagePublishedWindow(modalParent); win.setVisible(true); } /* ******************************************************************************* * * Dialog class overrides * * ************************************************************************** * ***** */ @SuppressWarnings("deprecation") @Override public void show() { if (!isVisible()) { pack(); MainWindow.centerShell(this); } super.show(); } @Override public boolean wantConfirmQuit() { return false; } @Override public void escapePressed() { dispose(); } }