diff --git a/docs/emc/EMC_config.md b/docs/emc/EMC_config.md
index 12e27bf..5c6238e 100644
--- a/docs/emc/EMC_config.md
+++ b/docs/emc/EMC_config.md
@@ -350,6 +350,16 @@ Indicates whether this space has a metadata name/value for the specified name.
+#### `boolean hasRealmWithName(String realm)`
+
+Returns true if there is a realm by this name.
+
+| Parameter | Description |
+|-----|-----|
+|`String realm` | *no description* |
+
+
+
#### `List` **`importEntityNames`**
Returns the names of the entities that have been imported into this space.
@@ -372,6 +382,16 @@ Spaces can define a dictionary of name/value pairs that provide some meta data a
+#### `MTRealm realmWithName(String realm)`
+
+Returns the realm object by its name.
+
+| Parameter | Description |
+|-----|-----|
+|`String realm` | *no description* |
+
+
+
#### `MTRepository repository(String name)`
Returns the repository object by its name.
diff --git a/docs/emc/EMC_domain.md b/docs/emc/EMC_domain.md
index 46ef9a8..3d00c61 100644
--- a/docs/emc/EMC_domain.md
+++ b/docs/emc/EMC_domain.md
@@ -11,6 +11,7 @@ Model classes that are domain specific are of this type. The classes are briefly
|[`MTDEAttribute`](#class_MTDEAttribute)|Represents an attribute in your model in the context of a domain.|
|[`MTDEAttributeConstraintExpression`](#class_MTDEAttributeConstraintExpression)|Represents a constraint on an attribute in the form of an expression.|
|[`MTDERelationship`](#class_MTDERelationship)|Represents a relationship in your model in the context of a domain.|
+|[`MTDERelationshipField`](#class_MTDERelationshipField)|Represents a field (attribute or relationship) associated with the __to__ entity of the relationship.|
|[`MTDEntity`](#class_MTDEntity)|Represents an entity in your model in the context of a domain.|
|[`MTDEnum`](#class_MTDEnum)|Represents an enum in the context of a domain.|
|[`MTDEnumItem`](#class_MTDEnumItem)|Represents an enum item in the context of a domain.|
@@ -236,6 +237,12 @@ If this relationship was explicitly renamed within its domain, it will return th
+#### `Collection` **`fields`**
+
+Returns all the declared fields of this relationship.
+
+
+
#### `String fullname(String delim)`
This returns the full name of this domain relationship which includes not only its domain based name but is also preceded with the domain's entity's full name. The delimiter can be provided which is used between all parts of the full name.
@@ -551,6 +558,18 @@ Returns the domain specific version of the specified relationship.
+#### `boolean` **`hasDeclaredDomainRelationships`**
+
+Indicates if any relationships were declared in this domain entity declaration.
+
+
+
+#### `boolean` **`hasParentRelationship`**
+
+Indicates whether this domain entity has a parent relationship. A parent relationship is one that has been declared as `parent`
+
+
+
#### `boolean` **`hasPrimaryParentRelationship`**
Indicates whether this domain entity has a primary parent relationship. A primary parent relationship is one that has been declared as `parent` and **not** declared `optional`.
diff --git a/docs/emc/EMC_entity.md b/docs/emc/EMC_entity.md
index 33b3b7f..4209d1d 100644
--- a/docs/emc/EMC_entity.md
+++ b/docs/emc/EMC_entity.md
@@ -355,6 +355,16 @@ These methods relate to an entity.
+#### `void addRealm(String realm)`
+
+Adds the entity to a realm.
+
+| Parameter | Description |
+|-----|-----|
+|`String realm` | *no description* |
+
+
+
#### `boolean` **`isDeclaredAsPrimary`**
Indicates whether this entity was **declared** `primary`. If the entity was **not** declared with the `primary` keyword then this will return false even if it is implied as primary.
@@ -379,6 +389,16 @@ Indicates whether this entity was created by the compiler because it represents
+#### `boolean isInRealm(String realm)`
+
+Returns true if this entity is part of a realm.
+
+| Parameter | Description |
+|-----|-----|
+|`String realm` | *no description* |
+
+
+
#### `boolean` **`isPrimary`**
Indicates whether this entity was declared `primary` or if it was inferred as primary. If an entity has a primary key it is inferred to be a primary entity.
@@ -576,6 +596,16 @@ Indicates whether this entity has any attributes.
Indicates whether this entity defines any bit fields.
+
+
+#### `MTRelationship relationshipNamed(String name)`
+
+Returns an relationship of this entity with the specified name.
+
+| Parameter | Description |
+|-----|-----|
+|`String name` | The name of the relationship to return. |
+
### Relationship Category
@@ -657,6 +687,16 @@ Indicates whether this entity has a primary parent relationship. A primary paren
+#### `boolean hasRelationshipNamed(String name)`
+
+Indicates whether this entity has an relationship with the specified name.
+
+| Parameter | Description |
+|-----|-----|
+|`String name` | *no description* |
+
+
+
#### `boolean` **`hasRelationships`**
Indicates whether this entity defines any relationships.
@@ -828,6 +868,16 @@ Indicates whether this entity has at least one relationship with the specified t
+#### `boolean hasRelationshipToEntityNamed(String toEntityName)`
+
+Indicates whether this entity has at least one relationship to a named other entity.
+
+| Parameter | Description |
+|-----|-----|
+|`String toEntityName` | The name of the other entity. |
+
+
+
#### `boolean hasRelationshipToEntityTagged(String tag)`
Indicates whether the entity **to** which a relationship references is tagged with the specified tag.
@@ -904,6 +954,16 @@ Indicates whether this was declared as `extern`.
+#### `MTEnumItem item(Long index)`
+
+Returns an item by its index.
+
+| Parameter | Description |
+|-----|-----|
+|`Long index` | *no description* |
+
+
+
#### `List` **`items`**
Gets the enum items.
@@ -1226,6 +1286,12 @@ Returns the "from" part of the relationship which references the entity in which
+#### `MTEntity` **`implicitToEntity`**
+
+Gets the entity on the other side of an implicit many-to-many entity.
+
+
+
#### `boolean` **`isImplicit`**
Indicates whether the relationship was created because although it was not declared it can be implied based on relationships declared to this entity.
@@ -1340,6 +1406,12 @@ Indicates whether this type is both an array type and also `byte` data type.
+#### `boolean` **`isDataType`**
+
+Indicates whether this type is the `data` data type.
+
+
+
#### `boolean` **`isDateType`**
Indicates whether this type is the `date` data type.
diff --git a/docs/emc/EMC_foundation.md b/docs/emc/EMC_foundation.md
index 82ed67b..be6a70d 100644
--- a/docs/emc/EMC_foundation.md
+++ b/docs/emc/EMC_foundation.md
@@ -75,6 +75,16 @@ Returns the first item in the array.
+#### `Object get(Integer index)`
+
+Returns the specified item by its index into the array.
+
+| Parameter | Description |
+|-----|-----|
+|`Integer index` | The index into the array that points to the item to be returned. |
+
+
+
#### `Object get(Long index)`
Returns the specified item by its index into the array.
diff --git a/docs/etl/ETL.md b/docs/etl/ETL.md
index 32624dd..61cc871 100644
--- a/docs/etl/ETL.md
+++ b/docs/etl/ETL.md
@@ -128,6 +128,7 @@ Here is the full list of filters:
| [`lowercase`](#filter_detail_lowercase) | Forces all characters of the input to be lowercase. |
| [`map`](#filter_detail_map) | This filter is probably the most complicated one but can be very powerful in helping to pattern match an expression at its input with one provided as a parameter. When the expressions match, it not only returns true but also maps operands from the input expression to the parameter expression. |
| [`name`](#filter_detail_name) | This simply calls `getName()` on the input. It is more of a convenient way to get the name by using a filter. |
+| [`nameas`](#filter_detail_nameas) | Places underscore between words then forces all characters to be lowercase. |
| [`path`](#filter_detail_path) | This will convert a string or namespace object into a string where by a '/' character is used as a delimiter instead of a '.'. This is useful when you need to convert a namespace into a filepath. |
| [`plural`](#filter_detail_plural) | This will attempt to pluralize the last word of the input string. If it can't determine the pluralization it may just return the same string. |
| [`reverse`](#filter_detail_reverse) | Given a collection of objects, this will return a collection that has the reverse order of the input. |
@@ -416,6 +417,25 @@ Valid inputs for this filter are:
+
+##### Filter: `nameas`
+
+Places underscore between words then forces all characters to be lowercase.
+
+Valid inputs for this filter are:
+
+| Class of Valid Input | Description |
+|---|---|
+| `String` | The string to change into an underscore lowercase format. |
+
+This filter has the following parameters:
+
+| Usage with Parameter | Description |
+|---|---|
+| `nameas:`*method* | Specifies the naming method: standard, underscore, underscoreLowercase, underscoreUppercase, lowercase, uppercase, capitalize, dashesLowercase, dashesUppercase, parentPrefix |
+
+
+
##### Filter: `path`
diff --git a/src/main/antlr4/org/entityc/compiler/EntityLanguage.g4 b/src/main/antlr4/org/entityc/compiler/EntityLanguage.g4
index 6131001..874276c 100644
--- a/src/main/antlr4/org/entityc/compiler/EntityLanguage.g4
+++ b/src/main/antlr4/org/entityc/compiler/EntityLanguage.g4
@@ -91,6 +91,7 @@ HUMAN : 'human' ;
READABLE : 'readable' ;
IDENTIFICATION : 'identification' ;
+REALM : 'realm' ;
DOMAIN : 'domain' ;
ATTRIBUTES : 'attributes' ;
REPLACES : 'replaces' ;
@@ -189,7 +190,7 @@ ident
| INTERFACE | OPERATION | QUERY | STATUS | CUSTOM | PARAM | TYPE | ENDPOINT
| CONFIG | CONTEXT | ARGUMENT | HUMAN | READABLE | IDENTIFICATION | NAME | ORGANIZATION
| REQUIRES | ROLE | READ | WRITE | WHEN | USER | ARRAY
- | APPLY | DESCRIPTION | TAGS | METADATA | FORMATTING | FORMAT | COMMENTS
+ | APPLY | DESCRIPTION | TAGS | METADATA | FORMATTING | FORMAT | COMMENTS | REALM
;
macro
@@ -274,6 +275,7 @@ root
| entity
| enumStatement
| domain
+ | realm
| configuration
| units
| language
@@ -364,7 +366,8 @@ attributes
attributesBody
:
- ( attribute
+ ( tagStatement
+ | attribute
)*
;
@@ -411,7 +414,8 @@ relationships
relationshipsBody
:
- ( relationshipStatement
+ ( tagStatement
+ | relationshipStatement
)*
;
@@ -583,6 +587,17 @@ bitCount
: '(' INTEGER ')'
;
+realm
+ : REALM id '{' realmBody '}'
+ ;
+
+realmBody
+ :
+ ( descriptionStatement
+ | tagStatement
+ | domain
+ )*
+ ;
/*
*
DOMAIN
@@ -753,7 +768,7 @@ domainApplyTemplateBody
:
( descriptionStatement
| tagStatement
- | templateConfig
+ | transformConfig
)*
;
@@ -761,7 +776,7 @@ defaultTemplateConfig
: DEFAULT CONFIG jsonObj
;
-templateConfig
+transformConfig
: CONFIG jsonObj
;
@@ -835,7 +850,8 @@ domainAttributes
domainAttributesBody
:
- ( domainAttributesRenameTo
+ ( tagStatement
+ | domainAttributesRenameTo
| domainAttributesRenameAppendPrepend
| domainAttributeReplaces
| domainAttributeExclude
@@ -895,13 +911,40 @@ domainAttributeBody
)*
;
+/*
+These are attributes of the "to" entity of a relationship. This allows
+tagging of attributes with respect to its "path" from a relationship.
+*/
+domainRelationshipAttributes
+ : ATTRIBUTES '{' domainRelationshipAttributesBody '}'
+ ;
+
+domainRelationshipAttributesBody
+ :
+ ( tagStatement
+ | domainRelationshipAttribute
+ )*
+ ;
+
+domainRelationshipAttribute
+ : id '{' domainRelationshipAttributeBody '}'
+ ;
+
+domainRelationshipAttributeBody
+ :
+ ( descriptionStatement
+ | tagStatement
+ )*
+ ;
+
domainRelationships
: RELATIONSHIPS '{' domainRelationshipsBody '}'
;
domainRelationshipsBody
:
- ( domainRelationship
+ ( tagStatement
+ | domainRelationship
)*
;
@@ -913,6 +956,7 @@ domainRelationshipBody
:
( descriptionStatement
| tagStatement
+ | domainRelationshipAttributes
)*
;
@@ -1216,7 +1260,7 @@ templateBody
( descriptionStatement
| tagStatement
| outputSpec
- | templateConfig
+ | transformConfig
)*
;
@@ -1236,6 +1280,8 @@ transform
transformBody
:
( outputSpec
+ | transformConfig
+ | REALM id
)*
;
diff --git a/src/main/java/org/entityc/compiler/ASTVisitor.java b/src/main/java/org/entityc/compiler/ASTVisitor.java
index 8c7280c..776cb52 100644
--- a/src/main/java/org/entityc/compiler/ASTVisitor.java
+++ b/src/main/java/org/entityc/compiler/ASTVisitor.java
@@ -6,11 +6,7 @@
package org.entityc.compiler;
-import org.entityc.compiler.model.MTCodeFormat;
-import org.entityc.compiler.model.MTModule;
-import org.entityc.compiler.model.MTNamespace;
-import org.entityc.compiler.model.MTNode;
-import org.entityc.compiler.model.MTRoot;
+import org.entityc.compiler.model.*;
import org.entityc.compiler.model.config.MTConfiguration;
import org.entityc.compiler.model.config.MTDirectory;
import org.entityc.compiler.model.config.MTProtoc;
@@ -22,37 +18,8 @@
import org.entityc.compiler.model.config.MTSpaceInclude;
import org.entityc.compiler.model.config.MTTemplate;
import org.entityc.compiler.model.config.MTTransform;
-import org.entityc.compiler.model.domain.MTDApplyTemplate;
-import org.entityc.compiler.model.domain.MTDEAttribute;
-import org.entityc.compiler.model.domain.MTDEAttributeBitField;
-import org.entityc.compiler.model.domain.MTDEInterface;
-import org.entityc.compiler.model.domain.MTDEInterfaceOperation;
-import org.entityc.compiler.model.domain.MTDEInterfaceOperationConfig;
-import org.entityc.compiler.model.domain.MTDERelationship;
-import org.entityc.compiler.model.domain.MTDEntity;
-import org.entityc.compiler.model.domain.MTDEnum;
-import org.entityc.compiler.model.domain.MTDEnumItem;
-import org.entityc.compiler.model.domain.MTDModule;
-import org.entityc.compiler.model.domain.MTDView;
-import org.entityc.compiler.model.domain.MTDomain;
-import org.entityc.compiler.model.domain.MTNaming;
-import org.entityc.compiler.model.domain.MTNamingMethod;
-import org.entityc.compiler.model.entity.HalfRelationshipPlurality;
-import org.entityc.compiler.model.entity.MTAttribute;
-import org.entityc.compiler.model.entity.MTAttributeConstraint;
-import org.entityc.compiler.model.entity.MTBitField;
-import org.entityc.compiler.model.entity.MTEntity;
-import org.entityc.compiler.model.entity.MTEntityTemplate;
-import org.entityc.compiler.model.entity.MTEntityTemplateInstantiation;
-import org.entityc.compiler.model.entity.MTEnum;
-import org.entityc.compiler.model.entity.MTEnumItem;
-import org.entityc.compiler.model.entity.MTNativeType;
-import org.entityc.compiler.model.entity.MTPrimaryKey;
-import org.entityc.compiler.model.entity.MTRelationship;
-import org.entityc.compiler.model.entity.MTTagSet;
-import org.entityc.compiler.model.entity.MTTypedef;
-import org.entityc.compiler.model.entity.MTUnit;
-import org.entityc.compiler.model.entity.MTView;
+import org.entityc.compiler.model.domain.*;
+import org.entityc.compiler.model.entity.*;
import org.entityc.compiler.model.expression.MTConstant;
import org.entityc.compiler.model.expression.MTExpression;
import org.entityc.compiler.model.expression.MTMethodCall;
@@ -97,22 +64,25 @@
public class ASTVisitor extends EntityLanguageBaseVisitor {
private final Map> abstractViewContexts = new HashMap<>();
- private final Stack spaceStack = new Stack<>();
- private MTRoot root;
- private MTDomain currentDomain;
- private MTModule currentModule;
- private MTEntity currentEntity;
- private MTAttribute currentAttribute;
- private MTDModule currentDomainModule;
- private MTDEntity currentDomainEntity;
- private MTDEnum currentDomainEnum;
- private MTLanguage currentLanguage;
- private MTConfiguration currentConfiguration;
- private MTInterface currentInterface;
- private MTRequest currentRequest;
- private MTDEInterface currentDomainEntityInterface;
- private MTDEInterfaceOperation currentDomainEntityInterfaceOperation;
- private MTSpace foundSpace;
+ private final Stack spaceStack = new Stack<>();
+ private MTRoot root;
+ private MTRealm currentRealm;
+ private MTDomain currentDomain;
+ private MTModule currentModule;
+ private MTEntity currentEntity;
+ private MTAttribute currentAttribute;
+ private MTDModule currentDomainModule;
+ private MTDEntity currentDomainEntity;
+ private MTDERelationship currentDomainRelationship;
+ private MTDEnum currentDomainEnum;
+ private MTLanguage currentLanguage;
+ private MTConfiguration currentConfiguration;
+ private MTInterface currentInterface;
+ private MTRequest currentRequest;
+ private MTDEInterface currentDomainEntityInterface;
+ private MTDEInterfaceOperation currentDomainEntityInterfaceOperation;
+ private MTSpace foundSpace;
+ private List> inheritedTags;
public MTSpace getFoundSpace() {
return foundSpace;
@@ -128,7 +98,8 @@ public MTRoot visitRoot(EntityLanguageParser.RootContext ctx, MTRoot root, MTSpa
if (!hasCurrentSpace()) {
if (space != null) {
pushSpace(space);
- } else if (root.getSpace() != null) {
+ }
+ else if (root.getSpace() != null) {
pushSpace(root.getSpace());
}
}
@@ -166,6 +137,14 @@ public MTRoot visitRoot(EntityLanguageParser.RootContext ctx, MTRoot root, MTSpa
currentSpace().addModule(module);
}
+ for (EntityLanguageParser.RealmContext realmContext : ctx.realm()) {
+ if (!hasCurrentSpace()) {
+ ECLog.logFatal("Realm" + fatalMessage);
+ }
+ MTRealm realm = (MTRealm) visit(realmContext);
+ currentSpace().addRealm(realm);
+ }
+
for (EntityLanguageParser.DomainContext domainContext : ctx.domain()) {
if (!hasCurrentSpace()) {
ECLog.logFatal("Domain" + fatalMessage);
@@ -228,18 +207,19 @@ public Object visitUnits(EntityLanguageParser.UnitsContext ctx) {
ECLog.logInfo("READING UNITS...");
}
for (EntityLanguageParser.UnitDefinitionContext unitDefinitionContext : ctx.unitsBody().unitDefinition()) {
- String name = unitDefinitionContext.id(0).getText();
- String baseUnitName = unitDefinitionContext.EXTENDS() != null ?
- unitDefinitionContext.id(1).getText() :
- null;
- EntityLanguageParser.UnitDefinitionBodyContext body = unitDefinitionContext.unitDefinitionBody();
- String abbr = null;
- double multiplier = 1.0;
+ String name = unitDefinitionContext.id(0).getText();
+ String baseUnitName = unitDefinitionContext.EXTENDS() != null ?
+ unitDefinitionContext.id(1).getText() :
+ null;
+ EntityLanguageParser.UnitDefinitionBodyContext body = unitDefinitionContext.unitDefinitionBody();
+ String abbr = null;
+ double multiplier = 1.0;
if (body != null) {
for (EntityLanguageParser.UnitDefinitionFieldContext field : body.unitDefinitionField()) {
if (field.ABBR() != null) {
abbr = ECStringUtil.ProcessParserString(field.STRING().getText());
- } else if (field.MULTIPLIER() != null) {
+ }
+ else if (field.MULTIPLIER() != null) {
multiplier = Double.valueOf(field.FLOAT().getText());
}
}
@@ -278,10 +258,10 @@ public MTInterface visitAbstractInterfaceStatement(EntityLanguageParser.Abstract
@Override
public MTTypedef visitTypedefStatement(EntityLanguageParser.TypedefStatementContext ctx) {
- int bitWidth = ctx.INT32_TYPE() != null ?
- 32 :
- 64;
- MTTypedef typedef = new MTTypedef(ctx, currentModule, bitWidth, ctx.id().getText());
+ int bitWidth = ctx.INT32_TYPE() != null ?
+ 32 :
+ 64;
+ MTTypedef typedef = new MTTypedef(ctx, currentModule, bitWidth, ctx.id().getText());
if (ctx.typedefBody().descriptionStatement() != null) {
setNodeDescription(typedef, ctx.typedefBody().descriptionStatement(), false);
}
@@ -323,8 +303,8 @@ public MTInterfaceOperation visitOperation(EntityLanguageParser.OperationContext
@Override
public MTOperationConfig visitOperationConfig(EntityLanguageParser.OperationConfigContext ctx) {
- MTOperationConfig config = new MTOperationConfig(ctx);
- EntityLanguageParser.OperationConfigBlockContext block = ctx.operationConfigBlock();
+ MTOperationConfig config = new MTOperationConfig(ctx);
+ EntityLanguageParser.OperationConfigBlockContext block = ctx.operationConfigBlock();
for (EntityLanguageParser.OperationConfigContextContext contextContext : block.operationConfigContext()) {
config.addArgument(visitOperationConfigContext(contextContext));
@@ -362,8 +342,8 @@ public MTRequest visitOperationRequest(EntityLanguageParser.OperationRequestCont
@Override
public MTResponse visitOperationResponse(EntityLanguageParser.OperationResponseContext ctx) {
- MTResponse response = new MTResponse(ctx);
- EntityLanguageParser.OperationResponseBlockContext block = ctx.operationResponseBlock();
+ MTResponse response = new MTResponse(ctx);
+ EntityLanguageParser.OperationResponseBlockContext block = ctx.operationResponseBlock();
if (block.operationResponseStatus() != null) {
for (EntityLanguageParser.OperationResponseStatusContext statusContext : block.operationResponseStatus()) {
@@ -382,12 +362,12 @@ public MTResponse visitOperationResponse(EntityLanguageParser.OperationResponseC
@Override
public MTOperationConfigArgument visitOperationConfigContext(EntityLanguageParser.OperationConfigContextContext ctx) {
MTOperationConfigArgument.ArgumentType contextType = MTOperationConfigArgument.ArgumentType.FromName(
- ctx.operationConfigContextType().getText());
- MTOperationConfigArgument argument = new MTOperationConfigArgument(ctx, contextType,
- ctx.id(0).getText(),
- ctx.id().size() > 1 ?
- ctx.id(1).getText() :
- null, true);
+ ctx.operationConfigContextType().getText());
+ MTOperationConfigArgument argument = new MTOperationConfigArgument(ctx, contextType,
+ ctx.id(0).getText(),
+ ctx.id().size() > 1 ?
+ ctx.id(1).getText() :
+ null, true);
if (ctx.operationContextBlock().descriptionStatement() != null) {
setNodeDescription(argument, ctx.operationContextBlock().descriptionStatement(), false);
}
@@ -397,12 +377,12 @@ public MTOperationConfigArgument visitOperationConfigContext(EntityLanguageParse
@Override
public MTOperationConfigArgument visitOperationConfigArgument(EntityLanguageParser.OperationConfigArgumentContext ctx) {
MTOperationConfigArgument.ArgumentType argumentType = MTOperationConfigArgument.ArgumentType.FromName(
- ctx.operationConfigArgumentType().getText());
- MTOperationConfigArgument argument = new MTOperationConfigArgument(ctx, argumentType,
- ctx.id(0).getText(),
- ctx.id().size() > 1 ?
- ctx.id(1).getText() :
- null, false);
+ ctx.operationConfigArgumentType().getText());
+ MTOperationConfigArgument argument = new MTOperationConfigArgument(ctx, argumentType,
+ ctx.id(0).getText(),
+ ctx.id().size() > 1 ?
+ ctx.id(1).getText() :
+ null, false);
if (ctx.operationArgumentBlock().descriptionStatement() != null) {
setNodeDescription(argument, ctx.operationArgumentBlock().descriptionStatement(), false);
}
@@ -411,7 +391,7 @@ public MTOperationConfigArgument visitOperationConfigArgument(EntityLanguagePars
@Override
public MTRequestBody visitOperationRequestBody(EntityLanguageParser.OperationRequestBodyContext ctx) {
- MTRequestBody body = new MTRequestBody(ctx);
+ MTRequestBody body = new MTRequestBody(ctx);
EntityLanguageParser.OperationRequestBodyBlockContext block = ctx.operationRequestBodyBlock();
if (block.operationBodyContentType() != null && block.operationBodyContentType().size() > 0) {
body.setContentType(ECStringUtil.ProcessParserString(block.operationBodyContentType(0).STRING().getText()));
@@ -433,8 +413,8 @@ public MTRequestEndpoint visitOperationRequestEndpoint(EntityLanguageParser.Oper
if (ctx.STRING() != null) {
pathUrlString = ctx.STRING().getText();
}
- MTRequestEndpoint path = new MTRequestEndpoint(ctx, currentRequest,
- pathUrlString);
+ MTRequestEndpoint path = new MTRequestEndpoint(ctx, currentRequest,
+ pathUrlString);
EntityLanguageParser.OperationRequestEndpointBlockContext block = ctx.operationRequestEndpointBlock();
if (block != null) {
@@ -455,11 +435,12 @@ public MTResponseStatus visitOperationResponseStatus(EntityLanguageParser.Operat
String statusText = null;
if (ctx.id() != null) {
statusText = ctx.id().getText();
- } else if (ctx.INTEGER() != null) {
+ }
+ else if (ctx.INTEGER() != null) {
statusText = ctx.INTEGER().getText();
}
- MTResponseStatus status = new MTResponseStatus(ctx, statusText);
- EntityLanguageParser.OperationResponseStatusBlockContext block = ctx.operationResponseStatusBlock();
+ MTResponseStatus status = new MTResponseStatus(ctx, statusText);
+ EntityLanguageParser.OperationResponseStatusBlockContext block = ctx.operationResponseStatusBlock();
if (block.descriptionStatement() != null) {
setNodeDescription(status, block.descriptionStatement(), false);
@@ -475,7 +456,7 @@ public MTResponseStatus visitOperationResponseStatus(EntityLanguageParser.Operat
@Override
public MTResponseBody visitOperationResponseBody(EntityLanguageParser.OperationResponseBodyContext ctx) {
- MTResponseBody body = new MTResponseBody(ctx);
+ MTResponseBody body = new MTResponseBody(ctx);
EntityLanguageParser.OperationResponseBodyBlockContext block = ctx.operationResponseBodyBlock();
if (block.operationBodyContentType() != null && block.operationBodyContentType().size() > 0) {
body.setContentType(ECStringUtil.ProcessParserString(block.operationBodyContentType(0).STRING().getText()));
@@ -492,17 +473,17 @@ public MTResponseBody visitOperationResponseBody(EntityLanguageParser.OperationR
@Override
public MTRequestEndpointParam visitOperationRequestEndpointParam(EntityLanguageParser.OperationRequestEndpointParamContext ctx) {
- String paramName = ctx.id().getText();
- boolean query = ctx.QUERY() != null;
- String typeName = ctx.type().getText();
- MTNativeType.DataType dataType = MTNativeType.DataType.FromName(typeName);
+ String paramName = ctx.id().getText();
+ boolean query = ctx.QUERY() != null;
+ String typeName = ctx.type().getText();
+ MTNativeType.DataType dataType = MTNativeType.DataType.FromName(typeName);
if (dataType == null) {
ECLog.logWarning(ctx.type(), "Operation parameters must be of a native type. Using int32.");
dataType = MTNativeType.DataType.INT32;
}
MTRequestEndpointParam param = new MTRequestEndpointParam(ctx, query, new MTNativeType(ctx.type(), dataType),
- paramName);
+ paramName);
if (ctx.operationRequestEndpointParamBlock() != null
&& ctx.operationRequestEndpointParamBlock().descriptionStatement() != null) {
@@ -520,21 +501,23 @@ public MTExpression visitExpression(EntityLanguageParser.ExpressionContext ctx)
// Binary operator
String opSymbol = ctx.bop.getText();
if (MTOperation.Operator.isValidOperator(opSymbol)) {
- MTOperation.Operator operator = MTOperation.Operator.getOperatorBySymbol(opSymbol);
- List operandExpressions = new ArrayList<>(3);
+ MTOperation.Operator operator = MTOperation.Operator.getOperatorBySymbol(opSymbol);
+ List operandExpressions = new ArrayList<>(3);
if (ctx.ID() != null) {
MTOperand operand = new MTOperand(ctx, MTOperand.Type.UNKNOWN, ctx.ID().getText());
if (operand != null) {
operandExpressions.add(operand);
}
//ECLog.logInfo(">>>> With Operator: " + opSymbol + " and ID: " + ctx.ID().getText());
- } else if (ctx.methodCall() != null) {
+ }
+ else if (ctx.methodCall() != null) {
MTExpression methodCall = visitMethodCall(ctx.methodCall());
if (methodCall != null) {
operandExpressions.add(methodCall);
}
//ECLog.logInfo(">>>> With Operator: " + opSymbol + " and method call: " + ctx.methodCall().getText());
- } else {
+ }
+ else {
//ECLog.logInfo(">>>> With Operator: " + opSymbol);
}
@@ -546,7 +529,8 @@ public MTExpression visitExpression(EntityLanguageParser.ExpressionContext ctx)
MTExpression operandExpression = visitExpression(expressionContext);
if (operandExpression != null) {
operandExpressions.add(operandExpression);
- } else {
+ }
+ else {
ECLog.logFatal(expressionContext, "Unable to parse: " + expressionContext.getText());
}
}
@@ -556,17 +540,21 @@ public MTExpression visitExpression(EntityLanguageParser.ExpressionContext ctx)
expression = new MTOperation(ctx, operator, operandExpressions);
}
- } else if (ctx.methodCall() != null) {
+ }
+ else if (ctx.methodCall() != null) {
// Method call
expression = visitMethodCall(ctx.methodCall());
- } else if (ctx.primary() != null) {
+ }
+ else if (ctx.primary() != null) {
// Constant or a variable
EntityLanguageParser.ConstantContext constantContext = ctx.primary().constant();
if (constantContext != null) {
expression = visitConstant(ctx.primary().constant());
- } else if (ctx.primary().expression() != null) {
+ }
+ else if (ctx.primary().expression() != null) {
expression = visitExpression(ctx.primary().expression());
- } else if (ctx.primary().ident() != null) {
+ }
+ else if (ctx.primary().ident() != null) {
// could be either an entity attribute name or a config of an interface
if (currentDomainEntityInterfaceOperation != null
@@ -578,27 +566,30 @@ public MTExpression visitExpression(EntityLanguageParser.ExpressionContext ctx)
return expression;
}
}
- } else {
+ }
+ else {
//ECLog.logInfo(ctx.primary(), "No domain operation context here: " + ctx.primary().ID().getText());
}
// variable to an attribute name or other variable in the model
if (currentDomainEntity == null) {
expression = new MTOperand(ctx.primary(), MTOperand.Type.ATTRIBUTE, currentEntity.getName(),
- ctx.primary().ident().getText());
+ ctx.primary().ident().getText());
//ECLog.logFatal(ctx.primary(), "Attribute references can only be made in the context of an entity.");
- } else {
+ }
+ else {
expression = new MTOperand(ctx.primary(), MTOperand.Type.ATTRIBUTE,
- currentDomainEntity.getEntityName(), ctx.primary().ident().getText());
+ currentDomainEntity.getEntityName(), ctx.primary().ident().getText());
}
}
- } else if (ctx.prefix != null) {
+ }
+ else if (ctx.prefix != null) {
String opSymbol = ctx.prefix.getText();
if (MTOperation.Operator.isValidOperator(opSymbol)) {
if (ctx.expression().size() < 1) {
ECLog.logFatal(ctx, "Unsupported expression: " + ctx.getText());
}
MTOperation.Operator operator = MTOperation.Operator.getOperatorBySymbol(opSymbol);
- List operands = new ArrayList<>();
+ List operands = new ArrayList<>();
operands.add(visitExpression(ctx.expression().get(0)));
expression = new MTOperation(ctx, operator, operands);
}
@@ -614,14 +605,18 @@ public MTConstant visitConstant(EntityLanguageParser.ConstantContext ctx) {
MTConstant expression = null;
if (ctx.STRING() != null) {
expression = new MTConstant(ctx, ctx.STRING().getText());
- } else if (ctx.INTEGER() != null) {
+ }
+ else if (ctx.INTEGER() != null) {
expression = new MTConstant(ctx, Long.valueOf(ctx.INTEGER().getText()));
- } else if (ctx.FLOAT() != null) {
+ }
+ else if (ctx.FLOAT() != null) {
expression = new MTConstant(ctx, Double.valueOf(ctx.FLOAT().getText()));
- } else if (ctx.BOOLEAN != null) {
+ }
+ else if (ctx.BOOLEAN != null) {
boolean value = ctx.BOOLEAN.getText().equals("true");
expression = new MTConstant(ctx, value);
- } else {
+ }
+ else {
ECLog.logFatal(ctx, "Unknown constant: " + ctx.getText());
}
return expression;
@@ -638,7 +633,8 @@ public MTMethodCall visitMethodCall(EntityLanguageParser.MethodCallContext ctx)
MTExpression operandExpression = visitExpression(expressionContext);
if (operandExpression != null) {
methodCall.addArgument(operandExpression);
- } else {
+ }
+ else {
ECLog.logFatal(expressionContext, "Unable to parse: " + expressionContext.getText());
}
}
@@ -656,7 +652,8 @@ public String visitDefineVariableString(EntityLanguageParser.DefineVariableStrin
ECLog.logFatal("Command line define variable \"" + ctx.id().getText() + "\" not set.");
}
path = idPath;
- } else {
+ }
+ else {
path = ECStringUtil.ProcessParserString(ctx.STRING().getText());
}
return path;
@@ -664,13 +661,13 @@ public String visitDefineVariableString(EntityLanguageParser.DefineVariableStrin
@Override
public Object visitRepository(EntityLanguageParser.RepositoryContext ctx) {
- MTRepository repository = new MTRepository(ctx, ctx.id().getText());
+ MTRepository repository = new MTRepository(ctx, ctx.id().getText());
EntityLanguageParser.RepositoryBodyContext repositoryBodyContext = ctx.repositoryBody();
List repositoryOrganizationContexts = repositoryBodyContext.repositoryOrganization();
if (repositoryOrganizationContexts != null && repositoryOrganizationContexts.size() > 0) {
repository.setOrganization(
- ECStringUtil.ProcessParserString(repositoryOrganizationContexts.get(0).STRING().getText()));
+ ECStringUtil.ProcessParserString(repositoryOrganizationContexts.get(0).STRING().getText()));
}
List repositoryNameContexts = repositoryBodyContext.repositoryName();
@@ -696,7 +693,7 @@ public Object visitRepository(EntityLanguageParser.RepositoryContext ctx) {
MTRepositoryType type = MTRepositoryType.FromName(repositoryTypeContexts.get(0).id().getText());
if (type == null) {
ECLog.logFatal(repositoryTypeContexts.get(0),
- "Unknown repository type: " + repositoryTypeContexts.get(0).id().getText());
+ "Unknown repository type: " + repositoryTypeContexts.get(0).id().getText());
}
repository.setType(type);
}
@@ -710,8 +707,8 @@ public Object visitRepository(EntityLanguageParser.RepositoryContext ctx) {
public MTSpace currentSpace() {
return hasCurrentSpace() ?
- spaceStack.peek() :
- null;
+ spaceStack.peek() :
+ null;
}
private boolean hasCurrentSpace() {
@@ -737,10 +734,11 @@ public MTSpace visitSpace(EntityLanguageParser.SpaceContext ctx) {
int numNamespaces = body.spaceNamespace().size();
if (numNamespaces > 1) {
ECLog.logError(body, "Only one namespace declaration is allowed.");
- } else if (numNamespaces == 1) {
+ }
+ else if (numNamespaces == 1) {
EntityLanguageParser.SpaceNamespaceContext ns = body.spaceNamespace(0);
space.setNamespace(
- new MTNamespace(ns, segmentsForPathID(ns.namespaceIdent().id()).toArray(new String[0]), false));
+ new MTNamespace(ns, segmentsForPathID(ns.namespaceIdent().id()).toArray(new String[0]), false));
}
// List importContexts = body.spaceImport();
@@ -789,9 +787,11 @@ public MTProtoc visitProtoc(EntityLanguageParser.ProtocContext ctx) {
for (EntityLanguageParser.OutputSpecContext outputSpecContext : ctx.protocBody().outputSpec()) {
if (outputSpecContext.id().size() == 1) {
protoc.setSourceOutputName(outputSpecContext.id(0).getText());
- } else if (outputSpecContext.id(0).getText().equals("source")) {
+ }
+ else if (outputSpecContext.id(0).getText().equals("source")) {
protoc.setSourceOutputName(outputSpecContext.id(1).getText());
- } else if (outputSpecContext.id(0).getText().equals("header")) {
+ }
+ else if (outputSpecContext.id(0).getText().equals("header")) {
protoc.setHeaderOutputName(outputSpecContext.id(1).getText());
}
}
@@ -813,9 +813,9 @@ public MTProtoc visitProtoc(EntityLanguageParser.ProtocContext ctx) {
public MTSpaceImport visitSpaceImport(EntityLanguageParser.SpaceImportContext ctx) {
MTSpaceImport modelImport = new MTSpaceImport();
for (EntityLanguageParser.IdContext idContext : ctx.idList().id()) {
- MTRepositoryImport repoImport = new MTRepositoryImport(ctx, false);
- String filename = idContext.getText();
- String repositoryName = idText(ctx.id());
+ MTRepositoryImport repoImport = new MTRepositoryImport(ctx, false);
+ String filename = idContext.getText();
+ String repositoryName = idText(ctx.id());
repoImport.setFilename(filename);
repoImport.setRepositoryName(repositoryName);
modelImport.addImport(repoImport);
@@ -829,9 +829,9 @@ public MTSpaceInclude visitSpaceInclude(EntityLanguageParser.SpaceIncludeContext
MTSpaceInclude spaceInclude = new MTSpaceInclude();
for (EntityLanguageParser.IdContext idContext : ctx.idList().id()) {
- MTRepositoryImport modelImport = new MTRepositoryImport(ctx, true);
- String filename = idContext.getText();
- String repositoryName = idText(ctx.id());
+ MTRepositoryImport modelImport = new MTRepositoryImport(ctx, true);
+ String filename = idContext.getText();
+ String repositoryName = idText(ctx.id());
modelImport.setFilename(filename);
modelImport.setRepositoryName(repositoryName);
spaceInclude.addImport(modelImport);
@@ -858,8 +858,8 @@ public MTSpaceInclude visitSpaceInclude(EntityLanguageParser.SpaceIncludeContext
@Override
public MTModule visitModule(EntityLanguageParser.ModuleContext ctx) {
- String moduleName = ctx.id().getText();
- MTModule module = currentSpace().getModuleWithName(moduleName);
+ String moduleName = ctx.id().getText();
+ MTModule module = currentSpace().getModuleWithName(moduleName);
if (module == null) {
module = new MTModule(ctx, currentSpace(), moduleName);
}
@@ -872,13 +872,13 @@ public MTModule visitModule(EntityLanguageParser.ModuleContext ctx) {
}
private void setNodeDescription
- (MTNode node,
- List statementContexts,
- boolean append) {
- StringBuilder mainBuilder = new StringBuilder();
- StringBuilder summaryBuilder = new StringBuilder();
- StringBuilder detailBuilder = new StringBuilder();
- Map builderMap = new HashMap<>();
+ (MTNode node,
+ List statementContexts,
+ boolean append) {
+ StringBuilder mainBuilder = new StringBuilder();
+ StringBuilder summaryBuilder = new StringBuilder();
+ StringBuilder detailBuilder = new StringBuilder();
+ Map builderMap = new HashMap<>();
builderMap.put("main", mainBuilder);
builderMap.put("summary", summaryBuilder);
builderMap.put("detail", detailBuilder);
@@ -886,14 +886,15 @@ public MTModule visitModule(EntityLanguageParser.ModuleContext ctx) {
List types = new ArrayList<>();
if (statementContext.id().size() == 0) {
types.add("main"); // default when none specified
- } else {
+ }
+ else {
types =
- statementContext.id().stream()
- .map(EntityLanguageParser.IdContext::getText)
- .collect(Collectors.toList());
+ statementContext.id().stream()
+ .map(EntityLanguageParser.IdContext::getText)
+ .collect(Collectors.toList());
}
String lineWithQuotes = statementContext.STRING().getSymbol().getText();
- String line = ECStringUtil.ProcessParserString(lineWithQuotes).trim();
+ String line = ECStringUtil.ProcessParserString(lineWithQuotes).trim();
if (line.equals("")) {
line = "\n\n";
@@ -903,8 +904,8 @@ public MTModule visitModule(EntityLanguageParser.ModuleContext ctx) {
if (!builderMap.containsKey(type)) {
ECLog.logFatal("Description type of \"" + type + "\" not supported.");
}
- StringBuilder builder = builderMap.get(type);
- int builderLength = builder.length();
+ StringBuilder builder = builderMap.get(type);
+ int builderLength = builder.length();
if (builderLength > 0) {
char lastChar = builder.charAt(builderLength - 1);
if (lastChar != '\n' && line.charAt(0) != '\n') {
@@ -919,7 +920,8 @@ public MTModule visitModule(EntityLanguageParser.ModuleContext ctx) {
mainString = mainString.replace("\\\"", "\"");
if (append) {
node.appendDescription(mainString);
- } else {
+ }
+ else {
node.setDescription(mainString);
}
}
@@ -928,7 +930,8 @@ public MTModule visitModule(EntityLanguageParser.ModuleContext ctx) {
summaryString = summaryString.replace("\\\"", "\"");
if (append) {
node.appendSummary(summaryString);
- } else {
+ }
+ else {
node.setSummary(summaryString);
}
}
@@ -937,7 +940,8 @@ public MTModule visitModule(EntityLanguageParser.ModuleContext ctx) {
detailString = detailString.replace("\\\"", "\"");
if (append) {
node.appendDetail(detailString);
- } else {
+ }
+ else {
node.setDetail(detailString);
}
}
@@ -960,8 +964,8 @@ private List> tagStringsFromTagStatements(List templateArgs = new ArrayList<>();
- String entityName = null;
+ List templateArgs = new ArrayList<>();
+ String entityName = null;
EntityLanguageParser.EntityTemplateDeclContext templateDeclContext = ctx.entityDecl().entityTemplateDecl();
currentDomainEntity = null;
@@ -971,8 +975,9 @@ public MTEntity visitEntity(EntityLanguageParser.EntityContext ctx) {
templateArgs.add(templateDeclContext.id(i).getText());
}
currentEntity = new MTEntityTemplate(ctx, currentModule, entityName, templateArgs);
- } else {
- entityName = ctx.entityDecl().entityName().id().getText();
+ }
+ else {
+ entityName = ctx.entityDecl().entityName().id().getText();
currentEntity = new MTEntity(ctx, currentModule, entityName);
}
@@ -981,7 +986,8 @@ public MTEntity visitEntity(EntityLanguageParser.EntityContext ctx) {
if (ctx.entityDecl().PRIMARY() != null) {
currentEntity.setDeclaredAsPrimary(true);
- } else if (ctx.entityDecl().SECONDARY() != null) {
+ }
+ else if (ctx.entityDecl().SECONDARY() != null) {
currentEntity.setDeclaredAsSecondary(true);
}
@@ -1011,17 +1017,18 @@ public MTEntity visitEntity(EntityLanguageParser.EntityContext ctx) {
if (primaryKeyAttributes.size() > 0) {
if (currentEntity.isDeclaredAsSecondary()) {
ECLog.logError(ctx.entityDecl().entityName().id(),
- "A secondary entity \"" + currentEntity.getName() + "\" cannot declare a primary key!");
+ "A secondary entity \"" + currentEntity.getName() + "\" cannot declare a primary key!");
}
MTPrimaryKey primaryKey = new MTPrimaryKey(ctx);
for (MTAttribute attribute : primaryKeyAttributes) {
primaryKey.addAttribute(attribute);
}
currentEntity.setPrimaryKey(primaryKey);
- } else {
+ }
+ else {
if (currentEntity.isDeclaredAsPrimary() && !currentEntity.isTransient()) {
ECLog.logError(ctx.entityDecl().entityName().id(),
- "A primary entity \"" + currentEntity.getName() + "\" must declare a primary key!");
+ "A primary entity \"" + currentEntity.getName() + "\" must declare a primary key!");
}
}
@@ -1068,8 +1075,8 @@ public MTEntity visitEntity(EntityLanguageParser.EntityContext ctx) {
@Override
public MTEnum visitEnumStatement(EntityLanguageParser.EnumStatementContext ctx) {
- String enumName = ctx.id().getText();
- boolean extern = ctx.EXTERN() != null;
+ String enumName = ctx.id().getText();
+ boolean extern = ctx.EXTERN() != null;
if (extern) {
MTEnum existingEnum = currentSpace().getEnumWithName(enumName);
if (existingEnum != null) {
@@ -1083,8 +1090,8 @@ public MTEnum visitEnumStatement(EntityLanguageParser.EnumStatementContext ctx)
}
mtEnum.addTagsWithValues(tagStringsFromTagStatements(ctx.tagStatement()));
for (EntityLanguageParser.EnumItemContext ic : ctx.enumItem()) {
- String itemName = ic.id().getText();
- Integer itemNumber = Integer.valueOf(ic.INTEGER().getSymbol().getText());
+ String itemName = ic.id().getText();
+ Integer itemNumber = Integer.valueOf(ic.INTEGER().getSymbol().getText());
MTEnumItem mtEnumItem = mtEnum.addItem(ic, itemName, itemNumber);
if (ic.enumItemBody() != null && ic.enumItemBody().tagStatement() != null) {
mtEnumItem.addTagsWithValues(tagStringsFromTagStatements(ic.enumItemBody().tagStatement()));
@@ -1107,10 +1114,10 @@ public MTEnum visitEnumStatement(EntityLanguageParser.EnumStatementContext ctx)
@Override
public MTDView visitView(EntityLanguageParser.ViewContext ctx) {
- String currentEntityName = currentDomainEntity != null ?
- currentDomainEntity.getEntityName() :
- null;
- MTDView domainView = new MTDView(ctx, currentDomain, currentEntityName, ctx.id().getText());
+ String currentEntityName = currentDomainEntity != null ?
+ currentDomainEntity.getEntityName() :
+ null;
+ MTDView domainView = new MTDView(ctx, currentDomain, currentEntityName, ctx.id().getText());
// , ctx.DEFAULT() != null
if (ctx.viewBlock() != null) {
EntityLanguageParser.ViewBlockContext viewBlockContext = ctx.viewBlock();
@@ -1123,7 +1130,7 @@ public MTDView visitView(EntityLanguageParser.ViewContext ctx) {
if (viewBlockContext.viewAttributes() != null && viewBlockContext.viewAttributes().size() > 0) {
if (viewBlockContext.viewAttributes().size() > 1) {
ECLog.logFatal(viewBlockContext.viewAttributes(1),
- "Only specify one attributes section of a view.");
+ "Only specify one attributes section of a view.");
}
// INCLUDE
EntityLanguageParser.ViewAttributesContext attributesContext = viewBlockContext.viewAttributes(0);
@@ -1134,21 +1141,27 @@ public MTDView visitView(EntityLanguageParser.ViewContext ctx) {
for (MTTagSet tagSet : visitViewTaggedList(vaiContext.viewTaggedList())) {
if (secondaryEntities) {
domainView.addIncludedAttributeSecondaryEntityTagSet(tagSet);
- } else {
+ }
+ else {
domainView.addIncludedAttributeTagSet(tagSet);
}
}
- } else if (vaiContext.ARRAY() != null) {
+ }
+ else if (vaiContext.ARRAY() != null) {
domainView.setIncludedArrayAttributes(true);
- } else if (vaiContext.CREATION() != null) {
+ }
+ else if (vaiContext.CREATION() != null) {
domainView.setIncludedCreationAttributes(true);
- } else if (vaiContext.MODIFICATION() != null) {
+ }
+ else if (vaiContext.MODIFICATION() != null) {
domainView.setIncludedModificationAttributes(true);
- } else if (vaiContext.viewIdentifierList() != null && !vaiContext.viewIdentifierList().isEmpty()) {
+ }
+ else if (vaiContext.viewIdentifierList() != null && !vaiContext.viewIdentifierList().isEmpty()) {
for (EntityLanguageParser.IdContext attrName : vaiContext.viewIdentifierList().id()) {
domainView.addIncludedAttributeName(attrName.getText());
}
- } else {
+ }
+ else {
domainView.setIncludedAllAttributes(true);
}
}
@@ -1160,21 +1173,27 @@ public MTDView visitView(EntityLanguageParser.ViewContext ctx) {
for (MTTagSet tagSet : visitViewTaggedList(vaeContext.viewTaggedList())) {
if (secondaryEntities) {
domainView.addExcludedAttributeSecondaryEntityTagSet(tagSet);
- } else {
+ }
+ else {
domainView.addExcludedAttributeTagSet(tagSet);
}
}
- } else if (vaeContext.ARRAY() != null) {
+ }
+ else if (vaeContext.ARRAY() != null) {
domainView.setExcludedArrayAttributes(true);
- } else if (vaeContext.CREATION() != null) {
+ }
+ else if (vaeContext.CREATION() != null) {
domainView.setExcludedCreationAttributes(true);
- } else if (vaeContext.MODIFICATION() != null) {
+ }
+ else if (vaeContext.MODIFICATION() != null) {
domainView.setExcludedModificationAttributes(true);
- } else if (vaeContext.viewIdentifierList() != null && !vaeContext.viewIdentifierList().isEmpty()) {
+ }
+ else if (vaeContext.viewIdentifierList() != null && !vaeContext.viewIdentifierList().isEmpty()) {
for (EntityLanguageParser.IdContext attrName : vaeContext.viewIdentifierList().id()) {
domainView.addExcludedAttributeName(attrName.getText());
}
- } else {
+ }
+ else {
domainView.setExcludedAllAttributes(true);
}
}
@@ -1183,50 +1202,55 @@ public MTDView visitView(EntityLanguageParser.ViewContext ctx) {
if (viewBlockContext.viewRelationships() != null && viewBlockContext.viewRelationships().size() > 0) {
if (viewBlockContext.viewRelationships().size() > 1) {
ECLog.logFatal(viewBlockContext.viewRelationships(1),
- "Only specify one relationships section of a view.");
+ "Only specify one relationships section of a view.");
}
// INCLUDE
EntityLanguageParser.ViewRelationshipsContext relationshipsContext = viewBlockContext.viewRelationships(
- 0);
+ 0);
for (EntityLanguageParser.ViewRelationshipIncludeContext vriContext : relationshipsContext.viewRelationshipsBlock().viewRelationshipInclude()) {
- boolean hasAs = vriContext.AS() != null;
- boolean hasWithView = vriContext.WITH() != null && vriContext.VIEW() != null;
- boolean entityRef = vriContext.ENTITY() != null;
- int usedIdCount = (hasAs ?
- 1 :
- 0) + (hasWithView ?
- 1 :
- 0);
+ boolean hasAs = vriContext.AS() != null;
+ boolean hasWithView = vriContext.WITH() != null && vriContext.VIEW() != null;
+ boolean entityRef = vriContext.ENTITY() != null;
+ int usedIdCount = (hasAs ?
+ 1 :
+ 0) + (hasWithView ?
+ 1 :
+ 0);
boolean hasEntityOrRelationshipId = vriContext.id().size() > usedIdCount;
- int viewIdIndex = hasEntityOrRelationshipId ?
- 1 :
- 0;
- String relationshipOrEntityName = hasEntityOrRelationshipId ?
- vriContext.id(0).getText() :
- null;
+ int viewIdIndex = hasEntityOrRelationshipId ?
+ 1 :
+ 0;
+ String relationshipOrEntityName = hasEntityOrRelationshipId ?
+ vriContext.id(0).getText() :
+ null;
if (vriContext.TAGGED() != null) {
for (MTTagSet tagSet : visitViewTaggedList(vriContext.viewTaggedList())) {
domainView.addIncludedRelationshipTagSet(tagSet);
}
- } else if (!hasEntityOrRelationshipId) {
+ }
+ else if (!hasEntityOrRelationshipId) {
if (vriContext.PARENT() != null) {
domainView.setIncludedParentRelationships(true);
- } else if (vriContext.TOONE() != null) {
+ }
+ else if (vriContext.TOONE() != null) {
domainView.setIncludedOneRelationships(true);
- } else if (vriContext.TOMANY() != null) {
+ }
+ else if (vriContext.TOMANY() != null) {
domainView.setIncludedManyRelationships(true);
}
- } else {
+ }
+ else {
if (entityRef) {
domainView.addIncludedRelationshipEntityName(relationshipOrEntityName);
if (vriContext.AS() != null) {
domainView.renameRelationshipOfEntityName(relationshipOrEntityName,
- vriContext.id(1).getText());
+ vriContext.id(1).getText());
viewIdIndex++;
}
- } else {
+ }
+ else {
domainView.addIncludedRelationshipName(relationshipOrEntityName);
if (vriContext.AS() != null) {
domainView.renameRelationship(relationshipOrEntityName, vriContext.id(1).getText());
@@ -1239,17 +1263,22 @@ public MTDView visitView(EntityLanguageParser.ViewContext ctx) {
String viewName = vriContext.id(viewIdIndex).getText();
if (relationshipOrEntityName == null) {
domainView.setRelationshipWithViewName(viewName);
- } else if (entityRef) {
+ }
+ else if (entityRef) {
domainView.setViewNameForRelationshipEntityName(relationshipOrEntityName, viewName);
- } else {
+ }
+ else {
domainView.setViewNameForRelationshipName(relationshipOrEntityName, viewName);
}
- } else if (vriContext.PRIMARYKEY() != null) {
+ }
+ else if (vriContext.PRIMARYKEY() != null) {
if (relationshipOrEntityName == null) {
domainView.setRelationshipWithPrimaryKey(true);
- } else if (entityRef) {
+ }
+ else if (entityRef) {
domainView.setPrimaryKeyForRelationshipEntityName(relationshipOrEntityName);
- } else {
+ }
+ else {
domainView.setPrimaryKeyForRelationshipName(relationshipOrEntityName);
}
}
@@ -1262,27 +1291,34 @@ public MTDView visitView(EntityLanguageParser.ViewContext ctx) {
for (MTTagSet tagSet : visitViewTaggedList(vreContext.viewTaggedList())) {
domainView.addExcludedRelationshipTagSet(tagSet);
}
- } else if (!hasEntityOrRelationshipId) {
+ }
+ else if (!hasEntityOrRelationshipId) {
if (vreContext.PARENT() != null) {
domainView.setExcludedParentRelationships(true);
- } else if (vreContext.TOONE() != null) {
+ }
+ else if (vreContext.TOONE() != null) {
domainView.setExcludedOneRelationships(true);
- } else if (vreContext.TOMANY() != null) {
+ }
+ else if (vreContext.TOMANY() != null) {
domainView.setExcludedManyRelationships(true);
- } else {
+ }
+ else {
domainView.setExcludedAllRelationships(true);
}
- } else if (vreContext.TOONE() != null || vreContext.TOMANY() != null
- || vreContext.PARENT() != null) {
+ }
+ else if (vreContext.TOONE() != null || vreContext.TOMANY() != null
+ || vreContext.PARENT() != null) {
boolean entityRef = vreContext.ENTITY() != null;
String relationshipOrEntityName = vreContext.id().getText();
if (entityRef) {
domainView.addExcludedRelationshipEntityName(relationshipOrEntityName);
- } else {
+ }
+ else {
domainView.addExcludedRelationshipName(relationshipOrEntityName);
}
- } else {
+ }
+ else {
domainView.setExcludedAllRelationships(true);
}
}
@@ -1309,19 +1345,32 @@ public MTTagSet visitViewTaggedListItem(EntityLanguageParser.ViewTaggedListItemC
return tagSet;
}
+ @Override
+ public Object visitRelationshipsBody(EntityLanguageParser.RelationshipsBodyContext ctx) {
+ if (ctx.tagStatement() != null) {
+ inheritedTags = tagStringsFromTagStatements(ctx.tagStatement());
+ }
+
+ Object object = super.visitRelationshipsBody(ctx);
+
+ inheritedTags = null;
+
+ return object;
+ }
+
@Override
public MTRelationship visitRelationshipStatement(EntityLanguageParser.RelationshipStatementContext ctx) {
HalfRelationshipPlurality toPlurality = HalfRelationshipPlurality.ONE;
if (ctx.MANY() != null) {
toPlurality = HalfRelationshipPlurality.MANY;
}
- String fromEntityName = currentEntity.getName();
- String toEntityName = null;
- String relationshipName = null;
- MTEntityTemplateInstantiation instantiation = null;
+ String fromEntityName = currentEntity.getName();
+ String toEntityName = null;
+ String relationshipName = null;
+ MTEntityTemplateInstantiation instantiation = null;
if (ctx.relationshipTemplateAs() != null) {
instantiation = new MTEntityTemplateInstantiation(ctx.relationshipTemplateAs(),
- ctx.relationshipTemplateAs().id().getText());
+ ctx.relationshipTemplateAs().id().getText());
for (EntityLanguageParser.RelationshipTemplateArgContext argContext : ctx.relationshipTemplateAs().relationshipTemplateArg()) {
instantiation.addTemplateArgEntityName(argContext.id().getText(), argContext.UNIQUE() != null);
}
@@ -1329,13 +1378,14 @@ public MTRelationship visitRelationshipStatement(EntityLanguageParser.Relationsh
toEntityName = ctx.id(0).getText();
if (ctx.id().size() == 1) {
relationshipName = ECStringUtil.Uncapitalize(toEntityName);
- } else {
+ }
+ else {
relationshipName = ctx.id(1).getText();
}
- boolean optional = ctx.OPTIONAL() != null;
- boolean parent = ctx.PARENT() != null;
- String reverseName = null;
+ boolean optional = ctx.OPTIONAL() != null;
+ boolean parent = ctx.PARENT() != null;
+ String reverseName = null;
if (ctx.relationshipReverseName() != null && ctx.relationshipReverseName().id() != null) {
reverseName = ctx.relationshipReverseName().id().getText();
@@ -1347,9 +1397,12 @@ public MTRelationship visitRelationshipStatement(EntityLanguageParser.Relationsh
}
MTRelationship relationship = new MTRelationship(ctx, relationshipName, fromEntityName, toPlurality,
- toEntityName, optional, parent, reverseName, toEntityIdName,
- null);
+ toEntityName, optional, parent, reverseName, toEntityIdName,
+ null);
+ if (inheritedTags != null) {
+ relationship.addTagsWithValues(inheritedTags);
+ }
if (instantiation != null) {
relationship.getTo().setTemplateInstantiation(instantiation);
}
@@ -1364,21 +1417,21 @@ public MTRelationship visitRelationshipStatement(EntityLanguageParser.Relationsh
@Override
public MTAttributeConstraint visitAttributeConstraint(EntityLanguageParser.AttributeConstraintContext ctx) {
- String constraintName = ctx.id().getText();
- EntityLanguageParser.AttributeConstraintBodyContext block = ctx.attributeConstraintBody();
+ String constraintName = ctx.id().getText();
+ EntityLanguageParser.AttributeConstraintBodyContext block = ctx.attributeConstraintBody();
if (block == null || block.expression().size() == 0) {
ECLog.logFatal("Attribute constraints must have an expression. Constraint " + currentEntity.getName() + "."
- + currentAttribute.getName() + "." + constraintName + " does not.");
+ + currentAttribute.getName() + "." + constraintName + " does not.");
}
if (ctx.attributeConstraintBody().expression().size() > 1) {
ECLog.logFatal(
- "Attribute constraints can only have one expression. Constraint " + currentEntity.getName() + "."
+ "Attribute constraints can only have one expression. Constraint " + currentEntity.getName() + "."
+ currentAttribute.getName() + "." + constraintName + " is specified with "
+ ctx.attributeConstraintBody().expression().size() + " expressions: "
+ ctx.attributeConstraintBody().expression().toString());
}
MTAttributeConstraint constraint = new MTAttributeConstraint(ctx, currentAttribute, constraintName,
- visitExpression(block.expression(0)));
+ visitExpression(block.expression(0)));
if (block.descriptionStatement() != null) {
setNodeDescription(constraint, block.descriptionStatement(), false);
@@ -1393,21 +1446,29 @@ public MTAttributeConstraint visitAttributeConstraint(EntityLanguageParser.Attri
@Override
public MTDomain visitDomain(EntityLanguageParser.DomainContext ctx) {
- String name = ctx.ID(0).getText();
- boolean extending = ctx.EXTENDS() != null;
- boolean specializing = !extending && (ctx.ID().size() > 1);
- String extendingDomainName = extending ?
- ctx.ID(1).getText() :
- null;
- String specializingName = specializing ?
- ctx.ID(1).getText() :
- null;
-
+ String name = ctx.ID(0).getText();
+ boolean extending = ctx.EXTENDS() != null;
+ boolean specializing = !extending && (ctx.ID().size() > 1);
+ String extendingDomainName = extending ?
+ ctx.ID(1).getText() :
+ null;
+ String specializingName = specializing ?
+ ctx.ID(1).getText() :
+ null;
+
+ if (currentRealm != null) {
+ ECLog.logInfo("Visiting domain: " + name + " in realm: " + currentRealm.getName());
+ if (!specializing) {
+ ECLog.logFatal("Only specialized domains can be defined in a realm. Domain: " + name + " realm: " + currentRealm.getName());
+ }
+ }
if (currentSpace().getDomainWithName(name) != null) {
currentDomain = currentSpace().getDomainWithName(name);
- } else {
+ }
+ else {
currentDomain = new MTDomain(ctx, currentSpace(), name, extendingDomainName);
}
+
if (specializingName != null) {
currentDomain.addSpecializedAsName(specializingName);
}
@@ -1457,11 +1518,12 @@ public MTDomain visitDomain(EntityLanguageParser.DomainContext ctx) {
int numNamespaces = block.domainNamespace().size();
if (numNamespaces > 1) {
ECLog.logError(block, "Only one namespace declaration is allowed.");
- } else if (numNamespaces == 1) {
+ }
+ else if (numNamespaces == 1) {
EntityLanguageParser.DomainNamespaceContext ns = block.domainNamespace(0);
currentDomain.setNamespace(
- new MTNamespace(ns, segmentsForPathID(ns.namespaceIdent().id()).toArray(new String[0]),
- ns.SPACE() != null));
+ new MTNamespace(ns, segmentsForPathID(ns.namespaceIdent().id()).toArray(new String[0]),
+ ns.SPACE() != null));
}
if (block.domainFlattenSecondaryEntities() != null
@@ -1489,9 +1551,9 @@ private List segmentsForPathID(List node
@Override
public MTDApplyTemplate visitDomainApplyTemplate(EntityLanguageParser.DomainApplyTemplateContext ctx) {
- MTDApplyTemplate applyTemplate = new MTDApplyTemplate(ctx, currentDomain,
- ctx.id().getText());
- EntityLanguageParser.DomainApplyTemplateBodyContext body = ctx.domainApplyTemplateBody();
+ MTDApplyTemplate applyTemplate = new MTDApplyTemplate(ctx, currentDomain,
+ ctx.id().getText());
+ EntityLanguageParser.DomainApplyTemplateBodyContext body = ctx.domainApplyTemplateBody();
if (body != null) {
if (body.descriptionStatement() != null) {
setNodeDescription(applyTemplate, body.descriptionStatement(), false);
@@ -1499,8 +1561,8 @@ public MTDApplyTemplate visitDomainApplyTemplate(EntityLanguageParser.DomainAppl
if (body.tagStatement() != null) {
applyTemplate.addTagsWithValues(tagStringsFromTagStatements(body.tagStatement()));
}
- if (body.templateConfig() != null && body.templateConfig().size() > 0) {
- EntityLanguageParser.TemplateConfigContext configContext = body.templateConfig().get(0);
+ if (body.transformConfig() != null && body.transformConfig().size() > 0) {
+ EntityLanguageParser.TransformConfigContext configContext = body.transformConfig().get(0);
applyTemplate.setConfig(visitJsonObj(configContext.jsonObj()));
}
}
@@ -1511,19 +1573,24 @@ public MTDApplyTemplate visitDomainApplyTemplate(EntityLanguageParser.DomainAppl
public JsonObject visitJsonObj(EntityLanguageParser.JsonObjContext ctx) {
JsonObjectBuilder builder = Json.createObjectBuilder();
for (EntityLanguageParser.JsonPairContext context : ctx.jsonPair()) {
- String name = ECStringUtil.ProcessParserString(context.STRING().getText());
+ String name = ECStringUtil.ProcessParserString(context.STRING().getText());
Object value = visitJsonValue(context.jsonValue());
if (value instanceof JsonArray) {
builder.add(name, (JsonArray) value);
- } else if (value instanceof JsonObject) {
+ }
+ else if (value instanceof JsonObject) {
builder.add(name, (JsonObject) value);
- } else if (value instanceof JsonValue) {
+ }
+ else if (value instanceof JsonValue) {
builder.add(name, (JsonValue) value);
- } else if (value instanceof Long) {
+ }
+ else if (value instanceof Long) {
builder.add(name, ((Long) value).longValue());
- } else if (value instanceof Double) {
+ }
+ else if (value instanceof Double) {
builder.add(name, ((Double) value).doubleValue());
- } else if (value instanceof String) {
+ }
+ else if (value instanceof String) {
builder.add(name, (String) value);
}
}
@@ -1534,19 +1601,26 @@ public JsonObject visitJsonObj(EntityLanguageParser.JsonObjContext ctx) {
public Object visitJsonValue(EntityLanguageParser.JsonValueContext ctx) {
if (ctx.jsonArr() != null) {
return visitJsonArr(ctx.jsonArr());
- } else if (ctx.jsonObj() != null) {
+ }
+ else if (ctx.jsonObj() != null) {
return visitJsonObj(ctx.jsonObj());
- } else if (ctx.STRING() != null) {
+ }
+ else if (ctx.STRING() != null) {
return ECStringUtil.ProcessParserString(ctx.STRING().getText());
- } else if (ctx.FLOAT() != null) {
+ }
+ else if (ctx.FLOAT() != null) {
return Double.valueOf(ctx.FLOAT().getText());
- } else if (ctx.INTEGER() != null) {
+ }
+ else if (ctx.INTEGER() != null) {
return Long.valueOf(ctx.INTEGER().getText());
- } else if (ctx.getText().equals("true")) {
+ }
+ else if (ctx.getText().equals("true")) {
return JsonValue.TRUE;
- } else if (ctx.getText().equals("false")) {
+ }
+ else if (ctx.getText().equals("false")) {
return JsonValue.FALSE;
- } else if (ctx.getText().equals("null")) {
+ }
+ else if (ctx.getText().equals("null")) {
return JsonValue.NULL;
}
ECLog.logFatal(ctx, "Specified Json value is not supported: " + ctx.getText());
@@ -1556,20 +1630,25 @@ public Object visitJsonValue(EntityLanguageParser.JsonValueContext ctx) {
@Override
public Object visitDomainTagging(EntityLanguageParser.DomainTaggingContext ctx) {
for (EntityLanguageParser.DomainTaggingTagContext taggingTagContext : ctx.domainTaggingTag()) {
- MTTagDef tagDef = visitDomainTaggingTag(taggingTagContext);
- String context = ctx.id().getText();
+ MTTagDef tagDef = visitDomainTaggingTag(taggingTagContext);
+ String context = ctx.id().getText();
MTTagContext tagContext = null;
if (context.equals("entity")) {
tagContext = MTTagContext.ENTITY;
- } else if (context.equals("attribute")) {
+ }
+ else if (context.equals("attribute")) {
tagContext = MTTagContext.ATTRIBUTE;
- } else if (context.equals("relationship")) {
+ }
+ else if (context.equals("relationship")) {
tagContext = MTTagContext.RELATIONSHIP;
- } else if (context.equals("domain")) {
+ }
+ else if (context.equals("domain")) {
tagContext = MTTagContext.DOMAIN;
- } else if (context.equals("enum")) {
+ }
+ else if (context.equals("enum")) {
tagContext = MTTagContext.ENUM;
- } else if (context.equals("enum_item")) {
+ }
+ else if (context.equals("enum_item")) {
tagContext = MTTagContext.ENUM_ITEM;
}
tagDef.setTagContext(tagContext);
@@ -1591,12 +1670,12 @@ public MTTagDef visitDomainTaggingTag(EntityLanguageParser.DomainTaggingTagConte
if (!ctx.domainTaggingTagValue().isEmpty()) {
if (ctx.domainTaggingTagValue().size() > 1) {
ECLog.logFatal(ctx.domainTaggingTagValue(1),
- "A tag definition can only have at most one value definition.");
+ "A tag definition can only have at most one value definition.");
}
EntityLanguageParser.DomainTaggingTagValueContext valueContext = ctx.domainTaggingTagValue(0);
- MTNativeType.DataType dataType = MTNativeType.DataType.FromName(
- valueContext.domainTaggingTagValueType().getText());
- MTTagValueDef tagValueDef = new MTTagValueDef(valueContext, dataType);
+ MTNativeType.DataType dataType = MTNativeType.DataType.FromName(
+ valueContext.domainTaggingTagValueType().getText());
+ MTTagValueDef tagValueDef = new MTTagValueDef(valueContext, dataType);
if (valueContext.descriptionStatement() != null) {
setNodeDescription(tagValueDef, valueContext.descriptionStatement(), false);
}
@@ -1611,11 +1690,11 @@ public MTTagDef visitDomainTaggingTag(EntityLanguageParser.DomainTaggingTagConte
@Override
public Object visitDomainNaming(EntityLanguageParser.DomainNamingContext ctx) {
- MTNamingMethod method = null;
- String prefix = null;
- String suffix = null;
- String primaryKeyName = null;
- Boolean withUnits = null;
+ MTNamingMethod method = null;
+ String prefix = null;
+ String suffix = null;
+ String primaryKeyName = null;
+ Boolean withUnits = null;
for (EntityLanguageParser.DomainNamingMethodContext methodContext : ctx.domainNamingBody().domainNamingMethod()) {
method = MTNamingMethod.fromName(methodContext.ID().getSymbol().getText());
@@ -1645,22 +1724,31 @@ public Object visitDomainNaming(EntityLanguageParser.DomainNamingContext ctx) {
for (EntityLanguageParser.NamingClassContext namingClassContext : ctx.namingClass()) {
if (namingClassContext.SPACE() != null) {
classesWithNaming.add(MTSpace.class);
- } else if (namingClassContext.MODULE() != null) {
+ }
+ else if (namingClassContext.MODULE() != null) {
classesWithNaming.add(MTModule.class);
- } else if (namingClassContext.ENTITY() != null) {
+ }
+ else if (namingClassContext.ENTITY() != null) {
+ classesWithNaming.add(MTCompositeEntity.class);
classesWithNaming.add(MTEntity.class);
classesWithNaming.add(MTView.class);
- } else if (namingClassContext.ATTRIBUTE() != null) {
+ }
+ else if (namingClassContext.ATTRIBUTE() != null) {
classesWithNaming.add(MTAttribute.class);
- } else if (namingClassContext.RELATIONSHIP() != null) {
+ }
+ else if (namingClassContext.RELATIONSHIP() != null) {
classesWithNaming.add(MTRelationship.class);
- } else if (namingClassContext.ENUM() != null) {
+ }
+ else if (namingClassContext.ENUM() != null) {
classesWithNaming.add(MTEnum.class);
- } else if (namingClassContext.ENUMITEM() != null) {
+ }
+ else if (namingClassContext.ENUMITEM() != null) {
classesWithNaming.add(MTEnumItem.class);
- } else if (namingClassContext.TYPEDEF() != null) {
+ }
+ else if (namingClassContext.TYPEDEF() != null) {
classesWithNaming.add(MTTypedef.class);
- } else {
+ }
+ else {
ECLog.logError("That naming class is not supported: " + namingClassContext.getText());
}
}
@@ -1703,7 +1791,7 @@ public MTDModule visitDomainModule(EntityLanguageParser.DomainModuleContext ctx)
ECLog.logFatal("Domain module can only have one applied template.");
}
MTDApplyTemplate applyTemplate = visitDomainModuleApplyTemplate(
- block.domainModuleApplyTemplate().get(0));
+ block.domainModuleApplyTemplate().get(0));
currentDomainModule.setApplyTemplate(applyTemplate);
}
}
@@ -1767,8 +1855,8 @@ public Object visitDomainEntity(EntityLanguageParser.DomainEntityContext ctx) {
public Object visitDomainEnum(EntityLanguageParser.DomainEnumContext ctx) {
MTNamingMethod method = null;
- String prefix = null;
- String suffix = null;
+ String prefix = null;
+ String suffix = null;
String currentDomainEnumName = ctx.ID().getText();
this.currentDomainEnum = new MTDEnum(ctx, this.currentDomain, currentDomainEnumName);
@@ -1787,19 +1875,20 @@ public Object visitDomainEnum(EntityLanguageParser.DomainEnumContext ctx) {
}
if (block.domainEnumItemRenameTo() != null) {
- for(EntityLanguageParser.DomainEnumItemRenameToContext renameToContext : block.domainEnumItemRenameTo()) {
+ for (EntityLanguageParser.DomainEnumItemRenameToContext renameToContext : block.domainEnumItemRenameTo()) {
MTDEnumItem domainEnumItem = currentDomainEnum.getDomainEnumItem(renameToContext.id(0).getText(), true);
domainEnumItem.setExplicitName(renameToContext.id(1).getText());
}
}
for (EntityLanguageParser.DomainEnumItemContext itemContext : block.domainEnumItem()) {
- String itemName = itemContext.ID().getText();
+ String itemName = itemContext.ID().getText();
MTDEnumItem mtdEnumItem = null;
if (currentDomainEnum.getEnum() != null) {
MTEnumItem enumItem = currentDomainEnum.getEnum().getItemByName(itemName);
mtdEnumItem = currentDomainEnum.getDomainEnumItem(enumItem, true);
- } else {
+ }
+ else {
mtdEnumItem = currentDomainEnum.getDomainEnumItem(itemName, true);
}
@@ -1858,7 +1947,7 @@ public MTDEInterface visitDomainInterfaceStatement(EntityLanguageParser.DomainIn
public MTDEInterfaceOperation visitDomainOperation(EntityLanguageParser.DomainOperationContext ctx) {
currentDomainEntityInterfaceOperation = new MTDEInterfaceOperation(ctx, currentDomainEntityInterface,
- ctx.id(0).getText(), ctx.id(1).getText());
+ ctx.id(0).getText(), ctx.id(1).getText());
if (ctx.EXTENDS() != null) {
EntityLanguageParser.ExtendingOperationBodyContext body = ctx.extendingOperationBody();
@@ -1868,14 +1957,14 @@ public MTDEInterfaceOperation visitDomainOperation(EntityLanguageParser.DomainOp
}
if (body.extendingOperationConfig() != null && body.extendingOperationConfig().size() > 0) {
currentDomainEntityInterfaceOperation.setExtendingOperationConfig(
- visitExtendingOperationConfig(body.extendingOperationConfig(0)));
+ visitExtendingOperationConfig(body.extendingOperationConfig(0)));
}
if (body.operationRequest() != null && body.operationRequest().size() > 0) {
currentDomainEntityInterfaceOperation.setRequest(visitOperationRequest(body.operationRequest(0)));
}
if (body.operationResponse() != null && body.operationResponse().size() > 0) {
currentDomainEntityInterfaceOperation.setResponse(
- visitOperationResponse(body.operationResponse(0)));
+ visitOperationResponse(body.operationResponse(0)));
}
visitExtendingOperationBody(body);
@@ -1888,12 +1977,12 @@ public MTDEInterfaceOperation visitDomainOperation(EntityLanguageParser.DomainOp
@Override
public MTDEInterfaceOperationConfig visitExtendingOperationConfig
- (EntityLanguageParser.ExtendingOperationConfigContext ctx) {
+ (EntityLanguageParser.ExtendingOperationConfigContext ctx) {
MTDEInterfaceOperationConfig extendingConfig = new MTDEInterfaceOperationConfig(ctx, ctx.id() != null ?
- ctx.id().getText() :
- null,
- currentDomainEntityInterface.getInterfaceName(),
- currentDomainEntityInterfaceOperation.getExtendedOperationName());
+ ctx.id().getText() :
+ null,
+ currentDomainEntityInterface.getInterfaceName(),
+ currentDomainEntityInterfaceOperation.getExtendedOperationName());
for (EntityLanguageParser.ExtendingOperationAssignmentContext assignmentContext : ctx.extendingOperationConfigBlock().extendingOperationAssignment()) {
extendingConfig.addConfigAssignment(assignmentContext.id(0).getText(), assignmentContext.id(1).getText());
}
@@ -1909,13 +1998,27 @@ public Object visitDomainVirtualAttribute(EntityLanguageParser.DomainVirtualAttr
return null;
}
+ @Override
+ public Object visitDomainAttributesBody(EntityLanguageParser.DomainAttributesBodyContext ctx) {
+ if (ctx.tagStatement() != null) {
+ inheritedTags = tagStringsFromTagStatements(ctx.tagStatement());
+ }
+ Object object = super.visitDomainAttributesBody(ctx);
+ inheritedTags = null;
+
+ return object;
+ }
+
@Override
public Object visitDomainAttribute(EntityLanguageParser.DomainAttributeContext ctx) {
String attributeName = ctx.id().getText();
if (currentDomainEntity != null) {
- MTDEAttribute domainEntityAttribute = currentDomainEntity.addDomainAttributeWithName(
- attributeName);
- EntityLanguageParser.DomainAttributeBodyContext bodyContext = ctx.domainAttributeBody();
+ MTDEAttribute domainEntityAttribute = currentDomainEntity.addDomainAttributeWithName(
+ attributeName);
+ if (inheritedTags != null) {
+ domainEntityAttribute.addTagsWithValues(inheritedTags);
+ }
+ EntityLanguageParser.DomainAttributeBodyContext bodyContext = ctx.domainAttributeBody();
if (bodyContext != null) {
if (bodyContext.descriptionStatement() != null) {
setNodeDescription(domainEntityAttribute, bodyContext.descriptionStatement(), false);
@@ -1928,34 +2031,67 @@ public Object visitDomainAttribute(EntityLanguageParser.DomainAttributeContext c
return null;
}
+ @Override
+ public Object visitDomainRelationshipsBody(EntityLanguageParser.DomainRelationshipsBodyContext ctx) {
+ if (ctx.tagStatement() != null) {
+ inheritedTags = tagStringsFromTagStatements(ctx.tagStatement());
+ }
+
+ Object object = super.visitDomainRelationshipsBody(ctx);
+
+ inheritedTags = null;
+
+ return object;
+ }
+
@Override
public Object visitDomainRelationship(EntityLanguageParser.DomainRelationshipContext ctx) {
String relationshipName = ctx.id().getText();
if (currentDomainEntity != null) {
- MTDERelationship domainEntityAttribute = currentDomainEntity.addDomainRelationshipWithName(
- relationshipName);
- EntityLanguageParser.DomainRelationshipBodyContext bodyContext = ctx.domainRelationshipBody();
+ MTDERelationship domainEntityRelationship = currentDomainEntity.addDomainRelationshipWithName(
+ relationshipName);
+ if (inheritedTags != null) {
+ domainEntityRelationship.addTagsWithValues(inheritedTags);
+ }
+ EntityLanguageParser.DomainRelationshipBodyContext bodyContext = ctx.domainRelationshipBody();
if (bodyContext != null) {
if (bodyContext.descriptionStatement() != null) {
- setNodeDescription(domainEntityAttribute, bodyContext.descriptionStatement(), false);
+ setNodeDescription(domainEntityRelationship, bodyContext.descriptionStatement(), false);
}
if (bodyContext.tagStatement() != null) {
- domainEntityAttribute.addTagsWithValues(tagStringsFromTagStatements(bodyContext.tagStatement()));
+ domainEntityRelationship.addTagsWithValues(tagStringsFromTagStatements(bodyContext.tagStatement()));
}
}
+ this.currentDomainRelationship = domainEntityRelationship;
}
- return null;
+ Object object = super.visitDomainRelationship(ctx);
+
+ this.currentDomainRelationship = null;
+
+ return object;
+ }
+
+ @Override
+ public Object visitDomainRelationshipAttribute(EntityLanguageParser.DomainRelationshipAttributeContext ctx) {
+ String attributeName = ctx.id().getText();
+
+ MTDERelationshipField relationshipField = new MTDERelationshipField(ctx, currentDomainRelationship, attributeName);
+ currentDomainRelationship.addField(relationshipField);
+ Object object = super.visitDomainRelationshipAttribute(ctx);
+
+ return object;
}
@Override
public Object visitDomainAttributesRenameTo(EntityLanguageParser.DomainAttributesRenameToContext ctx) {
- String attributeName = ctx.id(0).getText();
+ String attributeName = ctx.id(0).getText();
String renamedAttributeName = ctx.id(1).getText();
if (currentDomainEntity == null) {
currentDomain.setExplicitAttributeName(attributeName, renamedAttributeName);
- } else {
+ }
+ else {
currentDomainEntity.getDomainAttributeByName(attributeName, true).setExplicitAttributeName(
- renamedAttributeName);
+ renamedAttributeName);
}
return null;
}
@@ -1971,8 +2107,8 @@ public Object visitDomainAttributeExclude(EntityLanguageParser.DomainAttributeEx
@Override
public Object visitDomainAttributeAdd(EntityLanguageParser.DomainAttributeAddContext ctx) {
- String attributeName = ctx.attribute().id(0).getText();
- MTAttribute attribute = visitAttribute(ctx.attribute());
+ String attributeName = ctx.attribute().id(0).getText();
+ MTAttribute attribute = visitAttribute(ctx.attribute());
ECLog.logInfo(ctx, "Adding domain entity attribute: " + attribute.getName());
if (currentDomainEntity != null) {
currentDomainEntity.addAttribute(attribute);
@@ -1980,6 +2116,20 @@ public Object visitDomainAttributeAdd(EntityLanguageParser.DomainAttributeAddCon
return null;
}
+ @Override
+ public Object visitAttributesBody(EntityLanguageParser.AttributesBodyContext ctx) {
+
+ if (ctx.tagStatement() != null) {
+ inheritedTags = tagStringsFromTagStatements(ctx.tagStatement());
+ }
+
+ Object object = super.visitAttributesBody(ctx);
+
+ inheritedTags = null;
+
+ return object;
+ }
+
@Override
public MTAttribute visitAttribute(EntityLanguageParser.AttributeContext ctx) {
String attributeName = ctx.id(0).getText();
@@ -1992,7 +2142,8 @@ public MTAttribute visitAttribute(EntityLanguageParser.AttributeContext ctx) {
if (ctx.type() != null) {
if (ctx.type().BYTE_TYPE() != null) {
typeName = ctx.type().BYTE_TYPE().getText();
- } else {
+ }
+ else {
typeName = ctx.type().getText();
}
}
@@ -2010,24 +2161,25 @@ public MTAttribute visitAttribute(EntityLanguageParser.AttributeContext ctx) {
unitName = ctx.id(1).getText();
}
- MTEntity entity = currentDomainEntity != null ?
- currentDomainEntity.getEntity() :
- currentEntity;
+ MTEntity entity = currentDomainEntity != null ?
+ currentDomainEntity.getEntity() :
+ currentEntity;
MTAttribute attribute = new MTAttribute(ctx, entity, typeName, attributeName, unitName, arraySize);
this.currentAttribute = attribute;
- int indexOfDefaultValueId = unitName == null ?
- 1 :
- 2;
- MTConstant defaultValue = null;
+ int indexOfDefaultValueId = unitName == null ?
+ 1 :
+ 2;
+ MTConstant defaultValue = null;
if (ctx.constant() != null) {
defaultValue = visitConstant(ctx.constant());
- } else if (ctx.id().size() > indexOfDefaultValueId) {
+ }
+ else if (ctx.id().size() > indexOfDefaultValueId) {
EntityLanguageParser.IdContext enumItemContext = ctx.id(indexOfDefaultValueId);
- String enumItemName = enumItemContext.getText();
+ String enumItemName = enumItemContext.getText();
if (attribute.getTypeName() == null) {
ECLog.logFatal(enumItemContext,
- "The default value can only be an enum item if the attribute type is an enum.");
+ "The default value can only be an enum item if the attribute type is an enum.");
}
defaultValue = new MTConstant(enumItemContext, attribute.getTypeName(), enumItemName);
}
@@ -2065,6 +2217,10 @@ public MTAttribute visitAttribute(EntityLanguageParser.AttributeContext ctx) {
}
}
+ if (inheritedTags != null) {
+ attribute.addTagsWithValues(inheritedTags);
+ }
+
EntityLanguageParser.AttributeBodyContext bodyContext = ctx.attributeBody();
if (bodyContext != null) {
if (bodyContext.descriptionStatement() != null) {
@@ -2075,7 +2231,7 @@ public MTAttribute visitAttribute(EntityLanguageParser.AttributeContext ctx) {
}
if (bodyContext.contentType() != null && bodyContext.contentType().size() > 0) {
attribute.setContentType(
- ECStringUtil.ProcessParserString(bodyContext.contentType(0).STRING().getSymbol().getText()));
+ ECStringUtil.ProcessParserString(bodyContext.contentType(0).STRING().getSymbol().getText()));
}
if (bodyContext.bitfield() != null && bodyContext.bitfield().size() > 0) {
for (EntityLanguageParser.BitfieldContext bitfieldContext : bodyContext.bitfield()) {
@@ -2094,7 +2250,7 @@ public MTAttribute visitAttribute(EntityLanguageParser.AttributeContext ctx) {
@Override
public Object visitDomainAttributesRenameAppendPrepend
- (EntityLanguageParser.DomainAttributesRenameAppendPrependContext ctx) {
+ (EntityLanguageParser.DomainAttributesRenameAppendPrependContext ctx) {
return null;
}
@@ -2102,8 +2258,8 @@ public MTAttribute visitAttribute(EntityLanguageParser.AttributeContext ctx) {
public Object visitDomainAttributeReplaces(EntityLanguageParser.DomainAttributeReplacesContext ctx) {
String replacingAttributeName = ctx.id(0).getText();
- String typeName = ctx.type().getText();
- MTUnit unit = null;
+ String typeName = ctx.type().getText();
+ MTUnit unit = null;
if (ctx.id().size() > 1) {
String unitName = ctx.id(1).getText();
@@ -2115,7 +2271,7 @@ public Object visitDomainAttributeReplaces(EntityLanguageParser.DomainAttributeR
MTNativeType.DataType dataType = MTNativeType.DataType.FromName(typeName);
MTAttribute attribute = new MTAttribute(ctx, currentDomainEntity.getEntityName(), typeName,
- replacingAttributeName);
+ replacingAttributeName);
if (unit != null) {
attribute.setUnit(unit);
}
@@ -2126,7 +2282,8 @@ public Object visitDomainAttributeReplaces(EntityLanguageParser.DomainAttributeR
if (dataType != null) {
if (dataType == MTNativeType.DataType.INT32) {
numberOfBits = 32;
- } else if (dataType == MTNativeType.DataType.INT64) {
+ }
+ else if (dataType == MTNativeType.DataType.INT64) {
numberOfBits = 64;
}
}
@@ -2136,11 +2293,11 @@ public Object visitDomainAttributeReplaces(EntityLanguageParser.DomainAttributeR
}
for (EntityLanguageParser.BitfieldContext bitfieldContext : ctx.replacesBody().bitfield()) {
- MTBitField bitField = visitBitfield(bitfieldContext);
+ MTBitField bitField = visitBitfield(bitfieldContext);
MTDEAttributeBitField domainAttributeBitField = new MTDEAttributeBitField(bitfieldContext, domainAttribute,
- bitField.getHigh(),
- bitField.getLow(),
- bitField.getName());
+ bitField.getHigh(),
+ bitField.getLow(),
+ bitField.getName());
domainAttribute.addReplacedBitField(domainAttributeBitField);
}
// TODO: check for overlapping bit fields - display error if so
@@ -2153,12 +2310,13 @@ public MTBitField visitBitfield(EntityLanguageParser.BitfieldContext ctx) {
String name = null;
if (ctx.UNUSED() != null) {
name = ctx.UNUSED().getText();
- } else {
+ }
+ else {
name = ctx.id().getText();
}
EntityLanguageParser.BitCountContext bitCountContext = ctx.bitCount();
MTBitField bitField = new MTBitField(ctx, Integer.valueOf(bitCountContext.INTEGER().getText()),
- name);
+ name);
if (ctx.UNUSED() != null) {
bitField.setUnused(true);
}
@@ -2175,15 +2333,20 @@ public JsonArray visitJsonArr(EntityLanguageParser.JsonArrContext ctx) {
Object value = visitJsonValue(context);
if (value instanceof JsonArray) {
builder.add((JsonArray) value);
- } else if (value instanceof JsonObject) {
+ }
+ else if (value instanceof JsonObject) {
builder.add((JsonObject) value);
- } else if (value instanceof JsonValue) {
+ }
+ else if (value instanceof JsonValue) {
builder.add((JsonValue) value);
- } else if (value instanceof Long) {
+ }
+ else if (value instanceof Long) {
builder.add(((Long) value).longValue());
- } else if (value instanceof Double) {
+ }
+ else if (value instanceof Double) {
builder.add(((Double) value).doubleValue());
- } else if (value instanceof String) {
+ }
+ else if (value instanceof String) {
builder.add((String) value);
}
}
@@ -2192,16 +2355,16 @@ public JsonArray visitJsonArr(EntityLanguageParser.JsonArrContext ctx) {
@Override
public MTDApplyTemplate visitDomainEntityApplyTemplate(EntityLanguageParser.DomainEntityApplyTemplateContext
- ctx) {
- MTDApplyTemplate applyTemplate = new MTDApplyTemplate(ctx,
- currentDomainEntity,
- ctx.id().getText());
- EntityLanguageParser.DomainApplyTemplateBodyContext body = ctx.domainApplyTemplateBody();
+ ctx) {
+ MTDApplyTemplate applyTemplate = new MTDApplyTemplate(ctx,
+ currentDomainEntity,
+ ctx.id().getText());
+ EntityLanguageParser.DomainApplyTemplateBodyContext body = ctx.domainApplyTemplateBody();
if (ctx.domainApplyTemplateBody().descriptionStatement() != null) {
setNodeDescription(applyTemplate, ctx.domainApplyTemplateBody().descriptionStatement(), false);
}
- if (body.templateConfig() != null && body.templateConfig().size() > 0) {
- EntityLanguageParser.TemplateConfigContext configContext = body.templateConfig().get(0);
+ if (body.transformConfig() != null && body.transformConfig().size() > 0) {
+ EntityLanguageParser.TransformConfigContext configContext = body.transformConfig().get(0);
applyTemplate.setConfig(visitJsonObj(configContext.jsonObj()));
}
return applyTemplate;
@@ -2209,16 +2372,16 @@ public MTDApplyTemplate visitDomainEntityApplyTemplate(EntityLanguageParser.Doma
@Override
public MTDApplyTemplate visitDomainModuleApplyTemplate(EntityLanguageParser.DomainModuleApplyTemplateContext
- ctx) {
- MTDApplyTemplate applyTemplate = new MTDApplyTemplate(ctx,
- currentDomainModule,
- ctx.id().getText());
- EntityLanguageParser.DomainApplyTemplateBodyContext body = ctx.domainApplyTemplateBody();
+ ctx) {
+ MTDApplyTemplate applyTemplate = new MTDApplyTemplate(ctx,
+ currentDomainModule,
+ ctx.id().getText());
+ EntityLanguageParser.DomainApplyTemplateBodyContext body = ctx.domainApplyTemplateBody();
if (ctx.domainApplyTemplateBody().descriptionStatement() != null) {
setNodeDescription(applyTemplate, ctx.domainApplyTemplateBody().descriptionStatement(), false);
}
- if (body.templateConfig() != null && body.templateConfig().size() > 0) {
- EntityLanguageParser.TemplateConfigContext configContext = body.templateConfig().get(0);
+ if (body.transformConfig() != null && body.transformConfig().size() > 0) {
+ EntityLanguageParser.TransformConfigContext configContext = body.transformConfig().get(0);
applyTemplate.setConfig(visitJsonObj(configContext.jsonObj()));
}
return applyTemplate;
@@ -2226,7 +2389,7 @@ public MTDApplyTemplate visitDomainModuleApplyTemplate(EntityLanguageParser.Doma
@Override
public MTDirectory visitDirectory(EntityLanguageParser.DirectoryContext ctx) {
- MTDirectory output = new MTDirectory(ctx, ctx.id().getText());
+ MTDirectory output = new MTDirectory(ctx, ctx.id().getText());
EntityLanguageParser.OutputBodyContext body = ctx.outputBody();
if (body.descriptionStatement() != null) {
setNodeDescription(output, body.descriptionStatement(), false);
@@ -2243,11 +2406,12 @@ public MTDirectory visitDirectory(EntityLanguageParser.DirectoryContext ctx) {
private String idText(EntityLanguageParser.IdContext idNode) {
if (idNode.macro() != null) {
- String macroName = idNode.macro().ident(0).getText();
+ String macroName = idNode.macro().ident(0).getText();
String defaultValue = null;
if (idNode.macro().ident().size() > 1) {
defaultValue = idNode.macro().ident(1).getText();
- } else if (idNode.macro().STRING() != null) {
+ }
+ else if (idNode.macro().STRING() != null) {
defaultValue = ECStringUtil.ProcessParserString(idNode.macro().STRING().getText());
}
String value = EntityCompiler.GetDefineValue(macroName, defaultValue);
@@ -2285,7 +2449,7 @@ public Object visitTemplates(EntityLanguageParser.TemplatesContext ctx) {
@Override
public MTRepositoryImport visitTemplatesImport(EntityLanguageParser.TemplatesImportContext ctx) {
- String repositoryName = ctx.id().getText();
+ String repositoryName = ctx.id().getText();
MTRepositoryImport repositoryImport = new MTRepositoryImport(ctx, false);
repositoryImport.setRepositoryName(repositoryName);
return repositoryImport;
@@ -2308,18 +2472,20 @@ public MTTemplate visitTemplate(EntityLanguageParser.TemplateContext ctx) {
for (EntityLanguageParser.OutputSpecContext specContext : body.outputSpec()) {
if (specContext.id().size() == 2) {
template.addNamedOutput(specContext.id(0).getText(), specContext.id(1).getText());
- } else if (specContext.id().size() == 1) {
+ }
+ else if (specContext.id().size() == 1) {
template.addNamedOutput(specContext.PRIMARY().getText(), specContext.id(0).getText());
- } else {
+ }
+ else {
ECLog.logFatal(ctx, "Template output spec requires 2 arguments.");
}
}
if (body.descriptionStatement() != null) {
setNodeDescription(template, body.descriptionStatement(), false);
}
- if (body.templateConfig() != null) {
- if (body.templateConfig() != null && body.templateConfig().size() > 0) {
- EntityLanguageParser.TemplateConfigContext configContext = body.templateConfig().get(0);
+ if (body.transformConfig() != null) {
+ if (body.transformConfig() != null && body.transformConfig().size() > 0) {
+ EntityLanguageParser.TransformConfigContext configContext = body.transformConfig().get(0);
template.setConfig(visitJsonObj(configContext.jsonObj()));
}
}
@@ -2331,15 +2497,27 @@ public MTTemplate visitTemplate(EntityLanguageParser.TemplateContext ctx) {
@Override
public MTTransform visitTransform(EntityLanguageParser.TransformContext ctx) {
MTTransform transform = new MTTransform(ctx, currentConfiguration, ctx.id().getText());
+ EntityLanguageParser.TransformBodyContext body = ctx.transformBody();
+ if (body == null) {
+ ECLog.logFatal(ctx, "Invalid transform definition.");
+ }
for (EntityLanguageParser.OutputSpecContext specContext : ctx.transformBody().outputSpec()) {
if (specContext.id().size() == 2) {
transform.addNamedOutput(specContext.id(0).getText(), specContext.id(1).getText());
- } else if (specContext.id().size() == 1) {
+ }
+ else if (specContext.id().size() == 1) {
transform.addNamedOutput(specContext.PRIMARY().getText(), specContext.id(0).getText());
- } else {
+ }
+ else {
ECLog.logFatal(ctx, "Transform output spec requires 2 arguments.");
}
}
+ if (body.transformConfig() != null) {
+ if (body.transformConfig() != null && body.transformConfig().size() > 0) {
+ EntityLanguageParser.TransformConfigContext configContext = body.transformConfig().get(0);
+ transform.setConfig(visitJsonObj(configContext.jsonObj()));
+ }
+ }
currentConfiguration.addTransform(transform);
return transform;
}
@@ -2364,7 +2542,8 @@ public Object visitLanguageType(EntityLanguageParser.LanguageTypeContext ctx) {
String mappedToTypeName = null;
if (ctx.STRING() != null) {
mappedToTypeName = ECStringUtil.ProcessParserString(ctx.STRING().getText());
- } else {
+ }
+ else {
mappedToTypeName = ctx.id().getText();
}
currentLanguage.addType(ctx.type().getText(), mappedToTypeName, ctx.REF() != null, ctx.NULLABLE() != null);
@@ -2377,9 +2556,11 @@ public Object visitLanguageComments(EntityLanguageParser.LanguageCommentsContext
String commentText = ECStringUtil.ProcessParserString(body.STRING().getText());
if (body.LINE() != null) {
currentLanguage.setLineComment(commentText);
- } else if (body.BLOCK_START() != null) {
+ }
+ else if (body.BLOCK_START() != null) {
currentLanguage.setBlockCommentStart(commentText);
- } else if (body.BLOCK_END() != null) {
+ }
+ else if (body.BLOCK_END() != null) {
currentLanguage.setBlockCommentEnd(commentText);
}
}
@@ -2389,8 +2570,8 @@ public Object visitLanguageComments(EntityLanguageParser.LanguageCommentsContext
@Override
public Object visitLanguageOperators(EntityLanguageParser.LanguageOperatorsContext ctx) {
for (EntityLanguageParser.OperatorsBodyContext body : ctx.operatorsBody()) {
- String operatorName = body.id().getText();
- List symbols = new ArrayList<>();
+ String operatorName = body.id().getText();
+ List symbols = new ArrayList<>();
for (TerminalNode symbolString : body.STRING()) {
symbols.add(ECStringUtil.ProcessParserString(symbolString.getText()));
}
@@ -2402,15 +2583,15 @@ public Object visitLanguageOperators(EntityLanguageParser.LanguageOperatorsConte
@Override
public Object visitLanguageFunctions(EntityLanguageParser.LanguageFunctionsContext ctx) {
for (EntityLanguageParser.FunctionsBodyContext body : ctx.functionsBody()) {
- String name = body.id(0).getText();
- String mapping = ECStringUtil.ProcessParserString(body.STRING().getText());
+ String name = body.id(0).getText();
+ String mapping = ECStringUtil.ProcessParserString(body.STRING().getText());
MTLanguageFunction function = new MTLanguageFunction(body, currentLanguage, name, mapping);
for (int i = 0; i < body.type().size(); i++) {
- String typeStr = body.type(i).getText();
- String argName = body.id(i + 1).getText();
- MTNativeType.DataType argType = MTNativeType.DataType.FromName(typeStr);
- MTLanguageFunctionArgument arg = new MTLanguageFunctionArgument(body.id(i + 1), function, argType,
- argName);
+ String typeStr = body.type(i).getText();
+ String argName = body.id(i + 1).getText();
+ MTNativeType.DataType argType = MTNativeType.DataType.FromName(typeStr);
+ MTLanguageFunctionArgument arg = new MTLanguageFunctionArgument(body.id(i + 1), function, argType,
+ argName);
function.addArg(arg);
}
currentLanguage.addFunction(function);
@@ -2422,7 +2603,7 @@ public Object visitLanguageFunctions(EntityLanguageParser.LanguageFunctionsConte
public Object visitVersion(EntityLanguageParser.VersionContext ctx) {
Integer[] parts = new Integer[]{0, 0, 0};
- int partIndex = 0;
+ int partIndex = 0;
String versionString = ctx.VERSIONNUM().getText();
for (String partStr : versionString.split(".")) {
parts[partIndex++] = Integer.valueOf(partStr);
@@ -2436,10 +2617,27 @@ public Object visitVersion(EntityLanguageParser.VersionContext ctx) {
@Override
public Object visitFormatStatement(EntityLanguageParser.FormatStatementContext ctx) {
- String formatName = ctx.id().getText();
- JsonObject settings = visitJsonObj(ctx.jsonObj());
+ String formatName = ctx.id().getText();
+ JsonObject settings = visitJsonObj(ctx.jsonObj());
MTCodeFormat codeFormat = new MTCodeFormat(ctx, formatName, settings);
root.addCodeFormat(codeFormat);
return super.visitFormatStatement(ctx);
}
+
+ @Override
+ public Object visitRealm(EntityLanguageParser.RealmContext ctx) {
+ EntityLanguageParser.RealmBodyContext bodyContext = ctx.realmBody();
+ String realmName = ctx.id().getText();
+ MTRealm realm = null;
+ if (currentSpace().hasRealmWithName(realmName)) {
+ realm = currentSpace().getRealmWithName(realmName);
+ } else {
+ realm = new MTRealm(realmName);
+ }
+ this.currentRealm = realm;
+ visit(bodyContext);
+ this.currentRealm = null;
+
+ return realm;
+ }
}
diff --git a/src/main/java/org/entityc/compiler/EntityCompiler.java b/src/main/java/org/entityc/compiler/EntityCompiler.java
index edf072d..15a2474 100644
--- a/src/main/java/org/entityc/compiler/EntityCompiler.java
+++ b/src/main/java/org/entityc/compiler/EntityCompiler.java
@@ -24,6 +24,8 @@
import org.entityc.compiler.repository.RepositoryFile;
import org.entityc.compiler.repository.RepositoryImportManager;
import org.entityc.compiler.transform.MTBaseTransform;
+import org.entityc.compiler.transform.MTVImplicitTransform;
+import org.entityc.compiler.transform.MTVReleasedTransform;
import org.entityc.compiler.transform.TransformManager;
import org.entityc.compiler.transform.template.FileTemplateTransform;
import org.entityc.compiler.transform.template.TemplatePublishing;
@@ -52,8 +54,8 @@
public class EntityCompiler {
- public static final String COMPILER_VERSION = "0.15.0";
- public static final String LANGUAGE_VERSION = "0.12.6";
+ public static final String COMPILER_VERSION = "0.18.0";
+ public static final String LANGUAGE_VERSION = "0.15.0";
private static final Map defineValues = new HashMap<>();
private static final Set templateSearchPath = new HashSet<>();
private static CommandLine commandLine;
@@ -132,8 +134,9 @@ public static void RunTransforms(MTRoot root, MTConfiguration configuration) {
root.resolveReferences(false);
//model.processAssetAttributes();
root.getSpace().checkValidReferences();
+ final String ImplicitTransformName = "Implicit";
- TransformManager.GetTransformByName("Implicit").start();
+ TransformManager.GetTransformByName(ImplicitTransformName).start(null);
for (MTTransform transformSpec : configuration.getTransforms()) {
MTBaseTransform transform = TransformManager.GetTransformByName(transformSpec.getName());
@@ -143,8 +146,10 @@ public static void RunTransforms(MTRoot root, MTConfiguration configuration) {
if (commandLine.verbose) {
System.out.println("Running " + "transform" + " " + transform.getName());
}
- transform.start();
+ transform.start(null);
}
+ MTBaseTransform implicitTransform = TransformManager.GetTransformByName(ImplicitTransformName);
+ ((MTVImplicitTransform)implicitTransform).start(MTVReleasedTransform.realm);
root.resolveReferences(true);
root.getSpace().checkValidReferences();
diff --git a/src/main/java/org/entityc/compiler/model/MTRealm.java b/src/main/java/org/entityc/compiler/model/MTRealm.java
new file mode 100644
index 0000000..66cdf61
--- /dev/null
+++ b/src/main/java/org/entityc/compiler/model/MTRealm.java
@@ -0,0 +1,24 @@
+package org.entityc.compiler.model;
+
+import org.entityc.compiler.model.domain.MTNamed;
+import org.entityc.compiler.model.entity.MTTemplateSupport;
+import org.entityc.compiler.model.visitor.MTVisitor;
+
+public class MTRealm extends MTNode implements MTTemplateSupport, MTNamed {
+
+ private final String name;
+
+ public MTRealm(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public void accept(MTVisitor visitor) {
+
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+}
diff --git a/src/main/java/org/entityc/compiler/model/config/MTSpace.java b/src/main/java/org/entityc/compiler/model/config/MTSpace.java
index c6a35ab..31c3dd5 100644
--- a/src/main/java/org/entityc/compiler/model/config/MTSpace.java
+++ b/src/main/java/org/entityc/compiler/model/config/MTSpace.java
@@ -13,10 +13,7 @@
import org.entityc.compiler.doc.annotation.ModelMethod;
import org.entityc.compiler.doc.annotation.ModelMethodCategory;
import org.entityc.compiler.doc.annotation.ModelMethodParameter;
-import org.entityc.compiler.model.MTModule;
-import org.entityc.compiler.model.MTNamespace;
-import org.entityc.compiler.model.MTNode;
-import org.entityc.compiler.model.MTReferenceResolution;
+import org.entityc.compiler.model.*;
import org.entityc.compiler.model.domain.MTDomain;
import org.entityc.compiler.model.domain.MTNamed;
import org.entityc.compiler.model.entity.MTEntity;
@@ -46,6 +43,7 @@
+ "list of modules or entities in your model.")
public class MTSpace extends MTNode implements MTReferenceResolution, MTTemplateSupport, MTNamed {
+ private final Map realmMap = new HashMap<>();
private final Map moduleMap = new HashMap<>();
private final Map entityMap = new HashMap<>();
private final Map entityTemplateMap = new HashMap<>();
@@ -132,6 +130,20 @@ public MTRepository getRepository(
return repositoryMap.get(name);
}
+ public void addRealm(MTRealm realm) {
+ realmMap.put(realm.getName(), realm);
+ }
+
+ @ModelMethod(category = ModelMethodCategory.CONFIGURATION, description = "Returns the realm object by its name.")
+ public MTRealm getRealmWithName(String realm) {
+ return realmMap.get(realm);
+ }
+
+ @ModelMethod(category = ModelMethodCategory.CONFIGURATION, description = "Returns true if there is a realm by this name.")
+ public boolean hasRealmWithName(String realm) {
+ return realmMap.containsKey(realm);
+ }
+
public void addModule(MTModule module) {
module.setIncluded(includeMode);
moduleMap.put(module.getName(), module);
diff --git a/src/main/java/org/entityc/compiler/model/domain/MTDERelationship.java b/src/main/java/org/entityc/compiler/model/domain/MTDERelationship.java
index aaf1946..2aa8c7f 100644
--- a/src/main/java/org/entityc/compiler/model/domain/MTDERelationship.java
+++ b/src/main/java/org/entityc/compiler/model/domain/MTDERelationship.java
@@ -18,31 +18,36 @@
import org.entityc.compiler.model.entity.MTRelationship;
import org.entityc.compiler.model.visitor.MTVisitor;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
@ModelClass(type = ModelClassType.DOMAIN,
description = "Represents a relationship in your model in the context of a domain.")
public class MTDERelationship extends MTNode implements MTNamed, MTDomainBased, MTReferenceResolution {
- private final String relationshipName;
- private MTDomain domain;
- private MTDEntity domainEntity;
- private MTRelationship relationship;
- private String explicitName;
- private String withViewName; // to-entity should map to a specific view
- private boolean withPrimaryKey; // to-entity should map as its primary key only
- private MTDERelationshipHalf to;
- private boolean resolvedReferences = false;
+ private final String relationshipName;
+ private MTDomain domain;
+ private MTDEntity domainEntity;
+ private MTRelationship relationship;
+ private String explicitName;
+ private String withViewName; // to-entity should map to a specific view
+ private boolean withPrimaryKey; // to-entity should map as its primary key only
+ private MTDERelationshipHalf to;
+ private boolean resolvedReferences = false;
+ private List fields;
public MTDERelationship(ParserRuleContext ctx, MTDEntity domainEntity, String relationshipName) {
super(ctx);
- this.domain = domainEntity.getDomain();
- this.domainEntity = domainEntity;
+ this.domain = domainEntity.getDomain();
+ this.domainEntity = domainEntity;
this.relationshipName = relationshipName;
}
public MTDERelationship(ParserRuleContext ctx, MTDomain domain, MTRelationship relationship) {
super(ctx);
- this.domain = domain;
- this.relationship = relationship;
+ this.domain = domain;
+ this.relationship = relationship;
this.relationshipName = relationship.getName();
}
@@ -77,7 +82,7 @@ public void setWithViewName(String withViewName) {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description =
"If this relationship was explicitly renamed within its domain, it will return that name. Otherwise "
- + "it will return `null`.")
+ + "it will return `null`.")
public String getExplicitName() {
return explicitName;
}
@@ -99,13 +104,29 @@ public void setDomainEntity(MTDEntity domainEntity) {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description = "Indicates if this relationship is a one-to-many.")
public boolean isOneToMany() {
- return relationship.isOneToMany();
+ return relationship != null && relationship.isOneToMany();
}
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description = "Indicates if this relationship is a many-to-many.")
public boolean isManyToMany() {
- return relationship.isManyToMany();
+ return relationship != null && relationship.isManyToMany();
+ }
+
+ public void addField(MTDERelationshipField field) {
+ if (this.fields == null) {
+ this.fields = new ArrayList<>();
+ }
+ this.fields.add(field);
+ }
+
+ public boolean hasFields() {
+ return this.fields != null && this.fields.size() > 0;
+ }
+ @ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
+ description = "Returns all the declared fields of this relationship.")
+ public Collection getFields() {
+ return this.fields;
}
@Override
@@ -126,12 +147,19 @@ public boolean resolveReferences(MTSpace space, int pass) {
}
if (relationship != null && to == null) {
to = new MTDERelationshipHalf(relationship.getParserRuleContext(), domain, relationship.getTo(),
- withViewName);
+ withViewName);
to.setAsPrimaryKey(withPrimaryKey);
if (to.resolveReferences(space, pass)) {
anotherPass = true;
}
}
+ if (fields != null) {
+ for (MTDERelationshipField field : fields) {
+ if (field.resolveReferences(space, pass)) {
+ anotherPass = true;
+ }
+ }
+ }
if (!anotherPass) {
resolvedReferences = true;
}
@@ -146,21 +174,21 @@ public void accept(MTVisitor visitor) {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description =
"This returns the full name of this domain relationship which includes not only its domain based name "
- + "but is also preceded with the domain's entity's full name. The delimiter can be provided which "
- + "is used between all parts of the full name.")
+ + "but is also preceded with the domain's entity's full name. The delimiter can be provided which "
+ + "is used between all parts of the full name.")
@Override
public String getFullname(
@ModelMethodParameter(description = "A delimiter to place between the segments of the domain namespace as well "
- + "as between that namespace and the domain entity name and between the "
- + "domain entity name and the domain relationship name.")
- String delim) {
+ + "as between that namespace and the domain entity name and between the "
+ + "domain entity name and the domain relationship name.")
+ String delim) {
return domainEntity.getFullname(delim) + delim + getName();
}
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description =
"Returns the domain relationship name which is the result of applying any defined naming conventions "
- + "or explicit renaming.")
+ + "or explicit renaming.")
@Override
public String getName() {
if (explicitName != null) {
@@ -230,7 +258,7 @@ public boolean isPrimaryParent() {
description = "Returns whether this relationship's \"to\" entity is tagged with the specified tag.")
public boolean hasToEntityTagged(
@ModelMethodParameter(description = "The tag with which to check.")
- String tag) {
+ String tag) {
return to != null && to.getEntity().hasTag(tag);
}
}
diff --git a/src/main/java/org/entityc/compiler/model/domain/MTDERelationshipField.java b/src/main/java/org/entityc/compiler/model/domain/MTDERelationshipField.java
new file mode 100644
index 0000000..c87d31c
--- /dev/null
+++ b/src/main/java/org/entityc/compiler/model/domain/MTDERelationshipField.java
@@ -0,0 +1,85 @@
+package org.entityc.compiler.model.domain;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.entityc.compiler.doc.annotation.ModelClass;
+import org.entityc.compiler.doc.annotation.ModelClassType;
+import org.entityc.compiler.model.MTNode;
+import org.entityc.compiler.model.MTReferenceResolution;
+import org.entityc.compiler.model.config.MTSpace;
+import org.entityc.compiler.model.entity.MTEntity;
+import org.entityc.compiler.model.entity.MTRelationship;
+import org.entityc.compiler.model.visitor.MTVisitor;
+import org.entityc.compiler.util.ECLog;
+
+@ModelClass(type = ModelClassType.DOMAIN,
+ description = "Represents a field (attribute or relationship) associated with the __to__ entity of the relationship.")
+public class MTDERelationshipField extends MTNode implements MTNamed, MTDomainBased, MTReferenceResolution {
+
+ public MTDERelationshipField(ParserRuleContext ctx, MTDERelationship domainRelationship, String fieldName) {
+ super(ctx);
+ this.domainRelationship = domainRelationship;
+ this.fieldName = fieldName;
+ }
+ private MTDERelationship domainRelationship;
+ private MTDEAttribute fieldAttribute;
+ private MTDERelationship fieldRelationship;
+
+ private String fieldName;
+
+ public boolean fieldIsAttribute() {
+ return fieldAttribute != null;
+ }
+
+ public boolean fieldIsRelationship() {
+ return fieldRelationship != null;
+ }
+
+ public MTDEAttribute getAttribute() {
+ return fieldAttribute;
+ }
+
+ @Override
+ public void accept(MTVisitor visitor) {
+
+ }
+
+ @Override
+ public boolean resolveReferences(MTSpace space, int pass) {
+ if ( fieldIsAttribute() || fieldIsRelationship() ) {
+ return false;
+ }
+ MTRelationship relationship = domainRelationship.getRelationship();
+ if (relationship == null) {
+ return true;
+ }
+ MTEntity entity = relationship.getTo() != null && relationship.getTo().getEntity() != null ? relationship.getTo().getEntity() : null;
+ if (entity == null) {
+ return true;
+ }
+
+ if (entity.hasAttributeNamed(fieldName)) {
+ this.fieldAttribute = new MTDEAttribute(getParserRuleContext(), domainRelationship.getDomain(), entity.getName(), fieldName);
+ this.fieldAttribute.addTagsWithValues(this.getTagsWithValues()); // transfer the tags to it
+ } else if (entity.hasRelationshipNamed(fieldName)) {
+ ECLog.logFatal(getParserRuleContext(), "Domain relationship fields of type relationship currently not supported.");
+ } else {
+ ECLog.logFatal(getParserRuleContext(), "Domain relationship " + this.domainRelationship.getName() + " of entity " + entity.getName() + " does not have an attribute or relationship named: " + fieldName);
+ }
+ return false;
+ }
+
+ @Override
+ public MTDomain getDomain() {
+ return this.domainRelationship.getDomain();
+ }
+
+ @Override
+ public String getFullname(String delim) {
+ return this.domainRelationship.getFullname(delim) + delim + this.fieldName;
+ }
+
+ @Override
+ public String getName() {
+ return this.fieldName;
+ }
+}
diff --git a/src/main/java/org/entityc/compiler/model/domain/MTDERelationshipHalf.java b/src/main/java/org/entityc/compiler/model/domain/MTDERelationshipHalf.java
index 759ad70..bc88b8c 100644
--- a/src/main/java/org/entityc/compiler/model/domain/MTDERelationshipHalf.java
+++ b/src/main/java/org/entityc/compiler/model/domain/MTDERelationshipHalf.java
@@ -11,8 +11,10 @@
import org.entityc.compiler.model.MTReferenceResolution;
import org.entityc.compiler.model.config.MTSpace;
import org.entityc.compiler.model.entity.HalfRelationshipPlurality;
+import org.entityc.compiler.model.entity.MTEntity;
import org.entityc.compiler.model.entity.MTRelationshipHalf;
import org.entityc.compiler.model.visitor.MTVisitor;
+import org.entityc.compiler.util.ECLog;
public class MTDERelationshipHalf extends MTNode implements MTDomainBased, MTReferenceResolution {
diff --git a/src/main/java/org/entityc/compiler/model/domain/MTDEntity.java b/src/main/java/org/entityc/compiler/model/domain/MTDEntity.java
index e0c6360..b0e9c1c 100644
--- a/src/main/java/org/entityc/compiler/model/domain/MTDEntity.java
+++ b/src/main/java/org/entityc/compiler/model/domain/MTDEntity.java
@@ -104,6 +104,12 @@ public boolean hasDeclaredDomainAttributes() {
return declaredDomainAttributes.size() > 0;
}
+ @ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
+ description = "Indicates if any relationships were declared in this domain entity declaration.")
+ public boolean hasDeclaredDomainRelationships() {
+ return declaredDomainRelationships.size() > 0;
+ }
+
public void addAttribute(MTAttribute attribute) {
if (entity != null && entity.hasAttributeNamed(attribute.getName())) {
ECLog.logFatal(attribute, "The entity already has an attribute by the name: " + attribute.getName());
@@ -357,8 +363,14 @@ public MTDEAttribute getDomainAttributeByName(
return domainAttribute;
}
- @ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
- description = "Returns the domain specific version of the specified relationship.")
+ @ModelMethod(category = ModelMethodCategory.ATTRIBUTE,
+ description = "Returns the domain specific version of the specified attribute.")
+ public MTDEAttribute getDomainAttributeByName(
+ @ModelMethodParameter(description = "The name of the attribute to return.")
+ String attributeName) {
+ return getDomainAttributeByName(attributeName, false);
+ }
+
public MTDERelationship getDomainEntityRelationshipByName(
@ModelMethodParameter(description = "The name of the relationship to return.")
String name,
@@ -564,11 +576,18 @@ public MTDEntity primaryParentEntity() {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description = "Returns the primary parent relationship of this domain entity. A primary parent "
- + "relationship is one that has been declared as `parent` and **not** declared `optional`.")
+ + "relationship is one that has been declared as `parent` and **not** declared `optional`.")
public MTDERelationship primaryParentRelationship() {
return getDomainEntityRelationshipByName(entity.getPrimaryParentRelationship().getName(), true);
}
+ @ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
+ description = "Indicates whether this domain entity has a parent relationship. A parent "
+ + "relationship is one that has been declared as `parent`")
+ public boolean hasParentRelationship() {
+ return entity != null && entity.hasParentRelationship();
+ }
+
public MTDView getDomainEntityViewByName(String viewName, boolean createIfNeeded) {
MTDView domainEntityView = domainViewMap.get(viewName);
if (domainEntityView == null && domain.getParentDomain() != null) {
@@ -872,4 +891,9 @@ public MTSpace getSpace() {
}
return null;
}
+
+ @Override
+ public String toString() {
+ return domain.getName() + "." + entityName;
+ }
}
diff --git a/src/main/java/org/entityc/compiler/model/domain/MTDomain.java b/src/main/java/org/entityc/compiler/model/domain/MTDomain.java
index 45b4e55..1ee3f32 100644
--- a/src/main/java/org/entityc/compiler/model/domain/MTDomain.java
+++ b/src/main/java/org/entityc/compiler/model/domain/MTDomain.java
@@ -365,7 +365,7 @@ public void accept(MTVisitor visitor) {
public void checkValidReferences(MTSpace space) {
for (MTDEntity domainEntity : domainEntities) {
if (domainEntity.getEntity() == null) {
- ECLog.logFatal(domainEntity, "Could not find entity: " + domainEntity.getEntityName());
+ //ECLog.logFatal(domainEntity, "Could not find entity: " + domainEntity.getEntityName());
}
}
}
diff --git a/src/main/java/org/entityc/compiler/model/domain/MTNamingMethod.java b/src/main/java/org/entityc/compiler/model/domain/MTNamingMethod.java
index 7a76f13..63fefe0 100644
--- a/src/main/java/org/entityc/compiler/model/domain/MTNamingMethod.java
+++ b/src/main/java/org/entityc/compiler/model/domain/MTNamingMethod.java
@@ -6,6 +6,7 @@
package org.entityc.compiler.model.domain;
+import org.entityc.compiler.util.ECLog;
import org.entityc.compiler.util.ECStringUtil;
public enum MTNamingMethod {
@@ -39,6 +40,10 @@ public static MTNamingMethod fromName(String name) {
return null;
}
+ public String getName() {
+ return name;
+ }
+
public String getDelimiter() {
return delimiter;
}
diff --git a/src/main/java/org/entityc/compiler/model/entity/MTAttribute.java b/src/main/java/org/entityc/compiler/model/entity/MTAttribute.java
index e96f308..7e5df55 100644
--- a/src/main/java/org/entityc/compiler/model/entity/MTAttribute.java
+++ b/src/main/java/org/entityc/compiler/model/entity/MTAttribute.java
@@ -95,6 +95,9 @@ public MTAttribute(ParserRuleContext ctx, String entityName, String typeName, St
protected MTAttribute(String secondaryName, MTAttribute primaryAttribute) {
super(primaryAttribute.getParserRuleContext());
this.name = secondaryName;
+ this.description = primaryAttribute.getDescription();
+ this.setSummary(primaryAttribute.getSummary());;
+ this.setDetail(primaryAttribute.getDetail());;
this.entityName = primaryAttribute.entityName;
this.entity = primaryAttribute.entity;
this.unit = primaryAttribute.unit;
diff --git a/src/main/java/org/entityc/compiler/model/entity/MTCompositeEntity.java b/src/main/java/org/entityc/compiler/model/entity/MTCompositeEntity.java
new file mode 100644
index 0000000..47c2508
--- /dev/null
+++ b/src/main/java/org/entityc/compiler/model/entity/MTCompositeEntity.java
@@ -0,0 +1,86 @@
+package org.entityc.compiler.model.entity;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.entityc.compiler.doc.annotation.*;
+import org.entityc.compiler.model.MTModule;
+import org.entityc.compiler.util.ECLog;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+@ModelClass(type = ModelClassType.ENTITY, description = "Represents a composite entity in your model.")
+public class MTCompositeEntity extends MTEntity {
+
+ public static final String ObjectTag = "object";
+ public static final String VersionTag = "version";
+ public static final String ReleaseTag = "release";
+ public static final String BinderTag = "binder";
+
+ Map constituentEntities = new HashMap<>();
+
+ public MTCompositeEntity(ParserRuleContext ctx, MTModule module, String name) {
+ super(ctx, module, name);
+ }
+
+ public void addConstituentEntity(String tag, MTEntity entity) {
+ if (this.constituentEntities.containsKey(tag) ) {
+ if (!this.constituentEntities.get(tag).name.equals(entity.name)) {
+ ECLog.logFatal("This composite entity " + this.name + " is already associated to a different entity with the " + tag + " tag.");
+ } else {
+ return;
+ }
+ }
+ this.constituentEntities.put(tag, entity);
+ }
+
+ public MTEntity getConstituentEntity(String tag) {
+ return constituentEntities.get(tag);
+ }
+
+ public boolean hasConstituentEntity(String tag) {
+ return constituentEntities.containsKey(tag);
+ }
+
+ public MTEntity getAnyConstituentEntity(String tag, HashSet history) {
+ MTEntity constituentEntity = constituentEntities.get(tag);
+ if (constituentEntity != null) {
+ return constituentEntity;
+ }
+ ECLog.logInfo("getAnyConstituentEntity(" + tag + ") Checking relationships for " + getName() + "...");
+ for (MTRelationship relationship : getRelationships()) {
+ MTEntity toEntity = relationship.getTo().getEntity();
+ if (history.contains(toEntity.getName())) {
+ continue; // break infinite recursion
+ }
+ if (toEntity.hasTag("release:top") && tag.equals(ReleaseTag)) {
+ return toEntity;
+ }
+ if (toEntity == null || !toEntity.isCompositeEntity()) {
+ ECLog.logInfo(" Relationship " + relationship.getName() + " to entity " + toEntity.getName() + " is not to a composite entity.");
+ continue;
+ }
+ history.add(toEntity.getName());
+ MTEntity compositeToEntity = ((MTCompositeEntity)toEntity).getAnyConstituentEntity(tag, history);
+ if (compositeToEntity != null) {
+ return compositeToEntity;
+ }
+ }
+ ECLog.logInfo(" Unable to find child constituent entity!");
+ return null;
+ }
+
+ public MTEntity getAnyConstituentEntity(String tag) {
+ return getAnyConstituentEntity(tag, new HashSet());
+ }
+
+ public boolean hasAnyConstituentEntity(String tag) {
+ return getAnyConstituentEntity(tag, new HashSet()) != null;
+ }
+
+ public void addAttribute(String tag, MTAttribute attribute, MTEntity fromEntity) {
+ addConstituentEntity(tag, fromEntity);
+ MTAttribute constituentAttribute = MTAttribute.Copy(attribute, this);
+ super.addAttribute(constituentAttribute);
+ }
+}
diff --git a/src/main/java/org/entityc/compiler/model/entity/MTEntity.java b/src/main/java/org/entityc/compiler/model/entity/MTEntity.java
index 10ade2a..0eb9439 100644
--- a/src/main/java/org/entityc/compiler/model/entity/MTEntity.java
+++ b/src/main/java/org/entityc/compiler/model/entity/MTEntity.java
@@ -21,13 +21,7 @@
import org.entityc.compiler.util.ECLog;
import org.entityc.compiler.util.ECStringUtil;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-import java.util.Vector;
+import java.util.*;
import java.util.stream.Collectors;
import static org.entityc.compiler.doc.annotation.ModelMethodCategory.ENTITY_TEMPLATE;
@@ -59,6 +53,7 @@ public class MTEntity extends MTType implements MTReferenceResolution, MTNamed,
private int largestFieldNumber = 0;
private MTSpace space;
private MTAttribute manyAttribute = null; // if the entity was created from a "many attributeName"
+ protected Set realms = new HashSet<>(); // a space entities can live in separate from the others - such as for composite entities
public MTEntity(ParserRuleContext ctx, MTModule module, String name) {
super(ctx);
@@ -89,6 +84,25 @@ public String getName() {
return name;
}
+ @ModelMethod(category = ModelMethodCategory.ENTITY,
+ description = "Adds the entity to a realm.")
+ public void addRealm(String realm) {
+ //ECLog.logInfo("Added entity: " + getName() + " to realm " + realm);
+ realms.add(realm);
+ }
+
+ @ModelMethod(category = ModelMethodCategory.ENTITY,
+ description = "Returns true if this entity is part of a realm.")
+ public boolean isInRealm(String realm) {
+ return this.realms.contains(realm);
+ }
+
+ @ModelMethod(category = ModelMethodCategory.ENTITY,
+ description = "Returns true if this entity is a composite entity.")
+ public boolean isCompositeEntity() {
+ return this instanceof MTCompositeEntity;
+ }
+
public static MTEntity AddImplicitManyToManyEntity(MTSpace space, MTEntity fromEntity, MTEntity toEntity) {
MTEntity combinedEntity = CombineEntities(fromEntity, toEntity);
MTEntity alreadyCreatedEntity = space.getEntityWithName(combinedEntity.getName());
@@ -783,6 +797,27 @@ public MTAttribute getAttributeByName(String attributeName) {
return attribute;
}
+ @ModelMethod(
+ category = ModelMethodCategory.RELATIONSHIP,
+ description = "Indicates whether this entity has an relationship with the specified name.")
+ public boolean hasRelationshipNamed(String name) {
+ for (MTRelationship relationship : relationships) {
+ if (relationship.getName().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @ModelMethod(
+ category = ModelMethodCategory.ATTRIBUTE,
+ description = "Returns an relationship of this entity with the specified name.")
+ public MTRelationship relationshipNamed(
+ @ModelMethodParameter(description = "The name of the relationship to return.")
+ String name) {
+ return getRelationshipByName(name);
+ }
+
@ModelMethod(
category = ModelMethodCategory.RELATIONSHIP,
description = "Returns the number of declared relationships.")
@@ -806,7 +841,7 @@ public void addUniqueness(MTUniqueness uniqueness) {
description = "Returns a list of relationships from this entity to a specified entity.")
public List getRelationshipsWithToEntity(
@ModelMethodParameter(description = "The entity that the relationships are **to**.")
- MTEntity toEntity) {
+ MTEntity toEntity) {
List matchingRelationships = new ArrayList<>();
for (MTRelationship relationship : relationships) {
if (relationship.getTo().getEntityName().equals(toEntity.getName())) {
@@ -816,6 +851,36 @@ public List getRelationshipsWithToEntity(
return matchingRelationships;
}
+ @ModelMethod(
+ category = ModelMethodCategory.RELATIONSHIP,
+ description = "Returns the first relationships from this entity to a specified entity. This method should be used when only one is expected.")
+ public MTRelationship getRelationshipWithToEntity(
+ @ModelMethodParameter(description = "The entity that the relationships are **to**.")
+ MTEntity toEntity) {
+ List matchingRelationships = new ArrayList<>();
+ for (MTRelationship relationship : relationships) {
+ if (relationship.getTo().getEntityName().equals(toEntity.getName())) {
+ return relationship;
+ }
+ }
+ return null;
+ }
+
+ @ModelMethod(
+ category = ModelMethodCategory.RELATIONSHIP,
+ description = "Returns the first relationships from this entity to a specified entity by its name. This method should be used when only one is expected.")
+ public MTRelationship getRelationshipWithToEntityNamed(
+ @ModelMethodParameter(description = "The entity that the relationships are **to**.")
+ String toEntityName) {
+ List matchingRelationships = new ArrayList<>();
+ for (MTRelationship relationship : relationships) {
+ if (relationship.getTo().getEntityName().equals(toEntityName)) {
+ return relationship;
+ }
+ }
+ return null;
+ }
+
@ModelMethod(
category = ModelMethodCategory.RELATIONSHIP,
description =
@@ -908,7 +973,7 @@ public MTAttribute attributeTagged(
description = "Indicates whether this entity has at least one relationship with the specified tag.")
public boolean hasRelationshipTagged(
@ModelMethodParameter(description = "The tag with which to search.")
- String tag) {
+ String tag) {
for (MTRelationship relationship : getRelationships()) {
if (relationship.hasTag(tag)) {
return true;
@@ -917,6 +982,20 @@ public boolean hasRelationshipTagged(
return false;
}
+ @ModelMethod(
+ category = ModelMethodCategory.TAGGING,
+ description = "Indicates whether this entity has at least one relationship to a named other entity.")
+ public boolean hasRelationshipToEntityNamed(
+ @ModelMethodParameter(description = "The name of the other entity.")
+ String toEntityName) {
+ for (MTRelationship relationship : getRelationships()) {
+ if (relationship.getTo().getEntityName().equals(toEntityName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@ModelMethod(
category = ModelMethodCategory.TAGGING,
description = "Returns a relationship of this entity that is tagged with the specified tag.")
diff --git a/src/main/java/org/entityc/compiler/model/entity/MTEnum.java b/src/main/java/org/entityc/compiler/model/entity/MTEnum.java
index 5b13f31..170a27c 100644
--- a/src/main/java/org/entityc/compiler/model/entity/MTEnum.java
+++ b/src/main/java/org/entityc/compiler/model/entity/MTEnum.java
@@ -65,6 +65,10 @@ public int getItemCount() {
return items.size();
}
+ @ModelMethod(category = ModelMethodCategory.ENUM, description = "Returns an item by its index.")
+ public MTEnumItem getItem(Long index) {
+ return getItem(index.intValue());
+ }
public MTEnumItem getItem(int index) {
return items.get(index);
}
diff --git a/src/main/java/org/entityc/compiler/model/entity/MTRelationship.java b/src/main/java/org/entityc/compiler/model/entity/MTRelationship.java
index 7b7ef85..23e99cd 100644
--- a/src/main/java/org/entityc/compiler/model/entity/MTRelationship.java
+++ b/src/main/java/org/entityc/compiler/model/entity/MTRelationship.java
@@ -18,6 +18,7 @@
import org.entityc.compiler.model.domain.MTNamed;
import org.entityc.compiler.model.visitor.MTVisitor;
import org.entityc.compiler.util.ECLog;
+import org.junit.jupiter.params.shadow.com.univocity.parsers.annotations.Copy;
import java.util.List;
@@ -28,17 +29,17 @@ public class MTRelationship extends MTNode implements MTReferenceResolution, MTT
public static final String INTERNAL_MANY_TO_MANY_TAG = "internal:many-to-many";
- private final String name;
+ private final String name;
private final MTRelationshipHalf to;
private final MTRelationshipHalf from;
- private final boolean optional;
- private final boolean parent;
- private final String reverseName;
- private final String toEntityIdName;
- private final String templateArgName;
- private boolean implicit;
- private MTRelationship reverseRelationship;
- private MTAttribute effectiveAttribute;
+ private final boolean optional;
+ private final boolean parent;
+ private final String reverseName;
+ private final String toEntityIdName;
+ private final String templateArgName;
+ private boolean implicit;
+ private MTRelationship reverseRelationship;
+ private MTAttribute effectiveAttribute;
public MTRelationship(ParserRuleContext ctx,
String name,
@@ -50,33 +51,66 @@ public MTRelationship(ParserRuleContext ctx,
String reverseName,
String toEntityIdName,
String templateArgName
- ) {
+ ) {
super(ctx);
- this.name = name;
- this.from = new MTRelationshipHalf(ctx, fromEntityName);
- this.to = new MTRelationshipHalf(ctx, toPlurality, toEntityName);
- this.optional = optional;
- this.parent = parent;
- this.reverseName = reverseName;
- this.toEntityIdName = toEntityIdName;
+ this.name = name;
+ this.from = new MTRelationshipHalf(ctx, fromEntityName);
+ this.to = new MTRelationshipHalf(ctx, toPlurality, toEntityName);
+ this.optional = optional;
+ this.parent = parent;
+ this.reverseName = reverseName;
+ this.toEntityIdName = toEntityIdName;
this.templateArgName = templateArgName;
+// if (name.equals("gearCompany")) {
+// ECLog.logInfo("Created gearCompany relationship");
+// }
}
- protected MTRelationship(String secondaryName, MTRelationship primaryRelationship) {
+ protected MTRelationship(String secondaryName, MTRelationship primaryRelationship, MTRelationshipHalf fromHalf, MTRelationshipHalf toHalf) {
super(primaryRelationship.getParserRuleContext());
- this.name = secondaryName;
- this.from = primaryRelationship.from;
- this.to = primaryRelationship.to;
- this.optional = primaryRelationship.optional;
- this.parent = primaryRelationship.parent;
- this.reverseName = primaryRelationship.reverseName;
- this.toEntityIdName = primaryRelationship.toEntityIdName;
+ this.name = secondaryName;
+ this.from = fromHalf;
+ if (toHalf != null) {
+ this.to = toHalf;
+ }
+ else {
+ this.to = primaryRelationship.to;
+ }
+ this.optional = primaryRelationship.optional;
+ this.parent = primaryRelationship.parent;
+ this.reverseName = primaryRelationship.reverseName;
+ this.toEntityIdName = primaryRelationship.toEntityIdName;
this.templateArgName = primaryRelationship.templateArgName;
+// if (name.equals("gearCompany")) {
+// ECLog.logInfo("Created gearCompany relationship");
+// }
+ }
+
+ @Override
+ public String toString() {
+ return getFrom().getEntityName() + "." + getName() + " -(" + to.getPlurality().toString() + ")-> " + getTo().getEntityName();
+ }
+
+ public static MTRelationship Copy(MTRelationship relationship, MTEntity newFromEntity, MTEntity newToEntity) {
+
+ MTRelationshipHalf fromHalf = new MTRelationshipHalf(relationship.getParserRuleContext(),
+ relationship.getFrom().getPlurality(), newFromEntity.getName());
+ fromHalf.setEntity(newFromEntity);
+
+ MTRelationshipHalf toHalf = null;
+ if (newToEntity != null) {
+ toHalf = new MTRelationshipHalf(relationship.getParserRuleContext(),
+ relationship.getTo().getPlurality(), newToEntity.getName());
+ toHalf.setEntity(newToEntity);
+ }
+
+ MTRelationship copy = new MTRelationship(relationship.getName(), relationship, fromHalf, toHalf);
+ return copy;
}
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description = "Indicates whether the relationship was created because although it was not declared it can be "
- + "implied based on relationships declared to this entity.")
+ + "implied based on relationships declared to this entity.")
public boolean isImplicit() {
return implicit;
}
@@ -87,14 +121,14 @@ public void setImplicit(boolean implicit) {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description = "When a relationship is defined as part of an entity template, it has a template argument that "
- + "will be used when an entity is created from it. This will return the name of that argument.")
+ + "will be used when an entity is created from it. This will return the name of that argument.")
public String getTemplateArgName() {
return templateArgName;
}
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description = "Returns the \"to\" part of the relationship. This part tells you about the entity to which this "
- + "relationship is bound.")
+ + "relationship is bound.")
public MTRelationshipHalf getTo() {
return to;
}
@@ -102,21 +136,21 @@ public MTRelationshipHalf getTo() {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description =
"Returns the \"from\" part of the relationship which references the entity in which this relationship "
- + "is defined.")
+ + "is defined.")
public MTRelationshipHalf getFrom() {
return from;
}
@ModelMethod(category = ModelMethodCategory.ATTRIBUTE,
description = "Returns the effective attribute associated with this relationship. The effective attribute "
- + "can help you persist the relationship in a database.")
+ + "can help you persist the relationship in a database.")
public MTAttribute getEffectiveAttribute() {
if (effectiveAttribute == null
&& to.getEntity() != null && from.getEntity() != null
) {
if (to.getPlurality() == HalfRelationshipPlurality.ONE) {
MTAttribute primarykeyAttribute = to.getEntity().getPrimaryKey().getAttributes().get(0);
- String typeName = INT64.getName();
+ String typeName = INT64.getName();
if (primarykeyAttribute.getType().isNativeType()) {
typeName = ((MTNativeType) (primarykeyAttribute.getType())).getDataType().getName();
}
@@ -135,23 +169,23 @@ else if (to.getPlurality() == HalfRelationshipPlurality.MANY && !isParent()) {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description =
"Indicates whether this relationship was defined with the `parent` keyword. Relationships defined "
- + "this way are ones that imply that this entity considers its identity as being the combination "
- + "of its parent entity and itself.")
+ + "this way are ones that imply that this entity considers its identity as being the combination "
+ + "of its parent entity and itself.")
public boolean isParent() {
return parent;
}
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description = "Indicates whether this relationship was defined with the `parent` keyword and **not** with "
- + "the `optional` keyword. Within the set of relationships of an entity, only one relationship "
- + "should be defined this way.")
+ + "the `optional` keyword. Within the set of relationships of an entity, only one relationship "
+ + "should be defined this way.")
public boolean isPrimaryParent() {
return isParent() && !isOptional();
}
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description = "Indicates whether this relationship was defined with the `optional` keyword, indicating that "
- + "relationships to the other entity is not required.")
+ + "relationships to the other entity is not required.")
public boolean isOptional() {
return optional;
}
@@ -162,7 +196,7 @@ public void setToPlurality(HalfRelationshipPlurality toPlurality) {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description = "Returns the relationship from the perspective \"to\" entity to this entity, that is, the "
- + "reverse relationship.")
+ + "reverse relationship.")
public MTRelationship getReverseRelationship() {
return reverseRelationship;
}
@@ -170,8 +204,8 @@ public MTRelationship getReverseRelationship() {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description =
"Indicates whether this relationship is a one-to-many; where in a one-to-many relationship an object "
- + "of this entity can have multiple relationships with objects of another entity but not the other way "
- + "around.")
+ + "of this entity can have multiple relationships with objects of another entity but not the other way "
+ + "around.")
public boolean isOneToMany() {
return getFullRelationshipPlurality() == FullRelationshipPlurality.ONE_TO_MANY;
}
@@ -196,11 +230,23 @@ public FullRelationshipPlurality getFullRelationshipPlurality() {
@ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
description =
"Indicates whether this relationship is a many-to-many; where in a many-to-many relationship multiple "
- + "objects of this entity can have multiple relationships with objects of another entity.")
+ + "objects of this entity can have multiple relationships with objects of another entity.")
public boolean isManyToMany() {
return getFullRelationshipPlurality() == FullRelationshipPlurality.MANY_TO_MANY;
}
+ @ModelMethod(category = ModelMethodCategory.RELATIONSHIP,
+ description =
+ "Gets the entity on the other side of an implicit many-to-many entity.")
+ public MTEntity getImplicitToEntity() {
+ for (MTRelationship mmRel : to.getEntity().implicitRelationships) {
+ if (!mmRel.to.getEntityName().equals(from.getEntityName())) {
+ return mmRel.to.getEntity();
+ }
+ }
+ return null;
+ }
+
@Override
public void accept(MTVisitor visitor) {
@@ -208,7 +254,7 @@ public void accept(MTVisitor visitor) {
@Override
public boolean resolveReferences(MTSpace space, int pass) {
- this.from.setEntity(space.getEntityWithName(from.getEntityName()));
+ this.from.resolveReferences(space, pass);
if (this.to.getEntity() == null) {
if (this.to.getTemplateInstantiation() != null) {
@@ -216,41 +262,38 @@ public boolean resolveReferences(MTSpace space, int pass) {
this.to.getTemplateInstantiation().getEntityTemplateName());
if (template == null) {
ECLog.logFatal(this.to.getTemplateInstantiation(), "Unable to find entity template with name: "
- + this.to.getTemplateInstantiation().getEntityTemplateName());
+ + this.to.getTemplateInstantiation().getEntityTemplateName());
}
this.to.setEntity(
template.makeEntity(from.getEntity(), to.getEntityName(), this.to.getTemplateInstantiation(),
- space));
+ space));
}
else {
- this.to.setEntity(space.getEntityWithName(to.getEntityName()));
+ this.to.resolveReferences(space, pass);
}
}
if (this.from.getEntityName() == null) {
- System.err.println("ERROR: Could not resolve from entity: " + this.from.getEntityName());
+ ECLog.logError("Could not resolve from entity: " + this.from.getEntityName());
return false;
}
if (this.to.getEntityName() == null) {
- System.err.println("ERROR: Could not resolve to entity: " + this.to.getEntityName());
+ ECLog.logError("Could not resolve to entity: " + this.to.getEntityName());
return false;
}
// find a list of possble relationships between entities
- if (to.getEntity() == null) {
- MTEntity toEntity = space.getEntityWithName(to.getEntityName());
- if (toEntity == null) {
- if (pass > 7) {
- ECLog.logFatal(this, "Unable to find entity named: " + to.getEntityName());
- }
- return false;
+ boolean anotherPass = this.to.resolveReferences(space, pass);
+ if (anotherPass) {
+ if (pass > 7) {
+ ECLog.logFatal(this, "Unable to find entity named: " + to.getEntityName());
}
- to.setEntity(toEntity);
+ return false;
}
List possibleFromRelationships = to.getEntity().findPossibleRelationshipsWithEntity(
from.getEntity());
- boolean found = false;
+ boolean found = false;
boolean duplicates = false;
if (pass == 0) {
@@ -262,7 +305,7 @@ public boolean resolveReferences(MTSpace space, int pass) {
duplicates = true;
ECLog.logError(
"Found duplicate reverse named relationship matches for: " + from.getEntityName() + " > "
- + getReverseName() + " < " + to.getEntityName());
+ + getReverseName() + " < " + to.getEntityName());
break;
}
else {
@@ -285,14 +328,14 @@ public boolean resolveReferences(MTSpace space, int pass) {
if (found) {
duplicates = true;
ECLog.logWarning(fromRelationship,
- "Found duplicate relationship matches between " + from.getEntity().getName()
- + "." + this.getName() + " and " + to.getEntity().getName() + "."
- + fromRelationship.getName());
+ "Found duplicate relationship matches between " + from.getEntity().getName()
+ + "." + this.getName() + " and " + to.getEntity().getName() + "."
+ + fromRelationship.getName());
break;
}
else {
// good unnamed pairing
- //System.out.println("unnamed Relationship \"" + getName() + "\" pairing between " + fromEntity.getName() + "." + this.getName() + " and " + toEntity.getName() + "." + fromRelationship.getName());
+ //System.out.println("unnamed Relationship \"" + getName() + "\" pairing between " + from.getEntityName() + "." + this.getName() + " and " + to.getEntityName() + "." + fromRelationship.getName());
this.reverseRelationship = fromRelationship;
this.from.setPlurality(fromRelationship.to.getPlurality());
found = true;
@@ -307,9 +350,9 @@ public boolean resolveReferences(MTSpace space, int pass) {
return false;
}
- if (!found && !alreadyProcessed) {
- //System.out.println("Could not find reverse relationship between " + fromEntityName + " and " + toEntityName);
- }
+// if (!found && !alreadyProcessed) {
+// ECLog.logWarning("Could not find reverse relationship between " + from.getEntityName() + " and " + to.getEntityName() + " for relationship: " + getName());
+// }
}
return false;
@@ -329,8 +372,8 @@ public String getName() {
public MTRelationship makeCopyFromEntityName(String fromEntityNameOfCopy) {
MTRelationship copy = new MTRelationship(null, name, fromEntityNameOfCopy, from.getPlurality(),
- to.getEntityName(), optional, parent, reverseName, toEntityIdName,
- templateArgName);
+ to.getEntityName(), optional, parent, reverseName, toEntityIdName,
+ templateArgName);
return copy;
}
@@ -343,7 +386,7 @@ public String getToEntityIdName() {
description = "Indicates whether the \"to\" entity of this relationship has been tagged with the specified tag.")
public boolean hasToEntityTagged(
@ModelMethodParameter(description = "The tag with which to search.")
- String tag) {
+ String tag) {
return to != null && to.getEntity().hasTag(tag);
}
}
diff --git a/src/main/java/org/entityc/compiler/model/entity/MTRelationshipHalf.java b/src/main/java/org/entityc/compiler/model/entity/MTRelationshipHalf.java
index a156d2a..0e0b25c 100644
--- a/src/main/java/org/entityc/compiler/model/entity/MTRelationshipHalf.java
+++ b/src/main/java/org/entityc/compiler/model/entity/MTRelationshipHalf.java
@@ -8,6 +8,7 @@
import org.antlr.v4.runtime.ParserRuleContext;
import org.entityc.compiler.model.MTNode;
+import org.entityc.compiler.model.config.MTSpace;
import org.entityc.compiler.model.visitor.MTVisitor;
public class MTRelationshipHalf extends MTNode {
@@ -28,7 +29,15 @@ public MTRelationshipHalf(ParserRuleContext ctx, HalfRelationshipPlurality plura
this.entityName = entityName;
}
- public HalfRelationshipPlurality getPlurality() {
+ public boolean resolveReferences(MTSpace space, int pass) {
+ if (this.entity != null) {
+ return false;
+ }
+ this.entity = space.getEntityWithName(entityName);
+ return this.entity == null;
+ }
+
+ public HalfRelationshipPlurality getPlurality() {
return plurality;
}
diff --git a/src/main/java/org/entityc/compiler/model/entity/MTSecondaryRelationship.java b/src/main/java/org/entityc/compiler/model/entity/MTSecondaryRelationship.java
index f7587e7..10b5301 100644
--- a/src/main/java/org/entityc/compiler/model/entity/MTSecondaryRelationship.java
+++ b/src/main/java/org/entityc/compiler/model/entity/MTSecondaryRelationship.java
@@ -15,7 +15,7 @@ public class MTSecondaryRelationship extends MTRelationship {
private MTRelationship relationship;
public MTSecondaryRelationship(String fullName, Stack path, MTRelationship relationship) {
- super(fullName, relationship);
+ super(fullName, relationship, relationship.getFrom(), null);
this.fullName = fullName;
this.path = path;
}
diff --git a/src/main/java/org/entityc/compiler/model/entity/MTType.java b/src/main/java/org/entityc/compiler/model/entity/MTType.java
index 6b8f8e6..5d2169e 100644
--- a/src/main/java/org/entityc/compiler/model/entity/MTType.java
+++ b/src/main/java/org/entityc/compiler/model/entity/MTType.java
@@ -55,6 +55,12 @@ public boolean isDateType() {
return isNativeDataType(MTNativeType.DataType.DATE);
}
+ @ModelMethod(category = ModelMethodCategory.TYPE,
+ description = "Indicates whether this type is the `data` data type.")
+ public boolean isDataType() {
+ return isNativeDataType(MTNativeType.DataType.BYTE_ARRAY);
+ }
+
public void accept(MTVisitor visitor) {
}
diff --git a/src/main/java/org/entityc/compiler/model/foundation/MFArray.java b/src/main/java/org/entityc/compiler/model/foundation/MFArray.java
index 7602105..891eaf1 100644
--- a/src/main/java/org/entityc/compiler/model/foundation/MFArray.java
+++ b/src/main/java/org/entityc/compiler/model/foundation/MFArray.java
@@ -106,10 +106,17 @@ public Object first() {
@ModelMethod(description = "Returns the specified item by its index into the array.")
public Object get(
@ModelMethodParameter(description = "The index into the array that points to the item to be returned.")
- Long index) {
+ Long index) {
return array.get(index.intValue());
}
+ @ModelMethod(description = "Returns the specified item by its index into the array.")
+ public Object get(
+ @ModelMethodParameter(description = "The index into the array that points to the item to be returned.")
+ Integer index) {
+ return array.get(index);
+ }
+
@ModelMethod(description =
"Returns the index into the array associated with the specified object. If the object is "
+ "not found, a -1 is returned.")
diff --git a/src/main/java/org/entityc/compiler/model/visitor/MTBaseVisitor.java b/src/main/java/org/entityc/compiler/model/visitor/MTBaseVisitor.java
index b9af97a..ce88916 100644
--- a/src/main/java/org/entityc/compiler/model/visitor/MTBaseVisitor.java
+++ b/src/main/java/org/entityc/compiler/model/visitor/MTBaseVisitor.java
@@ -26,7 +26,7 @@ public MTBaseVisitor(MTRoot root) {
this.root = root;
}
- public void start() {
+ public void start(String realm) {
//ECLog.logInfo("Starting to visit model: " + model.getName());
visit(this.root);
}
diff --git a/src/main/java/org/entityc/compiler/repository/LocalRepositoryImporter.java b/src/main/java/org/entityc/compiler/repository/LocalRepositoryImporter.java
index 3022d89..a755c8c 100644
--- a/src/main/java/org/entityc/compiler/repository/LocalRepositoryImporter.java
+++ b/src/main/java/org/entityc/compiler/repository/LocalRepositoryImporter.java
@@ -46,7 +46,8 @@ public RepositoryFile importFromRepository(MTRepository repository, MTRepository
fos.close();
} catch (IOException e) {
e.printStackTrace();
- ECLog.logFatal("Unable to import file: " + inputFilepath + " >> " + e.getMessage());
+ File infile = new File(inputFilepath);
+ ECLog.logFatal("Unable to import file: " + infile.getAbsolutePath() + " >> " + e.getMessage());
}
}
return cachedRepositoryFile;
diff --git a/src/main/java/org/entityc/compiler/repository/RepositoryImportManager.java b/src/main/java/org/entityc/compiler/repository/RepositoryImportManager.java
index 24f1baa..f80663e 100644
--- a/src/main/java/org/entityc/compiler/repository/RepositoryImportManager.java
+++ b/src/main/java/org/entityc/compiler/repository/RepositoryImportManager.java
@@ -21,10 +21,10 @@
public class RepositoryImportManager {
- private final RepositoryCache repositoryCache;
- private final Map importersByType = new HashMap<>();
- private List repositoryFilesInOrder = new ArrayList<>();
- private Map repositoryFilesByIdentifier = new HashMap<>();
+ private final RepositoryCache repositoryCache;
+ private final Map importersByType = new HashMap<>();
+ private List repositoryFilesInOrder = new ArrayList<>();
+ private Map repositoryFilesByIdentifier = new HashMap<>();
public RepositoryImportManager(RepositoryCache.CacheStructure structure) {
this.repositoryCache = new RepositoryCache(structure);
@@ -55,35 +55,36 @@ public void updateRepositoryCommitSHA1(MTRepository repository) {
public RepositoryFile importFromRepository(MTSpace space, MTRepositoryImport repositoryImport,
String extension, boolean asInclude) {
- String repositoryName = repositoryImport.getRepositoryName();
- MTRepository repository = space.getRepositoryByName(repositoryName);
+ String repositoryName = repositoryImport.getRepositoryName();
+ MTRepository repository = space.getRepositoryByName(repositoryName);
if (repository == null) {
ECLog.logFatal(repositoryImport,
- "In space \"" + space.getName() + "\" cannot find a repository named \"" + repositoryName
- + "\".");
- } else if (!repository.isValid()) {
+ "In space \"" + space.getName() + "\" cannot find a repository named \"" + repositoryName
+ + "\".");
+ }
+ else if (!repository.isValid()) {
ECLog.logFatal(repository, "Repository specification is not valid.");
}
- String name = repositoryImport.getFilename();
- String filename = name + "." + extension;
- MTRepositoryType type = repository.getType();
+ String name = repositoryImport.getFilename();
+ String filename = name + "." + extension;
+ MTRepositoryType type = repository.getType();
boolean shouldUseSpaceRepository = space.getRepositoryThatImportedThisSpace() != null
- && type == MTRepositoryType.LOCAL;
+ && type == MTRepositoryType.LOCAL;
MTRepository sourceRepository = repository;
- String alternatePath = null;
+ String alternatePath = null;
if (shouldUseSpaceRepository) {
sourceRepository = space.getRepositoryThatImportedThisSpace();
- alternatePath = repository.getPath();
+ alternatePath = repository.getPath();
}
RepositoryImporter repositoryImporter = importersByType.get(sourceRepository.getType());
repositoryImporter.updateRepositoryCommitSHA1(
- sourceRepository); // if it has one, fetch it so the cache will know if it needs to invalidate itself
+ sourceRepository); // if it has one, fetch it so the cache will know if it needs to invalidate itself
repositoryCache.validateRepositoryInCache(sourceRepository);
RepositoryFile cacheRepositoryFile = repositoryCache.getRepositoryFile(sourceRepository, filename,
- asInclude);
+ asInclude);
if (sourceRepository.getType() != MTRepositoryType.LOCAL
&& cacheRepositoryFile.exists()) { // check if it exists in the cache already
if (EntityCompiler.isVerbose()) {
@@ -94,11 +95,14 @@ public RepositoryFile importFromRepository(MTSpace space, MTRepositoryImport rep
}
RepositoryFile file = repositoryImporter.importFromRepository(sourceRepository, repositoryImport,
- cacheRepositoryFile, extension, alternatePath);
+ cacheRepositoryFile, extension, alternatePath);
if (file == null || !file.exists()) {
- String nameOrPath = repository.getType() == MTRepositoryType.LOCAL ?
- repository.getPath() :
- repositoryName;
+ String nameOrPath = repositoryName;
+
+ if (repository.getType() == MTRepositoryType.LOCAL) {
+ File f = new File(repository.getPath());
+ nameOrPath = f.getAbsolutePath();
+ }
ECLog.logFatal("Unable to import " + repository.getType() + " file: " + nameOrPath + "/" + filename);
}
addRepositoryFile(repositoryImport.getIdentifier(), file);
@@ -116,11 +120,11 @@ private String fileIdentifier(String repositoryName, String filename) {
private String getRepositoryCachePath(MTRepository repository) {
return repository.getOrganization() + File.separator + repository.getRepoName() + File.separator
- + repository.getTag();
+ + repository.getTag();
}
public void close() {
- repositoryFilesInOrder = new ArrayList<>();
+ repositoryFilesInOrder = new ArrayList<>();
repositoryFilesByIdentifier = new HashMap<>();
for (RepositoryImporter importer : importersByType.values()) {
importer.close();
diff --git a/src/main/java/org/entityc/compiler/transform/MTVImplicitTransform.java b/src/main/java/org/entityc/compiler/transform/MTVImplicitTransform.java
index 6d337cb..4fab275 100644
--- a/src/main/java/org/entityc/compiler/transform/MTVImplicitTransform.java
+++ b/src/main/java/org/entityc/compiler/transform/MTVImplicitTransform.java
@@ -8,16 +8,13 @@
import org.entityc.compiler.model.MTRoot;
import org.entityc.compiler.model.config.MTSpace;
-import org.entityc.compiler.model.entity.FullRelationshipPlurality;
-import org.entityc.compiler.model.entity.MTAttribute;
-import org.entityc.compiler.model.entity.MTEntity;
-import org.entityc.compiler.model.entity.MTEnum;
-import org.entityc.compiler.model.entity.MTPrimaryKey;
-import org.entityc.compiler.model.entity.MTRelationship;
+import org.entityc.compiler.model.entity.*;
+import org.entityc.compiler.util.ECLog;
// TODO: Create index from parent relationships
public class MTVImplicitTransform extends MTBaseTransform {
+ private String realm = null;
public MTVImplicitTransform(MTRoot root, String configurationName) {
super("Implicit", root, configurationName);
@@ -67,32 +64,48 @@ public void visitAttribute(MTAttribute attribute) {
public void visitRelationship(MTRelationship relationship) {
MTEntity fromEntity = relationship.getFrom().getEntity();
- MTEntity toEntity = relationship.getTo().getEntity();
+ MTEntity toEntity = relationship.getTo().getEntity();
if (toEntity == null || fromEntity == null) {
relationship.resolveReferences(root.getSpace(), 0);
- toEntity = relationship.getTo().getEntity();
+ toEntity = relationship.getTo().getEntity();
fromEntity = relationship.getFrom().getEntity();
+ if (toEntity == null) {
+ ECLog.logFatal("The entity \"" + fromEntity.getName() + "\" has a relationship \"" + relationship.getName() + "\" but not to anything.");
+ }
}
+
+ // if this is a realm based transform then make sure we are operating on entities from that realm.
+ if (realm != null) {
+ if (!(fromEntity instanceof MTCompositeEntity) && (toEntity instanceof MTCompositeEntity)) {
+ return;
+ }
+ if (!fromEntity.isInRealm(realm) || !toEntity.isInRealm(realm)) {
+ return;
+ }
+ }
+
+ //
+ // The "to" entity must have a primary key for this part of the transform.
+ //
MTPrimaryKey toPrimaryKey = toEntity.getPrimaryKey();
if (toPrimaryKey == null) {
return;
}
- FullRelationshipPlurality plurality = relationship.getFullRelationshipPlurality();
- MTPrimaryKey fromPrimaryKey = fromEntity.getPrimaryKey();
+ FullRelationshipPlurality plurality = relationship.getFullRelationshipPlurality();
+ MTPrimaryKey fromPrimaryKey = fromEntity.getPrimaryKey();
if (!relationship.getFrom().getEntity().isImplicit()) {
if (fromPrimaryKey == null && plurality != FullRelationshipPlurality.MANY_TO_ONE) {
return;
}
}
if (toPrimaryKey.getAttributes().size() != 1
- || (fromPrimaryKey != null && fromPrimaryKey.getAttributes().size() != 1)) {
+ || (fromPrimaryKey != null && fromPrimaryKey.getAttributes().size() != 1)) {
return; // unsupported right now
}
switch (plurality) {
case MANY_TO_MANY: {
// create table to support relationship
- String virtualEntityName = fromEntity.getName() + "-" + toEntity.getName();
MTEntity.AddImplicitManyToManyEntity(fromEntity.getSpace(), fromEntity, toEntity);
}
break;
@@ -104,6 +117,12 @@ public String[] requiredDomainNames() {
return new String[]{"Database"};
}
+ @Override
+ public void start(String realm) {
+ this.realm = realm;
+ super.start(realm);
+ }
+
@Override
public boolean canStart() {
return hasRequiredDomains();
diff --git a/src/main/java/org/entityc/compiler/transform/MTVPostgresTransform.java b/src/main/java/org/entityc/compiler/transform/MTVPostgresTransform.java
index e082bc7..d0c5747 100644
--- a/src/main/java/org/entityc/compiler/transform/MTVPostgresTransform.java
+++ b/src/main/java/org/entityc/compiler/transform/MTVPostgresTransform.java
@@ -62,9 +62,9 @@ public MTVPostgresTransform(MTRoot root, String configurationName) {
}
@Override
- public void start() {
+ public void start(String realm) {
- super.start();
+ super.start(realm);
MTTransform transform = getConfiguration().getTransformByName(getName());
String outputName = transform.getOutputNameByLocalName("primary");
diff --git a/src/main/java/org/entityc/compiler/transform/MTVReleasedTransform.java b/src/main/java/org/entityc/compiler/transform/MTVReleasedTransform.java
new file mode 100644
index 0000000..a548d26
--- /dev/null
+++ b/src/main/java/org/entityc/compiler/transform/MTVReleasedTransform.java
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2019-2023 The EntityC Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.md file in the project root.
+ */
+
+package org.entityc.compiler.transform;
+
+import org.entityc.compiler.model.MTModule;
+import org.entityc.compiler.model.MTRoot;
+import org.entityc.compiler.model.config.MTSpace;
+import org.entityc.compiler.model.config.MTTransform;
+import org.entityc.compiler.model.domain.MTDEAttribute;
+import org.entityc.compiler.model.domain.MTDERelationship;
+import org.entityc.compiler.model.domain.MTDEntity;
+import org.entityc.compiler.model.domain.MTDomain;
+import org.entityc.compiler.model.entity.*;
+import org.entityc.compiler.structure.sql.SSSourceFile;
+import org.entityc.compiler.util.ECLog;
+import org.entityc.compiler.util.ECStringUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This transform
+ */
+public class MTVReleasedTransform extends MTBaseTransform {
+ private final MTDomain releasedDomain;
+ private String compositEntityNamePrefix = "";
+ private SSSourceFile sourceFile;
+
+ public static final String realm = "Released";
+
+ public MTVReleasedTransform(MTRoot root, String configurationName) {
+ super("Released", root, configurationName);
+ releasedDomain = root.getSpace().getDomainWithName("Released");
+ compositEntityNamePrefix = "Released";
+ }
+
+ @Override
+ public boolean canStart() {
+ return true;
+ }
+
+ @Override
+ public void start(String ignore) {
+
+ super.start(realm);
+
+ MTTransform transform = getConfiguration().getTransformByName(getName());
+
+ MTSpace space = this.root.getSpace();
+
+ Map nonCompositeEntityMap = new HashMap<>();
+ Map compositeEntityConstituentMap = new HashMap<>();
+ Map releasedRelatedEntityMap = new HashMap<>();
+ Map releasedVarientOfEntityMap = new HashMap<>();
+
+ List relationshipsToResolve = new ArrayList<>();
+ List compositeEntityList = new ArrayList<>();
+
+ for (MTModule module : space.getModules()) {
+ //ECLog.logInfo("--------------------------------------------------------- MODULE: " + module.getName());
+ if (module.isIncluded()) {
+ //ECLog.logInfo("Ignoring module: " + module.getName());
+ continue;
+ }
+ //
+ // Find all the ones that are not involved in versioning and add them
+ // to our new "version-less" realm.
+ //
+ for (MTEntity entity : module.getEntities()) {
+ if (entity.hasTag("release:binder")
+ || entity.hasTag("release:object")
+ || entity.hasTag("release:version")) {
+ continue;
+ }
+ entity.addRealm(realm);
+ }
+ //
+ // Go through all the entities, find the ones that have both an object and version,
+ // create a new composite entity and then copy over the attributes (we will copy the
+ // relationships in another pass).
+ //
+ for (MTEntity entity : module.getEntities()) {
+ if (entity.isIncluded() || entity.isExtern() || entity.isImplicit() || entity.isTransient()
+ || !entity.hasTag("release:binder")) {
+ continue;
+ }
+
+ MTRelationship topRelationship = null;
+ MTRelationship objectRelationship = null;
+ MTRelationship versionRelationship = null;
+
+ for (MTRelationship relationship : entity.getRelationships()) {
+ MTEntity toEntity = relationship.getTo().getEntity();
+ if (relationship.isParent() && toEntity.hasTag("release:top")) {
+ topRelationship = relationship;
+ }
+ else if (toEntity.hasTag("release:object")) {
+ objectRelationship = relationship;
+ }
+ else if (toEntity.hasTag("release:version")) {
+ versionRelationship = relationship;
+ }
+ }
+ if (topRelationship == null) {
+ ECLog.logFatal(entity, "Unable to find release top.");
+ }
+ if (objectRelationship == null) {
+ ECLog.logFatal(entity, "Unable to find release object.");
+ }
+ if (versionRelationship == null) {
+ ECLog.logFatal(entity, "Unable to find release version.");
+ }
+
+ MTEntity releaseEntity = topRelationship.getTo().getEntity();
+ MTEntity objectEntity = objectRelationship.getTo().getEntity();
+ MTEntity versionEntity = versionRelationship.getTo().getEntity();
+
+ // keep track of ones related to the Released entities
+ releasedRelatedEntityMap.put(entity.getName(), entity); // binder
+ releasedRelatedEntityMap.put(releaseEntity.getName(), releaseEntity);
+ releasedRelatedEntityMap.put(objectEntity.getName(), objectEntity);
+ releasedRelatedEntityMap.put(versionEntity.getName(), versionEntity);
+
+ //
+ // Now create a new entity that unifies these three
+ //
+ MTCompositeEntity compositeEntity = new MTCompositeEntity(objectEntity.getParserRuleContext(),
+ objectEntity.getModule(),
+ compositEntityNamePrefix + objectEntity.getName());
+ compositeEntity.addRealm(realm);
+ releasedRelatedEntityMap.put(compositeEntity.getName(), compositeEntity);
+ releasedVarientOfEntityMap.put(objectEntity.getName(), compositeEntity);
+
+ compositeEntity.addConstituentEntity(MTCompositeEntity.BinderTag, entity);
+
+ //
+ // Object Entity Primary Key
+ //
+ MTAttribute primaryKeyAttribute = new MTAttribute(objectEntity.getParserRuleContext(),
+ compositeEntity, objectEntity.getPrimaryKeyAttribute().getTypeName(),
+ objectEntity.getPrimaryKeyAttribute().getName());
+ MTPrimaryKey newPrimaryKey = new MTPrimaryKey(objectEntity.getPrimaryKey().getParserRuleContext());
+ newPrimaryKey.addAttribute(primaryKeyAttribute);
+ compositeEntity.setPrimaryKey(newPrimaryKey);
+
+ //
+ // Foreign from Release
+ //
+ MTRelationship releaseFKRelationship = new MTRelationship(
+ topRelationship.getParserRuleContext(),
+ ECStringUtil.Uncapitalize(releaseEntity.getName()),
+ compositeEntity.getName(),
+ HalfRelationshipPlurality.ONE,
+ releaseEntity.getName(), true, true, null, null, null);
+ releaseFKRelationship.addTag("ignore");
+ compositeEntity.addRelationship(releaseFKRelationship);
+ compositeEntity.addConstituentEntity(MTCompositeEntity.ReleaseTag, releaseEntity);
+ relationshipsToResolve.add(releaseFKRelationship);
+ //
+ // Object Entity Attributes
+ //
+ for (MTAttribute attribute : objectEntity.getAttributes()) {
+ if (attribute.isModification() || versionEntity.hasAttributeNamed(attribute.getName())) {
+ continue;
+ }
+ MTAttribute compositAttribute = MTAttribute.Copy(attribute, compositeEntity);
+ compositeEntity.addAttribute(MTCompositeEntity.ObjectTag, compositAttribute, objectEntity);
+ }
+
+ //
+ // Version Entity Attributes
+ //
+ for (MTAttribute attribute : versionEntity.getAttributes()) {
+ if (attribute.isCreation()) {
+ continue;
+ }
+ MTAttribute compositAttribute = MTAttribute.Copy(attribute, compositeEntity);
+ compositAttribute.setDescription(attribute.getDescription());
+ compositeEntity.addAttribute(MTCompositeEntity.VersionTag, compositAttribute, versionEntity);
+ }
+
+ compositeEntityList.add(compositeEntity);
+ //ECLog.logInfo("Creating Composite Entity: " + compositeEntity.getName());
+ compositeEntityConstituentMap.put(objectEntity.getName(), compositeEntity);
+ compositeEntityConstituentMap.put(versionEntity.getName(), compositeEntity);
+
+ // create a one to many relationship on the release entity to this composite entity
+ MTRelationship releaseRelationship = new MTRelationship(
+ topRelationship.getParserRuleContext(),
+ ECStringUtil.Uncapitalize(compositEntityNamePrefix) + ECStringUtil.Capitalize(ECStringUtil.Pluralize(objectRelationship.getName())),
+ releaseEntity.getName(),
+ HalfRelationshipPlurality.MANY,
+ compositeEntity.getName(), true, false, null, null, null);
+ releaseEntity.addRelationship(releaseRelationship);
+ relationshipsToResolve.add(releaseRelationship);
+
+ // Relationships are more complicated so we first need to process all
+ // the entities first, then do another pass so we can randomly reference the other
+ // entities.
+ }
+ }
+ //ECLog.logInfo("FOUND " + compositeEntityList.size() + " composite entities");
+
+ //
+ // Now we need to see all the other entities related to the object or version entities and convert them also
+ // to composite entities (even though they don't have version entities) so that we don't have non-composite
+ // entities making reference to composite entities.
+ //
+ boolean foundReleasedRelated;
+ int newReleasedEntities = 0;
+ do {
+ foundReleasedRelated = false;
+ for (MTModule module : space.getModules()) {
+
+ if (module.isIncluded()) {
+ continue;
+ }
+
+ // TODO: we need to also check relationships from composite to not-fully-composite since it may be assumed
+ for (MTEntity entity : module.getEntities()) {
+ if (entity.isIncluded() || entity.isExtern() || entity.isImplicit()
+ || entity.isSecondary() || entity.isTransient()) {
+ continue;
+ }
+ if (entity.isCompositeEntity() || releasedVarientOfEntityMap.containsKey(entity.getName())) {
+ continue; // we have already determined this is release related
+ }
+
+ if (entity.hasTagPrefixed("release:")) {
+ continue;
+ }
+
+ //
+ // Determine if this entity has a relationship with a "Released" entity and if so, get the
+ // top Release entity.
+ //
+ MTEntity releaseEntity = null;
+ boolean isRelatedToReleased = false;
+ for (MTRelationship relationship : entity.getRelationships()) {
+ MTEntity toEntity = relationship.getTo().getEntity();
+ if (releasedVarientOfEntityMap.containsKey(toEntity.getName())) {
+ //ECLog.logInfo("----- is related to released via relationship: " + entity.getName() + "." + relationship.getName() + " toEntity = " + toEntity.getName());
+ MTEntity relatedEntity = releasedVarientOfEntityMap.get(toEntity.getName());
+ if (relatedEntity.isCompositeEntity()) {
+ releaseEntity = ((MTCompositeEntity) relatedEntity).getConstituentEntity(MTCompositeEntity.ReleaseTag);
+ isRelatedToReleased = true;
+ break;
+ }
+ }
+ }
+
+ //
+ // If it is not related to a released entity then skip the rest.
+ //
+ if (!isRelatedToReleased) {
+ continue;
+ }
+
+ //
+ // Create the Released "composite" entity. Even though it will be created as a composite entity, it will only have
+ // the object and release constituents.
+ //
+ foundReleasedRelated = true;
+ MTCompositeEntity releasedEntity = new MTCompositeEntity(entity.getParserRuleContext(), entity.getModule(), compositEntityNamePrefix + entity.getName());
+ releasedVarientOfEntityMap.put(entity.getName(), releasedEntity);
+ releasedEntity.addConstituentEntity(MTCompositeEntity.ObjectTag, entity);
+ compositeEntityConstituentMap.put(entity.getName(), releasedEntity);
+ releasedEntity.addRealm(realm);
+ compositeEntityList.add(releasedEntity);
+ //ECLog.logInfo("Creating Released Entity: " + releasedEntity.getName() + " related to object: " + entity.getName());
+ newReleasedEntities++;
+
+ //
+ // copy primary key
+ //
+ MTAttribute primaryKeyAttribute = new MTAttribute(entity.getParserRuleContext(),
+ releasedEntity, entity.getPrimaryKeyAttribute().getTypeName(),
+ entity.getPrimaryKeyAttribute().getName());
+ MTPrimaryKey newPrimaryKey = new MTPrimaryKey(entity.getPrimaryKey().getParserRuleContext());
+ newPrimaryKey.addAttribute(primaryKeyAttribute);
+ releasedEntity.setPrimaryKey(newPrimaryKey);
+
+
+ //
+ // Create relationship from this Released entity back to the "release" entity
+ //
+ MTRelationship releaseFKRelationship = new MTRelationship(
+ releasedEntity.getParserRuleContext(),
+ ECStringUtil.Uncapitalize(releaseEntity.getName()),
+ releasedEntity.getName(),
+ HalfRelationshipPlurality.ONE,
+ releaseEntity.getName(), true, true, null, null, null);
+ releaseFKRelationship.addTag("ignore");
+ releasedEntity.addRelationship(releaseFKRelationship);
+ releasedEntity.addConstituentEntity(MTCompositeEntity.ReleaseTag, releaseEntity);
+ relationshipsToResolve.add(releaseFKRelationship);
+
+ // create a one to many relationship on the release entity to this composite entity
+ MTRelationship releaseRelationship = new MTRelationship(
+ releasedEntity.getParserRuleContext(),
+ ECStringUtil.Uncapitalize(compositEntityNamePrefix) + ECStringUtil.Capitalize(ECStringUtil.Pluralize(entity.getName())),
+ releaseEntity.getName(),
+ HalfRelationshipPlurality.MANY,
+ releasedEntity.getName(), true, false, null, null, null);
+ releaseEntity.addRelationship(releaseRelationship);
+ relationshipsToResolve.add(releaseRelationship);
+
+ //
+ // copy attributes
+ //
+ for (MTAttribute attribute : entity.getAttributes()) {
+ MTAttribute releasedAttribute = MTAttribute.Copy(attribute, releasedEntity);
+ releasedEntity.addAttribute(releasedAttribute);
+ }
+
+ //
+ // copy relationships but change TO relationship to the Released version
+ //
+ for (MTRelationship relationship : entity.getRelationships()) {
+ MTEntity toEntity = relationship.getTo().getEntity();
+
+ //ECLog.logInfo("CHECKING relationships for: " + entity.getName() + " relationship to entity: " + toEntity.getName());
+ MTCompositeEntity toCompositeEntity = compositeEntityConstituentMap.get(toEntity.getName());
+ if (toCompositeEntity != null && toCompositeEntity.isCompositeEntity() && !((MTCompositeEntity) releasedEntity).hasConstituentEntity(MTCompositeEntity.ReleaseTag)) {
+ //ECLog.logInfo("COPYING CONSTITUENT ENTITY (" + MTCompositeEntity.ReleaseTag + ") "+ toCompositeEntity.getConstituentEntity(MTCompositeEntity.ReleaseTag).getName() + " to Composite Entity: " + toCompositeEntity.getName());
+ MTEntity toEntityReleaseEntity = toCompositeEntity.getConstituentEntity(MTCompositeEntity.ReleaseTag);
+ releasedEntity.addConstituentEntity(MTCompositeEntity.ReleaseTag, toEntityReleaseEntity);
+// compositeEntityConstituentMap.put(toEntityReleaseEntity.getName(), releasedEntity);
+ }
+
+ if (!compositeEntityConstituentMap.containsKey(toEntity.getName())) {
+ // we can copy the relationship exactly - just have to fix the "from" which is done
+ // in the Copy method.
+ MTRelationship newRelationship = MTRelationship.Copy(relationship, releasedEntity, null);
+ //ECLog.logInfo("Adding Composite Object Relationship to non-composite entity: " + newRelationship.getName());
+ releasedEntity.addRelationship(newRelationship);
+ continue;
+ }
+ if (compositeEntityConstituentMap.containsKey(toEntity.getName())) {
+ MTEntity releasedToEntity = compositeEntityConstituentMap.get(toEntity.getName());
+ releasedToEntity.addRealm(realm);
+ //ECLog.logInfo("Adding REALM " + realm + " to release entity: " + releasedToEntity.getName());
+ MTRelationship releasedRelationship = MTRelationship.Copy(relationship, releasedEntity, releasedToEntity);
+ releasedEntity.addRelationship(releasedRelationship);
+ }
+ }
+ releasedRelatedEntityMap.put(releasedEntity.getName(), releasedEntity);
+ releasedEntity.getModule().addEntity(releasedEntity);
+ space.addEntity(releasedEntity);
+ }
+ }
+ }
+ while (foundReleasedRelated);
+ //ECLog.logInfo("FOUND " + newReleasedEntities + " released entities");
+ //
+ // Now that all the composite entities have been created, we can copy the relationships.
+ //
+ //ECLog.logInfo("Resolving relationships...");
+ for (MTCompositeEntity compositeEntity : compositeEntityList) {
+ //ECLog.logInfo("Looking at composite entity: " + compositeEntity.getName());
+ MTEntity objectEntity = compositeEntity.getConstituentEntity(MTCompositeEntity.ObjectTag);
+ MTEntity versionEntity = compositeEntity.getConstituentEntity(MTCompositeEntity.VersionTag);
+ for (MTRelationship relationship : objectEntity.getRelationships()) {
+ if (compositeEntity.hasRelationshipNamed(relationship.getName())) {
+ //ECLog.logWarning("We have already copied relationship: " + relationship);
+ continue;
+ }
+ MTEntity toEntity = relationship.getTo().getEntity();
+ // don't take relationships to version
+ if (versionEntity != null && toEntity.getName().equals(versionEntity.getName())) {
+ continue;
+ }
+ if (!compositeEntityConstituentMap.containsKey(toEntity.getName())) {
+ // we can copy the relationship exactly - just have to fix the "from" which is done
+ // in the Copy method.
+ MTRelationship newRelationship = MTRelationship.Copy(relationship, compositeEntity, null);
+ //ECLog.logInfo("---- Adding Composite Object Relationship to non-composite entity: " + newRelationship);
+ compositeEntity.addRelationship(newRelationship);
+ relationshipsToResolve.add(newRelationship);
+ continue;
+ }
+ MTCompositeEntity toCompositeEntity = compositeEntityConstituentMap.get(toEntity.getName());
+ MTRelationship newRelationship = MTRelationship.Copy(relationship, compositeEntity, toCompositeEntity);
+ compositeEntity.addRelationship(newRelationship);
+ relationshipsToResolve.add(newRelationship);
+ //ECLog.logInfo("Adding Composite Object Relationship to Composite object: " + newRelationship);
+ }
+ if (versionEntity != null) {
+ //ECLog.logInfo("Entity " + compositeEntity.getName() + " has Version entity " + versionEntity.getName() + " has " + versionEntity.getRelationshipCount() + " relationships.");
+ for (MTRelationship relationship : versionEntity.getRelationships()) {
+ MTEntity toEntity = relationship.getTo().getEntity();
+ if (toEntity == null) {
+ ECLog.logWarning("Relationship " + versionEntity.getName() + "." + relationship.getName() + " does NOT have a \"to\" entity!");
+ continue;
+ }
+ // don't take relationships to object parent
+ if (relationship.isParent() && toEntity.getName().equals(objectEntity.getName())) {
+ continue;
+ }
+ if (!compositeEntityConstituentMap.containsKey(toEntity.getName())) {
+ // we can copy the relationship exactly - just have to fix the "from" which is done
+ // in the Copy method.
+ MTRelationship newRelationship = MTRelationship.Copy(relationship, compositeEntity, null);
+ //ECLog.logInfo("Adding Composite Version Relationship to non-composite entity: " + newRelationship.getName());
+ compositeEntity.addRelationship(newRelationship);
+ relationshipsToResolve.add(newRelationship);
+ continue;
+ }
+ MTCompositeEntity toCompositeEntity = compositeEntityConstituentMap.get(toEntity.getName());
+ MTRelationship newRelationship = MTRelationship.Copy(relationship, compositeEntity, toCompositeEntity);
+ //ECLog.logInfo("Adding Composite Version Relationship to Composite object: " + newRelationship);
+ compositeEntity.addRelationship(newRelationship);
+ relationshipsToResolve.add(newRelationship);
+ }
+ }
+ compositeEntity.getModule().addEntity(compositeEntity);
+ space.addEntity(compositeEntity);
+ }
+
+ // ------------------------------------------------
+ // It turns out that for any entity related to a
+ // Released entity we also need to create a Released
+ // version of it so it.
+ // ------------------------------------------------
+
+ for (MTRelationship relationship : relationshipsToResolve) {
+ relationship.resolveReferences(space, 3);
+ if (relationship.getTo().getEntity() == null) {
+ ECLog.logFatal("Why cant we resolve this relationship?: " + relationship.getName());
+ }
+ else {
+ //ECLog.logInfo("Newly created relationship is resolved: " + relationship.getFrom().getEntityName() + "." + relationship.getName());
+ }
+ }
+// for (MTModule module : space.getModules()) {
+//
+// if (module.isIncluded()) {
+// continue;
+// }
+//
+// for (MTEntity entity : module.getEntities()) {
+// if (entity.isIncluded() || entity.isExtern() || entity.isImplicit()
+// || entity.isSecondary()) {
+// continue;
+// }
+// if (releasedRelatedEntityMap.containsKey(entity.getName())) {
+// continue; // we have already determined this is release related
+// }
+// //ECLog.logInfo("FOUND NON-RELEASED ENTITY: " + entity.getName());
+// }
+// }
+ }
+}
diff --git a/src/main/java/org/entityc/compiler/transform/TransformManager.java b/src/main/java/org/entityc/compiler/transform/TransformManager.java
index 938643b..4d2a7dc 100644
--- a/src/main/java/org/entityc/compiler/transform/TransformManager.java
+++ b/src/main/java/org/entityc/compiler/transform/TransformManager.java
@@ -6,7 +6,6 @@
package org.entityc.compiler.transform;
-import org.entityc.compiler.EntityCompiler;
import org.entityc.compiler.cmdline.CommandLine;
import org.entityc.compiler.model.MTRoot;
@@ -22,6 +21,7 @@ public static void LoadBuiltins(MTRoot model, String configurationName) {
// Server
AddTransform(new MTVImplicitTransform(model, configurationName));
AddTransform(new MTVPostgresTransform(model, configurationName));
+ AddTransform(new MTVReleasedTransform(model, configurationName));
}
public static void AddTransform(MTBaseTransform transform) {
diff --git a/src/main/java/org/entityc/compiler/transform/template/tree/FTOutlet.java b/src/main/java/org/entityc/compiler/transform/template/tree/FTOutlet.java
index c053a52..0d97a31 100644
--- a/src/main/java/org/entityc/compiler/transform/template/tree/FTOutlet.java
+++ b/src/main/java/org/entityc/compiler/transform/template/tree/FTOutlet.java
@@ -68,6 +68,9 @@ public void transform(FTTransformSession session) {
session.setValue("__outlet", this);
session.setValue("__author", author);
author.transformFromOutlet(session);
+ if (session.isPendingReturn()) {
+ session.setPendingReturn(false); // now clear it
+ }
session.removeValue("__outlet");
session.removeValue("__author");
if (author.getScope() == FTPublishScope.Author) {
diff --git a/src/main/java/org/entityc/compiler/transform/template/tree/FTTransformSession.java b/src/main/java/org/entityc/compiler/transform/template/tree/FTTransformSession.java
index dba7326..dde29bc 100644
--- a/src/main/java/org/entityc/compiler/transform/template/tree/FTTransformSession.java
+++ b/src/main/java/org/entityc/compiler/transform/template/tree/FTTransformSession.java
@@ -34,6 +34,8 @@
import java.util.Stack;
import java.util.function.Predicate;
+import static org.entityc.compiler.transform.template.tree.FTLog.Level.FATAL;
+
public class FTTransformSession {
private static final List kUnasignable = Arrays.asList("null", "true", "false");
@@ -72,7 +74,11 @@ public FTTransformSession(MTRoot root, MTConfiguration configuration, FTTemplate
addReadonlyNamedValue("space", space);
addReadonlyNamedValue("rootTemplate", templateTransform);
if (template.getDefaultDomainName() != null) {
- addReadonlyNamedValue("domain", space.getDomainWithName(template.getDefaultDomainName()));
+ MTDomain defaultDomain = space.getDomainWithName(template.getDefaultDomainName());
+ if (defaultDomain == null) {
+ ECLog.logFatal("Unable to find default name named: " + template.getDefaultDomainName());
+ }
+ addReadonlyNamedValue("domain", defaultDomain);
}
setValue("__assert_info", false);
setValue("__assert_debug", false);
diff --git a/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTFullnameFilter.java b/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTFullnameFilter.java
index 27c03a2..cf7b5e7 100644
--- a/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTFullnameFilter.java
+++ b/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTFullnameFilter.java
@@ -8,6 +8,8 @@
import org.antlr.v4.runtime.ParserRuleContext;
import org.entityc.compiler.model.domain.MTDomainBased;
+import org.entityc.compiler.model.entity.MTAttribute;
+import org.entityc.compiler.model.entity.MTRelationship;
import org.entityc.compiler.transform.template.tree.FTTransformSession;
import org.entityc.compiler.transform.template.tree.expression.FTConstant;
import org.entityc.compiler.transform.template.tree.expression.FTExpression;
@@ -27,6 +29,10 @@ public FTFullnameFilter() {
+ "This can be useful for construction a Java import statement, for instance.");
addSingleInputType(MTDomainBased.class,
"Any class that is with respect to a domain (such as MTDEntity).");
+ addSingleInputType(MTAttribute.class,
+ "An attribute.");
+ addSingleInputType(MTRelationship.class,
+ "A relationship.");
addFilterParam(delimiterParam);
}
@@ -45,7 +51,12 @@ public Object filter(ParserRuleContext ctx, FTTransformSession session, Object i
}
if (input instanceof MTDomainBased) {
return ((MTDomainBased) input).getFullname(delim);
+ } else if (input instanceof MTAttribute) {
+ return ((MTAttribute) input).getEntityName() + delim + ((MTAttribute) input).getName();
+ } else if (input instanceof MTRelationship) {
+ return ((MTRelationship) input).getFrom().getEntityName() + delim + ((MTRelationship) input).getName();
}
+
return null;
}
}
diff --git a/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTJoinFilter.java b/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTJoinFilter.java
index f145f43..2b22677 100644
--- a/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTJoinFilter.java
+++ b/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTJoinFilter.java
@@ -10,6 +10,7 @@
import org.entityc.compiler.model.foundation.MFArray;
import org.entityc.compiler.transform.template.tree.FTTransformSession;
import org.entityc.compiler.transform.template.tree.expression.FTExpression;
+import org.entityc.compiler.util.ECStringUtil;
import java.util.List;
import java.util.Map;
@@ -32,6 +33,7 @@ public Object filter(ParserRuleContext ctx, FTTransformSession session, Object i
String delim = " ";
if (hasOptionValue(options, delimiterOption)) {
delim = getOptionStringValue(options, delimiterOption);
+ delim = ECStringUtil.ProcessParserString(delim);
}
if (input instanceof String) {
String inputString = (String) input;
diff --git a/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTNameAsFilter.java b/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTNameAsFilter.java
new file mode 100644
index 0000000..4461bc1
--- /dev/null
+++ b/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTNameAsFilter.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019-2022 The EntityC Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.md file in the project root.
+ */
+
+package org.entityc.compiler.transform.template.tree.filter;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.entityc.compiler.model.domain.MTNamingMethod;
+import org.entityc.compiler.transform.template.tree.FTTransformSession;
+import org.entityc.compiler.transform.template.tree.expression.FTExpression;
+import org.entityc.compiler.transform.template.tree.expression.FTOperand;
+import org.entityc.compiler.util.ECLog;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class FTNameAsFilter extends FTFilter {
+
+ public FTNameAsFilter() {
+ super(null, "nameas",
+ "Changes the input string (considered a \"name\" because it is using camel case) to another string based on the specified method.");
+ this.addFilterParam(new FTFilterParam("method",
+ "Specifies the naming method: " + String.join(", ", Arrays.stream(MTNamingMethod.values()).map(MTNamingMethod::getName).toArray(String[]::new))));
+ addSingleInputType(String.class, "The camel case name string to change.");
+ }
+
+ @Override
+ public Object filter(ParserRuleContext ctx, FTTransformSession session, Object input, List paramValues, Map options) {
+ checkInput(ctx, input, paramValues, options);
+
+ if (paramValues.size() == 0) {
+ ECLog.logFatal(ctx, "Must specify a naming method. Valid values are: " + String.join(", ", Arrays.stream(MTNamingMethod.values()).map(MTNamingMethod::getName).toArray(String[]::new)));
+ }
+
+ if (input instanceof String) {
+ String inputString = (String) input;
+ FTExpression methodParam = paramValues.get(0);
+ String methodName = null;
+ if (methodParam.isOperand()) {
+ methodName = ((FTOperand) methodParam).getName();
+ }
+ else
+ {
+ ECLog.logFatal(ctx, "Naming method must be specified directly. For example: entity.name|nameas:uppercase");
+ }
+ MTNamingMethod namingMethod = MTNamingMethod.fromName(methodName);
+ if (namingMethod == null) {
+ ECLog.logFatal(ctx, "Unknown naming method: " + methodName);
+ }
+ return namingMethod.rename(inputString);
+ }
+
+ return null;
+ }
+}
diff --git a/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTReverseFilter.java b/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTReverseFilter.java
index 8c8f54d..771889d 100644
--- a/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTReverseFilter.java
+++ b/src/main/java/org/entityc/compiler/transform/template/tree/filter/FTReverseFilter.java
@@ -11,11 +11,7 @@
import org.entityc.compiler.model.domain.MTDEAttribute;
import org.entityc.compiler.model.domain.MTDERelationship;
import org.entityc.compiler.model.domain.MTDEntity;
-import org.entityc.compiler.model.entity.MTAttribute;
-import org.entityc.compiler.model.entity.MTEntity;
-import org.entityc.compiler.model.entity.MTEnum;
-import org.entityc.compiler.model.entity.MTEnumItem;
-import org.entityc.compiler.model.entity.MTRelationship;
+import org.entityc.compiler.model.entity.*;
import org.entityc.compiler.model.foundation.MFObject;
import org.entityc.compiler.transform.template.tree.FTTemplate;
import org.entityc.compiler.transform.template.tree.FTTransformSession;
@@ -36,6 +32,7 @@ public FTReverseFilter() {
this.addCollectionInputType(MTAttribute.class);
this.addCollectionInputType(MTDEAttribute.class);
this.addCollectionInputType(MTEntity.class);
+ this.addCollectionInputType(MTCompositeEntity.class);
this.addCollectionInputType(MTDEntity.class);
this.addCollectionInputType(MTModule.class);
this.addCollectionInputType(MTEnum.class);
diff --git a/test/java/org/entityc/compiler/EntityCompilerTest.java b/test/java/org/entityc/compiler/EntityCompilerTest.java
index 49b12b0..86238ef 100644
--- a/test/java/org/entityc/compiler/EntityCompilerTest.java
+++ b/test/java/org/entityc/compiler/EntityCompilerTest.java
@@ -24,6 +24,12 @@ void compileBasicEntity() throws IOException {
runTemplateTest(TestName);
}
+ @Test
+ void compileReleasedTransform() throws IOException {
+ final String TestName = "ReleasedTransform";
+ runTemplateTest(TestName);
+ }
+
private void runTemplateTest(String testName) throws IOException {
final String TestResourceDir = BASE_RESOURCE_DIR + "/" + testName;
String strTmp = System.getProperty("java.io.tmpdir");
diff --git a/test/resources/compiler/main/CompilerDocs/CompilerDocsExpected.txt b/test/resources/compiler/main/CompilerDocs/CompilerDocsExpected.txt
index e878dc4..601e395 100644
--- a/test/resources/compiler/main/CompilerDocs/CompilerDocsExpected.txt
+++ b/test/resources/compiler/main/CompilerDocs/CompilerDocsExpected.txt
@@ -374,6 +374,9 @@ These methods relate to a part of application configuration.
| `boolean` [**`hasMetadataValue(String name)`**](#class_MTSpace_hasMetadataValue) |
| Indicates whether this space has a metadata name/value for the specified name. |
|
|
+| `boolean` [**`hasRealmWithName(String realm)`**](#class_MTSpace_hasRealmWithName) |
+| Returns true if there is a realm by this name. |
+|
|
| `List` **`importEntityNames`** |
| Returns the names of the entities that have been imported into this space. |
|
|
@@ -383,6 +386,9 @@ These methods relate to a part of application configuration.
| `Object` [**`metadataValue(String name)`**](#class_MTSpace_metadataValue) |
| Spaces can define a dictionary of name/value pairs that provide some meta data about the space and basically the application. This method allows you to get a value by its name. |
|
|
+| `MTRealm` [**`realmWithName(String realm)`**](#class_MTSpace_realmWithName) |
+| Returns the realm object by its name. |
+|
|
| `MTRepository` [**`repository(String name)`**](#class_MTSpace_repository) |
| Returns the repository object by its name. |
|
|
@@ -399,6 +405,16 @@ Indicates whether this space has a metadata name/value for the specified name.
|-----|-----|
|`String name` | The name of the metadata value to return. |
+
+#### Method `boolean hasRealmWithName(String realm)`
+
+
+Returns true if there is a realm by this name.
+
+| Parameter | Description |
+|-----|-----|
+|`String realm` | *no description* |
+
@@ -411,6 +427,16 @@ Spaces can define a dictionary of name/value pairs that provide some meta data a
|-----|-----|
|`String name` | The name of the meta data. |
+
+#### Method `MTRealm realmWithName(String realm)`
+
+
+Returns the realm object by its name.
+
+| Parameter | Description |
+|-----|-----|
+|`String realm` | *no description* |
+
#### Method `MTRepository repository(String name)`
@@ -729,6 +755,12 @@ These methods relate to an entity.
| Method/Property |
|---|
+| `void` [**`addRealm(String realm)`**](#class_MTEntity_addRealm) |
+| Adds the entity to a realm. |
+|
|
+| `boolean` **`isCompositeEntity`** |
+| Returns true if this entity is a composite entity. |
+|
|
| `boolean` **`isDeclaredAsPrimary`** |
| Indicates whether this entity was **declared** `primary`. If the entity was **not** declared with the `primary` keyword then this will return false even if it is implied as primary. |
|
|
@@ -741,6 +773,9 @@ These methods relate to an entity.
| `boolean` **`isImplicit`** |
| Indicates whether this entity was created by the compiler because it represents an implicit entity, such as in a many-to-many relationship. |
|
|
+| `boolean` [**`isInRealm(String realm)`**](#class_MTEntity_isInRealm) |
+| Returns true if this entity is part of a realm. |
+|
|
| `boolean` **`isPrimary`** |
| Indicates whether this entity was declared `primary` or if it was inferred as primary. If an entity has a primary key it is inferred to be a primary entity. |
|
|
@@ -759,6 +794,37 @@ These methods relate to an entity.
| `MTSpace` **`space`** |
| Returns the space in which this entity was declared. |
+
+#### Method `void addRealm(String realm)`
+
+
+Adds the entity to a realm.
+
+| Parameter | Description |
+|-----|-----|
+|`String realm` | *no description* |
+
+
+
+
+
+
+
+#### Method `boolean isInRealm(String realm)`
+
+
+Returns true if this entity is part of a realm.
+
+| Parameter | Description |
+|-----|-----|
+|`String realm` | *no description* |
+
+
+
+
+
+
+
### Entity Template Category
These methods relate to entity templates.
@@ -848,6 +914,9 @@ These methods relate to attributes.
|
|
| `boolean` **`hasBitFields`** |
| Indicates whether this entity defines any bit fields. |
+|
|
+| `MTRelationship` [**`relationshipNamed(String name)`**](#class_MTEntity_relationshipNamed) |
+| Returns an relationship of this entity with the specified name. |
#### Method `MTAttribute attributeByFullName(String fullName)`
@@ -916,6 +985,16 @@ Indicates whether any of the attributes of this entity are of the specified data
+
+#### Method `MTRelationship relationshipNamed(String name)`
+
+
+Returns an relationship of this entity with the specified name.
+
+| Parameter | Description |
+|-----|-----|
+|`String name` | The name of the relationship to return. |
+
### Relationship Category
These methods relate to relationships.
@@ -949,6 +1028,9 @@ These methods relate to relationships.
| `boolean` **`hasPrimaryParentRelationship`** |
| Indicates whether this entity has a primary parent relationship. A primary parent relationship is one which is declared `parent` and **not** declared `optional`. |
|
|
+| `boolean` [**`hasRelationshipNamed(String name)`**](#class_MTEntity_hasRelationshipNamed) |
+| Indicates whether this entity has an relationship with the specified name. |
+|
|
| `boolean` **`hasRelationships`** |
| Indicates whether this entity defines any relationships. |
|
|
@@ -973,6 +1055,9 @@ These methods relate to relationships.
| `int` **`relationshipCount`** |
| Returns the number of declared relationships. |
|
|
+| `MTRelationship` [**`relationshipWithToEntity(MTEntity toEntity)`**](#class_MTEntity_relationshipWithToEntity) |
+| Returns the first relationships from this entity to a specified entity. This method should be used when only one is expected. |
+|
|
| `List` **`relationships`** |
| Returns the list of relationships of this entity. |
|
|
@@ -1039,6 +1124,16 @@ Indicates whether it has a least one relationship declared as parent to the spec
|`MTEntity parentEntity` | *no description* |
+
+#### Method `boolean hasRelationshipNamed(String name)`
+
+
+Indicates whether this entity has an relationship with the specified name.
+
+| Parameter | Description |
+|-----|-----|
+|`String name` | *no description* |
+
@@ -1065,6 +1160,16 @@ Returns a relationship of this entity by name. If a relationship is not found wi
|`String relationshipName` | The name of the relationship to return. |
+
+#### Method `MTRelationship relationshipWithToEntity(MTEntity toEntity)`
+
+
+Returns the first relationships from this entity to a specified entity. This method should be used when only one is expected.
+
+| Parameter | Description |
+|-----|-----|
+|`MTEntity toEntity` | The entity that the relationships are **to**. |
+
#### Method `List relationshipsWithToEntity(MTEntity toEntity)`
@@ -1131,6 +1236,9 @@ These methods relate to the tagging.
| `boolean` [**`hasRelationshipTagged(String tag)`**](#class_MTEntity_hasRelationshipTagged) |
| Indicates whether this entity has at least one relationship with the specified tag. |
|
|
+| `boolean` [**`hasRelationshipToEntityNamed(String toEntityName)`**](#class_MTEntity_hasRelationshipToEntityNamed) |
+| Indicates whether this entity has at least one relationship to a named other entity. |
+|
|
| `boolean` [**`hasRelationshipToEntityTagged(String tag)`**](#class_MTEntity_hasRelationshipToEntityTagged) |
| Indicates whether the entity **to** which a relationship references is tagged with the specified tag. |
|
|
@@ -1190,6 +1298,16 @@ Indicates whether this entity has at least one relationship with the specified t
|-----|-----|
|`String tag` | The tag with which to search. |
+
+#### Method `boolean hasRelationshipToEntityNamed(String toEntityName)`
+
+
+Indicates whether this entity has at least one relationship to a named other entity.
+
+| Parameter | Description |
+|-----|-----|
+|`String toEntityName` | The name of the other entity. |
+
#### Method `boolean hasRelationshipToEntityTagged(String tag)`
@@ -1262,6 +1380,9 @@ These methods relate to enums.
| `boolean` **`isExtern`** |
| Indicates whether this was declared as `extern`. |
|
|
+| `MTEnumItem` [**`item(Long index)`**](#class_MTEnum_item) |
+| Returns an item by its index. |
+|
|
| `List` **`items`** |
| Gets the enum items. |
|
|
@@ -1271,6 +1392,22 @@ These methods relate to enums.
| `String` **`name`** |
| Gets the name of this enum. |
+
+
+
+
+#### Method `MTEnumItem item(Long index)`
+
+
+Returns an item by its index.
+
+| Parameter | Description |
+|-----|-----|
+|`Long index` | *no description* |
+
+
+
+
### Tagging Category
These methods relate to the tagging.
@@ -1572,6 +1709,9 @@ These methods relate to relationships.
| `MTRelationshipHalf` **`from`** |
| Returns the "from" part of the relationship which references the entity in which this relationship is defined. |
|
|
+| `MTEntity` **`implicitToEntity`** |
+| Gets the entity on the other side of an implicit many-to-many entity. |
+|
|
| `boolean` **`isImplicit`** |
| Indicates whether the relationship was created because although it was not declared it can be implied based on relationships declared to this entity. |
|
|
@@ -1651,6 +1791,9 @@ These methods relate to data types.
| `boolean` **`isByteArrayType`** |
| Indicates whether this type is both an array type and also `byte` data type. |
|
|
+| `boolean` **`isDataType`** |
+| Indicates whether this type is the `data` data type. |
+|
|
| `boolean` **`isDateType`** |
| Indicates whether this type is the `date` data type. |
|
|
@@ -1683,6 +1826,7 @@ These methods relate to data types.
+
#### Method `boolean isNativeDataType(DataType dataType)`
@@ -1764,6 +1908,7 @@ Model classes that are domain specific are of this type. The classes are briefly
|[`MTDEAttribute`](#class_MTDEAttribute)|Represents an attribute in your model in the context of a domain.|
|[`MTDEAttributeConstraintExpression`](#class_MTDEAttributeConstraintExpression)|Represents a constraint on an attribute in the form of an expression.|
|[`MTDERelationship`](#class_MTDERelationship)|Represents a relationship in your model in the context of a domain.|
+|[`MTDERelationshipField`](#class_MTDERelationshipField)|Represents a field (attribute or relationship) associated with the __to__ entity of the relationship.|
|[`MTDEntity`](#class_MTDEntity)|Represents an entity in your model in the context of a domain.|
|[`MTDEnum`](#class_MTDEnum)|Represents an enum in the context of a domain.|
|[`MTDEnumItem`](#class_MTDEnumItem)|Represents an enum item in the context of a domain.|
@@ -1957,6 +2102,9 @@ These methods relate to relationships.
| `String` **`explicitName`** |
| If this relationship was explicitly renamed within its domain, it will return that name. Otherwise it will return `null`. |
|
|
+| `Collection` **`fields`** |
+| Returns all the declared fields of this relationship. |
+|
|
| `String` [**`fullname(String delim)`**](#class_MTDERelationship_fullname) |
| This returns the full name of this domain relationship which includes not only its domain based name but is also preceded with the domain's entity's full name. The delimiter can be provided which is used between all parts of the full name. |
|
|
@@ -1992,6 +2140,7 @@ These methods relate to relationships.
+
#### Method `String fullname(String delim)`
@@ -2032,6 +2181,15 @@ Returns whether this relationship's "to" entity is tagged with the specified tag
|`String tag` | The tag with which to check. |
+
+## MTDERelationshipField Class
+
+
+Represents a field (attribute or relationship) associated with the __to__ entity of the relationship.
+
+This class has the following methods broken up into categories:
+
+
## MTDEntity Class
@@ -2235,6 +2393,12 @@ These methods relate to relationships.
| `MTDERelationship` [**`domainEntityRelationshipByName(String name, boolean createIfNeeded)`**](#class_MTDEntity_domainEntityRelationshipByName) |
| Returns the domain specific version of the specified relationship. |
|
|
+| `boolean` **`hasDeclaredDomainRelationships`** |
+| Indicates if any relationships were declared in this domain entity declaration. |
+|
|
+| `boolean` **`hasParentRelationship`** |
+| Indicates whether this domain entity has a parent relationship. A parent relationship is one that has been declared as `parent` |
+|
|
| `boolean` **`hasPrimaryParentRelationship`** |
| Indicates whether this domain entity has a primary parent relationship. A primary parent relationship is one that has been declared as `parent` and **not** declared `optional`. |
|
|
@@ -2263,6 +2427,8 @@ Returns the domain specific version of the specified relationship.
+
+
### Tagging Category
These methods relate to the tagging.
@@ -2706,6 +2872,7 @@ The model classes of this type are intended to provide support for foundation ty
| Class | Description |
|-----|-----|
|[`MFArray`](#class_MFArray)|This class represents a ordered array of objects. To create an empty array you can use: `$[let myList = @[]@]` then can use these methods on that variable (`myList` in this example) to access the array functionality that is exposed here.|
+|[`MFMap`](#class_MFMap)|This class represents a map of objects. To create an empty map you can use: `$[let myMap = @{}@]` then can use these methods on that variable (`myMap` in this example) to access the map functionality that is exposed here.|
|[`MFSet`](#class_MFSet)|This class represents a unique set of objects. You cannot create an object of this class in template code, however, some classes have methods that will return such an object. Since this class does not offer methods to manipulate the object, it should be considered immutable. You can iterate through the items in a set using the `foreach` instruction. For example: `$[foreach item in mySet] ... $[/foreach]` would allow you to process each item(object) in the set.|
@@ -2743,6 +2910,9 @@ These methods don't really have a category.
| `Object` **`first`** |
| Returns the first item in the array. |
|
|
+| `Object` [**`get(Integer index)`**](#class_MFArray_get) |
+| Returns the specified item by its index into the array. |
+|
|
| `Object` [**`get(Long index)`**](#class_MFArray_get) |
| Returns the specified item by its index into the array. |
|
|
@@ -2795,6 +2965,16 @@ Indicates if the array contains the specified object.
+
+#### Method `Object get(Integer index)`
+
+
+Returns the specified item by its index into the array.
+
+| Parameter | Description |
+|-----|-----|
+|`Integer index` | The index into the array that points to the item to be returned. |
+
#### Method `Object get(Long index)`
@@ -2829,6 +3009,138 @@ Allows you to remove a specified object from the array. This method returns the
+
+## MFMap Class
+
+
+This class represents a map of objects. To create an empty map you can use: `$[let myMap = @{}@]` then can use these methods on that variable (`myMap` in this example) to access the map functionality that is exposed here.
+
+This class has the following methods broken up into categories:
+
+### Other Category
+
+These methods don't really have a category.
+
+| Method/Property |
+|---|
+| `MFMap` **`clear`** |
+| This method removes all items in the map. |
+|
|
+| `boolean` [**`containsKey(Object key)`**](#class_MFMap_containsKey) |
+| Indicates if the map contains the specified key. |
+|
|
+| `boolean` [**`containsValue(Object value)`**](#class_MFMap_containsValue) |
+| Indicates if the map contains the specified value. |
+|
|
+| `MFMap` **`copy`** |
+| Allows you to make a copy of this map. Since it returns the new map you can chain other map methods after this one. |
+|
|
+| `int` **`count`** |
+| Returns the number of items in the map. |
+|
|
+| `Object` [**`get(Object key)`**](#class_MFMap_get) |
+| Returns the value in the map by its specified key. |
+|
|
+| `boolean` **`isEmpty`** |
+| Indicates if the map is empty (no items). |
+|
|
+| `Collection` **`keys`** |
+| Returns all the keys of the map |
+|
|
+| `MFMap` [**`put(Object key, Object o)`**](#class_MFMap_put) |
+| Allows you to add an object to this array. The `do` template instruction can be used to do this (e.g., `$[do array.add(obj)]`. This method returns the array itself so you can chain other array methods after this one. |
+|
|
+| `MFMap` [**`putAll(MFMap otherMap)`**](#class_MFMap_putAll) |
+| Allows you to add all elements of another map to this map. The `do` template instruction can be used to do this (e.g., `$[do map.putAll(otherMap)]`. This method returns the map itself so you can chain other map methods after this one. |
+|
|
+| `MFMap` [**`remove(Object key)`**](#class_MFMap_remove) |
+| Allows you to remove a specified entry from the map based on its key. This method returns the map itself so you can chain other map methods after this one. |
+|
|
+| `MFMap` [**`remove(Object key, Object o)`**](#class_MFMap_remove) |
+| Allows you to remove a specified object from the map based on its key. This method returns the map itself so you can chain other map methods after this one. |
+|
|
+| `Collection` **`values`** |
+| Returns all the values of the map. When iterating this array of values with a `foreach` you do **not** need to use this method. |
+
+
+
+#### Method `boolean containsKey(Object key)`
+
+
+Indicates if the map contains the specified key.
+
+| Parameter | Description |
+|-----|-----|
+|`Object key` | The key of which to determine its presence in the map. |
+
+
+#### Method `boolean containsValue(Object value)`
+
+
+Indicates if the map contains the specified value.
+
+| Parameter | Description |
+|-----|-----|
+|`Object value` | The object of which to determine its presence in the map. |
+
+
+
+
+#### Method `Object get(Object key)`
+
+
+Returns the value in the map by its specified key.
+
+| Parameter | Description |
+|-----|-----|
+|`Object key` | The key. |
+
+
+
+
+#### Method `MFMap put(Object key, Object o)`
+
+
+Allows you to add an object to this array. The `do` template instruction can be used to do this (e.g., `$[do array.add(obj)]`. This method returns the array itself so you can chain other array methods after this one.
+
+| Parameter | Description |
+|-----|-----|
+|`Object key` | The key to put to the map. |
+|`Object o` | The object to set to the map. |
+
+
+#### Method `MFMap putAll(MFMap otherMap)`
+
+
+Allows you to add all elements of another map to this map. The `do` template instruction can be used to do this (e.g., `$[do map.putAll(otherMap)]`. This method returns the map itself so you can chain other map methods after this one.
+
+| Parameter | Description |
+|-----|-----|
+|`MFMap otherMap` | The other map to add to this map. |
+
+
+#### Method `MFMap remove(Object key)`
+
+
+Allows you to remove a specified entry from the map based on its key. This method returns the map itself so you can chain other map methods after this one.
+
+| Parameter | Description |
+|-----|-----|
+|`Object key` | The key to remove from this map. |
+
+
+#### Method `MFMap remove(Object key, Object o)`
+
+
+Allows you to remove a specified object from the map based on its key. This method returns the map itself so you can chain other map methods after this one.
+
+| Parameter | Description |
+|-----|-----|
+|`Object key` | The key to remove from this map. |
+|`Object o` | The object to remove from this map. |
+
+
+
## MFSet Class
diff --git a/test/resources/compiler/main/ReleasedTransform/ReleasedTemplate.eml b/test/resources/compiler/main/ReleasedTransform/ReleasedTemplate.eml
new file mode 100644
index 0000000..84c2d01
--- /dev/null
+++ b/test/resources/compiler/main/ReleasedTransform/ReleasedTemplate.eml
@@ -0,0 +1,73 @@
+$[*
+ The purpose of this template is to test that the ReleasedTransform worked correctly.
+*]
+$[ function CheckIfReleasedEntity
+ (entity
+ )->
+ (isReleasedEntity
+ ) ]
+ $[ let isReleasedEntity = entity.isCompositeEntity && entity.isInRealm("Released") ]
+$[/ function ]
+$[ function GetReleaseEntityPKAttribute
+ (entity
+ )->
+ (releaseEntityPKAttribute
+ ) ]
+ $[ let isReleasedEntity = entity.isCompositeEntity && entity.isInRealm("Released") ]
+ $[ if !isReleasedEntity ]
+ $[ return ]
+ $[/ if ]
+ $[ let releaseEntity = entity.getAnyConstituentEntity("release") ]
+ $[ if releaseEntity != null ]
+ $[ let releaseEntityPKAttribute = releaseEntity.primaryKeyAttribute ]
+ $[/ if ]
+$[/ function ]
+$[ function GetRelationshipToReleaseEntity
+ (entity
+ )->
+ (relationship
+ ) ]
+ $[ let isReleasedEntity = entity.isCompositeEntity && entity.isInRealm("Released") ]
+ $[ if !isReleasedEntity ]
+ $[ return ]
+ $[/ if ]
+ $[ let releaseEntity = entity.getAnyConstituentEntity("release") ]
+ $[ let relationship = null ]
+ $[ if releaseEntity != null ]
+ $[ if entity.hasRelationshipToEntityNamed(releaseEntity.name) ]
+ $[ let relationship = entity.getRelationshipWithToEntity(releaseEntity) ]
+ $[/ if ]
+ $[/ if ]
+$[/ function ]
+$[ file "" "ReleasedTransform" "txt" ]
+
+ $[ foreach entity in space.entities ]
+ $[ call CheckIfReleasedEntity(entity: entity)->(isReleasedEntity: isReleasedEntity) ]
+ $[ if !isReleasedEntity ]
+ $[ continue ]
+ $[/ if ]
+entity ${entity.name} {
+
+ D "${entity.description}"
+
+ primarykey ${entity.primaryKeyAttribute.type} ${entity.primaryKeyAttribute.name} {
+ D "${entity.primaryKeyAttribute.description}"
+ }
+
+ attributes {
+ $[ foreach attribute in entity.attributes ]
+ ${attribute.type} ${attribute.name} { D "${attribute.description}" }
+ $[/ foreach ]
+ }
+
+ relationships {
+ $[ foreach relationship in entity.relationships ]
+ ${relationship.to.plurality} ${relationship.to.entity.name} ${relationship.name} {
+ D "${relationship.description}"
+ }
+ $[/ foreach ]
+ }
+}
+
+ $[/ foreach ]
+$[/ file ]
diff --git a/test/resources/compiler/main/ReleasedTransform/ReleasedTransform.edl b/test/resources/compiler/main/ReleasedTransform/ReleasedTransform.edl
new file mode 100644
index 0000000..d069e8c
--- /dev/null
+++ b/test/resources/compiler/main/ReleasedTransform/ReleasedTransform.edl
@@ -0,0 +1,124 @@
+space RevisionedStuff {
+
+
+}
+
+module Everything
+{
+
+entity WidgetType {
+ primarykey uuid widgetTypeId
+
+ attributes {
+ string identifier
+ string title
+ optional string description
+ }
+ relationships {
+ many Widget widgets
+ }
+}
+
+entity ProductRelease {
+ primarykey uuid productReleaseId
+
+ T "release:binder"
+
+ relationships {
+ parent one ProductLineRelease productLineRelease
+ one O
+ one V
+ }
+}
+
+entity ProductLineRelease {
+ primarykey uuid productLineReleaseId
+ T "release:top"
+
+ attributes {
+ string identifier
+ string notes
+ }
+ relationships {
+ many ProductRelease as WidgetRevisionRelease {}
+ many ProductRelease as ThingRevisionRelease {}
+ }
+}
+
+entity Widget {
+ primarykey uuid widgetId
+
+ T "release:object"
+
+ attributes {
+ string identifier
+ string title
+ optional string description
+ }
+ relationships {
+ many WidgetRevision revisions
+ parent one WidgetType type
+ }
+}
+
+entity WidgetRevision {
+ primarykey uuid widgetRevisionId
+
+ T "release:version"
+
+ attributes {
+ sequential int64 number
+ optional string notes
+ }
+ relationships {
+ parent one Widget widget
+ }
+}
+
+entity Thing {
+ primarykey uuid thingId
+
+ T "release:object"
+
+ attributes {
+ string identifier
+ string title
+ optional string description
+ }
+ relationships {
+ many ThingRevision revisions
+ parent one Widget widget
+ }
+}
+
+entity ThingRevision {
+ primarykey uuid thingRevisionId
+
+ T "release:version"
+
+ attributes {
+ sequential int64 number
+ optional string notes
+ }
+ relationships {
+ parent one Thing thing
+ }
+}
+}
+
+configuration Config
+{
+ output testOutput {
+ path $(TEMP_DIR:"/tmp")
+ }
+
+ transform Released {
+ }
+
+ templates {
+ template ReleasedTemplate {
+ output primary testOutput
+ }
+ }
+}
+
diff --git a/test/resources/compiler/main/ReleasedTransform/ReleasedTransformExpected.txt b/test/resources/compiler/main/ReleasedTransform/ReleasedTransformExpected.txt
new file mode 100644
index 0000000..102c1c9
--- /dev/null
+++ b/test/resources/compiler/main/ReleasedTransform/ReleasedTransformExpected.txt
@@ -0,0 +1,77 @@
+
+entity ReleasedThing {
+
+ D ""
+
+ primarykey uuid thingId {
+ D ""
+ }
+
+ attributes {
+ string identifier { D "" }
+ string title { D "" }
+ string description { D "" }
+ int64 number { D "" }
+ string notes { D "" }
+ }
+
+ relationships {
+ ONE ProductLineRelease productLineRelease {
+ D ""
+ }
+ ONE ReleasedWidget widget {
+ D ""
+ }
+ }
+}
+
+entity ReleasedWidget {
+
+ D ""
+
+ primarykey uuid widgetId {
+ D ""
+ }
+
+ attributes {
+ string identifier { D "" }
+ string title { D "" }
+ string description { D "" }
+ int64 number { D "" }
+ string notes { D "" }
+ }
+
+ relationships {
+ ONE ProductLineRelease productLineRelease {
+ D ""
+ }
+ ONE ReleasedWidgetType type {
+ D ""
+ }
+ }
+}
+
+entity ReleasedWidgetType {
+
+ D ""
+
+ primarykey uuid widgetTypeId {
+ D ""
+ }
+
+ attributes {
+ string identifier { D "" }
+ string title { D "" }
+ string description { D "" }
+ }
+
+ relationships {
+ ONE ProductLineRelease productLineRelease {
+ D ""
+ }
+ MANY ReleasedWidget widgets {
+ D ""
+ }
+ }
+}
+