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

com.sap.cds.reflect.impl.CdsModelBuilder Maven / Gradle / Ivy

There is a newer version: 3.6.1
Show newest version
/*******************************************************************
 * © 2020 SAP SE or an SAP affiliate company. All rights reserved. *
 *******************************************************************/
package com.sap.cds.reflect.impl;

import static com.sap.cds.reflect.impl.CdsDefinitionBuilder.byNamespace;
import static java.util.Collections.emptyList;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.sap.cds.reflect.CdsAction;
import com.sap.cds.reflect.CdsAnnotation;
import com.sap.cds.reflect.CdsDefinition;
import com.sap.cds.reflect.CdsDefinitionNotFoundException;
import com.sap.cds.reflect.CdsEntity;
import com.sap.cds.reflect.CdsEvent;
import com.sap.cds.reflect.CdsFunction;
import com.sap.cds.reflect.CdsModel;
import com.sap.cds.reflect.CdsService;
import com.sap.cds.reflect.CdsType;
import com.sap.cds.reflect.impl.reader.model.CdsConstants;

public class CdsModelBuilder {

	private final Map entities = new HashMap<>();
	private final Map services = new HashMap<>();
	private final Map actions = new HashMap<>();
	private final Map functions = new HashMap<>();
	private final Map events = new HashMap<>();
	private final Map> types = new HashMap<>();
	private final Map meta = new HashMap<>();
	private final Map>> contextAnnotations = new HashMap<>();

	private CdsModelBuilder() {
	}

	public static CdsModelBuilder create() {
		return new CdsModelBuilder();
	}

	public Stream concreteEntities() {
		return entities().filter(e -> !e.isAbstract());
	}

	void addAnnotations(String key, Collection> annotations) {
		contextAnnotations.put(key, annotations);
	}

	public Optional> findType(String qualifiedName) {
		CdsTypeBuilder type = types.get(qualifiedName);
		if (type != null) {
			return Optional.of(type);
		}
		return Optional.ofNullable(entities.get(qualifiedName));
	}

	public Stream entities() {
		return entities.values().stream();
	}

	public Optional findEntity(String qualifiedName) {
		return Optional.ofNullable(entities.get(qualifiedName));
	}

	public CdsEntityBuilder getEntity(String qualifiedName) {
		return findEntity(qualifiedName).orElseThrow(notFound("entity", qualifiedName));
	}

	public Optional findAction(String qualifiedName) {
		return Optional.ofNullable(actions.get(qualifiedName));
	}

	public Optional findFunction(String qualifiedName) {
		return Optional.ofNullable(functions.get(qualifiedName));
	}

	@SuppressWarnings("unchecked")
	public  T getMeta(String key) {
		return (T) meta.get(key);
	}

	void addType(String key, CdsTypeBuilder type) {
		this.types.put(key, type);
	}

	void addEntity(CdsEntityBuilder entity) {
		addEntity(entity.qualifiedName, entity);
	}

	void addEntity(String key, CdsEntityBuilder entity) {
		this.entities.put(key, entity);
	}

	void addEvent(CdsEventBuilder event) {
		addEvent(event.getQualifiedName(), event);
	}

	void addEvent(String key, CdsEventBuilder event) {
		this.events.put(key, event);
	}

	public void addService(CdsServiceBuilder service) {
		addService(service.getQualifiedName(), service);
	}

	void addService(String key, CdsServiceBuilder service) {
		this.services.put(key, service);
	}

	void addFunction(CdsFunctionBuilder function) {
		addFunction(function.getQualifiedName(), function);
	}

	void addFunction(String key, CdsFunctionBuilder function) {
		this.functions.put(key, function);
	}

	void addAction(CdsActionBuilder action) {
		addAction(action.getQualifiedName(), action);
	}

	void addAction(String key, CdsActionBuilder action) {
		this.actions.put(key, action);
	}

	void addMeta(String key, Object value) {
		this.meta.put(key, value);
	}

	void addMeta(Map meta) {
		this.meta.putAll(meta);
	}

	private static Supplier notFound(String type, String qualifiedName) {
		return () -> new CdsDefinitionNotFoundException(String.format("Cannot find %s '%s'", type, qualifiedName));
	}

