<commit_before>/*
 * This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
 *
 * Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
 *
 * The program is available in open source according to the GNU Affero
 * General Public License. All contributions in this program are covered
 * by the Geomajas Contributors License Agreement. For full licensing
 * details, see LICENSE.txt in the project root.
 */
package org.geomajas.internal.configuration;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.geomajas.configuration.FeatureStyleInfo;
import org.geomajas.configuration.LayerInfo;
import org.geomajas.configuration.NamedStyleInfo;
import org.geomajas.configuration.RasterLayerInfo;
import org.geomajas.configuration.VectorLayerInfo;
import org.geomajas.configuration.client.ClientApplicationInfo;
import org.geomajas.configuration.client.ClientLayerInfo;
import org.geomajas.configuration.client.ClientLayerTreeInfo;
import org.geomajas.configuration.client.ClientLayerTreeNodeInfo;
import org.geomajas.configuration.client.ClientMapInfo;
import org.geomajas.configuration.client.ClientVectorLayerInfo;
import org.geomajas.configuration.client.ScaleInfo;
import org.geomajas.geometry.Bbox;
import org.geomajas.geometry.Coordinate;
import org.geomajas.geometry.Crs;
import org.geomajas.geometry.CrsTransform;
import org.geomajas.global.ExceptionCode;
import org.geomajas.global.GeomajasException;
import org.geomajas.layer.Layer;
import org.geomajas.layer.LayerException;
import org.geomajas.layer.RasterLayer;
import org.geomajas.layer.VectorLayer;
import org.geomajas.service.DtoConverterService;
import org.geomajas.service.GeoService;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.referencing.GeodeticCalculator;
import org.opengis.referencing.operation.TransformException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.vividsolutions.jts.geom.Envelope;

/**
 * Post-processes configuration DTOs. Generally responsible for any behaviour that would violate the DTO contract
 * (especially for GWT) if it would be added to the configuration objects themselves, such as hooking up client
 * configurations to their server layers.
 * 
 * @author <NAME>
 */
@Component
public class ConfigurationDtoPostProcessor {

	private static final double METER_PER_INCH = 0.0254;

	private final Logger log = LoggerFactory.getLogger(ConfigurationDtoPostProcessor.class);

	@Autowired
	private DtoConverterService converterService;

	@Autowired
	private GeoService geoService;

	@Autowired(required = false)
	protected Map<String, ClientApplicationInfo> applicationMap = new LinkedHashMap<String, ClientApplicationInfo>();

	@Autowired(required = false)
	protected Map<String, NamedStyleInfo> namedStyleMap = new LinkedHashMap<String, NamedStyleInfo>();

	@Autowired(required = false)
	protected Map<String, Layer<?>> layerMap = new LinkedHashMap<String, Layer<?>>();

	@Autowired(required = false)
	protected Map<String, RasterLayer> rasterLayerMap = new LinkedHashMap<String, RasterLayer>();

	@Autowired(required = false)
	protected Map<String, VectorLayer> vectorLayerMap = new LinkedHashMap<String, VectorLayer>();

	public ConfigurationDtoPostProcessor() {

	}

	@PostConstruct
	public void processConfiguration() throws BeansException {
		try {
			for (RasterLayer layer : rasterLayerMap.values()) {
				postProcess(layer);
			}
			for (VectorLayer layer : vectorLayerMap.values()) {
				postProcess(layer);
			}
			for (ClientApplicationInfo application : applicationMap.values()) {
				postProcess(application);
			}
			for (NamedStyleInfo style : namedStyleMap.values()) {
				postProcess(style);
			}
		} catch (LayerException e) {
			throw new BeanInitializationException("Invalid configuration", e);
		}
	}

	private void postProcess(RasterLayer layer) throws LayerException {
		RasterLayerInfo info = layer.getLayerInfo();
		for (ScaleInfo scale : info.getZoomLevels()) {
			// for raster layers we don't accept 1 : x notation !
			if (scale.getDenominator() != 0) {
				throw new LayerException(ExceptionCode.CONVERSION_PROBLEM, "Raster layer " + layer.getId()
						+ " has zoom level " + scale.getNumerator() + " : " + scale.getDenominator()
						+ " in disallowed 1 : x notation");
			}
			// add the resolution for deprecated api support
			info.getResolutions().add(1. / scale.getPixelPerUnit());
		}
	}

