| /******************************************************************************** |
| * Copyright (c) 2015-2019 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| ********************************************************************************/ |
| |
| package org.eclipse.mdm.api.odsadapter.query; |
| |
| import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_ENUMERATION_NAME; |
| import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_SCALAR_TYPE; |
| import static org.eclipse.mdm.api.dflt.model.CatalogAttribute.VATTR_SEQUENCE; |
| |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.HashSet; |
| import java.util.Optional; |
| import java.util.Set; |
| |
| import org.eclipse.mdm.api.base.adapter.ChildrenStore; |
| import org.eclipse.mdm.api.base.adapter.Core; |
| import org.eclipse.mdm.api.base.adapter.DefaultCore; |
| import org.eclipse.mdm.api.base.adapter.EntityStore; |
| import org.eclipse.mdm.api.base.model.AxisType; |
| import org.eclipse.mdm.api.base.model.BaseEntity; |
| import org.eclipse.mdm.api.base.model.ContextType; |
| import org.eclipse.mdm.api.base.model.Entity; |
| import org.eclipse.mdm.api.base.model.EnumRegistry; |
| import org.eclipse.mdm.api.base.model.Enumeration; |
| import org.eclipse.mdm.api.base.model.EnumerationValue; |
| import org.eclipse.mdm.api.base.model.Interpolation; |
| import org.eclipse.mdm.api.base.model.ScalarType; |
| import org.eclipse.mdm.api.base.model.SequenceRepresentation; |
| import org.eclipse.mdm.api.base.model.TypeSpecification; |
| import org.eclipse.mdm.api.base.model.User; |
| import org.eclipse.mdm.api.base.model.ValueType; |
| import org.eclipse.mdm.api.base.model.VersionState; |
| import org.eclipse.mdm.api.dflt.model.CatalogAttribute; |
| import org.eclipse.mdm.api.dflt.model.EntityFactory; |
| import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig; |
| import org.eclipse.mdm.api.odsadapter.lookup.config.EntityConfig.Key; |
| |
| /** |
| * ODS implementation of the {@link EntityFactory}. |
| * |
| * @since 1.0.0 |
| * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH |
| */ |
| public final class ODSEntityFactory extends EntityFactory { |
| |
| // ====================================================================== |
| // Class variables |
| // ====================================================================== |
| |
| private static final Set<Class<? extends EnumerationValue>> ENUM_CLASSES = new HashSet<>(); |
| |
| static { |
| ENUM_CLASSES.add(ScalarType.class); |
| ENUM_CLASSES.add(VersionState.class); |
| ENUM_CLASSES.add(Interpolation.class); |
| ENUM_CLASSES.add(AxisType.class); |
| ENUM_CLASSES.add(SequenceRepresentation.class); |
| ENUM_CLASSES.add(TypeSpecification.class); |
| } |
| |
| // ====================================================================== |
| // Instance variables |
| // ====================================================================== |
| |
| private final ODSModelManager modelManager; |
| private final Optional<User> loggedInUser; |
| |
| // ====================================================================== |
| // Constructors |
| // ====================================================================== |
| |
| /** |
| * Constructor. |
| * |
| * @param modelManager Used to create {@link Core}s. |
| * @param loggedInUser The logged in {@link User}. |
| */ |
| public ODSEntityFactory(ODSModelManager modelManager, Optional<User> loggedInUser) { |
| this.modelManager = modelManager; |
| this.loggedInUser = loggedInUser; |
| } |
| |
| // ====================================================================== |
| // Public methods |
| // ====================================================================== |
| |
| /** |
| * Extracts the {@link Core} from an {@link Entity} instance. This method |
| * effectively makes access to the Core of a BaseEntity publicly available (by |
| * calling the corresponding protected method of BaseEntityFactory, which is |
| * this class's superclass) to users of ODSEntityFactory. |
| * |
| * @param entity The {@link Entity} from which to extract the {@link Core}. |
| * @return The entity's {@link Core}. |
| */ |
| public static Core extract(Entity entity) { |
| if (entity instanceof BaseEntity) { |
| return getCore((BaseEntity) entity); |
| } else { |
| throw new IllegalArgumentException("Entity of type '" + entity.getClass().getSimpleName() |
| + "' does not extend '" + BaseEntity.class.getName() + "'"); |
| } |
| } |
| |
| /** |
| * Create an instance of a class implementing the {@link Entity} interface with |
| * core as the instance's {@link Core}. This method effectively makes the |
| * protected BaseEntity constructor publicly available (by calling the |
| * corresponding protected method of BaseEntityFactory, which is this class's |
| * superclass) to users of ODSEntityFactory. |
| * |
| * @param clazz The class to instantiate, must implement the {@link Entity} |
| * interface. |
| * @param core The {@link Core} to use for the newly created instance. |
| * @return The newly created instance. |
| */ |
| @SuppressWarnings("unchecked") |
| public <T extends Entity> T createEntity(Class<T> clazz, Core core) { |
| if (BaseEntity.class.isAssignableFrom(clazz)) { |
| return (T) createBaseEntity(clazz.asSubclass(BaseEntity.class), core); |
| } else { |
| throw new IllegalArgumentException( |
| "Class '" + clazz.getSimpleName() + "' does not extend '" + BaseEntity.class.getName() + "'"); |
| } |
| |
| } |
| |
| // ====================================================================== |
| // Protected methods |
| // ====================================================================== |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected Optional<User> getLoggedInUser() { |
| return loggedInUser; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected <T extends Entity> Core createCore(Class<T> entityClass) { |
| return createCore(new Key<>(entityClass)); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected <T extends Entity> Core createCore(Class<T> entityClass, ContextType contextType) { |
| return createCore(new Key<>(entityClass, contextType)); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public static final EntityStore getMutableStore(BaseEntity entity) { |
| return EntityFactory.getMutableStore(entity); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public static final EntityStore getPermanentStore(BaseEntity entity) { |
| return EntityFactory.getPermanentStore(entity); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public static final ChildrenStore getChildrenStore(BaseEntity entity) { |
| return EntityFactory.getChildrenStore(entity); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected <T extends Entity> Core createCore(String name, Class<T> entityClass) { |
| EntityConfig<?> entityConfig = modelManager.getEntityConfig(modelManager.getEntityType(name)); |
| if (!entityClass.equals(entityConfig.getEntityClass())) { |
| throw new IllegalArgumentException("Incompatible entity class expected '" + entityClass.getName() |
| + "' but got '" + entityConfig.getEntityClass().getName() + "'"); |
| } |
| Core core = new DefaultCore(entityConfig.getEntityType()); |
| core.getValues().get(Entity.ATTR_MIMETYPE).set(entityConfig.getMimeType()); |
| |
| return core; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected void validateEnum(Enumeration<?> enumerationObj) { |
| EnumRegistry er = EnumRegistry.getInstance(); |
| // check if enum is properly registered |
| if (er.get(enumerationObj.getName()) == null) { |
| throw new IllegalArgumentException("Given enum class '" + enumerationObj.getName() + "' is not supported."); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected <T extends BaseEntity> T createBaseEntity(Class<T> clazz, Core core) { |
| try { |
| Constructor<T> constructor = clazz.getDeclaredConstructor(Core.class); |
| try { |
| return constructor.newInstance(core); |
| } catch (IllegalAccessException exc) { |
| return super.createBaseEntity(clazz, core); |
| } |
| } catch (NoSuchMethodException | InvocationTargetException | InstantiationException exc) { |
| throw new IllegalStateException(exc.getMessage(), exc); |
| } |
| } |
| |
| // ====================================================================== |
| // Private methods |
| // ====================================================================== |
| |
| /** |
| * Creates a configured {@link Core} for given {@link Key}. |
| * |
| * @param <T> The entity type. |
| * @param key Used as identifier to resolve the {@link EntityConfig}. |
| * @return The created {@code Core} is returned. |
| */ |
| private <T extends Entity> Core createCore(Key<T> key) { |
| EntityConfig<T> entityConfig = modelManager.findEntityConfig(key); |
| Core core = new DefaultCore(entityConfig.getEntityType()); |
| core.getValues().get(Entity.ATTR_MIMETYPE).set(entityConfig.getMimeType()); |
| |
| if (CatalogAttribute.class.equals(entityConfig.getEntityClass())) { |
| core.getValues().put(VATTR_ENUMERATION_NAME, ValueType.STRING.create(VATTR_ENUMERATION_NAME)); |
| core.getValues().put(VATTR_SCALAR_TYPE, |
| ValueType.ENUMERATION.create(EnumRegistry.getInstance().get("ScalarType"), VATTR_SCALAR_TYPE)); |
| core.getValues().put(VATTR_SEQUENCE, ValueType.BOOLEAN.create(VATTR_SEQUENCE)); |
| } |
| |
| return core; |
| } |
| } |