Java tutorial
/******************************************************************************* * Copyright (C) 2005, 2010 Wolfgang Schramm and Contributors * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA *******************************************************************************/ package de.byteholder.geoclipse.mapprovider; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.concurrent.locks.ReentrantLock; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import net.tourbook.util.StatusUtil; import net.tourbook.util.StringToArrayConverter; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IMemento; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.XMLMemento; import org.geotools.data.ows.CRSEnvelope; import org.geotools.data.ows.Layer; import org.geotools.data.ows.Service; import org.geotools.data.ows.WMSCapabilities; import org.geotools.data.wms.WebMapServer; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; import org.opengis.geometry.DirectPosition; import org.osgi.framework.Version; import org.w3c.dom.Document; import org.w3c.dom.Element; import de.byteholder.geoclipse.Activator; import de.byteholder.geoclipse.GeoclipseExtensions; import de.byteholder.geoclipse.Messages; import de.byteholder.geoclipse.logging.GeoException; import de.byteholder.geoclipse.map.TileImageCache; import de.byteholder.geoclipse.map.UI; import de.byteholder.geoclipse.mapprovider.DialogMPCustom.PART_TYPE; import de.byteholder.geoclipse.preferences.IMappingPreferences; import de.byteholder.gpx.GeoPosition; /** * this will manage all map providers */ public class MapProviderManager { /** * This prefix is used to sort the map providers at the end when the map provider is not a map * profile */ private static final String SINGLE_MAP_PROVIDER_NAME_PREFIX = "_"; //$NON-NLS-1$ private static final int OSM_BACKGROUND_COLOR = 0xE8EEF1; private static final int DEFAULT_ALPHA = 100; private static final String URL_PREFIX_HTTP = "http"; //$NON-NLS-1$ private static final String URL_PREFIX_HTTP_PROTOCOL = "http://"; //$NON-NLS-1$ private static final String MAP_PROVIDER_TYPE_WMS = "wms"; //$NON-NLS-1$ private static final String MAP_PROVIDER_TYPE_CUSTOM = "custom"; //$NON-NLS-1$ private static final String MAP_PROVIDER_TYPE_MAP_PROFILE = "profile"; //$NON-NLS-1$ private static final String MAP_PROVIDER_TYPE_PLUGIN = "plugin"; //$NON-NLS-1$ public static final String MIME_PNG = "image/png"; //$NON-NLS-1$ public static final String MIME_GIF = "image/gif"; //$NON-NLS-1$ public static final String MIME_JPG = "image/jpg"; //$NON-NLS-1$ public static final String MIME_JPEG = "image/jpeg"; //$NON-NLS-1$ public static final String DEFAULT_IMAGE_FORMAT = MIME_PNG; public static final String FILE_EXTENSION_PNG = "png"; //$NON-NLS-1$ public static final String FILE_EXTENSION_GIF = "gif"; //$NON-NLS-1$ public static final String FILE_EXTENSION_JPG = "jpg"; //$NON-NLS-1$ /** * This file name part is attached to saved tile images for profile map providers were only a * part of the child images are available. */ public static final String PART_IMAGE_FILE_NAME_SUFFIX = "-part"; //$NON-NLS-1$ /* * map provider file and root tag */ private static final String CUSTOM_MAP_PROVIDER_FILE = "custom-map-provider.xml"; //$NON-NLS-1$ private static final String TAG_MAP_PROVIDER_LIST = "MapProviderList"; //$NON-NLS-1$ private static final String ATTR_ROOT_DATETIME = "Created"; //$NON-NLS-1$ private static final String ATTR_ROOT_VERSION_MAJOR = "VersionMajor"; //$NON-NLS-1$ private static final String ATTR_ROOT_VERSION_MINOR = "VersionMinor"; //$NON-NLS-1$ private static final String ATTR_ROOT_VERSION_MICRO = "VersionMicro"; //$NON-NLS-1$ private static final String ATTR_ROOT_VERSION_QUALIFIER = "VersionQualifier"; //$NON-NLS-1$ private static final String ATTR_ROOT_IS_MANUAL_EXPORT = "IsExport"; //$NON-NLS-1$ /* * map provider common fields */ private static final String ROOT_CHILD_TAG_MAP_PROVIDER = "MapProvider"; //$NON-NLS-1$ /** * tag for map providers which are wrapped into a map profile */ private static final String ROOT_CHILD_TAG_WRAPPED_MAP_PROVIDER = "WrappedMapProvider"; //$NON-NLS-1$ private static final String ATTR_MP_NAME = "Name"; //$NON-NLS-1$ private static final String ATTR_MP_ID = "Id"; //$NON-NLS-1$ private static final String ATTR_MP_DESCRIPTION = "Description"; //$NON-NLS-1$ private static final String ATTR_MP_OFFLINE_FOLDER = "OfflineFolder"; //$NON-NLS-1$ private static final String ATTR_MP_TYPE = "Type"; //$NON-NLS-1$ private static final String ATTR_MP_IMAGE_SIZE = "ImageSize"; //$NON-NLS-1$ private static final String ATTR_MP_IMAGE_FORMAT = "ImageFormat"; //$NON-NLS-1$ private static final String ATTR_MP_ZOOM_LEVEL_MIN = "ZoomMin"; //$NON-NLS-1$ private static final String ATTR_MP_ZOOM_LEVEL_MAX = "ZoomMax"; //$NON-NLS-1$ private static final String ATTR_MP_LAST_USED_ZOOM_LEVEL = "LastUsedZoomLevel"; //$NON-NLS-1$ private static final String ATTR_MP_LAST_USED_LATITUDE = "LastUsedLatitude"; //$NON-NLS-1$ private static final String ATTR_MP_LAST_USED_LONGITUDE = "LastUsedLongitude"; //$NON-NLS-1$ private static final String ATTR_MP_FAVORITE_ZOOM_LEVEL = "FavoriteZoomLevel"; //$NON-NLS-1$ private static final String ATTR_MP_FAVORITE_LATITUDE = "FavoriteLatitude"; //$NON-NLS-1$ private static final String ATTR_MP_FAVORITE_LONGITUDE = "FavoriteLongitude"; //$NON-NLS-1$ /* * custom map provider */ private static final String ATTR_CUSTOM_CUSTOM_URL = "CustomUrl"; //$NON-NLS-1$ private static final String TAG_URL_PART = "UrlPart"; //$NON-NLS-1$ private static final String ATTR_CUSTOM_PART_TYPE = "PartType"; //$NON-NLS-1$ private static final String ATTR_CUSTOM_PART_POSITION = "Position"; //$NON-NLS-1$ private static final String ATTR_CUSTOM_PART_CONTENT_HTML = "Html"; //$NON-NLS-1$ private static final String ATTR_CUSTOM_PART_CONTENT_RANDOM_INTEGER_START = "RandomIntegerStart"; //$NON-NLS-1$ private static final String ATTR_CUSTOM_PART_CONTENT_RANDOM_INTEGER_END = "RandomIntegerEnd"; //$NON-NLS-1$ private static final String ATTR_CUSTOM_PART_CONTENT_RANDOM_ALPHA_START = "RandomAlphaStart"; //$NON-NLS-1$ private static final String ATTR_CUSTOM_PART_CONTENT_RANDOM_ALPHA_END = "RandomAlphaEnd"; //$NON-NLS-1$ private static final String PART_TYPE_HTML = "HTML"; //$NON-NLS-1$ private static final String PART_TYPE_RANDOM_INTEGER = "RANDOM_INTEGER"; //$NON-NLS-1$ private static final String PART_TYPE_RANDOM_ALPHA = "RANDOM_ALPHA"; //$NON-NLS-1$ private static final String PART_TYPE_X = "X"; //$NON-NLS-1$; private static final String PART_TYPE_Y = "Y"; //$NON-NLS-1$; private static final String PART_TYPE_ZOOM = "ZOOM"; //$NON-NLS-1$; // private static final String PART_TYPE_LAT_TOP = "LATITUDE_TOP"; //$NON-NLS-1$ // private static final String PART_TYPE_LAT_BOTTOM = "LATITUDE_BOTTOM"; //$NON-NLS-1$; // private static final String PART_TYPE_LON_LEFT = "LONGITUDE_LEFT"; //$NON-NLS-1$; // private static final String PART_TYPE_LON_RIGHT = "LONGITUDE_RIGHT"; //$NON-NLS-1$; /* * wms map provider */ private static final String ATTR_WMS_CAPS_URL = "CapsUrl"; //$NON-NLS-1$ private static final String ATTR_WMS_MAP_URL = "GetMapUrl"; //$NON-NLS-1$ private static final String ATTR_WMS_LOAD_TRANSPARENT_IMAGES = "LoadTransparentImages"; //$NON-NLS-1$ private static final String TAG_LAYER = "Layer"; //$NON-NLS-1$ private static final String ATTR_LAYER_NAME = "Name"; //$NON-NLS-1$ private static final String ATTR_LAYER_TITLE = "Title"; //$NON-NLS-1$ private static final String ATTR_LAYER_IS_DISPLAYED = "IsDisplayed"; //$NON-NLS-1$ private static final String ATTR_LAYER_POSITION = "Position"; //$NON-NLS-1$ /* * map profile */ private static final String TAG_MAP_PROVIDER_WRAPPER = "MapProviderWrapper"; //$NON-NLS-1$ private static final String ATTR_PMP_BACKGROUND_COLOR = "BackgroundColor"; //$NON-NLS-1$ // profile map provider settings private static final String ATTR_PMP_MAP_PROVIDER_ID = "Id"; //$NON-NLS-1$ private static final String ATTR_PMP_MAP_PROVIDER_TYPE = "Type"; //$NON-NLS-1$ private static final String ATTR_PMP_POSITION = "Position"; //$NON-NLS-1$ private static final String ATTR_PMP_IS_DISPLAYED = "IsDisplayed"; //$NON-NLS-1$ private static final String ATTR_PMP_ALPHA = "Alpha"; //$NON-NLS-1$ private static final String ATTR_PMP_IS_TRANSPARENT = "IsTransparent"; //$NON-NLS-1$ private static final String ATTR_PMP_IS_BLACK_TRANSPARENT = "IsBlackTransparent"; //$NON-NLS-1$ private static final String ATTR_PMP_IS_BRIGHTNESS_FOR_NEXT_MP = "IsBrightnessForNextMP"; //$NON-NLS-1$ private static final String ATTR_PMP_BRIGHTNESS_FOR_NEXT_MP = "BrightnessForNextMP"; //$NON-NLS-1$ // transparent pixel private static final String TAG_TRANSPARENT_COLOR = "TransparentColor"; //$NON-NLS-1$ private static final String ATTR_TRANSPARENT_COLOR_VALUE = "Value"; //$NON-NLS-1$ /** * Id for the default map provider */ public static String DEFAULT_MAP_PROVIDER_ID = OSMMapProvider.FACTORY_ID; /** * size for osm images */ public static final int OSM_IMAGE_SIZE = 256; public static final String DEFAULT_IMAGE_SIZE = Integer.toString(OSM_IMAGE_SIZE); public static final String[] IMAGE_SIZE = { DEFAULT_IMAGE_SIZE, "300", //$NON-NLS-1$ "400", //$NON-NLS-1$ "500", //$NON-NLS-1$ "512", //$NON-NLS-1$ "600", //$NON-NLS-1$ "700", //$NON-NLS-1$S "768", //$NON-NLS-1$ "800", //$NON-NLS-1$ "900", //$NON-NLS-1$ "1000", //$NON-NLS-1$ "1024", //$NON-NLS-1$ }; private static final ReentrantLock WMS_LOCK = new ReentrantLock(); private static MapProviderManager _instance; /** * contains all available map providers, including empty map provider and map profiles */ private static ArrayList<MP> _allMapProviders; private MPPlugin _mpDefault; private ArrayList<String> _errorLog = new ArrayList<String>(); private static IPreferenceStore _prefStore = Activator.getDefault().getPreferenceStore(); private static final ListenerList _mapProviderListeners = new ListenerList(ListenerList.IDENTITY); private static final DateTimeFormatter _dtFormatter = ISODateTimeFormat.basicDateTimeNoMillis(); private static boolean _isDeleteError; private static long _deleteUIUpdateTime; private MapProviderManager() { } /** * Checks if the WMS is initialized, if not it will be done (it is loading the WMS layers). It * also creates the wms tile factory. * * @param mpWms * can be <code>null</code> when capsUrl is <code>not null</code> to do an initial * loading * @param capsUrl * @return Returns a wms map provider or <code>null</code> when the wms cannot be initialized * which happens when an connection to the wms server cannot be established */ public static MPWms checkWms(final MPWms mpWms, final String capsUrl) { final MPWms[] returnMpWms = new MPWms[] { mpWms }; if (mpWms == null || mpWms.getWmsCaps() == null) { WMS_LOCK.lock(); try { // recheck again, it's possible tha another thread could have loaded the caps if (mpWms == null || mpWms.getWmsCaps() == null) { checkWmsRunnable(mpWms, capsUrl, returnMpWms); } } finally { WMS_LOCK.unlock(); } } return returnMpWms[0]; } /** * @param mpWms * @param capsUrl * @param returnMpWms * Contains the checked wms map provider */ private static void checkWmsRunnable(final MPWms mpWms, final String capsUrl, final MPWms[] returnMpWms) { final IRunnableWithProgress progressRunnable = new IRunnableWithProgress() { public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { final String capsUrlFinal = mpWms == null ? // capsUrl : mpWms.getCapabilitiesUrl(); monitor.beginTask(Messages.MP_Manager_Task_GetWms, 1); monitor.subTask(capsUrlFinal); try { returnMpWms[0] = initializeWMS(mpWms, capsUrlFinal); } catch (final Exception e) { StatusUtil.showStatus(e.getMessage(), e); /* * disable this wms map provider, it is possible that * the server is currently not available */ for (final MP mapProvider : _allMapProviders) { if (mapProvider instanceof MPWms) { final MPWms wmsMp = (MPWms) mapProvider; if (wmsMp.getCapabilitiesUrl().equalsIgnoreCase(capsUrlFinal)) { wmsMp.setWmsEnabled(false); } } else if (mapProvider instanceof MPProfile) { final MPProfile mpProfile = (MPProfile) mapProvider; for (final MPWrapper mpWrapper : mpProfile.getAllWrappers()) { final MP mp = mpWrapper.getMP(); if (mp instanceof MPWms) { final MPWms wmsMp = (MPWms) mp; if (wmsMp.getCapabilitiesUrl().equalsIgnoreCase(capsUrlFinal)) { wmsMp.setWmsEnabled(false); } } } } } returnMpWms[0] = null; } } }; final Display display = Display.getDefault(); display.syncExec(new Runnable() { public void run() { try { new ProgressMonitorDialog(display.getActiveShell()).run(false, false, progressRunnable); } catch (final InvocationTargetException e1) { StatusUtil.showStatus(e1.getMessage(), e1); } catch (final InterruptedException e1) { StatusUtil.showStatus(e1.getMessage(), e1); } } }); } /** * Deletes offline map image files * * @param mp * MapProvider * @param isDeletePartImages * When <code>true</code> only the part images are deleted, otherwise all images are * deleted. * @return Returns <code>true</code> when image files are deleted. */ public static boolean deleteOfflineMap(final MP mp, final boolean isDeletePartImages) { // reset state that offline images are available mp.resetTileImageAvailability(); // check base path IPath tileCacheBasePath = getTileCachePath(); if (tileCacheBasePath == null) { return false; } // check map provider offline folder final String tileOSFolder = mp.getOfflineFolder(); if (tileOSFolder == null) { return false; } tileCacheBasePath = tileCacheBasePath.addTrailingSeparator(); boolean isDeleted = false; // delete map provider files final File tileCacheDir = tileCacheBasePath.append(tileOSFolder).toFile(); if (tileCacheDir.exists()) { deleteOfflineMapFiles(tileCacheDir, isDeletePartImages); isDeleted = true; } // delete profile wms files final File wmsPath = tileCacheBasePath.append(MPProfile.WMS_CUSTOM_TILE_PATH).append(tileOSFolder).toFile(); if (wmsPath.exists()) { deleteOfflineMapFiles(wmsPath, isDeletePartImages); isDeleted = true; } return isDeleted; } private static void deleteOfflineMapFiles(final File offlineFolder, final boolean isDeletePartImages) { _isDeleteError = false; _deleteUIUpdateTime = System.currentTimeMillis(); try { final IRunnableWithProgress runnable = new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask(UI.EMPTY_STRING, IProgressMonitor.UNKNOWN); deleteOfflineMapFilesFolder(offlineFolder, isDeletePartImages, monitor); } }; new ProgressMonitorDialog(Display.getCurrent().getActiveShell()).run(true, true, runnable); } catch (final InvocationTargetException e) { e.printStackTrace(); } catch (final InterruptedException e) { e.printStackTrace(); } if (_isDeleteError) { StatusUtil.showStatus( NLS.bind(Messages.MP_Manager_DeleteOfflineImages_CannotDeleteFolder, offlineFolder), new Exception()); } } /** * !!!!!!!!!!!!!! RECURSIVE !!!!!!!!!!!!!!!!!<br> * <br> * Deletes all files and subdirectories. If a deletion fails, the method stops attempting to * delete and returns false. <br> * <br> * !!!!!!!!!!!!!! RECURSIVE !!!!!!!!!!!!!!!!! * * @param fileFolder * @param isDeletePartImages * @param monitor * @return Returns <code>true</code> if all deletions were successful */ private static void deleteOfflineMapFilesFolder(final File fileFolder, final boolean isDeletePartImages, final IProgressMonitor monitor) { if (monitor.isCanceled()) { return; } boolean doDeleteFileFolder = true; if (fileFolder.isDirectory()) { // file is a folder final String[] allFileFolder = fileFolder.list(); for (final String fileFolder2 : allFileFolder) { deleteOfflineMapFilesFolder(new File(fileFolder, fileFolder2), isDeletePartImages, monitor); } // update monitor every 200ms final long time = System.currentTimeMillis(); if (time > _deleteUIUpdateTime + 200) { _deleteUIUpdateTime = time; monitor.subTask(NLS.bind(isDeletePartImages ? // Messages.MP_Manager_DeletedOfflineImagesParts_MonitorMessage : Messages.MP_Manager_DeletedOfflineImages_MonitorMessage, // fileFolder.toString())); } if (isDeletePartImages) { // don't delete folders when only part images are deleted doDeleteFileFolder = false; } } else { // file is a file // check if only part images should be deleted if (isDeletePartImages) { final String fileName = fileFolder.getName(); if (fileName.contains(PART_IMAGE_FILE_NAME_SUFFIX) == false) { // this is not a part image -> DON'T delete doDeleteFileFolder = false; } } } boolean isFileFolderDeleted = false; if (doDeleteFileFolder) { // the folder is now empty so delete it isFileFolderDeleted = fileFolder.delete(); } /* * !!! canceled must be checked before isFileFolderDeleted is checked because this returns * false when the monitor is canceled !!! */ if (monitor.isCanceled()) { return; } if (doDeleteFileFolder && isFileFolderDeleted == false) { _isDeleteError = true; monitor.setCanceled(true); } } private static void fireChangeEvent() { final Object[] allListeners = _mapProviderListeners.getListeners(); for (final Object listener : allListeners) { ((IMapProviderListener) listener).mapProviderListChanged(); } } /** * Convert {@link DirectPosition} into a {@link GeoPosition} * * @param position * @return Returns a {@link GeoPosition} */ private static GeoPosition getGeoPosition(final DirectPosition position) { double latitude = 0; double longitude = 0; final int dimension = position.getDimension(); for (int dimensionIndex = 0; dimensionIndex < dimension; dimensionIndex++) { if (dimensionIndex == 0) { longitude = position.getOrdinate(dimensionIndex); } else if (dimensionIndex == 1) { latitude = position.getOrdinate(dimensionIndex); } } return new GeoPosition(latitude, longitude); } /** * @param imageType * SWT image format like {@link SWT#IMAGE_PNG} * @return Returns <code>null</code> when the image type cannot be recognized */ public static String getImageFileExtension(final int imageType) { switch (imageType) { case SWT.IMAGE_JPEG: return FILE_EXTENSION_JPG; case SWT.IMAGE_GIF: return FILE_EXTENSION_GIF; case SWT.IMAGE_PNG: return FILE_EXTENSION_PNG; default: } return null; } public static String getImageFileExtension(final String mimeImageFormat) { if (mimeImageFormat.equalsIgnoreCase(MIME_JPG) || mimeImageFormat.equalsIgnoreCase(MIME_JPEG)) { return FILE_EXTENSION_JPG; } else if (mimeImageFormat.equalsIgnoreCase(MIME_GIF)) { return FILE_EXTENSION_GIF; } else { // use png as default return FILE_EXTENSION_PNG; } } /** * @param imageType * SWT image format like {@link SWT#IMAGE_PNG} * @return Returns <code>null</code> when the image type cannot be recognized */ public static String getImageMimeType(final int imageType) { switch (imageType) { case SWT.IMAGE_JPEG: return MIME_JPG; case SWT.IMAGE_GIF: return MIME_GIF; case SWT.IMAGE_PNG: return MIME_PNG; default: } return null; } public static MapProviderManager getInstance() { if (_instance == null) { _instance = new MapProviderManager(); } return _instance; } private static String getMapProviderType(final MP mapProvider) { if (mapProvider instanceof MPCustom) { return MAP_PROVIDER_TYPE_CUSTOM; } else if (mapProvider instanceof MPWms) { return MAP_PROVIDER_TYPE_WMS; } else if (mapProvider instanceof MPPlugin) { return MAP_PROVIDER_TYPE_PLUGIN; } return null; } /** * @return Returns file path for the offline maps or <code>null</code> when offline is not used * or the path is not valid */ public static IPath getTileCachePath() { // get status if the tile is offline cache is activated final boolean useOffLineCache = _prefStore.getBoolean(IMappingPreferences.OFFLINE_CACHE_USE_OFFLINE); if (useOffLineCache == false) { return null; } if (useOffLineCache) { // check tile cache path String workingDirectory; final boolean useDefaultLocation = _prefStore .getBoolean(IMappingPreferences.OFFLINE_CACHE_USE_DEFAULT_LOCATION); if (useDefaultLocation) { workingDirectory = Platform.getInstanceLocation().getURL().getPath(); } else { workingDirectory = _prefStore.getString(IMappingPreferences.OFFLINE_CACHE_PATH); } if (new File(workingDirectory).exists() == false) { StatusUtil.showStatus("Map image offline folder is not available: " + workingDirectory); //$NON-NLS-1$ return null; } // append a unique path so that deleting tiles is not doing it in the wrong directory final IPath tileCachePath = new Path(workingDirectory) .append(TileImageCache.TILE_OFFLINE_CACHE_OS_PATH); if (tileCachePath.toFile().exists() == false) { return null; } return tileCachePath; } return null; } /** * Load WMS capabilities, update the map provider by setting the UI state for the layers<br> * <br> * * @param oldWmsMapProvider * when a map provider is set, this wms map provider will be updated, when * <code>null</code> a new map provider is created * @param capsUrl * capabilities url for the wms server * @return Returns a wms map provider when the data are loaded from the wms server or * <code>null</code> otherwise * @throws Exception * when the wms server cannot be accessed */ private static MPWms initializeWMS(final MPWms oldWmsMapProvider, String capsUrl) throws Exception { ArrayList<MtLayer> oldMtLayers = null; if (oldWmsMapProvider != null) { oldMtLayers = oldWmsMapProvider.getMtLayers(); } /* * load wms server */ WebMapServer wmsServer; try { wmsServer = WmsServerWrapper.getWmsServer(capsUrl); } catch (final Exception e) { // try it with http prefix if (e.getCause() instanceof MalformedURLException && capsUrl.startsWith(URL_PREFIX_HTTP) == false) { capsUrl = URL_PREFIX_HTTP_PROTOCOL + capsUrl; wmsServer = WmsServerWrapper.getWmsServer(capsUrl); } else { throw e; } } /* * get capabilities */ WMSCapabilities wmsCaps = null; String capsError = null; Service wmsService = null; Exception ex = null; try { wmsCaps = wmsServer.getCapabilities(); wmsService = wmsCaps.getService(); } catch (final Exception e) { capsError = e.getMessage(); ex = e; } if (wmsCaps == null || wmsService == null || capsError != null) { throw new GeoException(ex); } /* * create mt layers and check wms layers */ final ArrayList<MtLayer> loadedMtLayers = new ArrayList<MtLayer>(); final List<Layer> allGeoLayer = wmsCaps.getLayerList(); for (final Layer geoLayer : allGeoLayer) { final String layerName = geoLayer.getName(); if (layerName != null) { /* * get lat/lon from envelope */ final CRSEnvelope envelope = geoLayer.getLatLonBoundingBox(); if (envelope == null) { String wmsName = wmsService.getTitle(); if (wmsName == null || wmsName.length() == 0) { wmsName = wmsService.getName(); } StatusUtil.log(NLS.bind(Messages.DBG001_Error_Wms_LatLonBboxIsNotDefined, layerName, wmsName), new Exception()); continue; } /* * create new layer */ final GeoPosition lowerGeoPosition = getGeoPosition(envelope.getLowerCorner()); final GeoPosition upperGeoPosition = getGeoPosition(envelope.getUpperCorner()); final MtLayer mtLayer = new MtLayer(geoLayer, lowerGeoPosition, upperGeoPosition); loadedMtLayers.add(mtLayer); } } if (loadedMtLayers.size() == 0) { MessageDialog.openError(Display.getCurrent().getActiveShell(), Messages.MP_Error_DialogTitle_Wms, Messages.DBG002_Error_Wms_DialogMessage_InvalidLayers); return null; } MPWms updatedWmsMapProvider; if (oldWmsMapProvider == null) { // create WMS map provider updatedWmsMapProvider = new MPWms(); } else { // use existing updatedWmsMapProvider = oldWmsMapProvider; } // inizialize map provider by setting none UI data updatedWmsMapProvider.initializeWms(wmsServer, wmsCaps, loadedMtLayers); /* * update UI state */ if (oldWmsMapProvider != null) { // update UI state from old map provider if (oldMtLayers != null) { // update layers from old layers for (final MtLayer loadedMtLayer : loadedMtLayers) { final String mtLayerName = loadedMtLayer.getGeoLayer().getName(); for (final MtLayer oldMtLayer : oldMtLayers) { if (oldMtLayer.getGeoLayer().getName().equals(mtLayerName)) { // update state loadedMtLayer.setIsDisplayedInMap(oldMtLayer.isDisplayedInMap()); loadedMtLayer.setPositionIndex(oldMtLayer.getPositionIndex()); break; } } } } else { // update layers from offline data final ArrayList<LayerOfflineData> allOfflineLayer = oldWmsMapProvider.getOfflineLayers(); if (allOfflineLayer != null) { for (final MtLayer mtLayer : loadedMtLayers) { final String mtLayerName = mtLayer.getGeoLayer().getName(); for (final LayerOfflineData offlineLayer : allOfflineLayer) { if (offlineLayer.name.equals(mtLayerName)) { // update state mtLayer.setIsDisplayedInMap(offlineLayer.isDisplayedInMap); mtLayer.setPositionIndex(offlineLayer.position); break; } } } } } } updatedWmsMapProvider.initializeLayers(); // replace wms map provider in the list of map providers if (oldWmsMapProvider != null) { replaceMapProvider(updatedWmsMapProvider); } return updatedWmsMapProvider; } /** * updates a map provider in the model * * @param allMapProviders */ public static void replaceMapProvider(final MP mapProviderReplacement) { final String replaceMapProviderId = mapProviderReplacement.getId(); boolean isMapProviderReplaced = false; int mpIndex = 0; /* * replace map provider in the model */ for (final MP mapProvider : _allMapProviders) { if (replaceMapProviderId.equals(mapProvider.getId())) { isMapProviderReplaced = true; // replace map provider _allMapProviders.set(mpIndex, mapProviderReplacement); // a map provider exists only once break; } else { mpIndex++; } } if (mapProviderReplacement instanceof MPProfile) { /* * a map profile does not contain another map profile */ return; } if (isMapProviderReplaced) { /* * replace map provider within the map profiles */ // loop: all profiles for (final MP mapProvider : _allMapProviders) { if (mapProvider instanceof MPProfile) { final MPProfile mapProfile = (MPProfile) mapProvider; final ArrayList<MPWrapper> mpWrapperList = mapProfile.getAllWrappers(); // loop: all map providers which are set within the profiles for (final MPWrapper mpWrapper : mpWrapperList) { final MP profileMapProvider = mpWrapper.getMP(); if (profileMapProvider != null && profileMapProvider.getId().equals(replaceMapProviderId)) { // replace map provider with a clone of the original map provider try { mpWrapper.setMP((MP) mapProviderReplacement.clone()); } catch (final CloneNotSupportedException e) { StatusUtil.showStatus(e.getMessage(), e); } } } } } } } public void addMapProvider(final MP mp) { _allMapProviders.add(mp); updateMpSorting(mp); } public void addMapProviderListener(final IMapProviderListener listener) { _mapProviderListeners.add(listener); } private void checkMapProviders() { if (_allMapProviders != null) { return; } createAllMapProviders(); } /** * Create all map providers, osm as internal mp, all plugin mp's and the imported mp's from an * xml file */ private void createAllMapProviders() { _allMapProviders = new ArrayList<MP>(); // create default tile factories _mpDefault = new OSMMapProvider(); _allMapProviders.add(_mpDefault); /* * add plugin map providers */ final List<MPPlugin> allPluginMp = GeoclipseExtensions.getInstance().readFactories(); for (final MPPlugin pluginMp : allPluginMp) { final String pluginFactoryId = pluginMp.getId(); boolean isValid = true; for (final MP checkedMapProvider : _allMapProviders) { // check factory id if (checkedMapProvider.getId().equalsIgnoreCase(pluginFactoryId)) { StatusUtil.showStatus(NLS.bind(Messages.DBG003_Error_InvalidFactoryId, new Object[] { pluginFactoryId, pluginMp.getName(), checkedMapProvider.getName() // }), new Exception()); isValid = false; break; } // check offline folder final String pluginOfflineFolder = pluginMp.getOfflineFolder(); final String checkedOfflineFolder = checkedMapProvider.getOfflineFolder(); if (pluginOfflineFolder != null && checkedOfflineFolder != null && checkedOfflineFolder.equalsIgnoreCase(pluginOfflineFolder)) { StatusUtil.showStatus(NLS.bind(Messages.DBG004_Error_InvalidOfflineFolder, new Object[] { pluginOfflineFolder, pluginMp.getName(), checkedMapProvider.getName() // }), new Exception()); isValid = false; break; } } if (isValid) { // add valid map providers _allMapProviders.add(pluginMp); } } /* * add external map providers which are defined in a xml file */ final IPath stateLocation = Platform.getStateLocation(Activator.getDefault().getBundle()); final String filename = stateLocation.append(CUSTOM_MAP_PROVIDER_FILE).toFile().getAbsolutePath(); final ArrayList<MP> importedMapProviders = readXml1(filename, false, false); for (final MP mp : importedMapProviders) { /* * ignore plugin map providers, they should be already in the list but can occure in the * import file as a map profile wrapper */ if ((mp instanceof MPPlugin) == false) { _allMapProviders.add(mp); } } /* * initialize map profiles, this MUST be done AFTER all external map providers are read from * the xml file because they are referenced in the profile map provider */ for (final MP mapProvider : _allMapProviders) { if (mapProvider instanceof MPProfile) { ((MPProfile) mapProvider).synchronizeMPWrapper(); } } // sort by name Collections.sort(_allMapProviders); } private XMLMemento createXmlRoot(final boolean isManualExport) { try { final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); // create root element final Element rootElement = document.createElement(TAG_MAP_PROVIDER_LIST); document.appendChild(rootElement); // create tag from element final XMLMemento tagRoot = new XMLMemento(document, rootElement); // date/time tagRoot.putString(ATTR_ROOT_DATETIME, _dtFormatter.print(new Date().getTime())); // plugin version final Version version = Activator.getDefault().getVersion(); tagRoot.putInteger(ATTR_ROOT_VERSION_MAJOR, version.getMajor()); tagRoot.putInteger(ATTR_ROOT_VERSION_MINOR, version.getMinor()); tagRoot.putInteger(ATTR_ROOT_VERSION_MICRO, version.getMicro()); tagRoot.putString(ATTR_ROOT_VERSION_QUALIFIER, version.getQualifier()); // export flag if (isManualExport) { tagRoot.putBoolean(ATTR_ROOT_IS_MANUAL_EXPORT, true); } return tagRoot; } catch (final ParserConfigurationException e) { throw new Error(e.getMessage()); } } private void displayError(final String filename) { if (_errorLog.size() == 0) { return; } // log filename, that it's visible in the log logError(filename, new Exception()); final StringBuilder sb = new StringBuilder(); sb.append(Messages.MP_Error_Title_ErrorInXmlFile); sb.append(UI.NEW_LINE); sb.append(UI.NEW_LINE); sb.append(filename); sb.append(UI.NEW_LINE); sb.append(UI.NEW_LINE); for (final String log : _errorLog) { sb.append(log); sb.append(UI.NEW_LINE); } MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.MP_Error_DialogTitle_ConfigurationError, sb.toString()); } public void exportMapProvider(final MP mapProvider, final File file) { BufferedWriter writer = null; try { writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UI.UTF_8)); final XMLMemento xmlMemento = createXmlRoot(true); writeXml(mapProvider, xmlMemento.createChild(ROOT_CHILD_TAG_MAP_PROVIDER)); if (mapProvider instanceof MPProfile) { final MPProfile mpProfile = (MPProfile) mapProvider; // create xml for each map provider which is visible for (final MPWrapper mpWrapper : mpProfile.getAllWrappers()) { if (mpWrapper.isDisplayedInMap()) { writeXml(// mpWrapper.getMP(), xmlMemento.createChild(ROOT_CHILD_TAG_WRAPPED_MAP_PROVIDER)); } } } xmlMemento.save(writer); } catch (final IOException e) { StatusUtil.log(e); } finally { if (writer != null) { try { writer.close(); } catch (final IOException e) { StatusUtil.log(e); } } } } /** * @return Returns the backend list with all available map providers, including empty map * provider and map profiles */ public ArrayList<MP> getAllMapProviders() { checkMapProviders(); return _allMapProviders; } /** * @param withMapProfile * when <code>true</code> the map profiles are included otherwise they are ignored * @return Returns a list with all available map providers but without empty map providers */ public ArrayList<MP> getAllMapProviders(final boolean withMapProfile) { checkMapProviders(); final ArrayList<MP> mapProviders = new ArrayList<MP>(); for (final MP mapProvider : _allMapProviders) { boolean isValid = true; if (mapProvider instanceof MPProfile) { isValid = withMapProfile; } if (isValid) { mapProviders.add(mapProvider); } } return mapProviders; } /** * @return Return the default map provider which is currently OpenstreetMap */ public MPPlugin getDefaultMapProvider() { return _mpDefault; } /** * convert {@link PART_TYPE} into a string which can be saved in xml file * * @param partType * @return String representation of the {@link PART_TYPE} enum */ private String getPartType(final PART_TYPE partType) { switch (partType) { case HTML: return PART_TYPE_HTML; case X: return PART_TYPE_X; case Y: return PART_TYPE_Y; // case LAT_TOP: // return PART_TYPE_LAT_TOP; // case LAT_BOTTOM: // return PART_TYPE_LAT_BOTTOM; // // case LON_LEFT: // return PART_TYPE_LON_LEFT; // case LON_RIGHT: // return PART_TYPE_LON_RIGHT; case ZOOM: return PART_TYPE_ZOOM; case RANDOM_INTEGER: return PART_TYPE_RANDOM_INTEGER; case RANDOM_ALPHA: return PART_TYPE_RANDOM_ALPHA; } return null; } /** * convert part type from string into {@link PART_TYPE} enum * * @param partTypeText * @return */ private PART_TYPE getPartType(final String partTypeText) { if (partTypeText.equalsIgnoreCase(PART_TYPE_HTML)) { return PART_TYPE.HTML; } else if (partTypeText.equalsIgnoreCase(PART_TYPE_X)) { return PART_TYPE.X; } else if (partTypeText.equalsIgnoreCase(PART_TYPE_Y)) { return PART_TYPE.Y; // } else if (partTypeText.equalsIgnoreCase(PART_TYPE_LAT_TOP)) { // return PART_TYPE.LAT_TOP; // } else if (partTypeText.equalsIgnoreCase(PART_TYPE_LAT_BOTTOM)) { // return PART_TYPE.LAT_BOTTOM; // // } else if (partTypeText.equalsIgnoreCase(PART_TYPE_LON_LEFT)) { // return PART_TYPE.LON_LEFT; // } else if (partTypeText.equalsIgnoreCase(PART_TYPE_LON_RIGHT)) { // return PART_TYPE.LON_RIGHT; } else if (partTypeText.equalsIgnoreCase(PART_TYPE_ZOOM)) { return PART_TYPE.ZOOM; } else if (partTypeText.equalsIgnoreCase(PART_TYPE_RANDOM_INTEGER)) { return PART_TYPE.RANDOM_INTEGER; } else if (partTypeText.equalsIgnoreCase(PART_TYPE_RANDOM_ALPHA)) { return PART_TYPE.RANDOM_ALPHA; } StatusUtil.showStatus(NLS.bind(Messages.DBG006_Error_Custom_InvalidPartType, partTypeText), new Exception()); return null; } /** * @param importFilePath * @return Returns the imported map provider or <code>null</code> when an import * error occured<br> * <br> * Multiple map providers are returned when a map profile contains map providers * which do not yet exists */ public ArrayList<MP> importMapProvider(final String importFilePath) { final ArrayList<MP> importedMPList = readXml1(importFilePath, true, true); if (importedMPList.size() > 0) { // validate map provider return validateImportedMP(importedMPList); } return null; } private void logError(final String errorText, final Exception exception) { StatusUtil.log(errorText, exception); _errorLog.add(errorText); } /** * Read map provider list from a xml file * * @param filename * @param isShowExistError * @param isMpImport * is <code>true</code> when a map provider should be imported * @return Returns a list with all map providers from a xml file including wrapped plugin map * provider */ private ArrayList<MP> readXml1(final String filename, final boolean isShowExistError, final boolean isMpImport) { final ArrayList<MP> validMapProviders = new ArrayList<MP>(); InputStreamReader reader = null; _errorLog.clear(); try { // check if file is available final File inputFile = new File(filename); if (inputFile.exists() == false) { if (isShowExistError) { logError(Messages.DBG007_Error_FileIsNotAvailable, new Exception()); } return validMapProviders; } reader = new InputStreamReader(new FileInputStream(inputFile), UI.UTF_8); final XMLMemento mementoRoot = XMLMemento.createReadRoot(reader); // check if this is an exported map provider if (isMpImport) { final Boolean isExport = mementoRoot.getBoolean(ATTR_ROOT_IS_MANUAL_EXPORT); if (isExport == null || isExport == false) { logError(Messages.DBG039_Error_FileIsNotExported, new Exception()); return validMapProviders; } } readXml2(validMapProviders, mementoRoot, ROOT_CHILD_TAG_MAP_PROVIDER); if (isMpImport) { readXml2(validMapProviders, mementoRoot, ROOT_CHILD_TAG_WRAPPED_MAP_PROVIDER); } } catch (final UnsupportedEncodingException e) { logError(e.getMessage(), e); } catch (final FileNotFoundException e) { logError(e.getMessage(), e); } catch (final WorkbenchException e) { logError(e.getMessage(), e); } catch (final NumberFormatException e) { logError(e.getMessage(), e); } catch (final Exception e) { logError(e.getMessage(), e); } finally { if (reader != null) { try { reader.close(); } catch (final IOException e) { e.printStackTrace(); } } displayError(filename); } return validMapProviders; } /** * @param validMapProviders * @param mementoRoot * @param tagNameRootChildren */ private void readXml2(final ArrayList<MP> validMapProviders, final XMLMemento mementoRoot, final String tagNameRootChildren) { final ArrayList<MP> allMapProviders = getAllMapProviders(); final IMemento[] tagMapProviderList = mementoRoot.getChildren(tagNameRootChildren); for (final IMemento tagMapProvider : tagMapProviderList) { /* * get common fields */ final String mapProviderId = tagMapProvider.getString(ATTR_MP_ID); final String mapProviderName = tagMapProvider.getString(ATTR_MP_NAME); final String mapProviderType = tagMapProvider.getString(ATTR_MP_TYPE); final String offlineFolder = tagMapProvider.getString(ATTR_MP_OFFLINE_FOLDER); final String description = tagMapProvider.getString(ATTR_MP_DESCRIPTION); final Integer imageSize = tagMapProvider.getInteger(ATTR_MP_IMAGE_SIZE); final String imageFormat = tagMapProvider.getString(ATTR_MP_IMAGE_FORMAT); // zoom level final Integer zoomMin = tagMapProvider.getInteger(ATTR_MP_ZOOM_LEVEL_MIN); final Integer zoomMax = tagMapProvider.getInteger(ATTR_MP_ZOOM_LEVEL_MAX); // favorite position final Integer favoriteZoom = tagMapProvider.getInteger(ATTR_MP_FAVORITE_ZOOM_LEVEL); final Float favoriteLatitude = tagMapProvider.getFloat(ATTR_MP_FAVORITE_LATITUDE); final Float favoriteLongitude = tagMapProvider.getFloat(ATTR_MP_FAVORITE_LONGITUDE); // last used position final Integer lastUsedZoom = tagMapProvider.getInteger(ATTR_MP_LAST_USED_ZOOM_LEVEL); final Float lastUsedLatitude = tagMapProvider.getFloat(ATTR_MP_LAST_USED_LATITUDE); final Float lastUsedLongitude = tagMapProvider.getFloat(ATTR_MP_LAST_USED_LONGITUDE); // check common fields if (mapProviderId == null || mapProviderName == null || offlineFolder == null || mapProviderType == null) { logError(NLS.bind(// Messages.DBG008_Error_TagIsInvalid, mapProviderId, tagNameRootChildren), new Exception()); continue; } // check if the factory id is already used, ignore the duplicated factory boolean isValid = true; for (final MP checkMapProvider : validMapProviders) { if (checkMapProvider.getId().equalsIgnoreCase(mapProviderId)) { logError(NLS.bind(// Messages.DBG009_Error_MapProfileDuplicate, mapProviderId), new Exception()); isValid = false; break; } } if (isValid == false) { continue; } // check plugin map provider, they are also added to the list if (mapProviderType.equals(MAP_PROVIDER_TYPE_PLUGIN)) { for (final MP mp : allMapProviders) { if (mp.getId().equalsIgnoreCase(mapProviderId) && mp instanceof MPPlugin) { validMapProviders.add(mp); isValid = true; break; } } if (isValid == false) { logError(NLS.bind(// Messages.DBG027_ImportError_InvalidPlugin, mapProviderId), new Exception()); } continue; } // check map provider type if (mapProviderType.equals(MAP_PROVIDER_TYPE_CUSTOM) == false && mapProviderType.equals(MAP_PROVIDER_TYPE_WMS) == false && mapProviderType.equals(MAP_PROVIDER_TYPE_MAP_PROFILE) == false) { logError(NLS.bind(// Messages.DBG010_Error_InvalidType, mapProviderId, mapProviderType), new Exception()); continue; } /* * read map provider specific fields */ MP mapProvider = null; if (mapProviderType.equals(MAP_PROVIDER_TYPE_CUSTOM)) { // custom map provider mapProvider = readXmlCustom(tagMapProvider, mapProviderId); } else if (mapProviderType.equals(MAP_PROVIDER_TYPE_WMS)) { // wms map provider mapProvider = readXmlWms(tagMapProvider, mapProviderId, tagNameRootChildren); } else if (mapProviderType.equals(MAP_PROVIDER_TYPE_MAP_PROFILE)) { // map profile mapProvider = readXmlProfile(tagMapProvider, mapProviderId); } /* * set common fields */ if (mapProvider != null) { // id mapProvider.setId(mapProviderId); mapProvider.setName(mapProviderName); mapProvider.setDescription(description == null ? UI.EMPTY_STRING : description); mapProvider.setOfflineFolder(offlineFolder); // image mapProvider.setTileSize(imageSize == null ? Integer.parseInt(DEFAULT_IMAGE_SIZE) : imageSize); mapProvider.setImageFormat(imageFormat == null ? DEFAULT_IMAGE_FORMAT : imageFormat); // zoom level final int minZoom = zoomMin == null ? 0 : zoomMin; final int maxZoom = zoomMax == null ? 17 : zoomMax; mapProvider.setZoomLevel(minZoom, maxZoom); // favorite position mapProvider.setFavoriteZoom(favoriteZoom == null ? 0 : favoriteZoom); mapProvider.setFavoritePosition(new GeoPosition(favoriteLatitude == null ? 0.0 : favoriteLatitude, favoriteLongitude == null ? 0.0 : favoriteLongitude)); // last used position mapProvider.setLastUsedZoom(lastUsedZoom == null ? 0 : lastUsedZoom); mapProvider.setLastUsedPosition(new GeoPosition(lastUsedLatitude == null ? 0.0 : lastUsedLatitude, lastUsedLongitude == null ? 0.0 : lastUsedLongitude)); validMapProviders.add(mapProvider); } } } /** * @param mementoMapProvider * @param mapProviderId * @return */ private MPCustom readXmlCustom(final IMemento mementoMapProvider, final String mapProviderId) { final MPCustom mapProvider = new MPCustom(); /* * custom map provider specific fields */ final String customUrl = mementoMapProvider.getString(ATTR_CUSTOM_CUSTOM_URL); /* * url parts */ final ArrayList<UrlPart> urlParts = new ArrayList<UrlPart>(); // loop: all url parts which are defined in the xml file final IMemento[] tagParts = mementoMapProvider.getChildren(TAG_URL_PART); for (final IMemento partTag : tagParts) { final String partTypeText = partTag.getString(ATTR_CUSTOM_PART_TYPE); final Integer partPosition = partTag.getInteger(ATTR_CUSTOM_PART_POSITION); // check tag attributes if (partTypeText == null || partPosition == null) { logError(NLS.bind(Messages.DBG011_Error_Custom_InvalidPropertied, mapProviderId, TAG_URL_PART), new Exception()); } final UrlPart urlPart = new UrlPart(); final PART_TYPE partType = getPartType(partTypeText); urlPart.setPartType(partType); urlPart.setPosition(partPosition); // get part type specific fields switch (partType) { case HTML: final String html = partTag.getString(ATTR_CUSTOM_PART_CONTENT_HTML); if (html == null) { continue; } urlPart.setHtml(html); break; case RANDOM_INTEGER: final Integer randIntStart = partTag.getInteger(ATTR_CUSTOM_PART_CONTENT_RANDOM_INTEGER_START); final Integer randIntEnd = partTag.getInteger(ATTR_CUSTOM_PART_CONTENT_RANDOM_INTEGER_END); if (randIntStart == null || randIntEnd == null) { continue; } urlPart.setRandomIntegerStart(randIntStart); urlPart.setRandomIntegerStart(randIntEnd); break; case RANDOM_ALPHA: final String randAlphaStart = partTag.getString(ATTR_CUSTOM_PART_CONTENT_RANDOM_ALPHA_START); final String randAlphaEnd = partTag.getString(ATTR_CUSTOM_PART_CONTENT_RANDOM_ALPHA_END); if (randAlphaStart == null || randAlphaEnd == null) { continue; } urlPart.setRandomAlphaStart(randAlphaStart); urlPart.setRandomAlphaStart(randAlphaEnd); break; default: break; } // add validated part urlParts.add(urlPart); } // sort parts by position Collections.sort(urlParts, new Comparator<UrlPart>() { public int compare(final UrlPart p1, final UrlPart p2) { return p1.getPosition() - p2.getPosition(); } }); /* * update model */ mapProvider.setCustomUrl(customUrl == null ? UI.EMPTY_STRING : customUrl); mapProvider.setUrlParts(urlParts); return mapProvider; } /** * Reads the map profile items from the xml file. The contained map providers cannot be set * because they are not all loaded at the current time. <br> * <br> * The method {@link MPProfile#synchronizeMapProviders(MapProviderManager)} must be called to * initialize the {@link MPProfile} * * @param tagMapProvider * @param mapProviderId * @return */ private MPProfile readXmlProfile(final IMemento tagMapProvider, final String mapProviderId) { final ArrayList<MPWrapper> mpWrapperList = new ArrayList<MPWrapper>(); final MPProfile mapProfile = new MPProfile(mpWrapperList); final Integer backgroundColor = tagMapProvider.getInteger(ATTR_PMP_BACKGROUND_COLOR); mapProfile.setBackgroundColor(backgroundColor == null ? 0xFFFFFF : backgroundColor); final IMemento[] tagProfileMapProviderList = tagMapProvider.getChildren(TAG_MAP_PROVIDER_WRAPPER); // loop: all map provider wrapper within a map profile for (final IMemento tagProfileMapProvider : tagProfileMapProviderList) { final String mpType = tagProfileMapProvider.getString(ATTR_PMP_MAP_PROVIDER_TYPE); final String mpId = tagProfileMapProvider.getString(ATTR_PMP_MAP_PROVIDER_ID); final Integer positionIndex = tagProfileMapProvider.getInteger(ATTR_PMP_POSITION); final Boolean isDisplayed = tagProfileMapProvider.getBoolean(ATTR_PMP_IS_DISPLAYED); final Integer alpha = tagProfileMapProvider.getInteger(ATTR_PMP_ALPHA); final Boolean isTransparent = tagProfileMapProvider.getBoolean(ATTR_PMP_IS_TRANSPARENT); final Boolean isTransBlack = tagProfileMapProvider.getBoolean(ATTR_PMP_IS_BLACK_TRANSPARENT); final Boolean isBrightnessForNextMp = tagProfileMapProvider .getBoolean(ATTR_PMP_IS_BRIGHTNESS_FOR_NEXT_MP); final Integer brightnessForNextMp = tagProfileMapProvider.getInteger(ATTR_PMP_BRIGHTNESS_FOR_NEXT_MP); // transparent colors final IMemento[] tagTransColor = tagProfileMapProvider.getChildren(TAG_TRANSPARENT_COLOR); final int[] transColors = new int[tagTransColor.length]; int colorIndex = 0; for (final IMemento mementoTransColor : tagTransColor) { final Integer colorValue = mementoTransColor.getInteger(ATTR_TRANSPARENT_COLOR_VALUE); transColors[colorIndex++] = colorValue == null ? 0 : colorValue; } // validate fields if (mpId == null || mpType == null || positionIndex == null || isDisplayed == null) { logError(NLS.bind(Messages.DBG012_Error_Profile_InvalidAttributes, mapProviderId, TAG_MAP_PROVIDER_WRAPPER), new Exception()); continue; } // check if a map provider id is already in the list boolean isIdValid = true; for (final MPWrapper mpWrapper : mpWrapperList) { if (mpWrapper.getMapProviderId().equalsIgnoreCase(mpId)) { isIdValid = false; break; } } if (isIdValid == false) { logError(NLS.bind(// Messages.DBG013_Error_Profile_DuplicateMP, new Object[] { mapProviderId, mpId, TAG_MAP_PROVIDER_WRAPPER }), new Exception()); continue; } // check map provider type if (mpType.equals(MAP_PROVIDER_TYPE_CUSTOM) == false && mpType.equals(MAP_PROVIDER_TYPE_WMS) == false && mpType.equals(MAP_PROVIDER_TYPE_MAP_PROFILE) == false && mpType.equals(MAP_PROVIDER_TYPE_PLUGIN) == false) { logError(NLS.bind(Messages.DBG014_Error_Profile_InvalidMPType, mapProviderId, mpType), new Exception()); continue; } /* * initial data are valid, create map provider wrapper */ final MPWrapper mpWrapper = new MPWrapper(mpId); mpWrapper.setType(mpType); mpWrapper.setIsDisplayedInMap(isDisplayed); mpWrapper.setPositionIndex(positionIndex); mpWrapper.setAlpha(alpha == null ? DEFAULT_ALPHA : alpha); mpWrapper.setIsTransparentColors(isTransparent == null ? false : isTransparent); mpWrapper.setIsTransparentBlack(isTransBlack == null ? false : isTransBlack); mpWrapper.setTransparentColors( transColors.length == 0 ? new int[] { OSM_BACKGROUND_COLOR } : transColors); mpWrapper.setIsBrightnessForNextMp(isBrightnessForNextMp == null ? false : isBrightnessForNextMp); mpWrapper.setBrightnessForNextMp(brightnessForNextMp == null ? 88 : brightnessForNextMp); mpWrapperList.add(mpWrapper); // set map provider specific fields if (mpType.equals(MAP_PROVIDER_TYPE_WMS)) { /* * read wms layer state */ int displayedLayers = 0; final ArrayList<LayerOfflineData> wmsOfflineLayers = new ArrayList<LayerOfflineData>(); for (final IMemento tagLayer : tagProfileMapProvider.getChildren(TAG_LAYER)) { final String layerName = tagLayer.getString(ATTR_LAYER_NAME); final String layerTitle = tagLayer.getString(ATTR_LAYER_TITLE); final Boolean layerIsDisplayed = tagLayer.getBoolean(ATTR_LAYER_IS_DISPLAYED); final Integer layerPosition = tagLayer.getInteger(ATTR_LAYER_POSITION); // validate properties if (layerName == null || layerTitle == null || layerIsDisplayed == null) { logError(NLS.bind(Messages.DBG015_Error_Profile_LayerInvalidProperties, new Object[] { mapProviderId, TAG_LAYER, mapProviderId }), new Exception()); continue; } // check if a layer with the same name is already in the list, a layer MUST be unique boolean isLayerValid = true; { for (final LayerOfflineData layerOfflineData : wmsOfflineLayers) { if (layerOfflineData.name.equalsIgnoreCase(layerName)) { logError( NLS.bind(Messages.DBG016_Error_Profile_OfflineLayerInvalidProperties, new Object[] { mapProviderId, TAG_LAYER, mapProviderId }), new Exception()); isLayerValid = false; break; } } } if (isLayerValid == false) { logError(NLS.bind(Messages.DBG017_Error_Profile_DuplicateLayer, new Object[] { mapProviderId, layerName, mpId }), new Exception()); continue; } final LayerOfflineData offlineLayer = new LayerOfflineData(); offlineLayer.name = layerName; offlineLayer.title = layerTitle; offlineLayer.isDisplayedInMap = layerIsDisplayed; offlineLayer.position = layerPosition == null ? -1 : layerPosition; wmsOfflineLayers.add(offlineLayer); if (layerIsDisplayed) { displayedLayers++; } } mpWrapper.setWmsOfflineLayerList(wmsOfflineLayers); } } return mapProfile; } /** * @param mementoMapProvider * @param mapProviderId * @param tagNameRootChildren * @return */ private MPWms readXmlWms(final IMemento mementoMapProvider, final String mapProviderId, final String tagNameRootChildren) { final MPWms mapProvider = new MPWms(); /* * caps & maps url */ final String capsUrl = mementoMapProvider.getString(ATTR_WMS_CAPS_URL); final String mapUrl = mementoMapProvider.getString(ATTR_WMS_MAP_URL); if (capsUrl == null || mapUrl == null) { logError(NLS.bind(Messages.DBG018_Error_Wms_InvalidAttributes, mapProviderId, tagNameRootChildren), new Exception()); return null; } mapProvider.setCapabilitiesUrl(capsUrl); mapProvider.setGetMapUrl(mapUrl); /* * load transparent images */ Boolean isTransparent = mementoMapProvider.getBoolean(ATTR_WMS_LOAD_TRANSPARENT_IMAGES); if (isTransparent == null) { // set default isTransparent = false; } mapProvider.setTransparent(isTransparent); /* * layer */ final IMemento[] tagLayers = mementoMapProvider.getChildren(TAG_LAYER); // int displayedLayers = 0; final ArrayList<LayerOfflineData> offlineLayerList = new ArrayList<LayerOfflineData>(); for (final IMemento tagLayer : tagLayers) { final String layerName = tagLayer.getString(ATTR_LAYER_NAME); final String layerTitle = tagLayer.getString(ATTR_LAYER_TITLE); final Boolean layerIsDisplayed = tagLayer.getBoolean(ATTR_LAYER_IS_DISPLAYED); final Integer layerPosition = tagLayer.getInteger(ATTR_LAYER_POSITION); // validate properties if (layerName == null || layerTitle == null || layerIsDisplayed == null) { logError(NLS.bind(Messages.DBG019_Error_Wms_InvalidLayer, mapProviderId, TAG_LAYER), new Exception()); continue; } // check if a layer with the same name is already in the list, a layer MUST be unique boolean isLayerValid = true; { for (final LayerOfflineData layerOfflineData : offlineLayerList) { if (layerOfflineData.name.equalsIgnoreCase(layerName)) { logError(NLS.bind(Messages.DBG020_Error_Wms_DuplicateLayer, mapProviderId, layerName), new Exception()); isLayerValid = false; break; } } } if (isLayerValid == false) { continue; } final LayerOfflineData offlineLayer = new LayerOfflineData(); offlineLayer.name = layerName; offlineLayer.title = layerTitle; offlineLayer.isDisplayedInMap = layerIsDisplayed; offlineLayer.position = layerPosition == null ? -1 : layerPosition; offlineLayerList.add(offlineLayer); // if (layerIsDisplayed) { // displayedLayers++; // } } mapProvider.setOfflineLayers(offlineLayerList); // mapProvider.setDisplayedLayers(displayedLayers); return mapProvider; } public void remove(final MP mapProvider) { _allMapProviders.remove(mapProvider); } public void removeMapProviderListener(final IMapProviderListener listener) { if (listener != null) { _mapProviderListeners.remove(listener); } } private void updateMpSorting(final MP newMP) { final String[] storedMpIds = StringToArrayConverter.convertStringToArray(// _prefStore.getString(IMappingPreferences.MAP_PROVIDER_SORT_ORDER)); // check if the new mp is already in the list for (final String storedMpId : storedMpIds) { if (storedMpId.equals(newMP)) { // new mp is already in the list, this case should not happen return; } } final String[] newMpIds = new String[storedMpIds.length + 1]; final String newMpName = newMP.getName(); if (newMpName.startsWith(SINGLE_MAP_PROVIDER_NAME_PREFIX)) { // append at the end System.arraycopy(storedMpIds, 0, newMpIds, 0, storedMpIds.length); newMpIds[newMpIds.length - 1] = newMP.getId(); } else { // append at the start newMpIds[0] = newMP.getId(); System.arraycopy(storedMpIds, 0, newMpIds, 1, storedMpIds.length); } _prefStore.setValue(IMappingPreferences.MAP_PROVIDER_SORT_ORDER, StringToArrayConverter.convertArrayToString(newMpIds)); } /** * Validates an imported map provider * * @param importedMPList * contains all imported map provider including the plugin map provider * @return Returns the valid map provider or profile map providers which are not yet created. <br> * Returns <code>null</code> when the map provider is not valid. */ private ArrayList<MP> validateImportedMP(final ArrayList<MP> importedMPList) { final ArrayList<MP> newMPs = new ArrayList<MP>(); final ArrayList<MP> existingMPs = MapProviderManager.getInstance().getAllMapProviders(true); /* * first map provider is the main map provider, the others are wrapped map providers */ final MP importedMP = importedMPList.get(0); // check imported mp against existing mp's for (final MP mp : existingMPs) { // check ID if (mp.equals(importedMP)) { // duplicate ID MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.Import_Error_Dialog_Title, NLS.bind(Messages.DBG021_Import_Error_DuplicateId, mp.getId())); return null; } // check offline folder final String importedOfflineFolder = importedMP.getOfflineFolder(); if (mp.getOfflineFolder().equalsIgnoreCase(importedOfflineFolder)) { // duplicate folder MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.Import_Error_Dialog_Title, NLS.bind(Messages.DBG022_Import_Error_DuplicateOfflineFolder, mp.getId(), mp.getOfflineFolder())); return null; } } // update model with the imported MP _allMapProviders.add(importedMP); updateMpSorting(importedMP); /* * the imported map provider will be the first in the list, imported wrapped mp's come * afterwards */ newMPs.add(importedMP); if (importedMP instanceof MPCustom) { return newMPs; } else if (importedMP instanceof MPWms) { return newMPs; } else if (importedMP instanceof MPProfile) { return validateImportedProfile(importedMPList, newMPs); } return null; } /** * @param importedMP * @param newMPs * @return */ private ArrayList<MP> validateImportedProfile(final ArrayList<MP> importedMPList, final ArrayList<MP> newMPs) { final MPProfile importedMP = (MPProfile) importedMPList.get(0); // remove profile mp importedMPList.remove(0); /* * this list contains map providers which are wrapped in the profile but must be defined as * a ROOT_CHILD_TAG_WRAPPED_MAP_PROVIDER, this includes plugin map provider */ final ArrayList<MP> importedMpWrapperList = new ArrayList<MP>(importedMPList); final ArrayList<MP> existingMPs = MapProviderManager.getInstance().getAllMapProviders(true); final MPProfile importedMpProfile = importedMP; final ArrayList<MPWrapper> importedProfileWrappers = importedMpProfile.getAllWrappers(); // check all wrappers for (final MPWrapper importedWrapper : importedProfileWrappers) { // check wrapper map provider MP wrappedMP = null; // get map provider by id, wrapper and and map provider are linked with the id for (final MP importedWrappedMp : importedMpWrapperList) { if (importedWrappedMp.getId().equalsIgnoreCase(importedWrapper.getMapProviderId())) { wrappedMP = importedWrappedMp; break; } } if (wrappedMP == null) { // mp wrapper is not defined in the export file MessageDialog.openError(Display.getDefault().getActiveShell(), // Messages.Import_Error_Dialog_Title, NLS.bind(Messages.DBG023_Import_Error_WrappedMpIsNotDefined, new Object[] { importedMP.getId(), importedWrapper.getMapProviderId() })); return null; } final String importedWrapperMPClassName = wrappedMP.getClass().getName(); MP checkedMP = null; // check if the imported wrapper mp is available in the existing mp's for (final MP existingMp : existingMPs) { // check ID/class/folder if (existingMp.getId().equalsIgnoreCase(wrappedMP.getId())) { // same ID // check class if (existingMp.getClass().getName().equals(importedWrapperMPClassName)) { // same class // check folder for none Wms map provider, profile wms map providers are using another folder structure if (wrappedMP instanceof MPWms) { // the imported wrapper MP is an existing map provider checkedMP = wrappedMP; break; } else { // check offline folder if (existingMp.getOfflineFolder().equalsIgnoreCase(wrappedMP.getOfflineFolder())) { // same offline folder // the imported wrapper MP is an existing map provider checkedMP = wrappedMP; break; } else { // same ID/class but other offline folder MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.Import_Error_Dialog_Title, NLS.bind(Messages.DBG024_Import_Error_ProfileDuplicateOfflineFolder, new Object[] { importedMP.getId(), wrappedMP.getId(), wrappedMP.getOfflineFolder(), existingMp.getId() })); return null; } } } else { // same ID but another class MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.Import_Error_Dialog_Title, NLS.bind(Messages.DBG025_Import_Error_DifferentClass, new Object[] { importedMP.getId(), wrappedMP.getId(), importedWrapperMPClassName, existingMp.getClass().getName() })); return null; } } } if (checkedMP == null) { // imported wrapper mp do not yet exist and will be created // a plugin wrapper map provider must exist in the application if (wrappedMP instanceof MPPlugin) { MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.Import_Error_Dialog_Title, NLS.bind(Messages.DBG040_Import_Error_PluginMPIsNotAvailable, new Object[] { importedMP.getId(), wrappedMP.getId() })); return null; } if ((wrappedMP instanceof MPWms) == false) { // check folder for none Wms map provider, profile wms map providers are using another folder structure for (final MP existingMp : existingMPs) { if (existingMp.getOfflineFolder().equalsIgnoreCase(wrappedMP.getOfflineFolder())) { // folder is already used by another mp MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.Import_Error_Dialog_Title, NLS.bind(Messages.DBG026_Import_Error_ProfileDuplicateOfflineFolder, new Object[] { importedMP.getId(), wrappedMP.getId(), wrappedMP.getOfflineFolder(), existingMp.getId() })); return null; } } } newMPs.add(wrappedMP); // update model with the wrapped map provider _allMapProviders.add(wrappedMP); updateMpSorting(wrappedMP); } } return newMPs; } public void writeMapProviderXml() { BufferedWriter writer = null; try { final IPath stateLocation = Platform.getStateLocation(Activator.getDefault().getBundle()); final File file = stateLocation.append(CUSTOM_MAP_PROVIDER_FILE).toFile(); writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), UI.UTF_8)); final XMLMemento xmlMemento = createXmlRoot(false); for (final MP mapProvider : _allMapProviders) { if (mapProvider instanceof MPWms || mapProvider instanceof MPCustom || mapProvider instanceof MPProfile) { // a plugin map provider cannot be modified, save only none plugin map provider final IMemento tagMapProvider = xmlMemento.createChild(ROOT_CHILD_TAG_MAP_PROVIDER); writeXml(mapProvider, tagMapProvider); } } xmlMemento.save(writer); } catch (final IOException e) { StatusUtil.log(e); } finally { if (writer != null) { try { writer.close(); } catch (final IOException e) { StatusUtil.log(e); } } } fireChangeEvent(); } private void writeXml(final MP mp, final IMemento tagMapProvider) { final GeoPosition lastUsedPosition = mp.getLastUsedPosition(); final GeoPosition favoritePosition = mp.getFavoritePosition(); /* * set common fields */ tagMapProvider.putString(ATTR_MP_ID, mp.getId()); tagMapProvider.putString(ATTR_MP_NAME, mp.getName()); tagMapProvider.putString(ATTR_MP_DESCRIPTION, mp.getDescription()); tagMapProvider.putString(ATTR_MP_OFFLINE_FOLDER, mp.getOfflineFolder()); // image tagMapProvider.putInteger(ATTR_MP_IMAGE_SIZE, mp.getTileSize()); tagMapProvider.putString(ATTR_MP_IMAGE_FORMAT, mp.getImageFormat()); // zoom level tagMapProvider.putInteger(ATTR_MP_ZOOM_LEVEL_MIN, mp.getMinZoomLevel()); tagMapProvider.putInteger(ATTR_MP_ZOOM_LEVEL_MAX, mp.getMaxZoomLevel()); // favorite position tagMapProvider.putInteger(ATTR_MP_FAVORITE_ZOOM_LEVEL, mp.getFavoriteZoom()); tagMapProvider.putFloat(ATTR_MP_FAVORITE_LATITUDE, favoritePosition == null ? 0.0f : (float) favoritePosition.latitude); tagMapProvider.putFloat(ATTR_MP_FAVORITE_LONGITUDE, favoritePosition == null ? 0.0f : (float) favoritePosition.longitude); // last used position tagMapProvider.putInteger(ATTR_MP_LAST_USED_ZOOM_LEVEL, mp.getLastUsedZoom()); tagMapProvider.putFloat(ATTR_MP_LAST_USED_LATITUDE, lastUsedPosition == null ? 0.0f : (float) lastUsedPosition.latitude); tagMapProvider.putFloat(ATTR_MP_LAST_USED_LONGITUDE, lastUsedPosition == null ? 0.0f : (float) lastUsedPosition.longitude); /* * add special fields for each map provider */ if (mp instanceof MPWms) { writeXmlWms((MPWms) mp, tagMapProvider); } else if (mp instanceof MPCustom) { writeXmlCustom((MPCustom) mp, tagMapProvider); } else if (mp instanceof MPProfile) { writeXmlProfile((MPProfile) mp, tagMapProvider); } else if (mp instanceof MPPlugin) { // plugin mp can be exported in the map profile tagMapProvider.putString(ATTR_MP_TYPE, MAP_PROVIDER_TYPE_PLUGIN); } } private void writeXmlCustom(final MPCustom customMapProvider, final IMemento tagMapProvider) { tagMapProvider.putString(ATTR_MP_TYPE, MAP_PROVIDER_TYPE_CUSTOM); /* * custom map provider specific fields */ tagMapProvider.putString(ATTR_CUSTOM_CUSTOM_URL, customMapProvider.getCustomUrl()); /* * url parts */ for (final UrlPart urlPart : customMapProvider.getUrlParts()) { final IMemento partTag = tagMapProvider.createChild(TAG_URL_PART); final PART_TYPE partType = urlPart.getPartType(); partTag.putString(ATTR_CUSTOM_PART_TYPE, getPartType(partType)); partTag.putInteger(ATTR_CUSTOM_PART_POSITION, urlPart.getPosition()); switch (partType) { case HTML: partTag.putString(ATTR_CUSTOM_PART_CONTENT_HTML, urlPart.getHtml()); break; case RANDOM_INTEGER: partTag.putInteger(ATTR_CUSTOM_PART_CONTENT_RANDOM_INTEGER_START, urlPart.getRandomIntegerStart()); partTag.putInteger(ATTR_CUSTOM_PART_CONTENT_RANDOM_INTEGER_END, urlPart.getRandomIntegerEnd()); break; case RANDOM_ALPHA: partTag.putString(ATTR_CUSTOM_PART_CONTENT_RANDOM_ALPHA_START, urlPart.getRandomAlphaStart()); partTag.putString(ATTR_CUSTOM_PART_CONTENT_RANDOM_ALPHA_END, urlPart.getRandomAlphaEnd()); break; default: break; } } } private void writeXmlProfile(final MPProfile mapProfile, final IMemento tagProfile) { tagProfile.putString(ATTR_MP_TYPE, MAP_PROVIDER_TYPE_MAP_PROFILE); tagProfile.putInteger(ATTR_PMP_BACKGROUND_COLOR, mapProfile.getBackgroundColor()); /* * map provider specific fields */ for (final MPWrapper mpWrapper : mapProfile.getAllWrappers()) { final MP mp = mpWrapper.getMP(); final String mpType = getMapProviderType(mp); if (mpType == null) { continue; } final boolean isDisplayedInMap = mpWrapper.isDisplayedInMap(); if (isDisplayedInMap == false) { // save only displayed map providers to reduce space continue; } final IMemento tagProfileMapProvider = tagProfile.createChild(TAG_MAP_PROVIDER_WRAPPER); tagProfileMapProvider.putString(ATTR_PMP_MAP_PROVIDER_TYPE, mpType); tagProfileMapProvider.putString(ATTR_PMP_MAP_PROVIDER_ID, mp.getId()); tagProfileMapProvider.putInteger(ATTR_PMP_POSITION, mpWrapper.getPositionIndex()); tagProfileMapProvider.putBoolean(ATTR_PMP_IS_DISPLAYED, isDisplayedInMap); tagProfileMapProvider.putInteger(ATTR_PMP_ALPHA, mpWrapper.getAlpha()); tagProfileMapProvider.putBoolean(ATTR_PMP_IS_TRANSPARENT, mpWrapper.isTransparentColors()); tagProfileMapProvider.putBoolean(ATTR_PMP_IS_BLACK_TRANSPARENT, mpWrapper.isTransparentBlack()); tagProfileMapProvider.putBoolean(ATTR_PMP_IS_BRIGHTNESS_FOR_NEXT_MP, mpWrapper.isBrightnessForNextMp()); tagProfileMapProvider.putInteger(ATTR_PMP_BRIGHTNESS_FOR_NEXT_MP, mpWrapper.getBrightnessValueForNextMp()); // transparent colors final int[] transparentColors = mpWrapper.getTransparentColors(); if (transparentColors != null) { // create a child for each color for (final int color : transparentColors) { // don't write black color this is with the attribute ATTR_PMP_IS_TRANSPARENT_BLACK if (color > 0) { tagProfileMapProvider// .createChild(TAG_TRANSPARENT_COLOR).putInteger(ATTR_TRANSPARENT_COLOR_VALUE, color); } } } // wms layers if (mp instanceof MPWms) { writeXmlWmsLayers(tagProfileMapProvider, (MPWms) mp); } } } private void writeXmlWms(final MPWms wmsMapProvider, final IMemento tagMapProvider) { tagMapProvider.putString(ATTR_MP_TYPE, MAP_PROVIDER_TYPE_WMS); tagMapProvider.putString(ATTR_WMS_CAPS_URL, wmsMapProvider.getCapabilitiesUrl()); tagMapProvider.putString(ATTR_WMS_MAP_URL, wmsMapProvider.getGetMapUrl()); tagMapProvider.putBoolean(ATTR_WMS_LOAD_TRANSPARENT_IMAGES, wmsMapProvider.isTransparent()); writeXmlWmsLayers(tagMapProvider, wmsMapProvider); } /** * write all layers from the wms caps */ private void writeXmlWmsLayers(final IMemento parentTag, final MPWms wmsMapProvider) { final ArrayList<MtLayer> mtLayers = wmsMapProvider.getMtLayers(); if (mtLayers == null) { // caps are not loaded from the server // write all layers from the offline info final ArrayList<LayerOfflineData> offlineLayers = wmsMapProvider.getOfflineLayers(); if (offlineLayers != null) { for (final LayerOfflineData offlineLayer : offlineLayers) { final IMemento layerTag = parentTag.createChild(TAG_LAYER); layerTag.putString(ATTR_LAYER_NAME, offlineLayer.name); layerTag.putString(ATTR_LAYER_TITLE, offlineLayer.title); layerTag.putBoolean(ATTR_LAYER_IS_DISPLAYED, offlineLayer.isDisplayedInMap); layerTag.putInteger(ATTR_LAYER_POSITION, offlineLayer.position); } } } else { // caps are loaded from the wms server for (final MtLayer mtLayer : mtLayers) { final Layer layer = mtLayer.getGeoLayer(); // check if the layer is drawable final String layerName = layer.getName(); if (layerName != null && layerName.trim().length() > 0) { final IMemento layerTag = parentTag.createChild(TAG_LAYER); layerTag.putString(ATTR_LAYER_NAME, layerName); layerTag.putString(ATTR_LAYER_TITLE, layer.getTitle()); layerTag.putBoolean(ATTR_LAYER_IS_DISPLAYED, mtLayer.isDisplayedInMap()); layerTag.putInteger(ATTR_LAYER_POSITION, mtLayer.getPositionIndex()); } } } } }