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

com.sap.cds.reflect.impl.CdsElementBuilder 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 java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.sap.cds.reflect.CdsAnnotation;
import com.sap.cds.reflect.CdsDefinition;
import com.sap.cds.reflect.CdsElement;
import com.sap.cds.reflect.CdsEnumType;
import com.sap.cds.reflect.CdsEnumType.Enumeral;
import com.sap.cds.reflect.CdsType;

public class CdsElementBuilder extends CdsAnnotableBuilder {
	private static byte IS_KEY = 1;
	private static byte IS_VIRTUAL = 2;
	private static byte IS_NOT_NULL = 4;
	private static byte IS_LOCALIZED = 8;

	private String name;
	private final CdsTypeBuilder typeBuilder;

	public CdsTypeBuilder getTypeBuilder() {
		return typeBuilder;
	}

	private T type;
	private boolean isKey;
	private final boolean isVirtual;
	private final boolean isNotNull;
	private final boolean isLocalized;
	private final Object defaultValue;
	private final String doc;
	private CdsDefinitionBuilder declaringType;

	public CdsElementBuilder(List> annotations, String name, CdsTypeBuilder typeBuilder,
			boolean isKey, boolean isVirtual, boolean isNotNull, boolean isLocalized, Object defaultValue, String doc) {
		super(annotations);
		this.name = name;
		this.typeBuilder = typeBuilder;
		this.isKey = isKey;
		this.isVirtual = isVirtual;
		this.isNotNull = isNotNull;
		this.isLocalized = isLocalized;
		this.defaultValue = defaultValue;
		this.doc = doc;
	}

	public static  CdsElementBuilder element(String name) {
		return new CdsElementBuilder<>(Collections.emptyList(), name, null, false, false, false, false, null, null);
	}

	public static CdsElementBuilder copy(CdsElement element) {
		List> annotations = element.annotations().collect(Collectors.toList());
		String doc = null;
		Optional elementDoc = ((CdsAnnotatableImpl) element).getDoc();
		if (elementDoc.isPresent()) {
			doc = elementDoc.get();
		}
		return new CdsElementBuilder<>(annotations, element.getName(), null, element.isKey(), element.isVirtual(),
				element.isNotNull(), element.isLocalized(), element.defaultValue().orElse(null), doc)
				.type(element.getType());
	}

	public CdsElementBuilder name(String name) {
		this.name = name;
		return this;
	}

	public CdsElementBuilder isKey(boolean isKey) {
		this.isKey = isKey;
		return this;
	}

	public CdsElementBuilder type(T type) {
		this.type = type;
		return this;
	}

	public String getName() {
		return name;
	}

	void setDeclaringType(CdsDefinitionBuilder declaringType) {
		if (this.declaringType == null) {
			this.declaringType = declaringType;
		}
	}

	public CdsElement build(CdsDefinition declarator) {
		if (type == null) {
			type = typeBuilder.build();
		}
		return new CdsElementImpl<>(annotations, name, type, isKey, isVirtual, isNotNull, isLocalized, declarator,
				defaultValue, doc);
	}

	private static class CdsElementImpl extends CdsAnnotatableImpl implements CdsElement {

		private final String name;
		private final U type;
		private final byte flags;
		private final Object defaultValue;
		private final CdsDefinition declarator;

		public CdsElementImpl(Collection> annotations, String name, U type, boolean isKey,
				boolean isVirtual, boolean isNotNull, boolean isLocalized, CdsDefinition declarator,
				Object defaultValue, String doc) {
			super(annotations, doc);
			this.name = name.intern();
			this.type = type;
			this.defaultValue = resolveDefault(type, defaultValue);
			this.declarator = declarator;
			byte flags = 0;
			if (isKey)
				flags |= IS_KEY;
			if (isVirtual)
				flags |= IS_VIRTUAL;
			if (isNotNull)
				flags |= IS_NOT_NULL;
			if (isLocalized)
				flags |= IS_LOCALIZED;
			this.flags = flags;
		}

		@Override
		public String getName() {
			return name;
		}

		@Override
		@SuppressWarnings("unchecked")
		public  D getDeclaringType() {
			return (D) declarator;
		}

		@Override
		@SuppressWarnings("unchecked")
		public U getType() {
			return type;
		}

		@Override
		public boolean isKey() {
			return (flags & IS_KEY) != 0;
		}

		@Override
		public boolean isVirtual() {
			return (flags & IS_VIRTUAL) != 0;
		}

		@Override
		public boolean isNotNull() {
			return (flags & IS_NOT_NULL) != 0;
		}

		@Override
		public boolean isLocalized() {
			return (flags & IS_LOCALIZED) != 0;
		}

		@Override
		public boolean isUnique() {
			throw new UnsupportedOperationException();
		}

		@Override
		public Optional defaultValue() {
			return Optional.ofNullable(defaultValue);
		}

		@Override
		public String toString() {
			return name;
		}

		private static Object resolveDefault(CdsType type, Object defaultValue) {
			if (type.isEnum() && defaultValue instanceof EnumeralName) {
				CdsEnumType enumType = type.as(CdsEnumType.class);
				EnumeralName enumName = (EnumeralName) defaultValue;
				Enumeral enumeral = enumType.enumerals().get(enumName.get());

				return enumeral.value();
			}

			return defaultValue;
		}

	}

}