	public CdsModel build() {
		Map immutableEntities = buildDefinitions(entities);
		Map immuteableTypes = buildTypes(types);
		Map immutableEvents = buildDefinitions(events);
		Map immutableActions = buildDefinitions(actions);
		Map immutableFunctions = buildDefinitions(functions);
		Map immutableServices = new HashMap<>();
		for (Map.Entry pair : services.entrySet()) {
			CdsServiceBuilder serivceBuilder = pair.getValue();
			serivceBuilder.setEntities(entities.values().stream().filter(byNamespace(serivceBuilder.getQualifiedName()))
					.collect(Collectors.toList()));
			serivceBuilder.setEvents(events.values().stream().filter(byNamespace(serivceBuilder.getQualifiedName()))
					.collect(Collectors.toList()));
			serivceBuilder.setFunctions(functions.values().stream()
					.filter(byNamespace(serivceBuilder.getQualifiedName())).collect(Collectors.toList()));
			serivceBuilder.setActions(actions.values().stream().filter(byNamespace(serivceBuilder.getQualifiedName()))
					.collect(Collectors.toList()));
			immutableServices.put(pair.getKey(), serivceBuilder.build());
		}
		return new CdsModelImpl(immutableEntities, immutableServices, immutableActions, immutableFunctions,
				immutableEvents, immuteableTypes, meta, contextAnnotations);
	}

	private static  Map buildDefinitions(
			Map> builders) {
		Map definitions = new HashMap<>();
		builders.forEach((n, b) -> {
			if (!b.toBeIgnored(b.getQualifiedName())) {
				definitions.put(n, b.build());
			}
		});

		return definitions;
	}

	private static Map buildTypes(Map> builders) {
		Map types = new HashMap<>();
		builders.forEach((n, b) -> {
			if (!b.toBeIgnored(b.getQualifiedName())) {
				types.put(n, b.build());
			}
		});

		return types;
	}

	private static class CdsModelImpl implements CdsModel {

		private final Map entities;
		private final Map services;
		private final Map actions;
		private final Map functions;
		private final Map events;
		private final Map types;
		private final Map meta;
		private final Map>> contextAnnotations;

		private CdsModelImpl(Map entities, Map services,
				Map actions, Map functions, Map events,
				Map types, Map meta,
				Map>> contextAnnotations) {
			this.entities = entities;
			this.services = services;
			this.actions = actions;
			this.functions = functions;
			this.events = events;
			this.types = types;
			this.meta = meta;
			this.contextAnnotations = contextAnnotations;
		}

		@Override
		public Stream> annotations(String namespace) {
			return contextAnnotations.getOrDefault(namespace, emptyList()).stream();
		}

		@Override
		public Stream services() {
			return services.values().stream();
		}

		@Override
		public Optional findService(String qualifiedName) {
			return Optional.ofNullable(services.get(qualifiedName));
		}

		@Override
		public CdsService getService(String qualifiedName) {
			return findService(qualifiedName).orElseThrow(notFound("service", qualifiedName));
		}

		@Override
		public Stream types() {
			return types.values().stream();
		}

		@Override
		@SuppressWarnings("unchecked")
		public  Optional findType(String qualifiedName) {
			return Optional.ofNullable((T) types.get(qualifiedName));
		}

		@Override
		@SuppressWarnings("unchecked")
		public  T getType(String qualifiedName) {
			return (T) findType(qualifiedName).orElseThrow(notFound("type", qualifiedName));
		}

		@Override
		public Stream entities() {
			return entities.values().stream();
		}

		@Override
		public Optional findEntity(String qualifiedName) {
			return Optional.ofNullable(entities.get(qualifiedName));
		}

		@Override
		public CdsEntity getEntity(String qualifiedName) {
			return findEntity(qualifiedName).orElseThrow(notFound("entity", qualifiedName));
		}

		@Override
		public Stream actions() {
			return actions.values().stream();
		}

		@Override
		public Optional findAction(String qualifiedName) {
			return Optional.ofNullable(actions.get(qualifiedName));
		}

		@Override
		public CdsAction getAction(String qualifiedName) {
			return findAction(qualifiedName).orElseThrow(notFound("action", qualifiedName));
		}

		@Override
		public Stream functions() {
			return functions.values().stream();
		}

		@Override
		public Optional findFunction(String qualifiedName) {
			return Optional.ofNullable(functions.get(qualifiedName));
		}

		@Override
		public CdsFunction getFunction(String qualifiedName) {
			return findFunction(qualifiedName).orElseThrow(notFound("function", qualifiedName));
		}

		@Override
		public Stream events() {
			return events.values().stream();
		}

		@Override
		public CdsEvent getEvent(String qualifiedName) {
			return findEvent(qualifiedName).orElseThrow(notFound("event", qualifiedName));
		}

		@Override
		public Optional findEvent(String qualifiedName) {
			return Optional.ofNullable(events.get(qualifiedName));
		}

		@Override
		@SuppressWarnings("unchecked")
		public  T getMeta(String key) {
			return (T) meta.get(key);
		}

		@Override
		public String getVersion() {
			return getMeta(CdsConstants.VERSION);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy