*******************************************************************************/\r
package org.simantics.sysdyn.ui.utils;\r
\r
+import java.io.StringReader;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
import java.util.List;\r
import java.util.StringTokenizer;\r
\r
import org.simantics.db.request.Read;\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.manager.SysdynModel;\r
import org.simantics.sysdyn.representation.Configuration;\r
import org.simantics.sysdyn.representation.Model;\r
}\r
}\r
\r
- private String replaceAllWords(String original, String find, String replacement) {\r
- if(!original.contains(find)) return original;\r
- StringBuilder result = new StringBuilder(original.length());\r
- String delimiters = "+-*/(){}[],.: \t\n\r\f";\r
- StringTokenizer st = new StringTokenizer(original, delimiters, true);\r
- while (st.hasMoreTokens()) {\r
- String w = st.nextToken();\r
- if (w.equals(find)) {\r
- result.append(replacement);\r
- } else {\r
- result.append(w);\r
- }\r
+ private static String replaceAllWords(String original, String find, String replacement) {\r
+ // Test if the new name (String find) is found in the original \r
+ // string in some format.\r
+ String pattern = ".*" + find.replace(" ", "\\s+") + ".*";\r
+ if(!original.matches(pattern)) return original;\r
+ if (find.equals(replacement)) return original;\r
+\r
+ ExpressionParser parser = new ExpressionParser(new StringReader(original));\r
+ try {\r
+ parser.expr();\r
+ } catch (ParseException e) {\r
+ // Best effort; if there are syntax errors, the replace may fail.\r
}\r
- return result.toString();\r
+ \r
+ // Collect all references\r
+ HashMap<String, List<Token>> allReferences = new HashMap<String, List<Token>>();\r
+ allReferences.putAll(parser.getReferences());\r
+ allReferences.putAll(parser.getFunctionCallReferences());\r
+ allReferences.putAll(parser.getEnumerationReferences());\r
+ \r
+ List<Token> replacedTokens = allReferences.get(find);\r
+ if (replacedTokens == null)\r
+ return original;\r
+ \r
+ // Sort the tokens so that they are in the reversed order based on\r
+ // their location in the expression.\r
+ Collections.sort(replacedTokens);\r
+ Collections.reverse(replacedTokens);\r
+ \r
+ // Go through the tokens in the reversed order\r
+ String result = new String(original);\r
+ for (Token token : replacedTokens) {\r
+ // Find the place where the last token points to in the original string\r
+ // First find where the correct line starts:\r
+ int startingPoint = 0;\r
+ for (int i = 0; i < token.beginLine - 1; ++i)\r
+ startingPoint = result.indexOf('\n', startingPoint) + 1;\r
+ // Then where the replaced string starts: \r
+ startingPoint += token.beginColumn - 1;\r
+ \r
+ // Cut the string\r
+ String begin = result.substring(0, startingPoint);\r
+ String end = result.substring(startingPoint);\r
+ \r
+ // Replace the string\r
+ String regex = find.replaceAll(" ", "\\\\s+");\r
+ end = end.replaceFirst(regex, replacement);\r
+ result = begin + end;\r
+ }\r
+ \r
+ return result;\r
}\r
\r
\r
* @throws DatabaseException\r
*/\r
public boolean isValid(final Resource variable, final String name, final boolean hasRange) {\r
+ if (variable == null || name == null)\r
+ return false;\r
+ \r
boolean result = false;\r
try {\r
result = SimanticsUI.getSession().syncRequest(new Read<Boolean>() {\r