\r
VALIDATIONS = SYSDYN.Validations : L0.Library\r
\r
-SYSDYN.SysdynIssue <T ISSUE.Issue\r
-\r
+VALIDATIONS.Issue <T ISSUE.Sources.DependencyTracker.Issue\r
+ >-- VALIDATIONS.Issue.stringContexts --> L0.List <R L0.DependsOn \r
+ \r
// BASEFUNCTION\r
VALIDATIONS.Functions : L0.Library\r
VALIDATIONS.Functions.baseRealizationFunction : L0.Function\r
SYSDYN.Variable\r
@VALIDATIONS.constraint\r
VALIDATIONS.ExpressionConstraint\r
- VALIDATIONS.Expressions.ExpressionIssueSource \r
+ VALIDATIONS.Expressions.ExpressionIssueSource\r
+ @L0.assert L0.HasName "ExpressionIssueSource" \r
VALIDATIONS.Expressions.expressionValidator \r
VALIDATIONS.Functions.baseRealizationFunction \r
\r
@VALIDATIONS.constraint\r
VALIDATIONS.DependencyConstraint\r
VALIDATIONS.Dependencies.DependencyConnectionsIssueSource\r
+ @L0.assert L0.HasName "DependencyConnectionsIssueSource"\r
VALIDATIONS.Dependencies.dependencyValidator \r
VALIDATIONS.Functions.baseRealizationFunction \r
\r
SYSDYN.Enumeration\r
@VALIDATIONS.constraint\r
VALIDATIONS.EnumerationConstraint\r
- VALIDATIONS.Enumerations.EnumerationIssueSource \r
+ VALIDATIONS.Enumerations.EnumerationIssueSource\r
+ @L0.assert L0.HasName "EnumerationIssueSource" \r
VALIDATIONS.Enumerations.enumerationIndexValidator \r
VALIDATIONS.Functions.baseRealizationFunction \r
\r
@VALIDATIONS.listeningConstraint\r
VALIDATIONS.MissingDependencyConstraint\r
VALIDATIONS.Dependencies.MissingDependencyConnectionsIssueSource\r
+ @L0.assert L0.HasName "MissingDependencyConnectionsIssueSource"\r
VALIDATIONS.Dependencies.missingDependencyValidator \r
VALIDATIONS.Functions.baseRealizationFunction \r
\r
VALIDATIONS.Expressions.expressionIssueDescription : L0.Function\r
L0.HasValueType "String"\r
VALIDATIONS.Functions.path\r
- \r
+ \r
VALIDATIONS.MissingLinkIssue\r
@VALIDATIONS.issue\r
ISSUE.Severity.Warning\r
VALIDATIONS.Dependencies.missingLinkIssueDescription : L0.Function\r
L0.HasValueType "String"\r
VALIDATIONS.Functions.path\r
- \r
+ \r
VALIDATIONS.UnusedDependencyIssue\r
@VALIDATIONS.issue\r
ISSUE.Severity.Warning\r
VALIDATIONS.Dependencies.unusedDependencyIssueDescription : L0.Function \r
L0.HasValueType "String"\r
VALIDATIONS.Functions.path\r
- \r
+ \r
VALIDATIONS.NoSuchVariableIssue\r
@VALIDATIONS.issue\r
ISSUE.Severity.Error\r
VALIDATIONS.Dependencies.noSuchVariableIssueDescription : L0.Function \r
L0.HasValueType "String"\r
VALIDATIONS.Functions.path\r
- \r
+\r
+VALIDATIONS.RangeIssue\r
+ @VALIDATIONS.issue\r
+ ISSUE.Severity.Error\r
+ VALIDATIONS.Dependencies.rangeIssueDescription : L0.Function\r
+ L0.HasValueType "String"\r
+ VALIDATIONS.Functions.path \r
+ \r
+VALIDATIONS.RangeWarning\r
+ @VALIDATIONS.issue\r
+ ISSUE.Severity.Warning\r
+ VALIDATIONS.Dependencies.rangeWarningDescription : L0.Function\r
+ L0.HasValueType "String"\r
+ VALIDATIONS.Functions.path \r
+ \r
+VALIDATIONS.InvalidSheetReferenceIssue\r
+ @VALIDATIONS.issue\r
+ ISSUE.Severity.Error\r
+ VALIDATIONS.Dependencies.invalidSheetReferenceIssueDescription : L0.Function\r
+ L0.HasValueType "String"\r
+ VALIDATIONS.Functions.path \r
+ \r
VALIDATIONS.EmptyEnumerationIssue\r
@VALIDATIONS.issue\r
ISSUE.Severity.Error\r
VALIDATIONS.Enumerations.emptyEnumerationIssueDescription : L0.Function\r
L0.HasValueType "String"\r
- VALIDATIONS.Functions.path \r
-\r
+ VALIDATIONS.Functions.path \r
+ \r
+ \r
+ \r
// IssueSource template\r
VALIDATIONS.constraint : L0.Template\r
@template %type %constraint %source %validator %baseFunction\r
// Issue template\r
VALIDATIONS.issue : L0.Template\r
@template %issue %severity %description %path\r
- %issue <T ISSUE.Sources.DependencyTracker.Issue\r
+ %issue <T SYSDYN.Validations.Issue\r
L0.Asserts _ : L0.Assertion\r
L0.HasPredicate ISSUE.Issue.HasSeverity\r
L0.HasObject %severity\r
public final Resource Symbols;\r
public final Resource SysdynConnectionType;\r
public final Resource SysdynDiagramModelingRules;\r
- public final Resource SysdynIssue;\r
public final Resource SysdynModel;\r
public final Resource SysdynModel_outputInterval;\r
public final Resource SysdynModel_outputInterval_Inverse;\r
public final Resource Validations_Dependencies_DependencyConnectionsIssueSource;\r
public final Resource Validations_Dependencies_MissingDependencyConnectionsIssueSource;\r
public final Resource Validations_Dependencies_dependencyValidator;\r
+ public final Resource Validations_Dependencies_invalidSheetReferenceIssueDescription;\r
public final Resource Validations_Dependencies_missingDependencyValidator;\r
public final Resource Validations_Dependencies_missingLinkIssueDescription;\r
public final Resource Validations_Dependencies_noSuchVariableIssueDescription;\r
+ public final Resource Validations_Dependencies_rangeIssueDescription;\r
+ public final Resource Validations_Dependencies_rangeWarningDescription;\r
public final Resource Validations_Dependencies_unusedDependencyIssueDescription;\r
public final Resource Validations_DependencyConstraint;\r
public final Resource Validations_EmptyEnumerationIssue;\r
public final Resource Validations_Functions;\r
public final Resource Validations_Functions_baseRealizationFunction;\r
public final Resource Validations_Functions_path;\r
+ public final Resource Validations_InvalidSheetReferenceIssue;\r
+ public final Resource Validations_Issue;\r
+ public final Resource Validations_Issue_stringContexts;\r
+ public final Resource Validations_Issue_stringContexts_Inverse;\r
public final Resource Validations_MissingDependencyConstraint;\r
public final Resource Validations_MissingLinkIssue;\r
public final Resource Validations_NoSuchVariableIssue;\r
+ public final Resource Validations_RangeIssue;\r
+ public final Resource Validations_RangeWarning;\r
public final Resource Validations_UnusedDependencyIssue;\r
public final Resource Validations_constraint;\r
public final Resource Validations_issue;\r
public static final String Symbols = "http://www.simantics.org/Sysdyn-1.1/Symbols";\r
public static final String SysdynConnectionType = "http://www.simantics.org/Sysdyn-1.1/SysdynConnectionType";\r
public static final String SysdynDiagramModelingRules = "http://www.simantics.org/Sysdyn-1.1/SysdynDiagramModelingRules";\r
- public static final String SysdynIssue = "http://www.simantics.org/Sysdyn-1.1/SysdynIssue";\r
public static final String SysdynModel = "http://www.simantics.org/Sysdyn-1.1/SysdynModel";\r
public static final String SysdynModel_outputInterval = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/outputInterval";\r
public static final String SysdynModel_outputInterval_Inverse = "http://www.simantics.org/Sysdyn-1.1/SysdynModel/outputInterval/Inverse";\r
public static final String Validations_Dependencies_DependencyConnectionsIssueSource = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/DependencyConnectionsIssueSource";\r
public static final String Validations_Dependencies_MissingDependencyConnectionsIssueSource = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/MissingDependencyConnectionsIssueSource";\r
public static final String Validations_Dependencies_dependencyValidator = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/dependencyValidator";\r
+ public static final String Validations_Dependencies_invalidSheetReferenceIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/invalidSheetReferenceIssueDescription";\r
public static final String Validations_Dependencies_missingDependencyValidator = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/missingDependencyValidator";\r
public static final String Validations_Dependencies_missingLinkIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/missingLinkIssueDescription";\r
public static final String Validations_Dependencies_noSuchVariableIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/noSuchVariableIssueDescription";\r
+ public static final String Validations_Dependencies_rangeIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/rangeIssueDescription";\r
+ public static final String Validations_Dependencies_rangeWarningDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/rangeWarningDescription";\r
public static final String Validations_Dependencies_unusedDependencyIssueDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Dependencies/unusedDependencyIssueDescription";\r
public static final String Validations_DependencyConstraint = "http://www.simantics.org/Sysdyn-1.1/Validations/DependencyConstraint";\r
public static final String Validations_EmptyEnumerationIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/EmptyEnumerationIssue";\r
public static final String Validations_Functions = "http://www.simantics.org/Sysdyn-1.1/Validations/Functions";\r
public static final String Validations_Functions_baseRealizationFunction = "http://www.simantics.org/Sysdyn-1.1/Validations/Functions/baseRealizationFunction";\r
public static final String Validations_Functions_path = "http://www.simantics.org/Sysdyn-1.1/Validations/Functions/path";\r
+ public static final String Validations_InvalidSheetReferenceIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/InvalidSheetReferenceIssue";\r
+ public static final String Validations_Issue = "http://www.simantics.org/Sysdyn-1.1/Validations/Issue";\r
+ public static final String Validations_Issue_stringContexts = "http://www.simantics.org/Sysdyn-1.1/Validations/Issue/stringContexts";\r
+ public static final String Validations_Issue_stringContexts_Inverse = "http://www.simantics.org/Sysdyn-1.1/Validations/Issue/stringContexts/Inverse";\r
public static final String Validations_MissingDependencyConstraint = "http://www.simantics.org/Sysdyn-1.1/Validations/MissingDependencyConstraint";\r
public static final String Validations_MissingLinkIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/MissingLinkIssue";\r
public static final String Validations_NoSuchVariableIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/NoSuchVariableIssue";\r
+ public static final String Validations_RangeIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/RangeIssue";\r
+ public static final String Validations_RangeWarning = "http://www.simantics.org/Sysdyn-1.1/Validations/RangeWarning";\r
public static final String Validations_UnusedDependencyIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/UnusedDependencyIssue";\r
public static final String Validations_constraint = "http://www.simantics.org/Sysdyn-1.1/Validations/constraint";\r
public static final String Validations_issue = "http://www.simantics.org/Sysdyn-1.1/Validations/issue";\r
Symbols = getResourceOrNull(graph, URIs.Symbols);\r
SysdynConnectionType = getResourceOrNull(graph, URIs.SysdynConnectionType);\r
SysdynDiagramModelingRules = getResourceOrNull(graph, URIs.SysdynDiagramModelingRules);\r
- SysdynIssue = getResourceOrNull(graph, URIs.SysdynIssue);\r
SysdynModel = getResourceOrNull(graph, URIs.SysdynModel);\r
SysdynModel_outputInterval = getResourceOrNull(graph, URIs.SysdynModel_outputInterval);\r
SysdynModel_outputInterval_Inverse = getResourceOrNull(graph, URIs.SysdynModel_outputInterval_Inverse);\r
Validations_Dependencies_DependencyConnectionsIssueSource = getResourceOrNull(graph, URIs.Validations_Dependencies_DependencyConnectionsIssueSource);\r
Validations_Dependencies_MissingDependencyConnectionsIssueSource = getResourceOrNull(graph, URIs.Validations_Dependencies_MissingDependencyConnectionsIssueSource);\r
Validations_Dependencies_dependencyValidator = getResourceOrNull(graph, URIs.Validations_Dependencies_dependencyValidator);\r
+ Validations_Dependencies_invalidSheetReferenceIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_invalidSheetReferenceIssueDescription);\r
Validations_Dependencies_missingDependencyValidator = getResourceOrNull(graph, URIs.Validations_Dependencies_missingDependencyValidator);\r
Validations_Dependencies_missingLinkIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_missingLinkIssueDescription);\r
Validations_Dependencies_noSuchVariableIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_noSuchVariableIssueDescription);\r
+ Validations_Dependencies_rangeIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_rangeIssueDescription);\r
+ Validations_Dependencies_rangeWarningDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_rangeWarningDescription);\r
Validations_Dependencies_unusedDependencyIssueDescription = getResourceOrNull(graph, URIs.Validations_Dependencies_unusedDependencyIssueDescription);\r
Validations_DependencyConstraint = getResourceOrNull(graph, URIs.Validations_DependencyConstraint);\r
Validations_EmptyEnumerationIssue = getResourceOrNull(graph, URIs.Validations_EmptyEnumerationIssue);\r
Validations_Functions = getResourceOrNull(graph, URIs.Validations_Functions);\r
Validations_Functions_baseRealizationFunction = getResourceOrNull(graph, URIs.Validations_Functions_baseRealizationFunction);\r
Validations_Functions_path = getResourceOrNull(graph, URIs.Validations_Functions_path);\r
+ Validations_InvalidSheetReferenceIssue = getResourceOrNull(graph, URIs.Validations_InvalidSheetReferenceIssue);\r
+ Validations_Issue = getResourceOrNull(graph, URIs.Validations_Issue);\r
+ Validations_Issue_stringContexts = getResourceOrNull(graph, URIs.Validations_Issue_stringContexts);\r
+ Validations_Issue_stringContexts_Inverse = getResourceOrNull(graph, URIs.Validations_Issue_stringContexts_Inverse);\r
Validations_MissingDependencyConstraint = getResourceOrNull(graph, URIs.Validations_MissingDependencyConstraint);\r
Validations_MissingLinkIssue = getResourceOrNull(graph, URIs.Validations_MissingLinkIssue);\r
Validations_NoSuchVariableIssue = getResourceOrNull(graph, URIs.Validations_NoSuchVariableIssue);\r
+ Validations_RangeIssue = getResourceOrNull(graph, URIs.Validations_RangeIssue);\r
+ Validations_RangeWarning = getResourceOrNull(graph, URIs.Validations_RangeWarning);\r
Validations_UnusedDependencyIssue = getResourceOrNull(graph, URIs.Validations_UnusedDependencyIssue);\r
Validations_constraint = getResourceOrNull(graph, URIs.Validations_constraint);\r
Validations_issue = getResourceOrNull(graph, URIs.Validations_issue);\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;\r
import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.issues.ontology.IssueResource;\r
import org.simantics.layer0.Layer0;\r
import org.simantics.layer0.utils.direct.GraphUtils;\r
import org.simantics.operation.Layer0X;\r
} else {\r
fixHasTailAndHasHead(graph, ModelRoot);\r
addDependencies(graph, ModelRoot);\r
+ removeIssueSourcesFromModules(graph, ModelRoot);\r
addEnumerationIssueSource(graph, ModelRoot);\r
+ \r
+ activateModel(graph, ModelRoot);\r
}\r
}\r
\r
\r
}\r
\r
- protected void addDependencies(WriteGraph graph, Resource modelRoot) throws DatabaseException {\r
+ protected void removeIssueSourcesFromModules(WriteGraph graph, Resource modelRoot) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ IssueResource ISSUE = IssueResource.getInstance(graph);\r
+ \r
+ for(Resource m : findAllModelsAndModules(graph, modelRoot)) {\r
+ if(m.equals(modelRoot))\r
+ continue;\r
+ \r
+ // Module may contain issue sources due to legacy reasons. Remove these. \r
+ for(Resource issueSource : graph.syncRequest(new ObjectsWithType(m, L0.ConsistsOf, ISSUE.IssueSource))) {\r
+ // Issues are created to virtual graphs, so they should not need to be removed. Just in case they are created, remove them first\r
+ for(Resource issue : graph.getObjects(issueSource, ISSUE.IssueSource_Manages)) {\r
+ RemoverUtil.remove(graph, issue);\r
+ }\r
+ \r
+ // finally remove the issue source\r
+ RemoverUtil.remove(graph, issueSource);\r
+ }\r
+ }\r
+ \r
+ }\r
+\r
+ protected void activateModel(WriteGraph graph, Resource modelRoot) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ Layer0X L0X = Layer0X.getInstance(graph);\r
+ if(!graph.hasStatement(modelRoot, L0X.IsActivatedBy)) {\r
+ Resource project = graph.getPossibleObject(modelRoot, L0.PartOf);\r
+ if(project != null) {\r
+ graph.claim(modelRoot, L0X.IsActivatedBy, project);\r
+ }\r
+ }\r
+ }\r
+\r
+ protected void addDependencies(WriteGraph graph, Resource modelRoot) throws DatabaseException {\r
Layer0 L0 = Layer0.getInstance(graph);\r
\r
ArrayList<String> links = new ArrayList<String>();\r
\r
import org.eclipse.jface.layout.GridDataFactory;\r
import org.eclipse.jface.layout.GridLayoutFactory;\r
-import org.eclipse.jface.text.BadLocationException;\r
import org.eclipse.jface.text.Document;\r
import org.eclipse.jface.text.IDocument;\r
import org.eclipse.jface.text.PaintManager;\r
import org.eclipse.swt.events.KeyListener;\r
import org.eclipse.swt.events.VerifyEvent;\r
import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Point;\r
import org.eclipse.swt.graphics.RGB;\r
import org.eclipse.swt.widgets.Composite;\r
import org.eclipse.swt.widgets.Display;\r
import org.eclipse.swt.widgets.Table;\r
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;\r
-import org.eclipse.swt.graphics.Point;\r
-import org.simantics.sysdyn.expressionParser.Token;\r
+import org.simantics.sysdyn.ui.utils.SyntaxError;\r
\r
/**\r
* Field for displaying a part of an expression. Expression field uses SourceViewer\r
public static final String MISSING_LINK = "MissingLink";\r
public static final String NO_SUCH_VARIABLE = "NoSuchVariable";\r
public static final String SYNTAX_ERROR = "SyntaxError";\r
- \r
+ public static final String SYNTAX_WARNING = "SyntaxWarning";\r
+\r
String oldExpression;\r
\r
ColorManager cManager = new ColorManager();\r
painter.setAnnotationTypeColor(NO_SUCH_VARIABLE, new Color(this.getDisplay(), 255,0,0));\r
painter.addAnnotationType(SYNTAX_ERROR);\r
painter.setAnnotationTypeColor(SYNTAX_ERROR, new Color(this.getDisplay(), 255,0,0)); \r
+ painter.addAnnotationType(SYNTAX_WARNING);\r
+ painter.setAnnotationTypeColor(SYNTAX_WARNING, new Color(this.getDisplay(), 255,215,0));\r
\r
_sourceViewer.setDocument(_document, _annotationModel);\r
\r
}\r
}\r
\r
- /**\r
- * Sets syntax error for the given token\r
- * @param token Token with syntax error\r
- * @param message Message to be displayed in tool tips\r
- */\r
- public void setSyntaxError(Token token, String message){\r
- setSyntaxError(token.image, message, token.beginLine, token.beginColumn, token.endLine, token.endColumn);\r
- }\r
- \r
- /**\r
- * Sets syntax error for the given token\r
- * @param token Token with syntax error\r
- * @param message Message to be displayed in tool tips\r
- */\r
- public void setSyntaxError(org.simantics.sysdyn.tableParser.Token token, String message){\r
- setSyntaxError(token.image, message, token.beginLine, token.beginColumn, token.endLine, token.endColumn);\r
- }\r
- \r
- /**\r
- * Sets syntax error to given location\r
- * @param image Token image\r
- * @param message Message to be displayed in tool tips\r
- * @param beginLine Begin line\r
- * @param beginColumn Begin column\r
- * @param endLine End line\r
- * @param endColumn End column\r
- */\r
- public void setSyntaxError(String image, String message, int beginLine, int beginColumn, int endLine, int endColumn) {\r
- int start = 0;\r
- int offset = this._document.getLength();\r
- if(image != null && this._document.getLength() > 0) {\r
- try {\r
- start = this._document.getLineOffset(beginLine - 1) + beginColumn - 1;\r
- offset = this._document.getLineOffset(endLine - 1) + endColumn - start;\r
- } catch (BadLocationException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- setSyntaxError(start, offset, SYNTAX_ERROR, message == null ? "Syntax Error" : message);\r
- }\r
\r
/**\r
- * Sets syntax error to given start and offset\r
- * @param start Start location\r
- * @param offset Offset\r
- * @param type Error type (SYNTAX_ERROR, MISSING_LINK, NO_SUCH_VARIABLE)\r
- * @param text Message to be displayedin tool tips\r
+ * Sets a syntax error annoattion to the expression field\r
+ * @param syntaxError\r
*/\r
- public void setSyntaxError(int start, int offset, String type, String text) {\r
+ public void setSyntaxError(SyntaxError syntaxError) {\r
Annotation annotation = new Annotation(false);\r
- annotation.setType(type);\r
- annotation.setText(text);\r
- Position p = new Position(start, offset);\r
+ annotation.setType(syntaxError.getType());\r
+ annotation.setText(syntaxError.getMessage());\r
+ Position p = new Position(syntaxError.getStart(_document), syntaxError.getOffset(_document));\r
_annotationModel.addAnnotation(annotation, p); \r
}\r
\r
import org.simantics.sysdyn.tableParser.ParseException;\r
import org.simantics.sysdyn.tableParser.TableParser;\r
import org.simantics.sysdyn.tableParser.Token;\r
+import org.simantics.sysdyn.ui.utils.SyntaxError;\r
import org.simantics.ui.SimanticsUI;\r
\r
public class WithLookupExpression implements IExpression {\r
Double.parseDouble(yTokens.get(i).image)));\r
}\r
} catch (ParseException e1) {\r
- this.lookup.setSyntaxError(e1.currentToken, "Syntax Error");\r
+ this.lookup.setSyntaxError(new SyntaxError(e1.currentToken, "Syntax Error"));\r
System.out.println("MESSAGE: " + e1.getMessage());\r
return;\r
}\r
import org.simantics.sysdyn.modelParser.Token;\r
import org.simantics.sysdyn.modelParser.TokenMgrError;\r
import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.sysdyn.ui.utils.SyntaxError;\r
import org.simantics.ui.SimanticsUI;\r
import org.simantics.ui.utils.AdaptionUtils;\r
\r
modelParser.parse_composition();\r
} catch (ParseException e1) {\r
Token token = e1.currentToken;\r
- modelicaCode.setSyntaxError(token.image, "Syntax error", token.beginLine, token.beginColumn, token.endLine, token.endColumn);\r
+ modelicaCode.setSyntaxError(new SyntaxError(token.image, "Syntax error", token.beginLine, token.beginColumn, token.endLine, token.endColumn));\r
} catch (TokenMgrError err) {\r
String message = err.getMessage();\r
String line = message.substring(0, message.indexOf(","));\r
Integer endLine = Integer.parseInt(line);\r
Integer endColumn = Integer.parseInt(column);\r
Token token = modelParser.token;\r
- modelicaCode.setSyntaxError(token.image, "Syntax error", token.endLine, token.endColumn, endLine, endColumn);\r
+ modelicaCode.setSyntaxError(new SyntaxError(token.image, "Syntax error", token.endLine, token.endColumn, endLine, endColumn));\r
} catch (NumberFormatException e) {\r
\r
}\r
import org.simantics.sysdyn.representation.EnumerationIndex;\r
import org.simantics.sysdyn.representation.IElement;\r
import org.simantics.sysdyn.representation.Variable;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
\r
public class ArrayVariableUtils {\r
\r
\r
- /**\r
- * Checks if the given range elements can be applied to the given variable.\r
- * \r
- * @param graph ReadGraph\r
- * @param variable Resource of the variable \r
- * @param range Range elements in the correct order. Elements are separated in range definition by ',' \r
- * @return true if range is valid, false if not\r
- * @throws DatabaseException\r
- */\r
- public static Map<Integer, String> isRangeValid(ReadGraph graph, Variable variable, String[] elements) throws DatabaseException {\r
- if(variable == null)\r
- return null;\r
- Map<Integer, String> result = new HashMap<Integer, String>();\r
- // Not an array variable\r
- if(variable.getArrayIndexes() == null || \r
- variable.getArrayIndexes().getEnumerations() == null || \r
- variable.getArrayIndexes().getEnumerations().size() == 0) {\r
- for(int i = 0; i < elements.length ; i++)\r
- result.put(i, "Variable is not an array variable");\r
- return result;\r
- }\r
- ArrayList<Enumeration> enumerations = variable.getArrayIndexes().getEnumerations();\r
- // Too many elements\r
- if(elements.length > enumerations.size()) {\r
- result.put( enumerations.size(), "Too many elements");\r
- } else if(elements.length < enumerations.size()) {\r
- result.put( elements.length > 0 ? elements.length - 1 : 0, "Too few elements");\r
- }\r
- \r
- \r
- for(int i = 0; i < elements.length && i < enumerations.size(); i++) {\r
- if(elements[i].trim().equals(":"))\r
- continue;\r
- if(elements[i].indexOf(":") != elements[i].lastIndexOf(":")) {\r
- result.put( i, "Too many ':' elements");\r
- continue;\r
- }\r
+ /**\r
+ * Checks if the given range elements can be applied to the given variable.\r
+ * \r
+ * @param graph ReadGraph\r
+ * @param variable Resource of the variable \r
+ * @param range Range elements in the correct order. Elements are separated in range definition by ',' \r
+ * @return true if range is valid, false if not\r
+ * @throws DatabaseException\r
+ */\r
+ public static Map<Integer, SyntaxError> isRangeValid(ReadGraph graph, Variable variable, String[] elements) throws DatabaseException {\r
+ SyntaxError error;\r
+ if(variable == null)\r
+ return null;\r
+ Map<Integer, SyntaxError> result = new HashMap<Integer, SyntaxError>();\r
+ // Not an array variable\r
+ if(variable.getArrayIndexes() == null || \r
+ variable.getArrayIndexes().getEnumerations() == null || \r
+ variable.getArrayIndexes().getEnumerations().size() == 0) {\r
+ for(int i = 0; i < elements.length ; i++) {\r
+ error = new SyntaxError();\r
+ error.setMessage("Variable is not an array variable");\r
+ error.setType(ExpressionField.SYNTAX_ERROR);\r
+ result.put(i, error);\r
+ }\r
\r
- String[] rangeComponents = elements[i].split(":");\r
- if(rangeComponents.length > 2){\r
- result.put( i, "Too many ':' elements");\r
- continue;\r
- }\r
- // Single range component, equals to the enumeration at that index\r
- if(rangeComponents.length == 1 && rangeComponents[0].trim().equals(enumerations.get(i).getName()))\r
- continue;\r
- // one or two range components, they all equal to individual indexes in the enumeration\r
- for(String r : rangeComponents) {\r
- r = r.trim();\r
- boolean componentIsValid = false;\r
- for(EnumerationIndex ei : enumerations.get(i).getEnumerationIndexes()) {\r
- if(ei.getName().equals(r)) {\r
- componentIsValid = true;\r
- break;\r
- }\r
- }\r
- if(!componentIsValid)\r
- result.put( i, "Invalid range");\r
- }\r
- }\r
- if(result.isEmpty())\r
- return null;\r
- else\r
- return result;\r
- }\r
+ return result;\r
+ }\r
+ ArrayList<Enumeration> enumerations = variable.getArrayIndexes().getEnumerations();\r
+ // Too many elements\r
+ if(elements.length > enumerations.size()) {\r
+ error = new SyntaxError();\r
+ error.setMessage( "Too many elements");\r
+ error.setType(ExpressionField.SYNTAX_ERROR);\r
+ result.put(enumerations.size(), error);\r
+ } else if(elements.length < enumerations.size()) {\r
+ error = new SyntaxError();\r
+ error.setMessage("Too few elements");\r
+ error.setType(ExpressionField.SYNTAX_ERROR);\r
+ result.put(elements.length > 0 ? elements.length - 1 : 0, error);\r
+ }\r
\r
- /**\r
- * Checks if the given range can be applied to the given variable.\r
- * \r
- * @param graph ReadGraph\r
- * @param variable Resource of the variable \r
- * @param range Range WITHOUT [ and ] brackets\r
- * @return true if range is valid, false if not\r
- * @throws DatabaseException\r
- */\r
- public static boolean isRangeValid(ReadGraph graph, Resource variable, String range) throws DatabaseException {\r
- if(variable == null)\r
- return true;\r
- String[] elements = range.split(",");\r
- SysdynModel model = ModelUtils.getModel(graph, variable);\r
- if(model == null)\r
- return false;\r
- IElement e = model.getElement(variable);\r
- if(e != null && e instanceof Variable) {\r
- Variable v = (Variable) e;\r
- Map<Integer, String> result = isRangeValid(graph, v, elements);\r
- if(result == null)\r
- return true;\r
- else\r
- return false;\r
- } else {\r
- return false;\r
- }\r
- }\r
+\r
+ for(int i = 0; i < elements.length && i < enumerations.size(); i++) {\r
+ if(elements[i].trim().equals(":"))\r
+ continue;\r
+ if(elements[i].indexOf(":") != elements[i].lastIndexOf(":")) {\r
+ error = new SyntaxError();\r
+ error.setMessage( "Too many ':' elements");\r
+ error.setType(ExpressionField.SYNTAX_ERROR);\r
+ result.put(i, error);\r
+ continue;\r
+ }\r
+\r
+ String[] rangeComponents = elements[i].split(":");\r
+ if(rangeComponents.length > 2){\r
+ error = new SyntaxError();\r
+ error.setMessage( "Too many ':' elements");\r
+ error.setType(ExpressionField.SYNTAX_ERROR);\r
+ result.put(i, error);\r
+ continue;\r
+ }\r
+ // Single range component, equals to the enumeration at that index\r
+ if(rangeComponents.length == 1 && rangeComponents[0].trim().equals(enumerations.get(i).getName()))\r
+ continue;\r
+ // one or two range components, they all equal to individual indexes in the enumeration\r
+ for(String r : rangeComponents) {\r
+ r = r.trim();\r
+ boolean componentIsValid = false;\r
+ for(EnumerationIndex ei : enumerations.get(i).getEnumerationIndexes()) {\r
+ if(ei.getName().equals(r)) {\r
+ componentIsValid = true;\r
+ break;\r
+ }\r
+ }\r
+ if(!componentIsValid) {\r
+ // Check if the range is an integer that is between 0 and enumeration indexes size\r
+ try {\r
+ int index = Integer.parseInt(r);\r
+ int min = 1;\r
+ int max = enumerations.get(i).getEnumerationIndexes().size();\r
+ if(index >= min && index <= max) {\r
+ componentIsValid = true;\r
+ error = new SyntaxError();\r
+ error.setMessage("Using numbers as array indexes is not encouraged");\r
+ error.setType(ExpressionField.SYNTAX_WARNING);\r
+ result.put(i, error);\r
+ } else {\r
+ error = new SyntaxError();\r
+ error.setMessage("Invalid array index " + index + ". Numbered index must be between " + min + " and " + max + " unless the enumeration is overridden. In that case, ignore this warning.");\r
+ error.setType(ExpressionField.SYNTAX_ERROR);\r
+ result.put(i, error);\r
+ }\r
+ } catch (NumberFormatException e) {\r
+ error = new SyntaxError();\r
+ error.setMessage("Invalid range");\r
+ error.setType(ExpressionField.SYNTAX_ERROR);\r
+ result.put(i, error);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if(result.isEmpty())\r
+ return null;\r
+ else\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Checks if the given range can be applied to the given variable.\r
+ * \r
+ * @param graph ReadGraph\r
+ * @param variable Resource of the variable \r
+ * @param range Range WITHOUT [ and ] brackets\r
+ * @return true if range is valid, false if not\r
+ * @throws DatabaseException\r
+ */\r
+ public static boolean isRangeValid(ReadGraph graph, Resource variable, String range) throws DatabaseException {\r
+ if(variable == null)\r
+ return true;\r
+ String[] elements = range.split(",");\r
+ SysdynModel model = ModelUtils.getModel(graph, variable);\r
+ if(model == null)\r
+ return false;\r
+ IElement e = model.getElement(variable);\r
+ if(e != null && e instanceof Variable) {\r
+ Variable v = (Variable) e;\r
+ if(isRangeValid(graph, v, elements) == null)\r
+ return true;\r
+ else\r
+ return false;\r
+ } else {\r
+ return false;\r
+ }\r
+ }\r
}\r
\r
import java.io.StringReader;\r
import java.util.ArrayList;\r
+import java.util.Collections;\r
import java.util.HashMap;\r
import java.util.HashSet;\r
import java.util.Iterator;\r
functionReferences.put(ef, parser.getFunctionCallReferences());\r
\r
} catch (ParseException e1) {\r
- ef.setSyntaxError(e1.currentToken, "Syntax Error");\r
+ ef.setSyntaxError(new SyntaxError(e1.currentToken, "Syntax Error"));\r
} catch (TokenMgrError err) {\r
- ef.setSyntaxError(0, textString.length(), ExpressionField.SYNTAX_ERROR, "Expression contains unsupported characters");\r
+ ef.setSyntaxError(new SyntaxError(0, textString.length(), ExpressionField.SYNTAX_ERROR, "Expression contains unsupported characters"));\r
}\r
}\r
\r
\r
+ // Get model configuration\r
+ SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
+ SysdynModel model = sdm.getModel(configuration);\r
+ try {\r
+ model.update();\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ Configuration conf = model.getConfiguration();\r
+ \r
+ // Check variable references\r
final HashMap<String, Variable> modelVariables = new HashMap<String, Variable>();\r
HashSet<String> ignoreVariables = new HashSet<String>();\r
-\r
if(!variables.isEmpty() || !functionReferences.isEmpty()) {\r
Set<String> noSuchVariables = new HashSet<String>();\r
- SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
- SysdynModel model = sdm.getModel(configuration);\r
- try {\r
- model.update();\r
- } catch (DatabaseException e1) {\r
- e1.printStackTrace();\r
- }\r
-\r
- Configuration conf = model.getConfiguration();\r
ArrayList<IElement> elements = conf.getElements();\r
for(IElement e : elements) {\r
if(e instanceof Variable) {\r
// Examine sheets\r
for(ExpressionField ef : functionReferences.keySet()) {\r
for(String key : functionReferences.get(ef).keySet()) {\r
- String[] parts = key.split("\\.");\r
- Object current = conf;\r
- for(int i = 0; i < parts.length && current != null; i++) {\r
- current = getElement(current, parts[i]);\r
- }\r
\r
- if(current == null && conf.getModuleType() != null) {\r
- // Sheets are currently located in the model root. Try to find the sheet.\r
- current = conf.getModuleType().getParent(); // Get module type parent (should be a model)\r
- if(current instanceof Model)\r
- current = getElement(((Model)current).getModelConfiguration(), parts[0]); // Try to get the sheet\r
- }\r
- \r
- if(current != null && current instanceof Sheet) {\r
- Sheet sheet = (Sheet) current;\r
- String e = ef.getExpression();\r
- int start = 0, end = 0, call = 0;\r
- String cellOrRange = null;\r
- while((call = e.indexOf(key, end)) >= 0) {\r
- start = e.indexOf("(", call) +1;\r
- end = e.indexOf(")", start);\r
- if(start < 0 || end < 0 || end < start) {\r
- break;\r
- }\r
- Pattern p = Pattern.compile("[-\\+\\*\\/\\(\\)\\{\\}\\[\\],\\.\\t\\n\\r\\f]");\r
- cellOrRange = e.substring(start, end);\r
- Matcher m = p.matcher(cellOrRange);\r
- if (m.find() || cellOrRange.split(":").length > 2) {\r
- ef.setSyntaxError(start, end - start, ExpressionField.SYNTAX_ERROR, "Not a valid cell or range");\r
- }\r
- }\r
-\r
- List<Token> tokens = functionReferences.get(ef).get(key);\r
- for(Token cell : tokens) {\r
- List<Token> refs = references.get(ef).get(cell.image);\r
- if(refs != null)\r
- refs.remove(cell);\r
- if(!sheet.getCells().containsKey(cell.image))\r
- ef.setSyntaxError(cell.image, "Invalid cell", cell.beginLine, cell.beginColumn, cell.endLine, cell.endColumn); \r
- }\r
-\r
+ List<SyntaxError> errors = examineSheetReferences(conf, key, functionReferences.get(ef).get(key), ef.getExpression(), references.get(ef));\r
+ if(errors != null) {\r
+ for(SyntaxError error : errors)\r
+ ef.setSyntaxError(error);\r
}\r
}\r
}\r
\r
+ // Examine variable references\r
for(String v : variables) {\r
-\r
- if(modelVariables.get(v) instanceof Enumeration || modelVariables.get(v) instanceof Sheet) {\r
- ignoreVariables.add(v);\r
- }\r
-\r
- // Reference to some other module, spreadsheet or enumeration\r
- if(v.contains(".")) {\r
- String[] parts = v.split("\\.");\r
- Object parent = conf;\r
- for(int i = 0; i < parts.length && parent != null; i++) {\r
- parent = getElement(parent, parts[i]);\r
- }\r
- if(parent == null) {\r
+ ReferenceOption option = getReferenceOption(conf, v);\r
+ switch(option) {\r
+ case DOES_NOT_EXIST:\r
noSuchVariables.add(v);\r
- } else {\r
+ break;\r
+ case CANNOT_BE_CONNECTED:\r
ignoreVariables.add(v);\r
- }\r
- } else if(!modelVariables.keySet().contains(v)) {\r
- noSuchVariables.add(v);\r
+ break;\r
+ case CAN_BE_CONNECTED:\r
}\r
}\r
\r
} \r
\r
\r
+ for(final ExpressionField ef : ranges.keySet()) {\r
+ List<SyntaxError> errors = new ArrayList<SyntaxError>();\r
+ // RANGES\r
+ errors.addAll(examineArrayRanges(conf, ranges.get(ef), forIndices.get(ef)));\r
+ \r
+ // ENUMERATION REFERENCES IN FOR-LOOPS\r
+ errors.addAll(examineEnumerationReferences(conf, enumerationReferences.get(ef)));\r
\r
- HashMap<ExpressionField, HashMap<Token, String>> errors = new HashMap<ExpressionField, HashMap<Token, String>>();\r
- HashMap<Token, String> result = null;\r
+ for(SyntaxError error : errors)\r
+ ef.setSyntaxError(error);\r
+ } \r
+ }\r
+ \r
+ \r
+ static public List<SyntaxError> examineArrayRanges(\r
+ final Configuration configuration,\r
+ final HashMap<String, List<List<Token>>> ranges,\r
+ final HashMap<Token, List<Token>> forIndices) {\r
+ \r
+ List<SyntaxError> result = Collections.emptyList();\r
+ try {\r
+ result = SimanticsUI.getSession().syncRequest(new Read<List<SyntaxError>>() {\r
\r
- for(final ExpressionField ef : ranges.keySet()) {\r
+ @Override\r
+ public List<SyntaxError> perform(ReadGraph graph) throws DatabaseException {\r
+ return examineArrayRanges(graph, configuration, ranges, forIndices);\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return result;\r
+ }\r
\r
- // RANGES\r
- try {\r
- result = SimanticsUI.getSession().syncRequest(new Read<HashMap<Token, String>>() {\r
-\r
- @Override\r
- public HashMap<Token, String> perform(ReadGraph graph) throws DatabaseException {\r
- HashMap<Token, String> result = new HashMap<Token, String>();\r
- for(String s : ranges.get(ef).keySet()) {\r
- if(ranges.get(ef).containsKey(s)) {\r
- for(List<Token> l : ranges.get(ef).get(s)) {\r
- String[] ss = new String[l.size()];\r
- for(int i = 0; i < l.size(); i++) {\r
- ss[i] = l.get(i).image;\r
- }\r
- Map<Integer, String> invalidRanges = ArrayVariableUtils.isRangeValid(graph, modelVariables.get(s), ss);\r
- if(invalidRanges != null && !invalidRanges.isEmpty()) {\r
- for(Integer i : invalidRanges.keySet()) {\r
- result.put(l.get(i), invalidRanges.get(i));\r
- }\r
- }\r
- }\r
+ static public List<SyntaxError> examineEnumerationReferences(Configuration configuration, HashMap<String, List<Token>> enumRefList) {\r
+ ArrayList<SyntaxError> result = new ArrayList<SyntaxError>();\r
+ for(String enumeration : enumRefList.keySet()) {\r
+ for(Token et : enumRefList.get(enumeration)) {\r
+ Object o = getElement(configuration, enumeration);\r
+ if(o != null && o instanceof Enumeration) {\r
+ boolean isFound = false;\r
+ Enumeration e = (Enumeration)o;\r
+\r
+ if(enumeration.equals(et.image) ||\r
+ "size".equals(et.image) || \r
+ "elements".equals(et.image)){\r
+ // The full enumeration\r
+ isFound = true;\r
+ } else {\r
+ for(EnumerationIndex ei : e.getEnumerationIndexes()) {\r
+ if(ei.getName().equals(et.image)) {\r
+ isFound = true;\r
+ break;\r
}\r
- } \r
- return result;\r
+ }\r
}\r
- });\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
\r
- // FOR-INDICES\r
-\r
- HashMap<Token, List<Token>> indexList = forIndices.get(ef);\r
- for(Token t : indexList.keySet()) {\r
- boolean isFound = false;\r
- if(indexList.get(t) != null) {\r
- for(Token rt : indexList.get(t)) {\r
- if(rt.image.equals(t.image)) {\r
- isFound = true;\r
- // remove range token from invalid ranges\r
- result.remove(rt);\r
- break;\r
+ if(!isFound) {\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("Enumeration ");\r
+ sb.append(enumeration);\r
+ sb.append(" has no such index.\nAvailable indexes are: ");\r
+ Iterator<EnumerationIndex> iterator = e.getEnumerationIndexes().iterator();\r
+ while(iterator.hasNext()) {\r
+ sb.append(iterator.next().getName());\r
+ if(iterator.hasNext()) \r
+ sb.append(", ");\r
}\r
+ result.add(new SyntaxError(et, sb.toString()));\r
}\r
- }\r
- if(!isFound) {\r
- result.put(t, "Invalid index");\r
+\r
+\r
+ } else {\r
+ result.add(new SyntaxError(et, "No such enumeration (" + enumeration + ")")); \r
}\r
}\r
+ }\r
+ return result;\r
+ }\r
\r
- // ENUMERATION REFERENCES IN FOR-LOOPS\r
- HashMap<String, List<Token>> enumRefList = enumerationReferences.get(ef);\r
- for(String enumeration : enumRefList.keySet()) {\r
- for(Token et : enumRefList.get(enumeration)) {\r
- Variable v = modelVariables.get(enumeration);\r
- if(v != null && v instanceof Enumeration) {\r
- boolean isFound = false;\r
- Enumeration e = (Enumeration)v;\r
-\r
- if(enumeration.equals(et.image) ||\r
- "size".equals(et.image) || \r
- "elements".equals(et.image)){\r
- // The full enumeration\r
- isFound = true;\r
- } else {\r
- for(EnumerationIndex ei : e.getEnumerationIndexes()) {\r
- if(ei.getName().equals(et.image)) {\r
- isFound = true;\r
- break;\r
- }\r
- }\r
- }\r
+ /**\r
+ * \r
+ * @param graph\r
+ * @param configuration\r
+ * @param ranges\r
+ * @param forIndices\r
+ * @return\r
+ * @throws DatabaseException\r
+ */\r
+ static public List<SyntaxError> examineArrayRanges(\r
+ ReadGraph graph, \r
+ Configuration configuration,\r
+ HashMap<String, List<List<Token>>> ranges,\r
+ HashMap<Token, List<Token>> forIndices) throws DatabaseException {\r
+ HashMap<Token, SyntaxError> errors = new HashMap<Token, SyntaxError>();\r
+ for(String name : ranges.keySet()) {\r
+ if(ranges.get(name) != null) {\r
+ for(List<Token> l : ranges.get(name)) {\r
+ String[] rangeReferences = new String[l.size()];\r
+ for(int i = 0; i < l.size(); i++) {\r
+ rangeReferences[i] = l.get(i).image;\r
+ }\r
\r
- if(!isFound) {\r
- StringBuilder sb = new StringBuilder();\r
- sb.append("Enumeration ");\r
- sb.append(enumeration);\r
- sb.append(" has no such index.\nAvailable indexes are: ");\r
- Iterator<EnumerationIndex> iterator = e.getEnumerationIndexes().iterator();\r
- while(iterator.hasNext()) {\r
- sb.append(iterator.next().getName());\r
- if(iterator.hasNext()) \r
- sb.append(", ");\r
+ Object o = getElement(configuration, name);\r
+ if(o != null && o instanceof Variable) {\r
+ Map<Integer, SyntaxError> invalidRanges = ArrayVariableUtils.isRangeValid(graph, (Variable)o, rangeReferences);\r
+ if(invalidRanges != null && !invalidRanges.isEmpty()) {\r
+ for(Integer i : invalidRanges.keySet()) {\r
+ SyntaxError error = invalidRanges.get(i);\r
+ error.setToken(l.get(i));\r
+ errors.put(l.get(i), error);\r
}\r
- result.put(et, sb.toString());\r
}\r
-\r
-\r
- } else {\r
- result.put(et, "No such enumeration (" + enumeration + ")");\r
}\r
}\r
}\r
-\r
- errors.put(ef, result);\r
+ } \r
\r
\r
- } \r
+ // FOR-INDICES\r
\r
- for(ExpressionField ef : ranges.keySet()) {\r
- HashMap<Token, String> tokens = errors.get(ef);\r
- if(tokens == null || tokens.isEmpty()) continue;\r
- for(Token t : tokens.keySet()) {\r
- ef.setSyntaxError(t, tokens.get(t));\r
+ HashSet<Token> removes = new HashSet<Token>();\r
+ for(Token t : forIndices.keySet()) {\r
+ boolean isFound = false;\r
+ for(Token rt : errors.keySet()) {\r
+ if(rt.image.equals(t.image)) {\r
+ isFound = true;\r
+ // remove range token from invalid ranges\r
+ removes.add(rt);\r
+ }\r
}\r
+ if(!isFound) {\r
+ SyntaxError error = new SyntaxError(t, "Invalid index");\r
+ errors.put(t, error);\r
+ }\r
+ }\r
+ \r
+ for(Token t : removes)\r
+ errors.remove(t);\r
+\r
+ return new ArrayList<SyntaxError>(errors.values());\r
+ }\r
+\r
+\r
+ /**\r
+ * Examine if a given functionKey is a sheet reference and whether all the tokens in the function ( Sheet1(token1, token2) )\r
+ * are valid.\r
+ * \r
+ * @param configuration Configuration where the function is called\r
+ * @param functionKey Function name\r
+ * @param functionTokens Function parameters (sheet reference, either a cell or cell range)\r
+ * @param expression The whole expression where the function reference is\r
+ * @param expressionReferences All variable references, including function parameters\r
+ * @return A list of possible errors\r
+ */\r
+ static public List<SyntaxError> examineSheetReferences(\r
+ Configuration configuration, \r
+ String functionKey, \r
+ List<Token> functionTokens,\r
+ String expression, \r
+ HashMap<String, List<Token>> expressionReferences) {\r
+ \r
+ List<SyntaxError> result = new ArrayList<SyntaxError>();\r
+ \r
+ String[] parts = functionKey.split("\\.");\r
+ Object current = configuration;\r
+ for(int i = 0; i < parts.length && current != null; i++) {\r
+ current = getElement(current, parts[i]);\r
}\r
+ \r
+ if(current == null && configuration.getModuleType() != null) {\r
+ // Sheets are currently located in the model root. Try to find the sheet.\r
+ current = configuration.getModuleType().getParent(); // Get module type parent (should be a model)\r
+ if(current instanceof Model)\r
+ current = getElement(((Model)current).getModelConfiguration(), parts[0]); // Try to get the sheet\r
+ }\r
+ \r
+ if(current != null && current instanceof Sheet) {\r
+ Sheet sheet = (Sheet) current;\r
+ int start = 0, end = 0, call = 0;\r
+ String cellOrRange = null;\r
+ while((call = expression.indexOf(functionKey, end)) >= 0) {\r
+ start = expression.indexOf("(", call) +1;\r
+ end = expression.indexOf(")", start);\r
+ if(start < 0 || end < 0 || end < start) {\r
+ break;\r
+ }\r
+ Pattern p = Pattern.compile("[-\\+\\*\\/\\(\\)\\{\\}\\[\\],\\.\\t\\n\\r\\f]");\r
+ cellOrRange = expression.substring(start, end);\r
+ Matcher m = p.matcher(cellOrRange);\r
+ if (m.find() || cellOrRange.split(":").length > 2) {\r
+ result.add(new SyntaxError(start, end - start, ExpressionField.SYNTAX_ERROR, "Not a valid cell or range", cellOrRange));\r
+ }\r
+ }\r
+ \r
+ \r
+ for(Token cell : functionTokens) {\r
+ List<Token> refs = expressionReferences.get(cell.image);\r
+ if(refs != null)\r
+ refs.remove(cell);\r
+ if(!sheet.getCells().containsKey(cell.image))\r
+ result.add(new SyntaxError(cell.image, "Invalid cell", cell.beginLine, cell.beginColumn, cell.endLine, cell.endColumn)); \r
+ }\r
\r
+ }\r
+ \r
+ return result;\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Option for a reference. Whether the reference does not exist, \r
+ * it can be connected (normal variable) or it cannot be \r
+ * connected even though it exists (e.g. enumeration index)\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+ static public enum ReferenceOption {DOES_NOT_EXIST, CAN_BE_CONNECTED, CANNOT_BE_CONNECTED};\r
+ \r
+ /**\r
+ * Get the reference option for a reference (name) in a configuration.\r
+ * \r
+ * @param conf Configuration\r
+ * @param name Referred variable\r
+ * @return The result tells does the referred name exist and can it be connected to \r
+ */\r
+ static public ReferenceOption getReferenceOption(Configuration conf, String name) {\r
+ \r
+ String[] parts = name.split("\\.");\r
+ Object element = conf;\r
+ for(int i = 0; i < parts.length && element != null; i++) {\r
+ element = getElement(element, parts[i]);\r
+ }\r
+ if(element == null)\r
+ return ReferenceOption.DOES_NOT_EXIST;\r
+ else if(Boolean.TRUE.equals(element))\r
+ return ReferenceOption.CANNOT_BE_CONNECTED;\r
+ else if(element instanceof Variable) {\r
+ if(element instanceof Enumeration || element instanceof Sheet)\r
+ return ReferenceOption.CANNOT_BE_CONNECTED;\r
+ else\r
+ return ReferenceOption.CAN_BE_CONNECTED;\r
+ }\r
+ else \r
+ return ReferenceOption.DOES_NOT_EXIST;\r
}\r
\r
static private Object getElement(Object parent, String name) {\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+\r
+/**\r
+ * Class for containing errors caught in expression validation\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SyntaxError {\r
+ \r
+ private String type, message, image;\r
+ private int beginLine, beginColumn, endLine, endColumn;\r
+ private Integer start, offset;\r
+ \r
+ /**\r
+ * A syntax error without any info. Remember to assign location, \r
+ * type and message information.\r
+ */\r
+ public SyntaxError() {\r
+ \r
+ }\r
+ \r
+ /**\r
+ * Creates an error from expression parser token\r
+ * @param token expressionParser token\r
+ * @param message Error message\r
+ */\r
+ public SyntaxError(Token token, String message){\r
+ this(token.image, message, token.beginLine, token.beginColumn, token.endLine, token.endColumn);\r
+ }\r
+ \r
+ /**\r
+ * Creates an error from table parser token\r
+ * @param token tableParser token\r
+ * @param message Error message\r
+ */\r
+ public SyntaxError(org.simantics.sysdyn.tableParser.Token token, String message){\r
+ this(token.image, message, token.beginLine, token.beginColumn, token.endLine, token.endColumn);\r
+ }\r
+ \r
+ /**\r
+ * Create syntax error with full data\r
+ * @param image\r
+ * @param message\r
+ * @param beginLine\r
+ * @param beginColumn\r
+ * @param endLine\r
+ * @param endColumn\r
+ */\r
+ public SyntaxError(String image, String message, int beginLine, int beginColumn, int endLine, int endColumn) {\r
+ this.image = image;\r
+ this.message = message;\r
+ this.beginLine = beginLine;\r
+ this.beginColumn = beginColumn;\r
+ this.endLine = endLine;\r
+ this.endColumn = endColumn;\r
+ this.type = ExpressionField.SYNTAX_ERROR;\r
+ }\r
+ \r
+ /**\r
+ * Create syntax error with location, message and type data\r
+ * @param start\r
+ * @param offset\r
+ * @param type\r
+ * @param message\r
+ */\r
+ public SyntaxError(int start, int offset, String type, String message) {\r
+ this(start, offset, type, message, null);\r
+ }\r
+ \r
+ /**\r
+ * Create syntax error with location, message and type data\r
+ * @param start\r
+ * @param offset\r
+ * @param type\r
+ * @param message\r
+ */\r
+ public SyntaxError(int start, int offset, String type, String message, String image) {\r
+ this.image = image;\r
+ this.start = start;\r
+ this.offset = offset;\r
+ this.type = type;\r
+ this.message = message;\r
+ }\r
+ \r
+ /**\r
+ * Get start location of the issue. If start has not been set,\r
+ * document is used to calculate it.\r
+ * @param document\r
+ * @return\r
+ */\r
+ public int getStart(IDocument document) {\r
+ if(this.start != null)\r
+ return this.start;\r
+ else if(document != null){\r
+ int start = 0;\r
+ if(document.getLength() > 0) {\r
+ try {\r
+ start = document.getLineOffset(beginLine - 1) + beginColumn - 1;\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ return start;\r
+ } else {\r
+ return 0;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Get offset data of the issue. If offset has not been set,\r
+ * document is used to calculate it.\r
+ * \r
+ * @param document\r
+ * @return\r
+ */\r
+ public int getOffset(IDocument document) {\r
+ if(this.offset != null) \r
+ return this.offset;\r
+ else if(document != null){\r
+ int start = getStart(document);\r
+ int offset = document.getLength();\r
+ if(document.getLength() > 0) {\r
+ try {\r
+ offset = document.getLineOffset(endLine - 1) + endColumn - start;\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ return offset;\r
+ } else {\r
+ return 0;\r
+ }\r
+ }\r
+ \r
+ public void setToken(Token token){\r
+ this.image = token.image;\r
+ this.beginLine = token.beginLine;\r
+ this.beginColumn = token.beginColumn;\r
+ this.endLine = token.endLine;\r
+ this.endColumn = token.endColumn;\r
+ }\r
+ \r
+ public void setToken(org.simantics.sysdyn.tableParser.Token token){\r
+ this.image = token.image;\r
+ this.beginLine = token.beginLine;\r
+ this.beginColumn = token.beginColumn;\r
+ this.endLine = token.endLine;\r
+ this.endColumn = token.endColumn;\r
+ }\r
+ \r
+ public String getType() {\r
+ return type;\r
+ }\r
+\r
+ public void setType(String type) {\r
+ this.type = type;\r
+ }\r
+\r
+ public String getMessage() {\r
+ return message;\r
+ }\r
+\r
+ public void setMessage(String message) {\r
+ this.message = message;\r
+ }\r
+\r
+ public String getImage() {\r
+ return image;\r
+ }\r
+\r
+ public void setImage(String image) {\r
+ this.image = image;\r
+ }\r
+\r
+ public int getBeginLine() {\r
+ return beginLine;\r
+ }\r
+\r
+ public void setBeginLine(int beginLine) {\r
+ this.beginLine = beginLine;\r
+ }\r
+\r
+ public int getBeginColumn() {\r
+ return beginColumn;\r
+ }\r
+\r
+ public void setBeginColumn(int beginColumn) {\r
+ this.beginColumn = beginColumn;\r
+ }\r
+\r
+ public int getEndLine() {\r
+ return endLine;\r
+ }\r
+\r
+ public void setEndLine(int endLine) {\r
+ this.endLine = endLine;\r
+ }\r
+\r
+ public int getEndColumn() {\r
+ return endColumn;\r
+ }\r
+\r
+ public void setEndColumn(int endColumn) {\r
+ this.endColumn = endColumn;\r
+ }\r
+\r
+}\r
\r
import java.util.ArrayList;\r
import java.util.Collections;\r
-import java.util.Iterator;\r
import java.util.List;\r
import java.util.Set;\r
\r
import org.simantics.db.Issue;\r
import org.simantics.db.ReadGraph;\r
import org.simantics.db.Resource;\r
-import org.simantics.db.common.utils.NameUtils;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.layer0.variable.Variable;\r
-import org.simantics.issues.common.IssueUtils;\r
-import org.simantics.issues.common.StandardIssue;\r
import org.simantics.layer0.Layer0;\r
import org.simantics.scl.reflection.annotations.SCLValue;\r
import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.sysdyn.ui.utils.ExpressionUtils;\r
+import org.simantics.sysdyn.ui.utils.ExpressionUtils.ReferenceOption;\r
+import org.simantics.sysdyn.ui.utils.SyntaxError;\r
import org.simantics.utils.datastructures.collections.CollectionUtils;\r
\r
/**\r
\r
// Find all references in equations of component\r
try {\r
- references = ValidationUtils.getReferences(graph, component);\r
+ references = ValidationUtils.getAllReferences(graph, component).getVariableReferences();\r
} catch (Exception e) {\r
return result;\r
} \r
if (dependencies != null) {\r
for (String dependency : dependencies) {\r
if (references == null || !references.contains(dependency)) {\r
- Resource variable = ValidationUtils.reach(graph, component, dependency);\r
- result.add(new StandardIssue(sr.Validations_UnusedDependencyIssue, component, variable));\r
+ result.add(new IssueWithStringContext(sr.Validations_UnusedDependencyIssue, component, dependency));\r
}\r
}\r
}\r
\r
return result;\r
}\r
+ \r
+\r
+ private static Configuration getConfiguration(ReadGraph graph, Resource component) throws DatabaseException {\r
+ Resource configuration = graph.getPossibleObject(component, Layer0.getInstance(graph).PartOf);\r
+ \r
+ if(configuration == null)\r
+ return null;\r
+ \r
+ SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+ SysdynModel sm = smm.getModel(graph, configuration);\r
+ if(sm == null)\r
+ return null;\r
+\r
+ return sm.getConfiguration();\r
+ }\r
\r
/**\r
* Evaluates dependency-related issues for a component.\r
if (!graph.hasStatement(component) || !graph.hasStatement(component, l0.PartOf))\r
return Collections.emptyList();\r
\r
- // Find all variables that are linked to component with arrows\r
- Set<String> dependencies = ValidationUtils.getDependencies(graph, component);\r
- Set<String> references = null;\r
-\r
// Find all references in equations of component\r
+ References references = null;\r
try {\r
- references = ValidationUtils.getReferences(graph, component);\r
- } catch (SyntaxErrorException e) {\r
- } catch (UnsupportedCharactersException e) {\r
- } catch (UndefinedExpressionException e) {\r
+ references = ValidationUtils.getAllReferences(graph, component);\r
+ } catch (Exception e) {\r
+ return Collections.emptyList();\r
}\r
-\r
+ \r
+ Configuration configuration = getConfiguration(graph, component);\r
ArrayList<Issue> result = new ArrayList<Issue>();\r
+ \r
+ // Examine Sheet references\r
+ for(Resource expressionResource : references.functionReferences.keySet()) {\r
+ for(String functionKey : references.functionReferences.get(expressionResource).keySet()) {\r
+ List<SyntaxError> sheetErrors = ExpressionUtils.examineSheetReferences(\r
+ configuration, \r
+ functionKey, \r
+ references.functionReferences.get(expressionResource).get(functionKey), \r
+ references.expressions.get(expressionResource), \r
+ references.references.get(expressionResource));\r
+ if(sheetErrors != null) {\r
+ for(SyntaxError error : sheetErrors)\r
+ result.add(new IssueWithStringContext(sr.Validations_InvalidSheetReferenceIssue, component, error.getMessage(), error.getImage()));\r
+ }\r
+ }\r
+ }\r
+ \r
+ \r
+ // Examine dependencies\r
+ Set<String> variablesReferences = references.getVariableReferences();\r
+ if(variablesReferences == null || variablesReferences.isEmpty())\r
+ return result;\r
+ \r
+ // Find all variables that are linked to component with arrows\r
+ Set<String> dependencies = ValidationUtils.getDependencies(graph, component);\r
+ dependencies.addAll(GLOBAL_VARIABLES);\r
+ \r
+ // Remove all dependency variables from reference maps \r
+ for(String dependency : dependencies)\r
+ variablesReferences.remove(dependency);\r
\r
boolean isStock = isStock(graph, component);\r
- StandardIssue noSuchVariableIssue = null;\r
- // Check that all references have corresponding arrows\r
- if (references != null && dependencies != null) {\r
- for (String reference : references) {\r
- if (!dependencies.contains(reference) && !GLOBAL_VARIABLES.contains(reference)) {\r
- Resource variable = null;\r
- if ((variable = ValidationUtils.reach(graph, component, reference)) != null) {\r
- if(isStock) {\r
- /* Stocks do not get incoming dependencies. They are allowed\r
- to have references without arrows */\r
- } else {\r
- result.add(new StandardIssue(sr.Validations_MissingLinkIssue, component, variable));\r
- }\r
+ ReferenceOption option;\r
+\r
+ for(String reference : variablesReferences) {\r
+ option = ExpressionUtils.getReferenceOption(configuration, reference);\r
+ switch(option) {\r
+ case DOES_NOT_EXIST:\r
+ result.add(new IssueWithStringContext(sr.Validations_NoSuchVariableIssue, component, reference));\r
+ case CAN_BE_CONNECTED:\r
+ if(isStock) {\r
+ /* Stocks do not get incoming dependencies. They are allowed\r
+ to have references without arrows */\r
} else {\r
- if (noSuchVariableIssue == null) {\r
- noSuchVariableIssue = new StandardIssue(sr.Validations_NoSuchVariableIssue, component);\r
- result.add(noSuchVariableIssue);\r
- }\r
+ result.add(new IssueWithStringContext(sr.Validations_MissingLinkIssue, component, reference));\r
}\r
- }\r
+ break;\r
+ case CANNOT_BE_CONNECTED:\r
}\r
}\r
+ \r
+ \r
+ for(Resource expression : references.ranges.keySet()) {\r
+ List<SyntaxError> errors = new ArrayList<SyntaxError>();\r
+ // RANGES\r
+ errors.addAll(ExpressionUtils.examineArrayRanges(graph, configuration, references.ranges.get(expression), references.forIndices.get(expression)));\r
+ \r
+ // ENUMERATION REFERENCES IN FOR-LOOPS\r
+ errors.addAll(ExpressionUtils.examineEnumerationReferences(configuration, references.enumerationReferences.get(expression)));\r
+\r
+ for(SyntaxError error : errors) {\r
+ Resource type = sr.Validations_RangeIssue;\r
+ if(ExpressionField.SYNTAX_WARNING.equals(error.getType())) {\r
+ type = sr.Validations_RangeWarning;\r
+ }\r
+ result.add(new IssueWithStringContext(type, component, error.getMessage()));\r
\r
+ }\r
+ } \r
+ \r
return result;\r
\r
}\r
public static String missingLinkIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
throws DatabaseException {\r
\r
- List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
+ List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
String result = "Missing a link to ";\r
if (contexts.size() > 0) {\r
- Resource component = contexts.get(1);\r
- String name = NameUtils.getSafeName(graph, component);\r
- result = result + name;\r
+ result = result + contexts.get(0);\r
}\r
+\r
return result;\r
\r
}\r
@SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
public static String unusedDependencyIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
throws DatabaseException {\r
- \r
- List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
+ \r
+ List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
String result = "Unused dependency: ";\r
if (contexts.size() > 0) {\r
- Resource component = contexts.get(1);\r
- String name = NameUtils.getSafeName(graph, component);\r
- result = result + name;\r
+ result = result + contexts.get(0);\r
}\r
+\r
return result;\r
}\r
\r
@SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
public static String noSuchVariableIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
throws DatabaseException {\r
- \r
- List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
- Resource component = contexts.get(0);\r
-\r
- // Find all variables that are linked to component with arrows\r
- Set<String> dependencies = ValidationUtils.getDependencies(graph, component);\r
- Set<String> references = null;\r
-\r
- // Find all references in equations of component\r
- try {\r
- references = ValidationUtils.getReferences(graph, component);\r
- } catch (SyntaxErrorException e) {\r
- } catch (UnsupportedCharactersException e) {\r
- } catch (UndefinedExpressionException e) {\r
+ \r
+ List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
+ String result = "Refers to unexisting variable ";\r
+ if (contexts.size() > 0) {\r
+ result = result + contexts.get(0);\r
}\r
+ \r
+ return result;\r
+ }\r
+ \r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+ public static String invalidSheetReferenceIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
+ throws DatabaseException {\r
+ \r
+ List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
+ String result = "";\r
+ \r
+ if(contexts.size() == 2)\r
+ result = contexts.get(0) + ": " + contexts.get(1);\r
+ else\r
+ result = "Spreadsheet reference error";\r
\r
- ArrayList<String> result = new ArrayList<String>();\r
- // Loop all references\r
- if (references != null && dependencies != null) {\r
- for (String reference : references) {\r
- // If dependencies does not contain reference and the reference\r
- // is not reachable from component, add the name\r
- if (!dependencies.contains(reference) && ValidationUtils.reach(graph, component, reference) == null) {\r
- result.add(reference);\r
- }\r
- }\r
- }\r
- if (result.size() == 0) {\r
- return "Missing link";\r
- } else if (result.size() == 1) {\r
- return "Refers to unexisting variable " + result.get(0);\r
+ return result;\r
+ }\r
+ \r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+ public static String rangeIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
+ throws DatabaseException {\r
+ \r
+ List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
+ if (contexts.size() > 0) {\r
+ return contexts.get(0);\r
} else {\r
- StringBuilder sb = new StringBuilder();\r
- sb.append("Refers to unexisting variables ");\r
- Iterator<String> iterator = result.iterator();\r
- String reference;\r
- while (iterator.hasNext()) {\r
- reference = iterator.next();\r
- sb.append(reference);\r
- if (iterator.hasNext())\r
- sb.append(", ");\r
- }\r
- return sb.toString();\r
+ return "Range Issue";\r
}\r
}\r
+ \r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+ public static String rangeWarningDescription(ReadGraph graph, Resource converter, Variable property)\r
+ throws DatabaseException {\r
+ return rangeIssueDescription(graph, converter, property);\r
+ }\r
+ \r
+ \r
+ \r
+ \r
}\r
\r
// Try if there are any errors while parsing the expressions\r
try {\r
- ValidationUtils.getReferences(graph, component);\r
+ ValidationUtils.getAllReferences(graph, component);\r
} catch (Exception e) {\r
return Collections.<Issue>singletonList(new StandardIssue(sr.Validations_ExpressionIssue, component));\r
}\r
\r
// There should be an error\r
try {\r
- ValidationUtils.getReferences(graph, component);\r
+ ValidationUtils.getAllReferences(graph, component);\r
} catch (SyntaxErrorException e) {\r
return SYNTAX_ERROR;\r
} catch (UnsupportedCharactersException e) {\r
import org.simantics.layer0.Layer0;\r
import org.simantics.project.ontology.ProjectResource;\r
import org.simantics.scl.reflection.annotations.SCLValue;\r
-import org.simantics.simulation.ontology.SimulationResource;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
import org.simantics.sysdyn.SysdynResource;\r
\r
/**\r
\r
@SCLValue(type = "ReadGraph -> Resource -> Resource")\r
public static Resource baseRealizationFunction(ReadGraph graph, Resource model) throws DatabaseException {\r
- SysdynResource sr = SysdynResource.getInstance(graph);\r
- if(graph.isInstanceOf(model, sr.SysdynModel))\r
- return graph.getSingleObject(model, SimulationResource.getInstance(graph).HasConfiguration);\r
- else if (graph.isInheritedFrom(model, sr.Module))\r
- return graph.getSingleObject(model, StructuralResource2.getInstance(graph).IsDefinedBy);\r
- else return null;\r
-\r
+ return model;\r
}\r
\r
\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.issues.common.StandardIssue;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Issue that can have string contexts.\r
+ * \r
+ * String contexts are written to a graph like resource contexts and can be accessed \r
+ * in issue description functions. This eliminates the need for making complex calculations \r
+ * for obtaining values that have already been calculated in the issue source function. \r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class IssueWithStringContext extends StandardIssue {\r
+\r
+ String[] stringContexts;\r
+\r
+ /**\r
+ * Creates an issue with one resource context and an arbitrary number of string contexts\r
+ * @param type\r
+ * @param context\r
+ * @param stringContexts\r
+ */\r
+ public IssueWithStringContext(Resource type, Resource context, String... stringContexts) {\r
+ super(type, context);\r
+ this.stringContexts = stringContexts;\r
+ }\r
+ \r
+ /**\r
+ * Get the string contexts of this issue\r
+ * @return string contexts\r
+ */\r
+ public String[] getStringContexts() {\r
+ return stringContexts;\r
+ }\r
+ \r
+ /**\r
+ * Overridden function from StandardResource. This writes a list of string contexts to the database.\r
+ */\r
+ public void writeAdditionalContext(WriteGraph graph, Resource issue) throws DatabaseException {\r
+ super.writeAdditionalContext(graph, issue);\r
+ \r
+ // Add possible string contexts to the contexts array\r
+ if(stringContexts != null && stringContexts.length > 0) {\r
+ SysdynResource SR = SysdynResource.getInstance(graph);\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ List<Resource> contexts = new ArrayList<Resource>();\r
+ for(String s : stringContexts) {\r
+ Resource r = graph.newResource();\r
+ graph.claim(r, L0.InstanceOf, L0.String);\r
+ graph.claimValue(r, s, Bindings.STRING);\r
+ contexts.add(r);\r
+ }\r
+ graph.claim(issue, SR.Validations_Issue_stringContexts, ListUtils.create(graph, L0.List, contexts));\r
+ }\r
+ \r
+ }\r
+ \r
+ /**\r
+ * Gets string contexts from IssueWithStringContexts\r
+ * @param graph ReadGraph\r
+ * @param property issue property\r
+ * @return String contexts of issue or empty list if none is found\r
+ * @throws DatabaseException\r
+ */\r
+ public static List<String> getStringContexts(ReadGraph graph, Variable property) throws DatabaseException {\r
+ SysdynResource SR = SysdynResource.getInstance(graph);\r
+ Variable issueVariable = property.getParent(graph);\r
+ Resource issueResource = issueVariable.getRepresents(graph);\r
+ Resource list = graph.getPossibleObject(issueResource, SR.Validations_Issue_stringContexts);\r
+ if(list == null) {\r
+ return Collections.emptyList();\r
+ } else {\r
+ List<Resource> stringResources = ListUtils.toList(graph, list);\r
+ ArrayList<String> result = new ArrayList<String>(stringResources.size());\r
+ for(Resource r : stringResources) {\r
+ result.add((String)graph.getValue(r, Bindings.STRING));\r
+ }\r
+ return result;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
+\r
+/**\r
+ * Container for different types of references got from expression parser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class References {\r
+ public HashMap<Resource, String> expressions = new HashMap<Resource, String>();\r
+ public HashMap<Resource, HashMap<String, List<Token>>> references = new HashMap<Resource, HashMap<String, List<Token>>>();\r
+ public HashMap<Resource, HashMap<String, List<List<Token>>>> ranges = new HashMap<Resource, HashMap<String, List<List<Token>>>>();\r
+ public HashMap<Resource, HashMap<Token, List<Token>>> forIndices = new HashMap<Resource, HashMap<Token, List<Token>>>();\r
+ public HashMap<Resource, HashMap<String, List<Token>>> enumerationReferences = new HashMap<Resource, HashMap<String, List<Token>>>();\r
+ public HashMap<Resource, HashMap<String, List<Token>>> functionReferences = new HashMap<Resource, HashMap<String, List<Token>>>();\r
+ \r
+ \r
+ /**\r
+ * Get all variable references from all expressions of the variable in a single set\r
+ * @return All variable references\r
+ */\r
+ public Set<String> getVariableReferences() {\r
+ HashSet<String> result = new HashSet<String>();\r
+ for(HashMap<String, List<Token>> map : references.values()) {\r
+ for(String key : map.keySet()) {\r
+ if(!map.get(key).isEmpty())\r
+ result.add(key);\r
+ }\r
+ }\r
+ \r
+ return result;\r
+ }\r
+}\r
\r
import java.io.StringReader;\r
import java.util.Collection;\r
+import java.util.HashMap;\r
import java.util.HashSet;\r
import java.util.List;\r
\r
-import org.simantics.databoard.Bindings;\r
import org.simantics.db.ReadGraph;\r
import org.simantics.db.Resource;\r
import org.simantics.db.Statement;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
import org.simantics.db.common.utils.OrderedSetUtils;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.layer0.Layer0;\r
import org.simantics.sysdyn.SysdynResource;\r
import org.simantics.sysdyn.expressionParser.ExpressionParser;\r
import org.simantics.sysdyn.expressionParser.ParseException;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
import org.simantics.sysdyn.expressionParser.TokenMgrError;\r
\r
/**\r
*\r
*/\r
public class ValidationUtils {\r
-\r
+ \r
/**\r
* Find all variables that are referred to in the expressions of variable r\r
* @param graph ReadGraph\r
* @throws UnsupportedCharactersException\r
* @throws UndefinedExpressionException\r
*/\r
- public static HashSet<String> getReferences(ReadGraph graph, Resource r) throws DatabaseException, SyntaxErrorException, UnsupportedCharactersException, UndefinedExpressionException {\r
- HashSet<String> references = new HashSet<String>();\r
+ public static References getAllReferences(ReadGraph graph, Resource r) throws DatabaseException, SyntaxErrorException, UnsupportedCharactersException, UndefinedExpressionException {\r
+ References result = new References();\r
+\r
ExpressionParser parser = new ExpressionParser(new StringReader(""));\r
\r
SysdynResource sr = SysdynResource.getInstance(graph);\r
\r
if(value.length() == 0) {\r
// Empty might be allowed\r
- if(graph.isSubrelationOf(statement.getPredicate(), sr.HasEquationOrEmpty))\r
- return references;\r
- else\r
+ if(!graph.isSubrelationOf(statement.getPredicate(), sr.HasEquationOrEmpty))\r
throw new UndefinedExpressionException();\r
}\r
\r
parser.ReInit(new StringReader(value));\r
try {\r
parser.expr();\r
- references.addAll(parser.getReferences().keySet());\r
+ \r
+ HashMap<String, List<Token>> refs = parser.getReferences();\r
+ result.references.put(expression, refs);\r
+ result.ranges.put(expression, parser.getRanges());\r
+ result.forIndices.put(expression, parser.getForIndices());\r
+ result.enumerationReferences.put(expression, parser.getEnumerationReferences());\r
+ result.functionReferences.put(expression, parser.getFunctionCallReferences());\r
+ result.expressions.put(expression, value);\r
+ \r
} catch (ParseException e1) {\r
throw new SyntaxErrorException();\r
} catch (TokenMgrError err) {\r
}\r
}\r
}\r
- return references;\r
+ return result;\r
}\r
-\r
+ \r
/**\r
* Get all expressions of a variable r\r
* @param graph ReadGraph\r
return variables;\r
}\r
\r
- /**\r
- * Is reference reachable from variable\r
- * \r
- * @param graph\r
- * @param variable\r
- * @param reference\r
- * @return\r
- * @throws DatabaseException\r
- */\r
- public static boolean isReachable(ReadGraph graph, Resource variable, String reference) throws DatabaseException {\r
- if(reach(graph, variable, reference) != null)\r
- return true;\r
- else \r
- return false;\r
- }\r
-\r
- /**\r
- * Find a resource starting from variable and using reference path\r
- * \r
- * @param graph ReadGraph\r
- * @param variable starting point\r
- * @param reference path to another variable\r
- * @return found variable or null\r
- * @throws DatabaseException\r
- */\r
- public static Resource reach(ReadGraph graph, Resource variable, String reference) throws DatabaseException {\r
- Layer0 l0 = Layer0.getInstance(graph);\r
- SysdynResource sr = SysdynResource.getInstance(graph);\r
- Resource configuration = graph.getSingleObject(variable, l0.PartOf);\r
- String varName;\r
- for(Resource var : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Variable))) {\r
- varName = graph.getRelatedValue(var, l0.HasName, Bindings.STRING);\r
- if(varName != null && reference.equals(varName))\r
- return var;\r
- }\r
- return null;\r
- }\r
-\r
}\r