org.geopublishing.atlasStyler.swing.AtlasStylerGUI.java Source code

Java tutorial

Introduction

Here is the source code for org.geopublishing.atlasStyler.swing.AtlasStylerGUI.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Stefan A. Tzeggai.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Stefan A. Tzeggai - initial API and implementation
 ******************************************************************************/
package org.geopublishing.atlasStyler.swing;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import javax.jnlp.SingleInstanceListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.xml.transform.TransformerException;

import org.apache.commons.lang.SystemUtils;
import org.apache.log4j.Logger;
import org.geopublishing.atlasStyler.ASProps;
import org.geopublishing.atlasStyler.ASProps.Keys;
import org.geopublishing.atlasStyler.ASUtil;
import org.geopublishing.atlasStyler.AsSwingUtil;
import org.geopublishing.atlasStyler.AtlasStylerVector;
import org.geopublishing.atlasStyler.swing.importWizard.ImportWizard;
import org.geopublishing.atlasViewer.GpCoreUtil;
import org.geopublishing.atlasViewer.JNLPUtil;
import org.geopublishing.atlasViewer.swing.AVSwingUtil;
import org.geopublishing.atlasViewer.swing.Icons;
import org.geopublishing.geopublisher.GpUtil;
import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
import org.geotools.data.DataStore;
import org.geotools.data.DataUtilities;
import org.geotools.data.shapefile.indexed.IndexedShapefileDataStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.Hints;
import org.geotools.map.event.MapLayerListEvent;
import org.geotools.map.event.MapLayerListListener;
import org.geotools.styling.NamedLayer;
import org.geotools.styling.SLDTransformer;
import org.geotools.styling.Style;
import org.geotools.styling.StyledLayerDescriptor;

import chrriis.dj.nativeswing.swtimpl.NativeInterface;
import de.schmitzm.geotools.MapContextManagerInterface;
import de.schmitzm.geotools.map.event.MapLayerListAdapter;
import de.schmitzm.geotools.styling.StyledFS;
import de.schmitzm.geotools.styling.StyledFeatureSourceInterface;
import de.schmitzm.geotools.styling.StyledLayerInterface;
import de.schmitzm.geotools.styling.StyledRasterInterface;
import de.schmitzm.geotools.styling.StylingUtil;
import de.schmitzm.i18n.Translation;
import de.schmitzm.io.IOUtil;
import de.schmitzm.lang.LangUtil;
import de.schmitzm.lang.ResourceProvider;
import de.schmitzm.swing.ExceptionDialog;
import de.schmitzm.swing.FileExtensionFilter;
import de.schmitzm.swing.ResourceProviderManagerFrame;
import de.schmitzm.swing.SwingUtil;
import de.schmitzm.versionnumber.ReleaseUtil;
import de.schmitzm.versionnumber.ReleaseUtil.License;

/**
 * This is the main GUI for the AtlasStyler standalone. It looks like a
 * condensed {@link AtlasViewer}, and its main purpose is to reach the "Style"
 * item in the tools menu.
 * 
 * @author Stefan A. Tzeggai
 * 
 */
public class AtlasStylerGUI extends JFrame implements SingleInstanceListener {

    static {
        AsSwingUtil.initAsLogging();

        // Vom Benutzer hinzugefgte bersetzungen aktivieren
        ResourceProvider.setAutoResetResourceBundle(true, "Translation", true);
    }

    private static final long serialVersionUID = 1231321321258008431L;

    final static private Logger LOGGER = LangUtil.createLogger(AtlasStylerGUI.class);

    private StylerMapView stylerMapView = null;

    final private HashMap<String, StyledLayerInterface<?>> styledObjCache = new HashMap<String, StyledLayerInterface<?>>();

    final private XMLCodeFrame xmlCodeFrame = new XMLCodeFrame(this, getStylerMapView().getMapManager());

    private final HashMap<String, DataStore> openDatastores = new HashMap<String, DataStore>();

    /**
     * This is the default constructor
     */
    public AtlasStylerGUI() {
        LOGGER.info("Starting " + AtlasStylerGUI.class.getSimpleName() + "... "
                + ReleaseUtil.getVersionInfo(GpCoreUtil.class));

        // Output information about the LGPL license
        LOGGER.info(ReleaseUtil.getLicense(License.LGPL3, "AtlasStyler"));

        LOGGER.debug("checking for correct permissions on tmpdir");
        GpUtil.checkAndResetTmpDir("/var/tmp");

        System.setProperty("file.encoding", "UTF-8");

        LOGGER.debug("checking for correct permissions on tmpdir");
        GpUtil.checkAndResetTmpDir("/var/tmp");

        JNLPUtil.registerAsSingleInstance(AtlasStylerGUI.this, true);

        initialize();

        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosed(WindowEvent e) {
                exitAS(0);
            }

            @Override
            public void windowClosing(WindowEvent e) {
                exitAS(0);
            }

        });

        /**
         * Setting a nice AtlasStylerGUI icons
         */
        List<Image> icons = new ArrayList<Image>(2);
        ClassLoader cl = AsSwingUtil.class.getClassLoader();
        final String imagePackageName = "icons/";
        icons.add(new ImageIcon(cl.getResource(imagePackageName + "as_icon16.png")).getImage());
        icons.add(new ImageIcon(cl.getResource(imagePackageName + "as_icon32.png")).getImage());
        icons.add(new ImageIcon(cl.getResource(imagePackageName + "as_icon64.png")).getImage());
        setIconImages(icons);

        AVSwingUtil.initEPSG(AtlasStylerGUI.this);
    }

    private void initialize() {
        this.setSize(750, 510);

        this.setJMenuBar(createMenuBar());

        this.setContentPane(getJContentPane());
        String AtlasStyler_MainWindowTitle = "AtlasStyler " + ReleaseUtil.getVersionInfo(GpCoreUtil.class);
        this.setTitle(AtlasStyler_MainWindowTitle);

        // In Xubuntu (OS-Geo Live DVD) the JFrame otherwise is hidden behind
        // the top-bar.
        SwingUtil.centerFrameOnScreen(this);
    }

    /**
     * Creates a nre {@link JMenuBar} instance
     */
    private JMenuBar createMenuBar() {
        JMenuBar jMenuBar = new JMenuBar();

        JMenu fileMenu = new JMenu(AsSwingUtil.R("MenuBar.FileMenu"));

        jMenuBar.add(fileMenu);

        { // Import WIzard
            JMenuItem mi = new JMenuItem(new AbstractAction(AsSwingUtil.R("MenuBar.FileMenu.ImportWizard")) {

                @Override
                public void actionPerformed(ActionEvent e) {
                    ImportWizard.showWizard(AtlasStylerGUI.this, AtlasStylerGUI.this);
                }
            });
            mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.CTRL_MASK, true));
            fileMenu.add(mi);
        }

        fileMenu.add(SwingUtil.createChangeLog4JLevelJMenu());

        /**
         * MenuItem to create a new language
         */
        JMenuItem manageLanguageJMenuitem = new JMenuItem(
                new AbstractAction(ASUtil.R("TranslateSoftwareDialog.Title"), Icons.ICON_FLAGS_SMALL) {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        String resPath = IOUtil
                                .escapePath(System.getProperty("user.home") + File.separator + ".Geopublishing");
                        ResourceProviderManagerFrame manLanguagesFrame = new ResourceProviderManagerFrame(
                                AtlasStylerGUI.this, true, AsSwingUtil.R("TranslateSoftwareDialog.Explanation.Html",
                                        resPath, SystemUtils.IS_OS_WINDOWS ? "bat" : "sh"));
                        manLanguagesFrame.setRootPath(new File(resPath));
                        manLanguagesFrame.setTitle(ASUtil.R("TranslateSoftwareDialog.Title"));
                        manLanguagesFrame.setPreferredSize(new Dimension(780, 450));
                        manLanguagesFrame.setVisible(true);
                    }
                });
        fileMenu.add(manageLanguageJMenuitem);

        AbstractAction optionsButton = new AbstractAction(AtlasStylerVector.R("Options.ButtonLabel")) {

            @Override
            public void actionPerformed(ActionEvent e) {
                new ASOptionsDialog(AtlasStylerGUI.this, AtlasStylerGUI.this);
            }
        };

        fileMenu.add(optionsButton);

        { // Exit
            JMenuItem mi = new JMenuItem(new AbstractAction(
                    GpCoreUtil.R("AtlasViewer.FileMenu.ExitMenuItem.exit_application"), Icons.ICON_EXIT_SMALL) {

                @Override
                public void actionPerformed(ActionEvent e) {
                    exitAS(0);
                }
            });
            fileMenu.add(mi);
        }

        return jMenuBar;
    }

    /**
     * Closes the GUI of the stand-alone {@link AtlasStylerGUI}
     * 
     * @param exitCode
     *            Code to pass to System.exit()
     */
    protected void exitAS(int exitCode) {

        /*
         * Ask the use to save the changed SLDs
         */
        List<StyledLayerInterface<?>> styledObjects = getMapManager().getStyledObjects();
        for (StyledLayerInterface<?> styledObj : styledObjects) {
            // if (styledObj instanceof StyledFS) {
            // StyledFS stedFS = (StyledFS) styledObj;

            askToSaveSld(styledObj);

            // } else {
            // JOptionPane
            // .showMessageDialog(
            // AtlasStylerGUI.this,
            // "The type of "
            // + styledObj.getTitle()
            // + " is not recognized. That must be a bug. Sorry."); // i8n
            // continue;
            // }

        }
        dispose();

        for (DataStore ds : openDatastores.values()) {
            if (ds != null)
                ds.dispose();
        }
        openDatastores.clear();

        /*
         * Unregister from JNLP SingleInstanceService
         */
        JNLPUtil.registerAsSingleInstance(AtlasStylerGUI.this, false);

        // Store the Logging Level in ~/.AtlasStyler/atlasStyler.properties
        {
            ASProps.set(Keys.logLevel, Logger.getRootLogger().getLevel().toString());
            ASProps.store();
        }

        System.exit(exitCode);
    }

    /**
     * This method initializes jContentPane
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane() {
        JPanel jContentPane = new JPanel(new BorderLayout());
        jContentPane.add(getStylerMapView(), BorderLayout.CENTER);
        jContentPane.add(getJToolBar(), BorderLayout.NORTH);
        return jContentPane;
    }

    public StylerMapView getStylerMapView() {
        if (stylerMapView == null) {
            stylerMapView = new StylerMapView(this);
            stylerMapView.getMapManager().addMapLayerListListener(new MapLayerListListener() {

                public void layerAdded(MapLayerListEvent event) {
                }

                public void layerChanged(MapLayerListEvent event) {
                }

                public void layerMoved(MapLayerListEvent event) {
                }

                public void layerRemoved(MapLayerListEvent event) {
                    String id = event.getLayer().getTitle();
                    LOGGER.debug("layer id=" + id + " removed");

                    askToSaveSld(styledObjCache.get(id));
                    styledObjCache.remove(id);

                    // Dispose the datastore when removing the layer
                    DataStore openDs = openDatastores.get(id);
                    if (openDs != null)
                        openDs.dispose();
                }

                @Override
                public void layerPreDispose(MapLayerListEvent event) {
                    // TODO Auto-generated method stub

                }

            });
        }
        return stylerMapView;
    }

    /**
     * A very basic dialog to asking the user to store the .SLD file for a
     * layer.
     * 
     * @param styledLayer
     *            The {@link StyledFS} that links to the geodata.
     */
    protected void askToSaveSld(StyledLayerInterface<?> styledLayer) {

        File sldFile = styledLayer.getSldFile();

        // Only ask to save if the style has changed
        if (!StylingUtil.isStyleDifferent(styledLayer.getStyle(), sldFile))
            return;

        if (sldFile == null) {
            // There is no .SLD set so far. Lets ask the user where to save it.

            styledLayer.setSldFile(sldFile);
            // TODO no SLD, ask the user!
            throw new RuntimeException("Not yet implemented. Please contact the authors.");
        }

        if (!SwingUtil.askYesNo(AtlasStylerGUI.this, ASUtil.R("AtlasStylerGUI.saveToSLDFileQuestion",
                styledLayer.getTitle(), IOUtil.escapePath(sldFile))))
            return;

        Style style = styledLayer.getStyle();

        if (style == null) {
            AVSwingUtil.showMessageDialog(AtlasStylerGUI.this,
                    "The Style for " + styledLayer.getTitle() + " is null. That must be a bug. Not saving.");
            return;
        }

        new AtlasStylerSaveLayerToSLDAction(this, styledLayer).actionPerformed(null);

    }

    /**
     * This method initializes jToolBar
     * 
     * @return javax.swing.JToolBar
     */
    private JToolBar getJToolBar() {
        JToolBar jToolBar = new JToolBar();

        jToolBar.setFloatable(false);

        AbstractAction importWiazrdAction = new AbstractAction(
                AtlasStylerVector.R("MenuBar.FileMenu.ImportWizard")) {

            @Override
            public void actionPerformed(ActionEvent e) {
                ImportWizard.showWizard(AtlasStylerGUI.this, AtlasStylerGUI.this);
            }
        };
        importWiazrdAction.putValue(Action.LONG_DESCRIPTION,
                KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.CTRL_MASK, true));
        jToolBar.add(importWiazrdAction);

        jToolBar.add(getJTButtonShowXML());
        jToolBar.add(getJTButtonExportAsSLD());

        return jToolBar;
    }

    public JToggleButton getJTButtonShowXML() {
        final JToggleButton jButtonShowXML = new JToggleButton(ASUtil.R("AtlasStylerGUI.toolbarButton.show_xml"));
        jButtonShowXML.setSelected(false);

        jButtonShowXML.addActionListener(new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                boolean anAus = !xmlCodeFrame.isVisible();
                xmlCodeFrame.setVisible(anAus);
                // jButtonShowXML.setSelected(anAus);
                xmlCodeFrame.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosed(WindowEvent e) {
                        jButtonShowXML.setSelected(false);
                    }
                });
            }

        });
        return jButtonShowXML;
    }

    /**
     * A button to export all layers in form of one SLD XML file (starting a
     * StyledLayerDescriptor tag)
     */
    private JButton getJTButtonExportAsSLD() {
        final JButton jButtonExportAsSLD = new JButton(ASUtil.R("AtlasStylerGUI.toolbarButton.exportSLD"));

        jButtonExportAsSLD.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    File saveDir = null;
                    String lastPath = ASProps.get(ASProps.Keys.lastExportDirectory);
                    if (lastPath != null)
                        saveDir = new File(lastPath);

                    File exportSLDFile = AsSwingUtil.chooseFileSave(AtlasStylerGUI.this, saveDir,
                            ASUtil.R("AtlasStylerGUI.saveStyledLayerDescFileDialogTitle"),
                            new FileExtensionFilter(ASUtil.FILTER_SLD));

                    // File exportSLDFile = chooser.getSelectedFile();
                    if (exportSLDFile == null
                            // || result != JFileChooser.APPROVE_OPTION
                            || exportSLDFile.isDirectory())
                        return;

                    ASProps.set(ASProps.Keys.lastExportDirectory, exportSLDFile.getParentFile().getAbsolutePath());

                    // If the file exists, the user will be asked about
                    // overwriting it
                    if (exportSLDFile.exists()) {
                        if (!AVSwingUtil.askOKCancel(AtlasStylerGUI.this,
                                AtlasStylerVector.R(
                                        "AtlasStylerGUI.saveStyledLayerDescFileDialogTitle.OverwriteQuestion",
                                        exportSLDFile.getName())))
                            return;
                    }

                    // Evt. wird .sld angehangen.
                    String filenamelc = exportSLDFile.getName().toLowerCase();
                    if (!filenamelc.endsWith(".sld") && !filenamelc.endsWith(".xml")
                            && !filenamelc.endsWith(".se")) {
                        exportSLDFile = new File(exportSLDFile.getParentFile(), filenamelc + ".sld");
                        JOptionPane.showMessageDialog(AtlasStylerGUI.this,
                                AsSwingUtil.R("AtlasStylerGUI.FileNameChangeTo.msg", exportSLDFile.getName()));
                    }

                    // // Export
                    // Charset charset = Charset.forName("UTF-8");
                    StyledLayerDescriptor sldTag = CommonFactoryFinder.getStyleFactory(null)
                            .createStyledLayerDescriptor();

                    /*******
                     * Export aller Styles als ein SLD Tag
                     */
                    for (StyledLayerInterface smi : getMapManager().getStyledObjects()) {

                        try {
                            // if (!(smi instanceof StyledFS)) {
                            // LOGGER.info("Ein Layer aus dem MapContextManagerInterface ist kein StyledFeatureSourceInterface. Es wird ignoriert: "
                            // + smi.getTitle());
                            // continue;
                            // }

                            String name = null;
                            if (smi instanceof StyledFeatureSourceInterface) {
                                StyledFeatureSourceInterface featureGeoObj = (StyledFeatureSourceInterface) smi;
                                name = featureGeoObj.getGeoObject().getSchema().getTypeName();
                            } else if (smi instanceof StyledRasterInterface) {
                                StyledRasterInterface ri = (StyledRasterInterface) smi;
                                if (ri.getGeoObject() instanceof AbstractGridCoverage2DReader) {
                                    AbstractGridCoverage2DReader agcr = (AbstractGridCoverage2DReader) ri
                                            .getGeoObject();
                                    if (agcr.getSource() instanceof File) {
                                        File rfile = (File) agcr.getSource();
                                        name = IOUtil.changeFileExt(rfile, "").getName();
                                    } else
                                        name = "someraster";
                                } else
                                    name = "someraster";
                            }

                            NamedLayer namedLayer = CommonFactoryFinder.getStyleFactory(null).createNamedLayer();
                            namedLayer.setName(name);
                            namedLayer.addStyle(smi.getStyle());

                            sldTag.addStyledLayer(namedLayer);
                        } catch (Exception e1) {
                            ExceptionDialog.show(AtlasStylerGUI.this, e1);
                        }
                    }

                    Writer w = null;
                    final SLDTransformer aTransformer = new SLDTransformer();
                    // if (charset != null) {
                    // aTransformer.setEncoding(charset);
                    // }
                    aTransformer.setIndentation(2);
                    final String xml = aTransformer.transform(sldTag);
                    w = new FileWriter(exportSLDFile);
                    w.write(xml);
                    w.close();
                } catch (IOException e1) {
                    ExceptionDialog.show(AtlasStylerGUI.this, e1);
                } catch (TransformerException e2) {
                    ExceptionDialog.show(AtlasStylerGUI.this, e2);
                }

            }

        });

        /**
         * Activate the button when more than one layer is available
         */
        jButtonExportAsSLD.setEnabled(getMapManager().getMapContext().getLayerCount() > 0);
        getMapManager().addMapLayerListListener(new MapLayerListAdapter() {

            @Override
            public void layerRemoved(MapLayerListEvent arg0) {
                jButtonExportAsSLD.setEnabled(getMapManager().getMapContext().getLayerCount() > 0);
            }

            @Override
            public void layerAdded(MapLayerListEvent arg0) {
                jButtonExportAsSLD.setEnabled(true);
            }
        });

        return jButtonExportAsSLD;
    }

    /**
     * Adds a layer to the map context to style it.
     */
    public boolean addLayer(StyledLayerInterface<?> styledFS) {

        if (styledFS.getStyle() == null) {
            // Einen default Style erstellen
            {
                // AVSwingUtil.showMessageDialog(this, AtlasStyler.R(
                // "AtlasStylerGUI.importVectorLayerNoSLD", styledFS
                // .getSldFile().getName()));
                styledFS.setStyle(AsSwingUtil.createDefaultStyle(styledFS));
            }
        }

        styledObjCache.put(styledFS.getId(), styledFS);
        return getMapManager().addStyledLayer(styledFS);
    }

    public MapContextManagerInterface getMapManager() {
        return getStylerMapView().getMapManager();
    }

    /**
     * AtlasStylerGUI main method.
     * 
     * @param args
     */
    public static void main(final String[] args) throws IOException {
        // System.out.println("Classpath: "+System.getProperty("java.class.path"));

        // Set the locale for running the application
        try {
            if (!ASProps.get(Keys.language, "system").equalsIgnoreCase("system")) {

                Translation.setDefaultLocale(new Locale(ASProps.get(Keys.language, "en")));

            }
        } catch (Exception e) {
            LOGGER.error("Could not set locale to " + ASProps.get(Keys.language), e);
            ExceptionDialog.show(e);
        }

        // Setup the AXIS order property TODO in settings GUI!
        Hints.putSystemDefault(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER,
                ASProps.get(Keys.FORCE_LONGITUDE_FIRST_AXIS_ORDER, true));

        /**
         * Check for addFix arguments. If found, the GUI will not start,
         */
        boolean addedIndexes = checkFixIndexCreation(args);

        if (!addedIndexes) {

            try {
                NativeInterface.open();
            } catch (Throwable e) {
                LOGGER.warn("Couldn't initialize the SWT subsystem. Trying fallback to Swing.", e);
            }

            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    AtlasStylerGUI asg = new AtlasStylerGUI();

                    // TODO Switch to Apache Commons-CLI
                    if (args.length != 0) {
                        LOGGER.warn(
                                "Sorry, command line arguments are ignored in this version. Please contact geopublishing.org if you need this function.");
                    }
                    asg.setVisible(true);
                }
            });

            try {
                NativeInterface.runEventPump();
            } catch (Throwable e) {
                LOGGER.warn("Couldn't initialize the SWT subsystem. Trying fallback to Swing.", e);
            }

        } else {
            LOGGER.info("Not starting GUI because command line parameter addFix was passed");
            System.out.println("Not starting GUI because command line parameter addFix was passed");
        }

    }

    /**
     * This method is evaluating command line arguments to look for
     * "addFix=FILE" paramters. If at least one "addFix=" parameter is passen,
     * the method returns <code>true</code> and the application is expected not
     * to start a GUI.
     */
    private static boolean checkFixIndexCreation(String[] args) {
        boolean fixParamFound = false;

        if (args.length != 0) {
            for (String param : args) {

                // Allows "addFix=/Eigene Dateien/Meine Dateien" etc...
                if ((param.startsWith("\"")) && (param.endsWith("\""))) {
                    param = param.substring(1, param.length() - 1);
                }

                // Here we just handle addFix paramters (for now)
                if (!param.startsWith("addFix="))
                    continue;

                param = param.substring(7);

                // Remember that a paramter was interpreted and the mnethod has
                // to return true
                fixParamFound = true;

                final File fileParamter = new File(param);

                if (!fileParamter.exists()) {
                    LOGGER.warn("Not understanding " + param + " as file to add an index.");
                    continue;
                }

                if (!fileParamter.canWrite()) {
                    LOGGER.warn("Can't write to " + param + " due to missing permissions, skipping.");
                    continue;
                }

                // Starting the .fix creation
                final URL shpUrl = DataUtilities.fileToURL(fileParamter);
                try {
                    final IndexedShapefileDataStore ds = new IndexedShapefileDataStore(shpUrl);
                    try {
                        ds.createSpatialIndex();
                    } catch (final IOException e) {
                        LOGGER.warn("", e);
                    } finally {
                        ds.dispose();
                    }

                    LOGGER.info("Added .fix to " + fileParamter);

                } catch (final MalformedURLException e) {
                    LOGGER.warn("Error adding a .fix to " + param, e);
                }
            }
        }

        return fixParamFound;
    }

    /**
     * Called via SingleInstanceListener / SingleInstanceService. Does nothing
     * except requesting the focus for the given application.
     */
    @Override
    public void newActivation(String[] arg0) {
        LOGGER.info(
                "A second instance of AtlasViewer has been started.. The single instance if requesting focus now...");
        requestFocus();
        toFront();
    }

    public void addOpenDatastore(String layerId, DataStore ds) {
        openDatastores.put(layerId, ds);
    }

}