diff --git a/structr-core/src/main/java/org/structr/core/GraphObject.java b/structr-core/src/main/java/org/structr/core/GraphObject.java index 6ca536d3d3..a31a652912 100644 --- a/structr-core/src/main/java/org/structr/core/GraphObject.java +++ b/structr-core/src/main/java/org/structr/core/GraphObject.java @@ -30,6 +30,7 @@ import org.structr.common.error.FrameworkException; import org.structr.core.entity.AbstractNode; import org.structr.core.entity.AbstractRelationship; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeInterface; import org.structr.core.graph.RelationshipInterface; import org.structr.core.property.BooleanProperty; @@ -201,7 +202,7 @@ public interface GraphObject { */ public void unlockReadOnlyPropertiesOnce(); - + public boolean isValid(ErrorBuffer errorBuffer); @@ -224,10 +225,11 @@ public interface GraphObject { * * @param securityContext the context in which the modification takes place * @param errorBuffer the error buffer to put error tokens into + * @param modificationQueue the modification queue that triggered this call to onModification * @return true if the transaction can go on, false if an error occurred * @throws FrameworkException */ - public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer) throws FrameworkException; + public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException; /** * Called when an entity of this type is deleted. This method can cause the underlying diff --git a/structr-core/src/main/java/org/structr/core/GraphObjectMap.java b/structr-core/src/main/java/org/structr/core/GraphObjectMap.java index 8f1d7dd01c..0644f977fb 100644 --- a/structr-core/src/main/java/org/structr/core/GraphObjectMap.java +++ b/structr-core/src/main/java/org/structr/core/GraphObjectMap.java @@ -27,13 +27,14 @@ import org.structr.api.graph.PropertyContainer; import org.structr.cmis.CMISInfo; import org.structr.common.PermissionResolutionMask; -import org.structr.core.property.PropertyKey; -import org.structr.core.property.PropertyMap; import org.structr.common.SecurityContext; import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeInterface; import org.structr.core.graph.RelationshipInterface; +import org.structr.core.property.PropertyKey; +import org.structr.core.property.PropertyMap; import org.structr.core.script.Scripting; import org.structr.schema.action.ActionContext; @@ -114,7 +115,7 @@ public boolean onCreation(final SecurityContext securityContext, final ErrorBuff } @Override - public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { return true; } diff --git a/structr-core/src/main/java/org/structr/core/entity/AbstractNode.java b/structr-core/src/main/java/org/structr/core/entity/AbstractNode.java index 39ef5d1c16..fa69d64a4a 100644 --- a/structr-core/src/main/java/org/structr/core/entity/AbstractNode.java +++ b/structr-core/src/main/java/org/structr/core/entity/AbstractNode.java @@ -42,15 +42,16 @@ import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.StringUtils; import org.structr.api.DatabaseService; -import org.structr.api.graph.Direction; -import org.structr.api.index.Index; import org.structr.api.NativeResult; +import org.structr.api.Predicate; +import org.structr.api.graph.Direction; import org.structr.api.graph.Node; import org.structr.api.graph.Path; -import org.structr.api.Predicate; import org.structr.api.graph.PropertyContainer; import org.structr.api.graph.Relationship; import org.structr.api.graph.RelationshipType; +import org.structr.api.index.Index; +import org.structr.api.util.FixedSizeCache; import org.structr.cmis.CMISInfo; import org.structr.cmis.common.CMISExtensionsData; import org.structr.cmis.common.StructrItemActions; @@ -62,7 +63,6 @@ import org.structr.cmis.info.CMISSecondaryInfo; import org.structr.common.AccessControllable; import org.structr.common.AccessPathCache; -import org.structr.api.util.FixedSizeCache; import org.structr.common.GraphObjectComparator; import org.structr.common.IdSorter; import org.structr.common.Permission; @@ -79,12 +79,13 @@ import org.structr.common.error.ReadOnlyPropertyToken; import org.structr.core.GraphObject; import org.structr.core.IterableAdapter; -import org.structr.core.entity.relationship.Ownership; import org.structr.core.Services; import org.structr.core.app.App; import org.structr.core.app.StructrApp; import org.structr.core.converter.PropertyConverter; +import org.structr.core.entity.relationship.Ownership; import org.structr.core.entity.relationship.PrincipalOwnsNode; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeInterface; import org.structr.core.graph.NodeRelationshipStatisticsCommand; import org.structr.core.graph.NodeService; @@ -383,11 +384,11 @@ public long getId() { @Override public String getUuid() { - + if (cachedUuid == null) { cachedUuid = getProperty(GraphObject.id); } - + return cachedUuid; } @@ -1245,7 +1246,7 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { return true; } @@ -1508,7 +1509,7 @@ public void indexPassiveProperties() { public static void clearRelationshipTemplateInstanceCache() { relationshipTemplateInstanceCache.clear(); } - + public static > R getRelationshipForType(final Class type) { R instance = (R) relationshipTemplateInstanceCache.get(type.getName()); diff --git a/structr-core/src/main/java/org/structr/core/entity/AbstractRelationship.java b/structr-core/src/main/java/org/structr/core/entity/AbstractRelationship.java index 04c574587f..3bb6db4f83 100644 --- a/structr-core/src/main/java/org/structr/core/entity/AbstractRelationship.java +++ b/structr-core/src/main/java/org/structr/core/entity/AbstractRelationship.java @@ -30,13 +30,13 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.apache.chemistry.opencmis.commons.enums.PropertyType; +import org.structr.api.Predicate; import org.structr.api.graph.Direction; -import org.structr.api.index.Index; import org.structr.api.graph.Node; -import org.structr.api.Predicate; import org.structr.api.graph.PropertyContainer; import org.structr.api.graph.Relationship; import org.structr.api.graph.RelationshipType; +import org.structr.api.index.Index; import org.structr.cmis.CMISInfo; import org.structr.common.GraphObjectComparator; import org.structr.common.PermissionResolutionMask; @@ -55,6 +55,7 @@ import org.structr.core.app.App; import org.structr.core.app.StructrApp; import org.structr.core.converter.PropertyConverter; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeFactory; import org.structr.core.graph.NodeInterface; import org.structr.core.graph.NodeService; @@ -106,7 +107,7 @@ public abstract class AbstractRelationship Object setProperty(final PropertyKey key, final T value) throws Fr } return key.setProperty(securityContext, this, value); - + } finally { // unconditionally lock read-only properties after every write (attempt) to avoid security problems diff --git a/structr-core/src/main/java/org/structr/core/entity/AbstractSchemaNode.java b/structr-core/src/main/java/org/structr/core/entity/AbstractSchemaNode.java index 69c72a8ba1..a82503f7c5 100644 --- a/structr-core/src/main/java/org/structr/core/entity/AbstractSchemaNode.java +++ b/structr-core/src/main/java/org/structr/core/entity/AbstractSchemaNode.java @@ -32,6 +32,7 @@ import org.structr.core.entity.relationship.SchemaNodeMethod; import org.structr.core.entity.relationship.SchemaNodeProperty; import org.structr.core.entity.relationship.SchemaNodeView; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeAttribute; import static org.structr.core.graph.NodeInterface.name; import org.structr.core.graph.TransactionCommand; @@ -99,9 +100,9 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { - if (super.onModification(securityContext, errorBuffer)) { + if (super.onModification(securityContext, errorBuffer, modificationQueue)) { // register transaction post processing that recreates the schema information TransactionCommand.postProcess("createDefaultProperties", new CreateBuiltInSchemaEntities(this)); diff --git a/structr-core/src/main/java/org/structr/core/entity/GenericNode.java b/structr-core/src/main/java/org/structr/core/entity/GenericNode.java index 56071f429d..a7b69cf4d6 100644 --- a/structr-core/src/main/java/org/structr/core/entity/GenericNode.java +++ b/structr-core/src/main/java/org/structr/core/entity/GenericNode.java @@ -23,15 +23,16 @@ import java.util.Set; import java.util.TreeSet; import java.util.function.Function; -import org.structr.api.util.Iterables; import org.structr.api.graph.Node; import org.structr.api.util.FixedSizeCache; -import org.structr.core.property.PropertyMap; +import org.structr.api.util.Iterables; import org.structr.common.SecurityContext; import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; +import org.structr.core.graph.ModificationQueue; import org.structr.core.property.GenericProperty; import org.structr.core.property.PropertyKey; +import org.structr.core.property.PropertyMap; //~--- classes ---------------------------------------------------------------- @@ -66,7 +67,7 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { return true; } diff --git a/structr-core/src/main/java/org/structr/core/entity/GenericRelationship.java b/structr-core/src/main/java/org/structr/core/entity/GenericRelationship.java index 554339764c..2b86bc46c9 100644 --- a/structr-core/src/main/java/org/structr/core/entity/GenericRelationship.java +++ b/structr-core/src/main/java/org/structr/core/entity/GenericRelationship.java @@ -25,15 +25,16 @@ import java.util.Map; import java.util.Set; import org.structr.api.graph.Relationship; -import org.structr.core.property.PropertyKey; -import org.structr.core.property.PropertyMap; import org.structr.common.PropertyView; import org.structr.common.SecurityContext; import org.structr.common.View; import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; import org.structr.core.app.StructrApp; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeInterface; +import org.structr.core.property.PropertyKey; +import org.structr.core.property.PropertyMap; import org.structr.core.property.SourceId; import org.structr.core.property.TargetId; @@ -87,7 +88,7 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { return true; } diff --git a/structr-core/src/main/java/org/structr/core/entity/Location.java b/structr-core/src/main/java/org/structr/core/entity/Location.java index 860496865c..a8b35f28d4 100644 --- a/structr-core/src/main/java/org/structr/core/entity/Location.java +++ b/structr-core/src/main/java/org/structr/core/entity/Location.java @@ -18,16 +18,17 @@ */ package org.structr.core.entity; -import org.structr.core.property.Property; import org.structr.common.PropertyView; import org.structr.common.SecurityContext; import org.structr.common.View; import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; import org.structr.core.entity.relationship.NodeHasLocation; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeInterface; import org.structr.core.graph.RelationshipInterface; import org.structr.core.property.DoubleProperty; +import org.structr.core.property.Property; //~--- classes ---------------------------------------------------------------- @@ -56,7 +57,7 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { return isValid(errorBuffer); } diff --git a/structr-core/src/main/java/org/structr/core/entity/PropertyAccess.java b/structr-core/src/main/java/org/structr/core/entity/PropertyAccess.java index 8cb78a546a..44e85a1535 100644 --- a/structr-core/src/main/java/org/structr/core/entity/PropertyAccess.java +++ b/structr-core/src/main/java/org/structr/core/entity/PropertyAccess.java @@ -19,19 +19,20 @@ package org.structr.core.entity; import java.util.logging.Logger; -import org.structr.core.property.Property; import org.structr.common.PropertyView; import org.structr.common.SecurityContext; import org.structr.common.ValidationHelper; import org.structr.common.View; import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; -import org.structr.core.property.LongProperty; +import org.structr.core.graph.ModificationQueue; import org.structr.core.property.IntProperty; +import org.structr.core.property.LongProperty; +import org.structr.core.property.Property; /** * Controls access to resource properties - * + * * Objects of this class act as a doorkeeper for properties of REST resources. *

* A PropertyAccess object defines access granted @@ -40,8 +41,8 @@ *

  • to authenticated principals *
  • to invidual principals (when connected to a {link @Principal} node * - * - * + * + * * */ public class PropertyAccess extends AbstractNode { @@ -50,73 +51,73 @@ public class PropertyAccess extends AbstractNode { private Long cachedFlags = null; private Integer cachedPosition = null; - + public static final Property flags = new LongProperty("flags").indexed(); public static final Property position = new IntProperty("position").indexed(); public static final View uiView = new View(PropertyAccess.class, PropertyView.Ui, flags, position ); - + public static final View publicView = new View(PropertyAccess.class, PropertyView.Public, flags ); @Override public String toString() { - + StringBuilder buf = new StringBuilder(); - + buf.append("('").append(flags.jsonName()).append(": ").append(getFlags()).append("', ").append(position.jsonName()).append(": ").append(getPosition()).append(")"); - + return buf.toString(); } - + public boolean hasFlag(long flag) { return (getFlags() & flag) == flag; } - + public void setFlag(long flag) throws FrameworkException { - + // reset cached field cachedFlags = null; // set modified property setProperty(ResourceAccess.flags, getFlags() | flag); } - + public void clearFlag(long flag) throws FrameworkException { - + // reset cached field cachedFlags = null; // set modified property setProperty(ResourceAccess.flags, getFlags() & ~flag); } - + public long getFlags() { - + if (cachedFlags == null) { cachedFlags = getProperty(ResourceAccess.flags); } - + if (cachedFlags != null) { return cachedFlags.longValue(); } - + return 0; } public int getPosition() { - + if (cachedPosition == null) { cachedPosition = getProperty(ResourceAccess.position); } - + if (cachedPosition != null) { return cachedPosition.intValue(); } - + return 0; } @@ -124,12 +125,12 @@ public int getPosition() { public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuffer) { return isValid(errorBuffer); } - + @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) { return isValid(errorBuffer); } - + @Override public boolean isValid(ErrorBuffer errorBuffer) { diff --git a/structr-core/src/main/java/org/structr/core/entity/ResourceAccess.java b/structr-core/src/main/java/org/structr/core/entity/ResourceAccess.java index d2295be791..321f5c4d05 100644 --- a/structr-core/src/main/java/org/structr/core/entity/ResourceAccess.java +++ b/structr-core/src/main/java/org/structr/core/entity/ResourceAccess.java @@ -31,6 +31,7 @@ import org.structr.common.error.FrameworkException; import org.structr.core.app.StructrApp; import org.structr.core.entity.relationship.Access; +import org.structr.core.graph.ModificationQueue; import org.structr.core.notion.PropertySetNotion; import org.structr.core.property.ConstantBooleanProperty; import org.structr.core.property.EndNodes; @@ -168,7 +169,7 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) { return isValid(errorBuffer); } diff --git a/structr-core/src/main/java/org/structr/core/entity/SchemaProperty.java b/structr-core/src/main/java/org/structr/core/entity/SchemaProperty.java index bbe00131a7..3eafa99679 100644 --- a/structr-core/src/main/java/org/structr/core/entity/SchemaProperty.java +++ b/structr-core/src/main/java/org/structr/core/entity/SchemaProperty.java @@ -32,6 +32,7 @@ import org.structr.common.error.FrameworkException; import org.structr.core.entity.relationship.SchemaNodeProperty; import org.structr.core.entity.relationship.SchemaViewProperty; +import org.structr.core.graph.ModificationQueue; import static org.structr.core.graph.NodeInterface.name; import org.structr.core.notion.PropertySetNotion; import org.structr.core.property.BooleanProperty; @@ -210,14 +211,14 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { // prevent modification of properties using a content hash value if (getProperty(isBuiltinProperty) && !getContentHash().equals(getProperty(contentHash))) { throw new FrameworkException(403, "Modification of built-in properties not permitted."); } - return super.onModification(securityContext, errorBuffer); + return super.onModification(securityContext, errorBuffer, modificationQueue); } public String getContentHash() { diff --git a/structr-core/src/main/java/org/structr/core/entity/SchemaRelationshipNode.java b/structr-core/src/main/java/org/structr/core/entity/SchemaRelationshipNode.java index 96c63c54f8..398e8ff27a 100644 --- a/structr-core/src/main/java/org/structr/core/entity/SchemaRelationshipNode.java +++ b/structr-core/src/main/java/org/structr/core/entity/SchemaRelationshipNode.java @@ -32,8 +32,8 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; -import org.structr.api.util.Iterables; import org.structr.api.Predicate; +import org.structr.api.util.Iterables; import org.structr.common.CaseHelper; import org.structr.common.PermissionPropagation; import org.structr.common.PropertyView; @@ -46,6 +46,7 @@ import org.structr.core.entity.relationship.Ownership; import org.structr.core.entity.relationship.SchemaRelationshipSourceNode; import org.structr.core.entity.relationship.SchemaRelationshipTargetNode; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.TransactionCommand; import org.structr.core.notion.PropertyNotion; import org.structr.core.property.EndNode; @@ -191,9 +192,9 @@ public boolean onCreation(SecurityContext securityContext, final ErrorBuffer err } @Override - public boolean onModification(SecurityContext securityContext, final ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, final ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { - if (super.onModification(securityContext, errorBuffer)) { + if (super.onModification(securityContext, errorBuffer, modificationQueue)) { checkClassName(); diff --git a/structr-core/src/main/java/org/structr/core/entity/SchemaReloadingNode.java b/structr-core/src/main/java/org/structr/core/entity/SchemaReloadingNode.java index 168754c9f1..8e3925447f 100644 --- a/structr-core/src/main/java/org/structr/core/entity/SchemaReloadingNode.java +++ b/structr-core/src/main/java/org/structr/core/entity/SchemaReloadingNode.java @@ -22,6 +22,7 @@ import org.structr.common.SecurityContext; import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; +import org.structr.core.graph.ModificationQueue; import static org.structr.core.graph.NodeInterface.name; import org.structr.core.graph.TransactionCommand; import org.structr.schema.ReloadSchema; @@ -48,9 +49,9 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { - if (super.onModification(securityContext, errorBuffer)) { + if (super.onModification(securityContext, errorBuffer, modificationQueue)) { // register transaction post processing that recreates the schema information TransactionCommand.postProcess("reloadSchema", new ReloadSchema()); diff --git a/structr-core/src/main/java/org/structr/core/entity/Security.java b/structr-core/src/main/java/org/structr/core/entity/Security.java index 0106c9eb0c..03558a87a7 100644 --- a/structr-core/src/main/java/org/structr/core/entity/Security.java +++ b/structr-core/src/main/java/org/structr/core/entity/Security.java @@ -32,6 +32,7 @@ import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; import org.structr.core.app.StructrApp; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeInterface; import org.structr.core.property.ArrayProperty; import org.structr.core.property.Property; @@ -91,7 +92,7 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { return true; } diff --git a/structr-core/src/main/java/org/structr/core/entity/SuperUser.java b/structr-core/src/main/java/org/structr/core/entity/SuperUser.java index cdd5f10bb6..81bc8f1cd5 100644 --- a/structr-core/src/main/java/org/structr/core/entity/SuperUser.java +++ b/structr-core/src/main/java/org/structr/core/entity/SuperUser.java @@ -24,8 +24,8 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.structr.api.graph.Node; import org.structr.api.Predicate; +import org.structr.api.graph.Node; import org.structr.api.graph.PropertyContainer; import org.structr.api.graph.Relationship; import org.structr.cmis.CMISInfo; @@ -36,6 +36,7 @@ import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; import org.structr.core.GraphObject; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeInterface; import org.structr.core.graph.RelationshipInterface; import org.structr.core.property.PropertyKey; @@ -70,23 +71,17 @@ public void unlockReadOnlyPropertiesOnce() {} @Override public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { - return true; - } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { - + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { return true; - } @Override public boolean onDeletion(SecurityContext securityContext, ErrorBuffer errorBuffer, PropertyMap properties) throws FrameworkException { - return true; - } @Override diff --git a/structr-core/src/main/java/org/structr/core/graph/GraphObjectModificationState.java b/structr-core/src/main/java/org/structr/core/graph/GraphObjectModificationState.java index 0e394108b2..808223f8d0 100644 --- a/structr-core/src/main/java/org/structr/core/graph/GraphObjectModificationState.java +++ b/structr-core/src/main/java/org/structr/core/graph/GraphObjectModificationState.java @@ -78,7 +78,7 @@ public class GraphObjectModificationState implements ModificationEvent { public String getCallbackId() { return this.callbackId; } - + public void setCallbackId(final String callbackId) { this.callbackId = callbackId; } @@ -307,7 +307,7 @@ public boolean doInnerCallback(ModificationQueue modificationQueue, SecurityCont break; case 2: // modified => modification callback - valid &= object.onModification(securityContext, errorBuffer); + valid &= object.onModification(securityContext, errorBuffer, modificationQueue); break; case 1: // deleted => deletion callback diff --git a/structr-core/src/main/java/org/structr/schema/SchemaHelper.java b/structr-core/src/main/java/org/structr/schema/SchemaHelper.java index 4a64fcba74..a845f90957 100644 --- a/structr-core/src/main/java/org/structr/schema/SchemaHelper.java +++ b/structr-core/src/main/java/org/structr/schema/SchemaHelper.java @@ -66,6 +66,7 @@ import org.structr.core.entity.SchemaProperty; import org.structr.core.entity.SchemaRelationshipNode; import org.structr.core.entity.SchemaView; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeAttribute; import org.structr.core.graph.NodeInterface; import org.structr.core.graph.RelationshipInterface; @@ -312,18 +313,18 @@ public static void cleanUnusedDynamicGrants(final List existingSchem try { final List existingDynamicGrants = StructrApp.getInstance().nodeQuery(DynamicResourceAccess.class).getAsList(); - + final Set existingSchemaNodeNames = new HashSet<>(); - + for (final SchemaNode schemaNode : existingSchemaNodes) { - + existingSchemaNodeNames.add(schemaNode.getResourceSignature()); } - + for (final DynamicResourceAccess grant : existingDynamicGrants) { boolean foundAllParts = true; - + final String sig; try { sig = grant.getResourceSignature(); @@ -332,31 +333,31 @@ public static void cleanUnusedDynamicGrants(final List existingSchem logger.log(Level.FINE, "Unable to get signature from grant"); continue; } - + // Try to find schema nodes for all parts of the grant signature final String[] parts = StringUtils.split(sig, "/"); - + if (parts != null) { - - + + for (final String sigPart : parts) { - + if ("/".equals(sigPart) || sigPart.startsWith("_")) { continue; } - + // If one of the signature parts doesn't have an equivalent existing schema node, remove it foundAllParts &= existingSchemaNodeNames.contains(sigPart); } } if (!foundAllParts) { - + logger.log(Level.INFO, "Did not find all parts of signature, will be removed: {0}, ", new Object[]{ sig }); - + removeDynamicGrants(sig); } - + } @@ -377,7 +378,7 @@ public static List createDynamicGrants(final String signa ResourceAccess grant = app.nodeQuery(ResourceAccess.class).and(ResourceAccess.signature, signature).getFirst(); if (grant == null) { - + // create new grant grants.add(app.create(DynamicResourceAccess.class, new NodeAttribute(DynamicResourceAccess.signature, signature), @@ -388,7 +389,7 @@ public static List createDynamicGrants(final String signa } final String schemaSig = schemaResourceSignature(signature); - + ResourceAccess schemaGrant = app.nodeQuery(ResourceAccess.class).and(ResourceAccess.signature, schemaSig).getFirst(); if (schemaGrant == null) { // create additional grant for the _schema resource @@ -401,7 +402,7 @@ public static List createDynamicGrants(final String signa } final String uiSig = uiViewResourceSignature(signature); - + ResourceAccess uiViewGrant = app.nodeQuery(ResourceAccess.class).and(ResourceAccess.signature, uiSig).getFirst(); if (uiViewGrant == null) { @@ -827,6 +828,7 @@ public static void formatImportStatements(final AbstractSchemaNode schemaNode, f src.append("import ").append(PermissionPropagation.class.getName()).append(";\n"); src.append("import ").append(FrameworkException.class.getName()).append(";\n"); src.append("import ").append(DatePropertyParser.class.getName()).append(";\n"); + src.append("import ").append(ModificationQueue.class.getName()).append(";\n"); src.append("import ").append(PropertyConverter.class.getName()).append(";\n"); src.append("import ").append(ValidationHelper.class.getName()).append(";\n"); src.append("import ").append(SecurityContext.class.getName()).append(";\n"); @@ -1210,7 +1212,7 @@ public int compare(final Type o1, final Type o2) { return o2.name().compareTo(o1.name()); } } - + private static String schemaResourceSignature(final String signature) { return "_schema/" + signature; } diff --git a/structr-core/src/main/java/org/structr/schema/action/Actions.java b/structr-core/src/main/java/org/structr/schema/action/Actions.java index f92751ef9b..ec6e275da7 100644 --- a/structr-core/src/main/java/org/structr/schema/action/Actions.java +++ b/structr-core/src/main/java/org/structr/schema/action/Actions.java @@ -49,7 +49,7 @@ public class Actions { public enum Type { Create("onCreation","SecurityContext securityContext, ErrorBuffer errorBuffer", "securityContext, errorBuffer"), - Save("onModification", "SecurityContext securityContext, ErrorBuffer errorBuffer", "securityContext, errorBuffer"), + Save("onModification", "SecurityContext securityContext, ErrorBuffer errorBuffer, ModificationQueue modificationQueue", "securityContext, errorBuffer, modificationQueue"), Delete("onDeletion", "SecurityContext securityContext, ErrorBuffer errorBuffer, PropertyMap properties", "securityContext, errorBuffer, properties"), Custom("", "", ""); diff --git a/structr-core/src/test/java/org/structr/core/entity/TestEight.java b/structr-core/src/test/java/org/structr/core/entity/TestEight.java index b2a1268d51..19790d5f2d 100644 --- a/structr-core/src/test/java/org/structr/core/entity/TestEight.java +++ b/structr-core/src/test/java/org/structr/core/entity/TestEight.java @@ -23,6 +23,7 @@ import org.structr.common.View; import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; +import org.structr.core.graph.ModificationQueue; import org.structr.core.property.IntProperty; import org.structr.core.property.Property; import org.structr.core.property.PropertyMap; @@ -34,9 +35,9 @@ public class TestEight extends AbstractNode { public static final Property testProperty = new IntProperty("testProperty"); - + public static final View defaultView = new View(TestEight.class, PropertyView.Public, testProperty); - + private long onCreationTimestamp = 0L; private long onModificationTimestamp = 0L; private long onDeletionTimestamp = 0L; @@ -45,39 +46,39 @@ public class TestEight extends AbstractNode { @Override public boolean onCreation(SecurityContext securityContext1, ErrorBuffer errorBuffer) throws FrameworkException { - + this.onCreationTimestamp = System.currentTimeMillis(); return true; } @Override - public boolean onModification(SecurityContext securityContext1, ErrorBuffer errorBuffer) throws FrameworkException { - + public boolean onModification(SecurityContext securityContext1, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { + this.onModificationTimestamp = System.currentTimeMillis(); return true; } @Override public boolean onDeletion(SecurityContext securityContext1, ErrorBuffer errorBuffer, PropertyMap properties) throws FrameworkException { - + this.onDeletionTimestamp = System.currentTimeMillis(); return true; } @Override public void afterCreation(SecurityContext securityContext1) { - + this.afterCreationTimestamp = System.currentTimeMillis(); } @Override public void afterModification(SecurityContext securityContext1) { - + this.afterModificationTimestamp = System.currentTimeMillis(); } - + public void resetTimestamps() { - + onCreationTimestamp = 0L; onModificationTimestamp = 0L; onDeletionTimestamp = 0L; diff --git a/structr-core/src/test/java/org/structr/core/entity/TestFive.java b/structr-core/src/test/java/org/structr/core/entity/TestFive.java index a014755807..400a4daade 100644 --- a/structr-core/src/test/java/org/structr/core/entity/TestFive.java +++ b/structr-core/src/test/java/org/structr/core/entity/TestFive.java @@ -20,8 +20,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.structr.core.property.IntProperty; -import org.structr.core.property.Property; import org.structr.common.PropertyView; import org.structr.common.SecurityContext; import org.structr.common.View; @@ -29,14 +27,17 @@ import org.structr.common.error.FrameworkException; import org.structr.core.app.App; import org.structr.core.app.StructrApp; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.Tx; +import org.structr.core.property.IntProperty; +import org.structr.core.property.Property; /** * * */ public class TestFive extends AbstractNode { - + private static final Logger logger = Logger.getLogger(TestFive.class.getName()); public static final Property intProperty = new IntProperty("integerProperty").indexed(); @@ -44,23 +45,23 @@ public class TestFive extends AbstractNode { public static final Property modifiedInBeforeModification = new IntProperty("modifiedInBeforeModification").defaultValue(0).indexed().unvalidated(); public static final Property modifiedInAfterCreation = new IntProperty("modifiedInAfterCreation").defaultValue(0).indexed().unvalidated(); public static final Property modifiedInAfterModification = new IntProperty("modifiedInAfterModification").defaultValue(0).indexed().unvalidated(); - + public static final View publicView = new View(TestFive.class, PropertyView.Public, intProperty, modifiedInBeforeCreation, modifiedInBeforeModification, modifiedInAfterCreation, modifiedInAfterModification ); - + @Override public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { - + int value = getIncreasedValue(modifiedInBeforeCreation); setProperty(modifiedInBeforeCreation, value); - + return true; } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { - + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { + int value = getIncreasedValue(modifiedInBeforeModification); setProperty(modifiedInBeforeModification, value); @@ -69,48 +70,48 @@ public boolean onModification(SecurityContext securityContext, ErrorBuffer error @Override public void afterCreation(SecurityContext securityContext) { - + final App app = StructrApp.getInstance(securityContext); try (final Tx tx = app.tx()) { final int value = getIncreasedValue(modifiedInAfterCreation); setProperty(modifiedInAfterCreation, value); - + tx.success(); - + } catch (Throwable t) { - + logger.log(Level.WARNING, "", t); } } @Override public void afterModification(SecurityContext securityContext) { - + final App app = StructrApp.getInstance(securityContext); try (final Tx tx = app.tx()) { final int value = getIncreasedValue(modifiedInAfterModification); - + setProperty(modifiedInAfterModification, value); tx.success(); - + } catch (Throwable t) { - + logger.log(Level.WARNING, "", t); } } - + private int getIncreasedValue(Property key) { - + Integer value = getProperty(key); - + if (value != null) { - + return value.intValue() + 1; } - + return 1; } } diff --git a/structr-core/src/test/java/org/structr/core/entity/TestSeven.java b/structr-core/src/test/java/org/structr/core/entity/TestSeven.java index be2f9ea8b8..6fb905ee2e 100644 --- a/structr-core/src/test/java/org/structr/core/entity/TestSeven.java +++ b/structr-core/src/test/java/org/structr/core/entity/TestSeven.java @@ -18,36 +18,37 @@ */ package org.structr.core.entity; -import org.structr.core.property.Property; import org.structr.common.PropertyView; import org.structr.common.SecurityContext; import org.structr.common.ValidationHelper; import org.structr.common.View; import org.structr.common.error.ErrorBuffer; +import org.structr.core.graph.ModificationQueue; import org.structr.core.property.DoubleProperty; +import org.structr.core.property.Property; /** * A simple entity with lat,lon coordinates - * - * + * + * * */ public class TestSeven extends AbstractNode { - + public static final Property latitude = new DoubleProperty("latitude").indexed(); public static final Property longitude = new DoubleProperty("longitude").indexed(); public static final View publicView = new View(TestSeven.class, PropertyView.Public, latitude, longitude ); - + @Override public boolean onCreation(final SecurityContext securityContext, final ErrorBuffer errorBuffer) { return isValid(errorBuffer); } - + @Override - public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer) { + public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) { return isValid(errorBuffer); } @@ -60,5 +61,5 @@ public boolean isValid(final ErrorBuffer errorBuffer) { return !error; } - + } diff --git a/structr-modules/structr-media-module/src/main/java/org/structr/media/VideoFile.java b/structr-modules/structr-media-module/src/main/java/org/structr/media/VideoFile.java index 424c095824..58358eac94 100644 --- a/structr-modules/structr-media-module/src/main/java/org/structr/media/VideoFile.java +++ b/structr-modules/structr-media-module/src/main/java/org/structr/media/VideoFile.java @@ -33,6 +33,7 @@ import org.structr.core.GraphObjectMap; import org.structr.core.JsonInput; import org.structr.core.app.StructrApp; +import org.structr.core.graph.ModificationQueue; import static org.structr.core.graph.NodeInterface.name; import static org.structr.core.graph.NodeInterface.owner; import org.structr.core.graph.Tx; @@ -48,9 +49,9 @@ import org.structr.rest.RestMethodResult; import org.structr.schema.SchemaService; import org.structr.web.common.FileHelper; -import org.structr.web.entity.Image; import static org.structr.web.entity.FileBase.relativeFilePath; import static org.structr.web.entity.FileBase.size; +import org.structr.web.entity.Image; //~--- classes ---------------------------------------------------------------- @@ -104,14 +105,16 @@ public class VideoFile extends File { public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { updateVideoInfo(); + return super.onCreation(securityContext, errorBuffer); } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { updateVideoInfo(); - return super.onModification(securityContext, errorBuffer); + + return super.onModification(securityContext, errorBuffer, modificationQueue); } public String getDiskFilePath(final SecurityContext securityContext) { diff --git a/structr-modules/structr-xmpp-module/src/main/java/org/structr/xmpp/XMPPClient.java b/structr-modules/structr-xmpp-module/src/main/java/org/structr/xmpp/XMPPClient.java index 70ce50aae7..e292ba6c82 100644 --- a/structr-modules/structr-xmpp-module/src/main/java/org/structr/xmpp/XMPPClient.java +++ b/structr-modules/structr-xmpp-module/src/main/java/org/structr/xmpp/XMPPClient.java @@ -35,6 +35,7 @@ import org.structr.core.app.App; import org.structr.core.app.StructrApp; import org.structr.core.entity.AbstractNode; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeAttribute; import org.structr.core.graph.Tx; import org.structr.core.property.BooleanProperty; @@ -91,7 +92,7 @@ public boolean onCreation(final SecurityContext securityContext, final ErrorBuff } @Override - public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { XMPPClientConnection connection = XMPPContext.getClientForId(getUuid()); boolean enabled = getProperty(isEnabled); @@ -122,7 +123,7 @@ public boolean onModification(final SecurityContext securityContext, final Error } } - return super.onModification(securityContext, errorBuffer); + return super.onModification(securityContext, errorBuffer, modificationQueue); } @Override diff --git a/structr-rest/src/test/java/org/structr/rest/entity/TestNine.java b/structr-rest/src/test/java/org/structr/rest/entity/TestNine.java index a1ea7dfc57..f5a2a8b59c 100644 --- a/structr-rest/src/test/java/org/structr/rest/entity/TestNine.java +++ b/structr-rest/src/test/java/org/structr/rest/entity/TestNine.java @@ -28,14 +28,13 @@ import org.structr.common.geo.GeoCodingResult; import org.structr.common.geo.GeoHelper; import org.structr.core.GraphObject; -import org.structr.core.app.App; -import org.structr.core.app.StructrApp; import org.structr.core.entity.AbstractNode; -import static org.structr.core.entity.AbstractNode.name; +import org.structr.core.graph.ModificationQueue; +import static org.structr.core.graph.NodeInterface.name; import org.structr.core.notion.PropertyNotion; import org.structr.core.property.CollectionNotionProperty; -import org.structr.core.property.EndNodes; import org.structr.core.property.DoubleProperty; +import org.structr.core.property.EndNodes; import org.structr.core.property.Property; import org.structr.core.property.StringProperty; @@ -47,32 +46,32 @@ public class TestNine extends AbstractNode { public static final Property> testEights = new EndNodes<>("testEights", NineEightManyToMany.class); public static final Property> testEightIds = new CollectionNotionProperty("testEightIds", testEights, new PropertyNotion(GraphObject.id)); - + public static final Property city = new StringProperty("city").indexed().indexedWhenEmpty(); public static final Property street = new StringProperty("street").indexed().indexedWhenEmpty(); public static final Property postalCode = new StringProperty("postalCode").indexed().indexedWhenEmpty(); - + public static final Property latitude = new DoubleProperty("latitude"); public static final Property longitude = new DoubleProperty("longitude"); - + public static final View defaultView = new View(TestNine.class, PropertyView.Public, name, city, street, postalCode, latitude, longitude ); @Override public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { - + geocode(); - + return super.onCreation(securityContext, errorBuffer); } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { - + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { + geocode(); - - return super.onModification(securityContext, errorBuffer); + + return super.onModification(securityContext, errorBuffer, modificationQueue); } public void geocode() throws FrameworkException { diff --git a/structr-ui/src/main/java/org/structr/web/entity/AbstractFile.java b/structr-ui/src/main/java/org/structr/web/entity/AbstractFile.java index 1c3498eab6..937f74f222 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/AbstractFile.java +++ b/structr-ui/src/main/java/org/structr/web/entity/AbstractFile.java @@ -29,6 +29,7 @@ import org.structr.core.Services; import org.structr.core.app.StructrApp; import org.structr.core.entity.LinkedTreeNode; +import org.structr.core.graph.ModificationQueue; import org.structr.core.property.BooleanProperty; import org.structr.core.property.CollectionIdProperty; import org.structr.core.property.EndNode; @@ -76,10 +77,10 @@ public boolean onCreation(final SecurityContext securityContext, final ErrorBuff } @Override - public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { final boolean valid = validatePath(securityContext, errorBuffer); - return valid && super.onModification(securityContext, errorBuffer); + return valid && super.onModification(securityContext, errorBuffer, modificationQueue); } public boolean validatePath(final SecurityContext securityContext, final ErrorBuffer errorBuffer) throws FrameworkException { diff --git a/structr-ui/src/main/java/org/structr/web/entity/AbstractMinifiedFile.java b/structr-ui/src/main/java/org/structr/web/entity/AbstractMinifiedFile.java index 24a967c14e..104034b024 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/AbstractMinifiedFile.java +++ b/structr-ui/src/main/java/org/structr/web/entity/AbstractMinifiedFile.java @@ -29,6 +29,8 @@ import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; import org.structr.core.Export; +import org.structr.core.graph.ModificationEvent; +import org.structr.core.graph.ModificationQueue; import org.structr.core.property.EndNodes; import org.structr.core.property.Property; import org.structr.dynamic.File; @@ -45,20 +47,41 @@ public abstract class AbstractMinifiedFile extends File { public static final Property> minificationSources = new EndNodes<>("minificationSources", MinificationNeighbor.class); @Override - public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { + + boolean shouldMinify = false; + + final String myUUID = getUuid(); + + for (ModificationEvent modState : modificationQueue.getModificationEvents()) { + + // only take changes on this exact file into account + if (myUUID.equals(modState.getUuid())) { + + shouldMinify = shouldMinify || shouldModificationTriggerMinifcation(modState); + + } - try { - this.minify(); - } catch (IOException ex) { - logger.log(Level.WARNING, "Could not automatically minify file", ex); } - return super.onModification(securityContext, errorBuffer); + if (shouldMinify) { + + try { + this.minify(); + } catch (IOException ex) { + logger.log(Level.WARNING, "Could not automatically minify file", ex); + } + + } + + return super.onModification(securityContext, errorBuffer, modificationQueue); } @Export public abstract void minify() throws FrameworkException, IOException; + public abstract boolean shouldModificationTriggerMinifcation(ModificationEvent modState); + public int getMaxPosition () { int max = 0; for (final MinificationNeighbor neighbor : getOutgoingRelationships(MinificationNeighbor.class)) { diff --git a/structr-ui/src/main/java/org/structr/web/entity/FileBase.java b/structr-ui/src/main/java/org/structr/web/entity/FileBase.java index 27445e269b..26b66e2f8d 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/FileBase.java +++ b/structr-ui/src/main/java/org/structr/web/entity/FileBase.java @@ -54,6 +54,8 @@ import org.structr.core.Services; import org.structr.core.app.StructrApp; import org.structr.core.entity.Principal; +import org.structr.core.graph.ModificationEvent; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeInterface; import org.structr.core.graph.Tx; import org.structr.core.property.ConstantBooleanProperty; @@ -120,9 +122,9 @@ public boolean onCreation(final SecurityContext securityContext, final ErrorBuff } @Override - public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { - if (super.onModification(securityContext, errorBuffer)) { + if (super.onModification(securityContext, errorBuffer, modificationQueue)) { synchronized (this) { @@ -139,14 +141,7 @@ public boolean onModification(final SecurityContext securityContext, final Error this.securityContext = previousSecurityContext; } - final AbstractMinifiedFile minifiedFile = getProperty(FileBase.minificationTarget); - if (minifiedFile != null) { - try { - minifiedFile.minify(); - } catch (IOException ex) { - logger.log(Level.WARNING, "Could not automatically update minification target", ex); - } - } + triggerMinificationIfNeeded(modificationQueue); return true; } @@ -334,6 +329,38 @@ public void increaseVersion() throws FrameworkException { } } + public void triggerMinificationIfNeeded(ModificationQueue modificationQueue) throws FrameworkException { + + final AbstractMinifiedFile minifiedFile = getProperty(FileBase.minificationTarget); + if (minifiedFile != null) { + + // only run minification if the file version changed + boolean versionChanged = false; + for (ModificationEvent modState : modificationQueue.getModificationEvents()) { + + if (getUuid().equals(modState.getUuid())) { + + versionChanged = versionChanged || + modState.getRemovedProperties().containsKey(FileBase.version) || + modState.getModifiedProperties().containsKey(FileBase.version) || + modState.getNewProperties().containsKey(FileBase.version); + + } + } + + if (versionChanged) { + + try { + minifiedFile.minify(); + } catch (IOException ex) { + logger.log(Level.WARNING, "Could not automatically update minification target", ex); + } + + } + + } + } + @Override public InputStream getInputStream() { diff --git a/structr-ui/src/main/java/org/structr/web/entity/Folder.java b/structr-ui/src/main/java/org/structr/web/entity/Folder.java index d255471822..ab46d978cc 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/Folder.java +++ b/structr-ui/src/main/java/org/structr/web/entity/Folder.java @@ -36,6 +36,7 @@ import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; import org.structr.core.GraphObject; +import org.structr.core.graph.ModificationQueue; import org.structr.core.notion.PropertySetNotion; import org.structr.core.property.BooleanProperty; import org.structr.core.property.ConstantBooleanProperty; @@ -101,9 +102,9 @@ public boolean onCreation(final SecurityContext securityContext, final ErrorBuff } @Override - public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(final SecurityContext securityContext, final ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { - if (super.onModification(securityContext, errorBuffer)) { + if (super.onModification(securityContext, errorBuffer, modificationQueue)) { synchronized (this) { diff --git a/structr-ui/src/main/java/org/structr/web/entity/MinifiedCssFile.java b/structr-ui/src/main/java/org/structr/web/entity/MinifiedCssFile.java index b6862b05a2..89f0a1d0f9 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/MinifiedCssFile.java +++ b/structr-ui/src/main/java/org/structr/web/entity/MinifiedCssFile.java @@ -23,11 +23,13 @@ import java.io.FileReader; import java.io.IOException; import java.io.OutputStreamWriter; +import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.io.FileUtils; import org.structr.common.PropertyView; import org.structr.common.View; import org.structr.common.error.FrameworkException; +import org.structr.core.graph.ModificationEvent; import org.structr.core.property.IntProperty; import org.structr.core.property.Property; import org.structr.web.common.FileHelper; @@ -41,19 +43,27 @@ public class MinifiedCssFile extends AbstractMinifiedFile { public static final View defaultView = new View(MinifiedJavaScriptFile.class, PropertyView.Public, minificationSources, lineBreak); public static final View uiView = new View(MinifiedJavaScriptFile.class, PropertyView.Ui, minificationSources, lineBreak); + @Override + public boolean shouldModificationTriggerMinifcation(ModificationEvent modState) { + + return modState.getModifiedProperties().containsKey(MinifiedCssFile.lineBreak); + + } + @Override public void minify() throws FrameworkException, IOException { + logger.log(Level.INFO, "Running minify: {0}", this.getType()); + FileHelper.setFileData(this, getConcatenatedSource().getBytes(), null); try (FileReader in = new FileReader(this.getFileOnDisk())) { final java.io.File temp = java.io.File.createTempFile("structr-minify", ".tmp"); - final OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(temp)); - - final CssCompressor compressor = new CssCompressor(in); - compressor.compress(out, getProperty(lineBreak)); - out.close(); + try (OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(temp))) { + final CssCompressor compressor = new CssCompressor(in); + compressor.compress(out, getProperty(lineBreak)); + } FileHelper.setFileData(this, FileUtils.readFileToString(temp).getBytes(), null); } diff --git a/structr-ui/src/main/java/org/structr/web/entity/MinifiedJavaScriptFile.java b/structr-ui/src/main/java/org/structr/web/entity/MinifiedJavaScriptFile.java index d275d3f188..d1453e3bf1 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/MinifiedJavaScriptFile.java +++ b/structr-ui/src/main/java/org/structr/web/entity/MinifiedJavaScriptFile.java @@ -36,6 +36,7 @@ import org.structr.common.PropertyView; import org.structr.common.View; import org.structr.common.error.FrameworkException; +import org.structr.core.graph.ModificationEvent; import org.structr.core.property.EnumProperty; import org.structr.core.property.Property; import org.structr.core.property.StringProperty; @@ -53,9 +54,18 @@ public class MinifiedJavaScriptFile extends AbstractMinifiedFile { public static final View defaultView = new View(MinifiedJavaScriptFile.class, PropertyView.Public, minificationSources, optimizationLevel, warnings, errors); public static final View uiView = new View(MinifiedJavaScriptFile.class, PropertyView.Ui, minificationSources, optimizationLevel, warnings, errors); + @Override + public boolean shouldModificationTriggerMinifcation(ModificationEvent modState) { + + return modState.getModifiedProperties().containsKey(MinifiedJavaScriptFile.optimizationLevel); + + } + @Override public void minify() throws FrameworkException, IOException { + logger.log(Level.INFO, "Running minify: {0}", this.getType()); + final Compiler compiler = new Compiler(); final CompilerOptions options = new CompilerOptions(); final CompilationLevel selectedLevel = getProperty(optimizationLevel); diff --git a/structr-ui/src/main/java/org/structr/web/entity/Tag.java b/structr-ui/src/main/java/org/structr/web/entity/Tag.java index 47d640b053..4d2895f9f9 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/Tag.java +++ b/structr-ui/src/main/java/org/structr/web/entity/Tag.java @@ -19,13 +19,13 @@ package org.structr.web.entity; import java.util.List; -import org.structr.core.entity.ValidatedNode; import org.structr.common.PropertyView; import org.structr.common.SecurityContext; import org.structr.common.View; import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; import org.structr.core.entity.AbstractNode; +import org.structr.core.entity.ValidatedNode; import org.structr.core.property.EndNodes; import org.structr.core.property.Property; import org.structr.web.entity.relation.Tagging; @@ -38,28 +38,28 @@ public class Tag extends ValidatedNode { public static final Property> taggables = new EndNodes<>("taggables", Tagging.class, new UiNotion()); - + public static final View defaultView = new View(Tag.class, PropertyView.Public, name, taggables); public static final View uiView = new View(Tag.class, PropertyView.Ui, name, taggables); - + @Override public boolean isValid(ErrorBuffer errorBuffer) { - + boolean valid = true; - + valid &= nonEmpty(AbstractNode.name, errorBuffer); - + return valid; } - + @Override public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { // Make tags visible to anyone upon creation setProperty(visibleToPublicUsers, true); setProperty(visibleToAuthenticatedUsers, true); - - return super.onModification(securityContext, errorBuffer); + + return super.onCreation(securityContext, errorBuffer); } diff --git a/structr-ui/src/main/java/org/structr/web/entity/User.java b/structr-ui/src/main/java/org/structr/web/entity/User.java index f982df7528..c3035c8c4c 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/User.java +++ b/structr-ui/src/main/java/org/structr/web/entity/User.java @@ -30,6 +30,7 @@ import org.structr.core.entity.AbstractUser; import org.structr.core.entity.Group; import org.structr.core.entity.relationship.Groups; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeAttribute; import org.structr.core.property.BooleanProperty; import org.structr.core.property.ConstantBooleanProperty; @@ -111,9 +112,9 @@ public boolean onCreation(SecurityContext securityContext, ErrorBuffer errorBuff } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { - if (super.onModification(securityContext, errorBuffer)) { + if (super.onModification(securityContext, errorBuffer, modificationQueue)) { checkAndCreateHomeDirectory(securityContext); diff --git a/structr-ui/src/main/java/org/structr/web/entity/dom/Content.java b/structr-ui/src/main/java/org/structr/web/entity/dom/Content.java index c6abc2f0c0..db8e546bbd 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/dom/Content.java +++ b/structr-ui/src/main/java/org/structr/web/entity/dom/Content.java @@ -41,6 +41,7 @@ import org.structr.common.error.ErrorBuffer; import org.structr.common.error.FrameworkException; import org.structr.core.Adapter; +import org.structr.core.graph.ModificationQueue; import org.structr.core.property.ConstantBooleanProperty; import org.structr.core.property.Property; import org.structr.core.property.PropertyKey; @@ -191,7 +192,7 @@ public String adapt(String s) throws FrameworkException { } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { for (final Sync rel : getOutgoingRelationships(Sync.class)) { @@ -419,7 +420,7 @@ public void renderContent(final RenderContext renderContext, final int depth) th // catch exception to prevent ugly status 500 error pages in frontend. logger.log(Level.SEVERE, "", t); - + } } diff --git a/structr-ui/src/main/java/org/structr/web/entity/dom/DOMElement.java b/structr-ui/src/main/java/org/structr/web/entity/dom/DOMElement.java index b6a419c59a..73ec2616e9 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/dom/DOMElement.java +++ b/structr-ui/src/main/java/org/structr/web/entity/dom/DOMElement.java @@ -38,6 +38,7 @@ import org.structr.core.Result; import org.structr.core.app.StructrApp; import org.structr.core.entity.AbstractRelationship; +import org.structr.core.graph.ModificationQueue; import org.structr.core.property.BooleanProperty; import org.structr.core.property.GenericProperty; import org.structr.core.property.Property; @@ -764,7 +765,7 @@ public Node doImport(final Page newPage) throws DOMException { // ----- nested classes ----- @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { for (Sync rel : getOutgoingRelationships(Sync.class)) { diff --git a/structr-ui/src/main/java/org/structr/web/entity/dom/DOMNode.java b/structr-ui/src/main/java/org/structr/web/entity/dom/DOMNode.java index 140cb8a9b6..287ec3f238 100644 --- a/structr-ui/src/main/java/org/structr/web/entity/dom/DOMNode.java +++ b/structr-ui/src/main/java/org/structr/web/entity/dom/DOMNode.java @@ -50,9 +50,10 @@ import org.structr.core.app.StructrApp; import org.structr.core.entity.AbstractNode; import org.structr.core.entity.LinkedTreeNode; +import org.structr.core.function.Functions; +import org.structr.core.graph.ModificationQueue; import org.structr.core.graph.NodeInterface; import org.structr.core.notion.PropertyNotion; -import org.structr.core.function.Functions; import org.structr.core.property.AbstractReadOnlyProperty; import org.structr.core.property.BooleanProperty; import org.structr.core.property.CollectionIdProperty; @@ -68,23 +69,6 @@ import org.structr.core.property.StartNode; import org.structr.core.property.StringProperty; import org.structr.core.script.Scripting; -import org.structr.web.function.AddHeaderFunction; -import org.structr.web.function.EscapeHtmlFunction; -import org.structr.web.function.FromJsonFunction; -import org.structr.web.function.FromXmlFunction; -import org.structr.web.function.GetContentFunction; -import org.structr.web.function.GetRequestHeaderFunction; -import org.structr.web.function.HttpHeadFunction; -import org.structr.web.function.IncludeFunction; -import org.structr.web.function.IsLocaleFunction; -import org.structr.web.function.LogEventFunction; -import org.structr.web.function.ParseFunction; -import org.structr.web.function.HttpPostFunction; -import org.structr.web.function.RenderFunction; -import org.structr.web.function.SetDetailsObjectFunction; -import org.structr.web.function.SetResponseHeaderFunction; -import org.structr.web.function.StripHtmlFunction; -import org.structr.web.function.ToJsonFunction; import org.structr.web.common.GraphDataSource; import org.structr.web.common.RenderContext; import org.structr.web.common.RenderContext.EditMode; @@ -101,12 +85,29 @@ import org.structr.web.entity.relation.PageLink; import org.structr.web.entity.relation.RenderNode; import org.structr.web.entity.relation.Sync; +import org.structr.web.function.AddHeaderFunction; +import org.structr.web.function.EscapeHtmlFunction; +import org.structr.web.function.FromJsonFunction; +import org.structr.web.function.FromXmlFunction; +import org.structr.web.function.GetContentFunction; +import org.structr.web.function.GetRequestHeaderFunction; import org.structr.web.function.GetSessionAttributeFunction; import org.structr.web.function.HttpGetFunction; +import org.structr.web.function.HttpHeadFunction; +import org.structr.web.function.HttpPostFunction; +import org.structr.web.function.IncludeFunction; +import org.structr.web.function.IsLocaleFunction; +import org.structr.web.function.LogEventFunction; +import org.structr.web.function.ParseFunction; import org.structr.web.function.RemoveSessionAttributeFunction; +import org.structr.web.function.RenderFunction; import org.structr.web.function.SendHtmlMailFunction; import org.structr.web.function.SendPlaintextMailFunction; +import org.structr.web.function.SetDetailsObjectFunction; +import org.structr.web.function.SetResponseHeaderFunction; import org.structr.web.function.SetSessionAttributeFunction; +import org.structr.web.function.StripHtmlFunction; +import org.structr.web.function.ToJsonFunction; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Node; @@ -297,7 +298,7 @@ public String getPositionPath() { } @Override - public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException { + public boolean onModification(SecurityContext securityContext, ErrorBuffer errorBuffer, final ModificationQueue modificationQueue) throws FrameworkException { try {