/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package de.cismet.cismap.commons.gui.layerwidget; import org.apache.log4j.Logger; import org.openide.util.NbBundle; import java.awt.Component; import java.awt.datatransfer.DataFlavor; import java.awt.dnd.DnDConstants; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.TransferHandler; import javax.swing.tree.TreePath; import de.cismet.cismap.commons.LayerConfig; import de.cismet.cismap.commons.featureservice.AbstractFeatureService; import de.cismet.cismap.commons.featureservice.DocumentFeatureServiceFactory; import de.cismet.cismap.commons.featureservice.H2FeatureService; import de.cismet.cismap.commons.featureservice.LayerProperties; import de.cismet.cismap.commons.featureservice.ShapeFileFeatureService; import de.cismet.cismap.commons.featureservice.WebFeatureService; import de.cismet.cismap.commons.gui.capabilitywidget.SelectionAndCapabilities; import de.cismet.cismap.commons.gui.capabilitywidget.WFSSelectionAndCapabilities; import de.cismet.cismap.commons.internaldb.DBTableInformation; import de.cismet.cismap.commons.raster.wms.SlidableWMSServiceLayerGroup; import de.cismet.cismap.commons.raster.wms.WMSServiceLayer; import de.cismet.cismap.commons.rasterservice.ImageFileUtils; import de.cismet.cismap.commons.rasterservice.ImageRasterService; import de.cismet.cismap.commons.util.DnDUtils; import de.cismet.cismap.commons.wfs.capabilities.FeatureType; import de.cismet.tools.gui.StaticSwingTools; /** * DOCUMENT ME! * * @author therter * @version $Revision$, $Date$ */ public class LayerDropUtils { //~ Static fields/initializers --------------------------------------------- public static final Logger LOG = Logger.getLogger(LayerDropUtils.class); //~ Methods ---------------------------------------------------------------- /** * DOCUMENT ME! * * @param data DOCUMENT ME! * @param activeLayerModel DOCUMENT ME! * @param parent DOCUMENT ME! * * @return DOCUMENT ME! */ public static boolean drop(final Collection<File> data, final ActiveLayerModel activeLayerModel, final JComponent parent) { if (LOG.isDebugEnabled()) { LOG.debug("Drag&Drop File List: " + data); // NOI18N } if (data != null) { if (handleFiles(data, activeLayerModel, -1, parent)) { return true; } } else { LOG.warn("No files available"); // NOI18N } return false; } /** * Handles a layer drop event. * * @param dtde the data of the drop event * @param activeLayerModel the model to add * @param parent a component that is used to message dialogs, if required */ public static void drop(final java.awt.dnd.DropTargetDropEvent dtde, final ActiveLayerModel activeLayerModel, final JComponent parent) { drop(new DnDUtils.TransferSupportWrapper(dtde), activeLayerModel, parent, -1); } /** * Handles a layer drop event. * * @param support the data of the drop event * @param activeLayerModel the model to add * @param index the index, the dropped element should be added * @param parent a component that is used to message dialogs, if required * * @return true, if the given element was added */ public static boolean drop(final TransferHandler.TransferSupport support, final ActiveLayerModel activeLayerModel, final int index, final JComponent parent) { return drop(new DnDUtils.TransferSupportWrapper(support), activeLayerModel, parent, index); } /** * DOCUMENT ME! * * @param dtde the data of the drop event * @param activeLayerModel the model to add * @param parent a component that is used to message dialogs, if required * @param index the index, the dropped element should be added or -1 if it should be added on top * * @return DOCUMENT ME! */ private static boolean drop(final DnDUtils.TransferSupportWrapper dtde, final ActiveLayerModel activeLayerModel, final JComponent parent, final int index) { final DataFlavor TREEPATH_FLAVOR = new DataFlavor( DataFlavor.javaJVMLocalObjectMimeType, "SelectionAndCapabilities"); // NOI18N if (LOG.isDebugEnabled()) { LOG.debug("Drop with this flavors:" + dtde.getCurrentDataFlavorsAsList()); // NOI18N } if (DnDUtils.isFilesOrUriList(dtde)) { dtde.acceptDrop(DnDConstants.ACTION_COPY); try { final List<File> data = DnDUtils.getFilesFrom(dtde); drop(data, activeLayerModel, parent); } catch (final Exception ex) { LOG.error("Failure during drag & drop opertation", ex); // NOI18N } } else if (dtde.isDataFlavorSupported(TREEPATH_FLAVOR)) { try { if (LOG.isDebugEnabled()) { LOG.debug("There are " + dtde.getTransferable().getTransferDataFlavors().length + " DataFlavours"); // NOI18N } for (int i = 0; i < dtde.getTransferable().getTransferDataFlavors().length; ++i) { if (LOG.isDebugEnabled()) { LOG.debug("DataFlavour" + i + ": " + dtde.getTransferable().getTransferDataFlavors()[i]); // NOI18N } } final Object o = dtde.getTransferable().getTransferData(TREEPATH_FLAVOR); final List<TreePath> v = new ArrayList<TreePath>(); dtde.dropComplete(true); if (o instanceof SelectionAndCapabilities) { final TreePath[] tpa = ((SelectionAndCapabilities)o).getSelection(); for (int i = 0; i < tpa.length; ++i) { v.add(tpa[i]); } if (isSlidableWMSServiceLayerGroup(v.get(0).getLastPathComponent())) { final SlidableWMSServiceLayerGroup l = new SlidableWMSServiceLayerGroup(v); l.setWmsCapabilities(((SelectionAndCapabilities)o).getCapabilities()); l.setCapabilitiesUrl(((SelectionAndCapabilities)o).getUrl()); if (index != -1) { activeLayerModel.addLayer(l, activeLayerModel.layers.size() - index); } else { activeLayerModel.addLayer(l); } return true; } else { WMSServiceLayer l; if (((SelectionAndCapabilities)o).getUrl().contains("cismap.dont.touch.ordering=true")) { l = new WMSServiceLayer(v, false, false); } else { l = new WMSServiceLayer(v, true, true); } if (LOG.isDebugEnabled()) { LOG.debug("((SelectionAndCapabilities)o).getUrl()" + ((SelectionAndCapabilities)o).getUrl()); // NOI18N } l.setWmsCapabilities(((SelectionAndCapabilities)o).getCapabilities()); l.setCapabilitiesUrl(((SelectionAndCapabilities)o).getUrl()); if (index != -1) { activeLayerModel.addLayer(l, activeLayerModel.layers.size() - index); } else { activeLayerModel.addLayer(l); } return true; } } else if (o instanceof WFSSelectionAndCapabilities) { // Drop-Objekt war ein WFS-Element final WFSSelectionAndCapabilities sac = (WFSSelectionAndCapabilities)o; for (final FeatureType feature : sac.getFeatures()) { try { final WebFeatureService wfs = new WebFeatureService(feature.getPrefixedNameString(), feature.getWFSCapabilities().getURL().toString(), feature.getWFSQuery(), feature.getFeatureAttributes(), feature, sac.isReverseAxisOrder()); if ((sac.getIdentifier() != null) && (sac.getIdentifier().length() > 0)) { if (LOG.isDebugEnabled()) { LOG.debug("setting PrimaryAnnotationExpression of WFS Layer to '" + sac.getIdentifier() + "' (EXPRESSIONTYPE_PROPERTYNAME)"); // NOI18N } wfs.getLayerProperties() .setPrimaryAnnotationExpression(sac.getIdentifier(), LayerProperties.EXPRESSIONTYPE_PROPERTYNAME); } else { LOG.warn("could not determine PrimaryAnnotationExpression"); // NOI18N } if (index != -1) { activeLayerModel.addLayer(wfs, activeLayerModel.layers.size() - index); } else { activeLayerModel.addLayer(wfs); } } catch (final IllegalArgumentException schonVorhanden) { JOptionPane.showMessageDialog( parent, org.openide.util.NbBundle.getMessage( LayerWidget.class, "LayerWidget.drop(DropTargetDropEvent).JOptionPane.message"), // NOI18N org.openide.util.NbBundle.getMessage( LayerWidget.class, "LayerWidget.drop(DropTargetDropEvent).JOptionPane.title"), // NOI18N JOptionPane.ERROR_MESSAGE); return false; } } return true; } else if (o instanceof LayerConfig[]) { for (final LayerConfig config : (LayerConfig[])o) { if (index != -1) { activeLayerModel.addLayer((config).createConfiguredLayer(), activeLayerModel.layers.size() - index); } else { activeLayerModel.addLayer((config).createConfiguredLayer()); } } return true; } else if (o instanceof File) { final List<File> list = new ArrayList<File>(1); list.add((File)o); if (handleFiles(list, activeLayerModel, index, parent)) { return true; } } else if (o instanceof DBTableInformation[]) { final DBTableInformation[] infos = (DBTableInformation[])o; for (final DBTableInformation i : infos) { if (i.isFolder()) { final LayerCollection lc = createH2Folder(i); lc.setModel(activeLayerModel); if (index != -1) { activeLayerModel.addLayer(lc, activeLayerModel.layers.size() - index); } else { activeLayerModel.addLayer(lc, 0); } } else { final H2FeatureService layer = new H2FeatureService(i.getName(), i.getDatabasePath(), i.getDatabaseTable(), null); if (index != -1) { activeLayerModel.addLayer(layer, activeLayerModel.layers.size() - index); } else { activeLayerModel.addLayer(layer); } } } } } catch (final IllegalArgumentException schonVorhanden) { JOptionPane.showMessageDialog( parent, org.openide.util.NbBundle.getMessage( LayerWidget.class, "LayerWidget.drop(DropTargetDropEvent).JOptionPane.message"), // NOI18N org.openide.util.NbBundle.getMessage( LayerWidget.class, "LayerWidget.drop(DropTargetDropEvent).JOptionPane.title"), // NOI18N JOptionPane.ERROR_MESSAGE); } catch (final Exception e) { LOG.error(e, e); } } else { LOG.warn("No Matching dataFlavour: " + dtde.getCurrentDataFlavorsAsList()); // NOI18N } return false; } /** * DOCUMENT ME! * * @param i DOCUMENT ME! * * @return DOCUMENT ME! * * @throws Exception DOCUMENT ME! */ private static LayerCollection createH2Folder(final DBTableInformation i) throws Exception { final LayerCollection lc = new LayerCollection(); lc.setName(i.getName()); for (final DBTableInformation tmp : i.getChildren()) { if (tmp.isFolder()) { lc.add(createH2Folder(tmp)); } else { final H2FeatureService layer = new H2FeatureService(tmp.getName(), tmp.getDatabasePath(), tmp.getDatabaseTable(), null); lc.add(layer); } } return lc; } /** * DOCUMENT ME! * * @param data DOCUMENT ME! * @param activeLayerModel DOCUMENT ME! * @param index DOCUMENT ME! * @param parent DOCUMENT ME! * * @return DOCUMENT ME! */ public static boolean handleFiles(final Collection<File> data, final ActiveLayerModel activeLayerModel, final int index, final Component parent) { boolean success = false; for (final File currentFile : data) { if (handleFile(currentFile, activeLayerModel, index, parent)) { success = true; } } return success; } /** * DOCUMENT ME! * * @param currentFile DOCUMENT ME! * @param activeLayerModel DOCUMENT ME! * @param index DOCUMENT ME! * @param parent DOCUMENT ME! * * @return DOCUMENT ME! */ public static boolean handleFile(final File currentFile, final ActiveLayerModel activeLayerModel, final int index, final Component parent) { LOG.info("DocumentUri: " + currentFile.toURI()); // NOI18N if (ImageFileUtils.isImageFileEnding(currentFile.getName())) { return handleImageFile( currentFile, activeLayerModel, index, parent, ImageFileUtils.determineMode(currentFile)); } else { return handleFeatureServiceFile(currentFile, activeLayerModel, index, parent); } } /** * DOCUMENT ME! * * @param currentFile DOCUMENT ME! * @param activeLayerModel DOCUMENT ME! * @param index DOCUMENT ME! * @param parent DOCUMENT ME! * @param imageFileMode DOCUMENT ME! * * @return DOCUMENT ME! */ public static boolean handleImageFile(final File currentFile, final ActiveLayerModel activeLayerModel, final int index, final Component parent, final ImageFileUtils.Mode imageFileMode) { final ImageRasterService irs = new ImageRasterService(currentFile, imageFileMode); if (index != -1) { activeLayerModel.addLayer(irs, activeLayerModel.layers.size() - index); } else { activeLayerModel.addLayer(irs); } return true; } /** * DOCUMENT ME! * * @param currentFile DOCUMENT ME! * @param activeLayerModel DOCUMENT ME! * @param index DOCUMENT ME! * @param parent DOCUMENT ME! * * @return DOCUMENT ME! */ public static boolean handleFeatureServiceFile(final File currentFile, final ActiveLayerModel activeLayerModel, final int index, final Component parent) { try { final AbstractFeatureService dfs = DocumentFeatureServiceFactory.createDocumentFeatureService( currentFile); if (index != -1) { activeLayerModel.addLayer(dfs, activeLayerModel.layers.size() - index); } else { activeLayerModel.addLayer(dfs); } if (dfs instanceof ShapeFileFeatureService) { new Thread(new Runnable() { @Override public void run() { do { try { Thread.sleep(500); } catch (final InterruptedException e) { // nothing to do } } while (!dfs.isInitialized()); if (((ShapeFileFeatureService)dfs).isErrorInGeometryFound()) { JOptionPane.showMessageDialog( StaticSwingTools.getParentFrame(parent), NbBundle.getMessage( LayerWidget.class, "LayerWidget.drop().errorInShapeGeometryFoundMessage"), NbBundle.getMessage( LayerWidget.class, "LayerWidget.drop().errorInShapeGeometryFoundTitle"), JOptionPane.ERROR_MESSAGE); } else if (((ShapeFileFeatureService)dfs).isNoGeometryRecognised()) { JOptionPane.showMessageDialog( StaticSwingTools.getParentFrame(parent), NbBundle.getMessage( LayerWidget.class, "LayerWidget.drop().noGeometryFoundInShapeMessage"), NbBundle.getMessage( LayerWidget.class, "LayerWidget.drop().noGeometryFoundInShapeTitle"), JOptionPane.WARNING_MESSAGE); } } }).start(); } } catch (final Exception ex) { LOG.error("Error during creation of a FeatureServices", ex); // NOI18N return false; } return true; } /** * Checks, if the given object is a SlidableWMSServiceLayerGroup. * * @param lastPathComponent the object to check * * @return true, if the given object is a SlidableWMSServiceLayerGroup */ private static boolean isSlidableWMSServiceLayerGroup(final Object lastPathComponent) { de.cismet.cismap.commons.wms.capabilities.deegree.DeegreeLayer layer = null; if (lastPathComponent instanceof de.cismet.cismap.commons.wms.capabilities.deegree.DeegreeLayer) { layer = (de.cismet.cismap.commons.wms.capabilities.deegree.DeegreeLayer)lastPathComponent; } else { return false; } final List<String> keywords = Arrays.asList(layer.getKeywords()); return keywords.contains("cismapSlidingLayerGroup"); } }