	private void postProcess(VectorLayer layer) throws LayerException {
		// apply defaults to all styles
		VectorLayerInfo info = layer.getLayerInfo();
		for (NamedStyleInfo namedStyle : info.getNamedStyleInfos()) {
			for (FeatureStyleInfo featureStyle : namedStyle.getFeatureStyles()) {
				featureStyle.applyDefaults();
			}
			namedStyle.getLabelStyle().getBackgroundStyle().applyDefaults();
			namedStyle.getLabelStyle().getFontStyle().applyDefaults();
		}
	}

	private ClientApplicationInfo postProcess(ClientApplicationInfo client) throws LayerException, BeansException {
		// initialize maps
		for (ClientMapInfo map : client.getMaps()) {
			map.setUnitLength(getUnitLength(map.getCrs(), map.getInitialBounds()));
			// result should be m = (m/inch) / (number/inch)
			map.setPixelLength(METER_PER_INCH / client.getScreenDpi());
			log.debug("Map " + map.getId() + " has unit length : " + map.getUnitLength() + "m, pixel length "
					+ map.getPixelLength() + "m");
			// calculate scales
			double pixPerUnit = map.getUnitLength() / map.getPixelLength();
			// if resolutions have been defined the old way, calculate the scale configuration
			if (map.getResolutions().size() > 0) {
				for (Double resolution : map.getResolutions()) {
					if (map.isResolutionsRelative()) {
						map.getScaleConfiguration().getZoomLevels().add(new ScaleInfo(1., resolution));
					} else {<commit_msg>GWTSHOW-84: null check for layer info<commit_after>/*
 * This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
 *
 * Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
 *
 * The program is available in open source according to the GNU Affero
 * General Public License. All contributions in this program are covered
 * by the Geomajas Contributors License Agreement. For full licensing
 * details, see LICENSE.txt in the project root.
 */
package org.geomajas.internal.configuration;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.geomajas.configuration.FeatureStyleInfo;
import org.geomajas.configuration.LayerInfo;
import org.geomajas.configuration.NamedStyleInfo;
import org.geomajas.configuration.RasterLayerInfo;
import org.geomajas.configuration.VectorLayerInfo;
import org.geomajas.configuration.client.ClientApplicationInfo;
import org.geomajas.configuration.client.ClientLayerInfo;
import org.geomajas.configuration.client.ClientLayerTreeInfo;
import org.geomajas.configuration.client.ClientLayerTreeNodeInfo;
import org.geomajas.configuration.client.ClientMapInfo;
import org.geomajas.configuration.client.ClientVectorLayerInfo;
import org.geomajas.configuration.client.ScaleInfo;
import org.geomajas.geometry.Bbox;
import org.geomajas.geometry.Coordinate;
import org.geomajas.geometry.Crs;
import org.geomajas.geometry.CrsTransform;
import org.geomajas.global.ExceptionCode;
import org.geomajas.global.GeomajasException;
import org.geomajas.layer.Layer;
import org.geomajas.layer.LayerException;
import org.geomajas.layer.RasterLayer;
import org.geomajas.layer.VectorLayer;
import org.geomajas.service.DtoConverterService;
import org.geomajas.service.GeoService;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.referencing.GeodeticCalculator;
import org.opengis.referencing.operation.TransformException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.vividsolutions.jts.geom.Envelope;

/**
 * Post-processes configuration DTOs. Generally responsible for any behaviour that would violate the DTO contract
 * (especially for GWT) if it would be added to the configuration objects themselves, such as hooking up client
 * configurations to their server layers.
 * 
 * @author <NAME>
 */
@Component
public class ConfigurationDtoPostProcessor {

	private static final double METER_PER_INCH = 0.0254;

	private final Logger log = LoggerFactory.getLogger(ConfigurationDtoPostProcessor.class);

	@Autowired
	private DtoConverterService converterService;

	@Autowired
	private GeoService geoService;

	@Autowired(required = false)
	protected Map<String, ClientApplicationInfo> applicationMap = new LinkedHashMap<String, ClientApplicationInfo>();

	@Autowired(required = false)
	protected Map<String, NamedStyleInfo> namedStyleMap = new LinkedHashMap<String, NamedStyleInfo>();

	@Autowired(required = false)
	protected Map<String, Layer<?>> layerMap = new LinkedHashMap<String, Layer<?>>();

	@Autowired(required = false)
	protected Map<String, RasterLayer> rasterLayerMap = new LinkedHashMap<String, RasterLayer>();

	@Autowired(required = false)
	protected Map<String, VectorLayer> vectorLayerMap = new LinkedHashMap<String, VectorLayer>();

	public ConfigurationDtoPostProcessor() {

	}

	@PostConstruct
	public void processConfiguration() throws BeansException {
		try {
			for (RasterLayer layer : rasterLayerMap.values()) {
				postProcess(layer);
			}
			for (VectorLayer layer : vectorLayerMap.values()) {
				postProcess(layer);
			}
			for (ClientApplicationInfo application : applicationMap.values()) {
				postProcess(application);
			}
			for (NamedStyleInfo style : namedStyleMap.values()) {
				postProcess(style);
			}
		} catch (LayerException e) {
			throw new BeanInitializationException("Invalid configuration", e);
		}
	}

	private void postProcess(RasterLayer layer) throws LayerException {
		RasterLayerInfo info = layer.getLayerInfo();
		for (ScaleInfo scale : info.getZoomLevels()) {
			// for raster layers we don't accept 1 : x notation !
			if (scale.getDenominator() != 0) {
				throw new LayerException(ExceptionCode.CONVERSION_PROBLEM, "Raster layer " + layer.getId()
						+ " has zoom level " + scale.getNumerator() + " : " + scale.getDenominator()
						+ " in disallowed 1 : x notation");
			}
			// add the resolution for deprecated api support
			info.getResolutions().add(1. / scale.getPixelPerUnit());
		}
	}

	private void postProcess(VectorLayer layer) throws LayerException {
		// apply defaults to all styles
		VectorLayerInfo info = layer.getLayerInfo();
		if (info != null) {
			for (NamedStyleInfo namedStyle : info.getNamedStyleInfos()) {
				for (FeatureStyleInfo featureStyle : namedStyle.getFeatureStyles()) {
					featureStyle.applyDefaults();
				}
				namedStyle.getLabelStyle().getBackgroundStyle().applyDefaults();
				namedStyle.getLabelStyle().getFontStyle().applyDefaults();
			}
		}
	}

	private ClientApplicationInfo postProcess(ClientApplicationInfo client) throws LayerException, BeansException {
		// initialize maps
		for (ClientMapInfo map : client.getMaps()) {
			map.setUnitLength(getUnitLength(map.getCrs(), map.getInitialBounds()));
			// result should be m = (m/inch) / (number/inch)
			map.setPixelLength(METER_PER_INCH / client.getScreenDpi());
			log.debug("Map " + map.getId() + " has unit length : " + map.getUnitLength() + "m, pixel length "
					+ map.getPixelLength() + "m");
			// calculate scales
			double pixPerUnit = map.getUnitLength() / map.getPixelLength();
			// if resolutions have been defined the old way, calculate the scale configuration
			if (map.getResolutions().size() > 0) {
				for (Double resolution : map.getResolutions()) {
					if (map.isResolutionsRelative()) {
						map.getScaleConfiguration().getZoomLevels().add(new ScaleInfo(1., resolution));
					} else {
{'fraction_non_alphanumeric': 0.10310630276206868, 'fraction_numerical': 0.003770182771903942, 'mean_word_length': 5.225510204081632, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '264706', 'n_tokens_mistral': 3830, 'n_tokens_neox': 3487, 'n_words': 836}