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

sirius.biz.web.BizController Maven / Gradle / Ivy

There is a newer version: 9.6
Show newest version
/*
 * Made with all the love in the world
 * by scireum in Remshalden, Germany
 *
 * Copyright by scireum GmbH
 * http://www.scireum.de - [email protected]
 */

package sirius.biz.web;

import sirius.biz.model.BizEntity;
import sirius.biz.tenants.Tenant;
import sirius.biz.tenants.TenantAware;
import sirius.biz.tenants.Tenants;
import sirius.biz.tenants.UserAccount;
import sirius.db.mixing.Column;
import sirius.db.mixing.Entity;
import sirius.db.mixing.EntityRef;
import sirius.db.mixing.OMA;
import sirius.db.mixing.Property;
import sirius.kernel.di.std.ConfigValue;
import sirius.kernel.di.std.Part;
import sirius.kernel.health.Exceptions;
import sirius.kernel.health.Log;
import sirius.web.controller.BasicController;
import sirius.web.http.WebContext;
import sirius.web.security.UserContext;

import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Base class for all controllers which operate on entities.
 * 

* Provides glue logic for filling entites from {@link WebContext}s and for resolving entities for a given id. * * @see Entity */ public class BizController extends BasicController { @Part protected OMA oma; @Part protected Tenants tenants; /** * Contains the central logger for biz-relatet messages. */ public static final Log LOG = Log.get("biz"); /** * Ensures that the tenant of the current user matches the tenant of the given entity. * * @param tenantAware the entity to check * @throws sirius.kernel.health.HandledException if the tenants do no match */ protected void assertTenant(TenantAware tenantAware) { if (currentTenant() == null && tenantAware.getTenant().getId() != null) { throw Exceptions.createHandled().withNLSKey("BizController.invalidTenant").handle(); } if (currentTenant().getId() != tenantAware.getTenant().getId()) { throw Exceptions.createHandled().withNLSKey("BizController.invalidTenant").handle(); } } /** * Enusures or establishes a parent child relation. *

* For new entities (owner), the given reference is initialized with the given entity. For existing entities * it is verified, that the given reference points to the given entity. * * @param owner the entity which contains the reference * @param ref the reference which is either filled or verified that it points to entity * @param entity the entity the reference must point to * @throws sirius.kernel.health.HandledException if the tenants do no match */ protected void setOrVerify(Entity owner, EntityRef ref, E entity) { if (!Objects.equals(ref.getId(), entity.getId())) { if (owner.isNew()) { ref.setValue(entity); } else { throw Exceptions.createHandled().withNLSKey("BizController.invalidReference").handle(); } } } /** * Ensures that the given entity is already persisted in the database. * * @param obj the entity to check * @throws sirius.kernel.health.HandledException if the entity is still new and not yet persisted in the database */ protected void assertNotNew(Entity obj) { assertNotNull(obj); if (obj.isNew()) { throw Exceptions.createHandled().withNLSKey("BizController.mustNotBeNew").handle(); } } @ConfigValue("product.baseUrl") private String baseUrl; /** * Returns the base URL of this instance. * * @return the base URL like http://www.mydomain.stuff */ protected String getBaseUrl() { return baseUrl; } /** * Fetches all autoloaded fields of the given entity from the given request and populates the entity. * * @param ctx the request to read parameters from * @param entity the entity to fill * @see Autoloaded */ protected void load(WebContext ctx, Entity entity) { for (Property property : entity.getDescriptor().getProperties()) { if (isAutoloaded(property)) { if (ctx.hasParameter(property.getName())) { property.parseValue(entity, ctx.get(property.getName())); } } } } /** * Reads the given properties from the given request and populates the given entity. * * @param ctx the request to read parameters from * @param entity the entity to fill * @param properties the list of properties to transfer */ protected void load(WebContext ctx, Entity entity, Column... properties) { Set columnsSet = Arrays.stream(properties).map(Column::getName).collect(Collectors.toSet()); for (Property property : entity.getDescriptor().getProperties()) { if (columnsSet.contains(property.getName())) { if (ctx.hasParameter(property.getName())) { property.parseValue(entity, ctx.get(property.getName())); } } } } private boolean isAutoloaded(Property property) { Autoloaded autoloaded = property.getAnnotation(Autoloaded.class); if (autoloaded == null) { return false; } if (autoloaded.permissions().length > 0) { return UserContext.getCurrentUser().hasPermissions(autoloaded.permissions()); } else { return true; } } /** * Tries to find an entity of the given type with the given id. *

* Note, if new is given as id, a new entity is created. This permits many editors to create a * new entity simply by calling /editor-uri/new * * @param type the type of the entity to find * @param id the id to lookup * @param the generic type of the entity class * @return the requested entity or a new one, if id was new * @throws sirius.kernel.health.HandledException if either the id is unknown or a new instance cannot be created */ protected E find(Class type, String id) { if (BizEntity.NEW.equals(id) && BizEntity.class.isAssignableFrom(type)) { try { return type.newInstance(); } catch (Throwable e) { throw Exceptions.handle() .to(LOG) .error(e) .withSystemErrorMessage("Cannot create a new instance of '%s'", type.getName()) .handle(); } } Optional result = oma.find(type, id); if (!result.isPresent()) { throw Exceptions.createHandled().withNLSKey("BizController.unknownObject").set("id", id).handle(); } return result.get(); } /** * Tries to find an existing entity with the given id. * * @param type the type of the entity to find * @param id the id of the entity to find * @param the generic type of the entity class * @return the requested entity wrapped as Optional or an empty optional, if no entity with the given id * was found * or if the id was new */ protected Optional tryFind(Class type, String id) { if (BizEntity.NEW.equals(id)) { return Optional.empty(); } return oma.find(type, id); } /** * Tries to find an entity for the given id, which belongs to the current tenant. *

* This behaves just like {@link #find(Class, String)} but once an existing entity was found, which also extends * {@link TenantAware}, it is ensured (using {@link #assertTenant(TenantAware)} that it belongs to the current * tenant. * * @param type the type of the entity to find * @param id the id of the entity to find * @param the generic type of the entity class * @return the requested entity, which is either new or belongs to the current tenant */ protected E findForTenant(Class type, String id) { E result = find(type, id); if (!result.isNew() && result instanceof TenantAware) { assertTenant((TenantAware) result); } return result; } /** * Tries to find an entity for the given id, which belongs to the current tenant. *

* This behaves just like {@link #tryFind(Class, String)} but once an existing entity was found, which also extends * {@link TenantAware}, it is ensured (using {@link #assertTenant(TenantAware)} that it belongs to the current * tenant. * * @param type the type of the entity to find * @param id the id of the entity to find * @param the generic type of the entity class * @return the requested entity, which belongs to the current tenant, wrapped as Optional or an empty * optional. */ protected Optional tryFindForTenant(Class type, String id) { return tryFind(type, id).map(e -> { if (e instanceof TenantAware) { assertTenant((TenantAware) e); } return e; }); } /** * Returns the {@link UserAccount} instance which belongs to the current user. * * @return the UserAccount instance of the current user or null if no user is logged in */ protected UserAccount currentUser() { if (!UserContext.getCurrentUser().isLoggedIn()) { return null; } return UserContext.getCurrentUser().getUserObject(UserAccount.class); } /** * Returns the {@link Tenant} instance which belongs to the current user. * * @return the Tenant instance of the current user or null if no user is logged in */ protected Tenant currentTenant() { if (!UserContext.getCurrentUser().isLoggedIn()) { return null; } return currentUser().getTenant().getValue(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy