All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cds.adapter.odata.v4.metadata.provider.DefaultEdmxProvider Maven / Gradle / Ivy

There is a newer version: 3.2.0
Show newest version
/**************************************************************************
 * (C) 2019-2024 SAP SE or an SAP affiliate company. All rights reserved. *
 **************************************************************************/
package com.sap.cds.adapter.odata.v4.metadata.provider;

import java.io.InputStream;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider;

import com.sap.cds.adapter.odata.v4.metadata.MetadataInfo;
import com.sap.cds.services.environment.CdsProperties.ODataV4;
import com.sap.cds.services.request.RequestContext;
import com.sap.cds.services.runtime.CdsRuntime;
import com.sap.cds.services.utils.CdsErrorStatuses;
import com.sap.cds.services.utils.ErrorStatusException;
import com.sap.cds.services.utils.LocaleUtils;

/**
 * Default implementation of the EDMX parsing. It looks for the EDMX in the applications resource folder.
 */
public class DefaultEdmxProvider implements OlingoAwareEdmxV4Provider {

	// base path for unlocalized EDMX files
	private final static String UNLOCALIZED_BASE_PATH = "edmx/odata/v4";

	private final Map metadataInfoMap = new ConcurrentHashMap<>();
	private final CdsRuntime runtime;
	private String basePath = "edmx";

	public DefaultEdmxProvider(CdsRuntime runtime) {
		this.runtime = runtime;
		ODataV4 config = runtime.getEnvironment().getCdsProperties().getOdataV4();
		if(getClass().getClassLoader().getResource(config.getEdmxPath()) != null) {
			this.basePath = config.getEdmxPath();
		} else if (config.getLazyI18n().isEnabled() && getClass().getClassLoader().getResource(UNLOCALIZED_BASE_PATH) != null) {
			this.basePath = UNLOCALIZED_BASE_PATH;
		}
	}

	@Override
	public String getETag(String serviceName) {
		return getMetadataInfo(serviceName).getETag();
	}

	@Override
	public InputStream getEdmx(String serviceName) {
		return getMetadataInfo(serviceName).getEdmx();
	}

	@Override
	public CsdlEdmProvider getEdmProvider(String serviceName) {
		return getMetadataInfo(serviceName).getEdmProvider();
	}

	MetadataInfo getMetadataInfo(String serviceName) {
		Locale locale = RequestContext.getCurrent(runtime).getParameterInfo().getLocale();
		MetadataInfo info = getMetadataInfo(serviceName, locale);
		if(locale != null && info.isEmpty()) {
			// retry without locale
			info = getMetadataInfo(serviceName, null);
		}
		if (info.isEmpty()) {
			throw new ErrorStatusException(CdsErrorStatuses.INVALID_METADATA, serviceName);
		}
		return info;
	}

	private MetadataInfo getMetadataInfo(String unlocalizedServiceName, Locale locale) {
		String serviceName;
		if(locale != null) {
			String language = LocaleUtils.getLocaleForBundle(locale).toString();
			serviceName = unlocalizedServiceName + "_" + language;
		} else {
			serviceName = unlocalizedServiceName;
		}

		return metadataInfoMap.computeIfAbsent(serviceName, (key) -> {
			try {
				String resourcePathToEdmx = basePath + "/" + serviceName + ".xml"; // getResourceAsStream accepts unnormalized paths containing e.g. "//"
				try(InputStream resource = getClass().getClassLoader().getResourceAsStream(resourcePathToEdmx)) {
					if (resource != null) {
						return MetadataInfo.create(serviceName, resource.readAllBytes(), runtime);
					}
				}
				return MetadataInfo.create(serviceName, null, runtime);
			} catch (Exception e) {
				throw new ErrorStatusException(CdsErrorStatuses.INVALID_METADATA, serviceName, e);
			}
		});
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy