Search in sources :

Example 1 with CreationContainer

use of org.structr.core.graph.CreationContainer in project structr by structr.

the class GraphObject method setProperties.

/**
 * Sets the given properties.
 *
 * @param securityContext
 * @param properties
 * @throws FrameworkException
 */
default void setProperties(final SecurityContext securityContext, final PropertyMap properties) throws FrameworkException {
    final CreationContainer container = new CreationContainer(this);
    boolean atLeastOnePropertyChanged = false;
    for (final Entry<PropertyKey, Object> attr : properties.entrySet()) {
        final PropertyKey key = attr.getKey();
        final Object value = attr.getValue();
        if (key.indexable(value)) {
            final Object oldValue = getProperty(key);
            if (!value.equals(oldValue)) {
                atLeastOnePropertyChanged = true;
                // bulk set possible, store in container
                key.setProperty(securityContext, container, value);
                if (isNode()) {
                    if (!key.isUnvalidated()) {
                        TransactionCommand.nodeModified(securityContext.getCachedUser(), (AbstractNode) this, key, getProperty(key), value);
                    }
                    if (key instanceof TypeProperty) {
                        if (this instanceof NodeInterface) {
                            final Class type = StructrApp.getConfiguration().getNodeEntityClass((String) value);
                            TypeProperty.updateLabels(StructrApp.getInstance().getDatabaseService(), (NodeInterface) this, type, true);
                        }
                    }
                } else if (isRelationship()) {
                    if (!key.isUnvalidated()) {
                        TransactionCommand.relationshipModified(securityContext.getCachedUser(), (AbstractRelationship) this, key, getProperty(key), value);
                    }
                    if (key instanceof TypeProperty) {
                        if (this instanceof NodeInterface) {
                            final Class type = StructrApp.getConfiguration().getNodeEntityClass((String) value);
                            TypeProperty.updateLabels(StructrApp.getInstance().getDatabaseService(), (NodeInterface) this, type, true);
                        }
                    }
                }
            }
        } else {
            // bulk set NOT possible, set on entity
            if (key.isSystemInternal()) {
                unlockSystemPropertiesOnce();
            }
            setProperty(key, value);
        }
    }
    if (atLeastOnePropertyChanged) {
        // set primitive values directly for better performance
        getPropertyContainer().setProperties(container.getData());
    }
}
Also used : TypeProperty(org.structr.core.property.TypeProperty) AbstractRelationship(org.structr.core.entity.AbstractRelationship) CreationContainer(org.structr.core.graph.CreationContainer) PropertyKey(org.structr.core.property.PropertyKey) NodeInterface(org.structr.core.graph.NodeInterface)

Example 2 with CreationContainer

use of org.structr.core.graph.CreationContainer in project structr by structr.

the class AbstractPrimitiveProperty method setProperty.

@Override
public Object setProperty(final SecurityContext securityContext, final GraphObject obj, final T value) throws FrameworkException {
    final PropertyConverter converter = databaseConverter(securityContext, PropertyMap.unwrap(obj));
    Object convertedValue = value;
    if (converter != null) {
        convertedValue = converter.convert(value);
    }
    // use transformators from property
    for (final String fqcn : transformators) {
        // first test, use caching here later..
        final Transformer transformator = getTransformator(fqcn);
        if (transformator != null) {
            convertedValue = transformator.setProperty(PropertyMap.unwrap(obj), this, convertedValue);
        }
    }
    final PropertyContainer propertyContainer = obj.getPropertyContainer();
    if (propertyContainer != null) {
        if (!TransactionCommand.inTransaction()) {
            throw new NotInTransactionException("setProperty outside of transaction");
        }
        boolean internalSystemPropertiesUnlocked = (obj instanceof CreationContainer);
        // collect modified properties
        if (obj instanceof AbstractNode) {
            if (!unvalidated) {
                TransactionCommand.nodeModified(securityContext.getCachedUser(), (AbstractNode) obj, AbstractPrimitiveProperty.this, propertyContainer.hasProperty(dbName()) ? propertyContainer.getProperty(dbName()) : null, value);
            }
            internalSystemPropertiesUnlocked = ((AbstractNode) obj).internalSystemPropertiesUnlocked;
        } else if (obj instanceof AbstractRelationship) {
            if (!unvalidated) {
                TransactionCommand.relationshipModified(securityContext.getCachedUser(), (AbstractRelationship) obj, AbstractPrimitiveProperty.this, propertyContainer.hasProperty(dbName()) ? propertyContainer.getProperty(dbName()) : null, value);
            }
            internalSystemPropertiesUnlocked = ((AbstractRelationship) obj).internalSystemPropertiesUnlocked;
        }
        // catch all sorts of errors and wrap them in a FrameworkException
        try {
            // save space
            if (convertedValue == null) {
                propertyContainer.removeProperty(dbName());
            } else {
                if (!isSystemInternal() || internalSystemPropertiesUnlocked) {
                    propertyContainer.setProperty(dbName(), convertedValue);
                } else {
                    logger.warn("Tried to set internal system property {} to {}. Action was denied.", new Object[] { dbName(), convertedValue });
                }
            }
            updateAccessInformation(securityContext, propertyContainer);
        } catch (final RetryException rex) {
            // don't catch RetryException here
            throw rex;
        } catch (Throwable t) {
            // throw FrameworkException with the given cause
            final FrameworkException fex = new FrameworkException(500, "Unable to set property " + jsonName() + " on entity with ID " + obj.getUuid() + ": " + t.toString());
            fex.initCause(t);
            throw fex;
        }
        if (isIndexed()) {
            // work
            if (!isPassivelyIndexed()) {
                index(obj, convertedValue);
            }
        }
    }
    return null;
}
Also used : PropertyContainer(org.structr.api.graph.PropertyContainer) Transformer(org.structr.schema.Transformer) FrameworkException(org.structr.common.error.FrameworkException) AbstractNode(org.structr.core.entity.AbstractNode) AbstractRelationship(org.structr.core.entity.AbstractRelationship) CreationContainer(org.structr.core.graph.CreationContainer) RetryException(org.structr.api.RetryException) NotInTransactionException(org.structr.api.NotInTransactionException) PropertyConverter(org.structr.core.converter.PropertyConverter) GraphObject(org.structr.core.GraphObject)

Aggregations

AbstractRelationship (org.structr.core.entity.AbstractRelationship)2 CreationContainer (org.structr.core.graph.CreationContainer)2 NotInTransactionException (org.structr.api.NotInTransactionException)1 RetryException (org.structr.api.RetryException)1 PropertyContainer (org.structr.api.graph.PropertyContainer)1 FrameworkException (org.structr.common.error.FrameworkException)1 GraphObject (org.structr.core.GraphObject)1 PropertyConverter (org.structr.core.converter.PropertyConverter)1 AbstractNode (org.structr.core.entity.AbstractNode)1 NodeInterface (org.structr.core.graph.NodeInterface)1 PropertyKey (org.structr.core.property.PropertyKey)1 TypeProperty (org.structr.core.property.TypeProperty)1 Transformer (org.structr.schema.Transformer)1