it.tidalwave.geo.viewer.impl.DefaultGeoViewProviderManager Maven / Gradle / Ivy
/***********************************************************************************************************************
*
* forceTen - open source geography
* Copyright (C) 2007-2012 by Tidalwave s.a.s. (http://www.tidalwave.it)
*
***********************************************************************************************************************
*
* Licensed 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.
*
***********************************************************************************************************************
*
* WWW: http://forceten.tidalwave.it
* SCM: https://bitbucket.org/tidalwave/forceten-src
*
**********************************************************************************************************************/
package it.tidalwave.geo.viewer.impl;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Provider;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.text.Collator;
import javax.swing.SwingUtilities;
import org.jdesktop.observablecollections.ObservableCollections;
import org.jdesktop.observablecollections.ObservableList;
import org.openide.util.Lookup;
import org.openide.util.Parameters;
import org.openide.util.RequestProcessor;
import it.tidalwave.util.logging.Logger;
import it.tidalwave.netbeans.windows.role.PresentationLocker;
import it.tidalwave.geo.Coordinate;
import it.tidalwave.geo.viewer.GeoViewProviderManager;
import it.tidalwave.geo.viewer.spi.GeoViewProviderSupport;
import it.tidalwave.geo.viewer.spi.GeoViewProvider;
import it.tidalwave.geo.viewer.impl.spi.VoidGeoViewProvider;
import org.netbeans.platformx.inject.api.Injector;
/***********************************************************************************************************************
*
* @author Fabrizio Giudici
* @version $Id$
*
**********************************************************************************************************************/
public class DefaultGeoViewProviderManager implements GeoViewProviderManager
{
private static final String CLASS = DefaultGeoViewProviderManager.class.getName();
private static final Logger logger = Logger.getLogger(CLASS);
private static final int PROVIDER_INITIALIZATION_TIMEOUT = 3000;
private static final GeoViewProviderSupport VOID_GEO_VIEW_PROVIDER = new VoidGeoViewProvider();
private static final Comparator COMP1 = new Comparator()
{
private final Collator collator = Collator.getInstance();
@Override
public int compare (final GeoViewProvider gp1, final GeoViewProvider gp2)
{
return collator.compare(gp1.getName(), gp2.getName());
}
};
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
@Inject
protected Lookup lookup;
@Inject
protected Provider presentationLocker;
protected final ObservableList geoViewProviders =
ObservableCollections.observableList(new ArrayList());
protected GeoViewProviderSupport selectedGeoViewProvider = VOID_GEO_VIEW_PROVIDER;
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void setSelectedGeoViewProvider (final @Nonnull GeoViewProvider selectedGeoViewProvider)
{
logger.fine("setSelectedGeoViewProvider(%s)", selectedGeoViewProvider);
if (selectedGeoViewProvider == null) // FIXME: shouldn't be there, but it gets invoked at boot
{
return;
}
Parameters.notNull("selectedGeoViewProvider", selectedGeoViewProvider);
assert selectedGeoViewProvider != null; // for FindBugs
if (!selectedGeoViewProvider.isReady())
{
return;
}
final GeoViewProvider oldSelectedGeoViewProvider = this.selectedGeoViewProvider;
final Coordinate centerPosition = this.selectedGeoViewProvider.getCenterPosition();
final int zoom = this.selectedGeoViewProvider.getZoom() - this.selectedGeoViewProvider.getMaximumZoomLevel();
final GeoViewProvider.LifeCycle oldLifeCycle = this.selectedGeoViewProvider;
presentationLocker.get().lock("");
oldLifeCycle.deactivating();
selectedGeoViewProvider.setCoordinatesTracker(GeoViewProvider.CoordinateTracker.VOID);
oldLifeCycle.deactivated();
this.selectedGeoViewProvider = (GeoViewProviderSupport)selectedGeoViewProvider; // FIXME: drop the cast
final GeoViewProvider.LifeCycle newLifeCycle = this.selectedGeoViewProvider;
newLifeCycle.activating();
if (centerPosition != null)
{
try
{
selectedGeoViewProvider.setCenterPosition(centerPosition);
}
catch (Exception e) // FIXME: the above gives problems with WWJ
{
logger.severe(e.toString());
}
selectedGeoViewProvider.setZoom(zoom + selectedGeoViewProvider.getMaximumZoomLevel());
}
newLifeCycle.activated();
presentationLocker.get().unlock();
propertyChangeSupport.firePropertyChange(PROP_SELECTED_GEO_VIEW_PROVIDER, oldSelectedGeoViewProvider, selectedGeoViewProvider);
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
@Nonnull
public GeoViewProvider getSelectedGeoViewProvider()
{
return selectedGeoViewProvider;
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
@Nonnull
public ObservableList getGeoViewProviders()
{
return geoViewProviders;
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void addPropertyChangeListener (final @Nonnull PropertyChangeListener listener)
{
propertyChangeSupport.addPropertyChangeListener(listener);
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void removePropertyChangeListener (final @Nonnull PropertyChangeListener listener)
{
propertyChangeSupport.removePropertyChangeListener(listener);
}
/*******************************************************************************************************************
*
*
*
******************************************************************************************************************/
@PostConstruct
@SuppressWarnings("PMD.UnusedPrivateMethod") @edu.umd.cs.findbugs.annotations.SuppressWarnings("UPM_UNCALLED_PRIVATE_METHOD")
protected void initialize() // FIXME: make private once you can invoke it from tests
{
if (!SwingUtilities.isEventDispatchThread())
{
throw new IllegalStateException("Must be called inside the AWT Thread");
}
installProviders();
selectInitialProvider();
}
/*******************************************************************************************************************
*
* Scans for all GeoViewProvider
s and puts them in the combobox model.
*
******************************************************************************************************************/
@edu.umd.cs.findbugs.annotations.SuppressWarnings("SIC_INNER_SHOULD_BE_STATIC_ANON")
private void installProviders()
{
logger.info("installProviders()");
geoViewProviders.clear();
geoViewProviders.addAll(lookup.lookupAll(GeoViewProvider.class));
Collections.sort(geoViewProviders, COMP1);
logger.info(">>>> found GeoViewProviders: %s", geoViewProviders);
for (final GeoViewProvider geoViewProvider : geoViewProviders)
{
logger.fine(">>>>>>>> initializing: %s...", geoViewProvider);
Injector.getDefault().inject(geoViewProvider, lookup);
RequestProcessor.getDefault().post(new Runnable()
{
@Override
public void run()
{
geoViewProvider.initResources();
}
});
}
}
/*******************************************************************************************************************
*
* Select an initial provider. Providers are initialized in background to avoid blocking the GUI, but we have to
* wait at least until the first provider is ready since having no selected provider would cause NPEs later.
*
******************************************************************************************************************/
private void selectInitialProvider()
{
logger.info("selectInitialProvider()");
assert SwingUtilities.isEventDispatchThread() : "Must be called from the AWT Thread";
final long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < PROVIDER_INITIALIZATION_TIMEOUT)
{
for (final GeoViewProvider geoViewProvider : geoViewProviders)
{
logger.fine(">>>> %s is ready: %s", geoViewProvider, geoViewProvider.isReady());
if (geoViewProvider.isReady())
{
logger.info(">>>> %s selected as default", geoViewProvider);
setSelectedGeoViewProvider(geoViewProvider);
return;
}
}
logger.warning("No providers ready, retrying...");
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
break;
}
}
logger.severe("Couldn't set a default provider.");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy