00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 package cast.configuration;
00027
00028 import java.io.BufferedReader;
00029 import java.io.File;
00030 import java.io.FileNotFoundException;
00031 import java.io.FileReader;
00032 import java.io.IOException;
00033 import java.io.StringReader;
00034 import java.util.ArrayList;
00035 import java.util.HashMap;
00036 import java.util.HashSet;
00037 import java.util.Map;
00038 import java.util.NoSuchElementException;
00039 import java.util.regex.Pattern;
00040 import java.util.regex.Matcher;
00041
00042 import cast.cdl.COMPONENTIDSKEY;
00043 import cast.cdl.COMPONENTNUMBERKEY;
00044 import cast.cdl.CONFIGFILEKEY;
00045 import cast.cdl.ComponentDescription;
00046 import cast.cdl.ComponentLanguage;
00047 import cast.cdl.WMIDSKEY;
00048
00054 public class CASTConfigParser {
00055
00059 public static final String CONFIG_FILE_FLAG = "--config-file";
00060
00061 private static final String INCLUDE_FLAG = "INCLUDE";
00062
00063 private static final String CPP_FLAG = "CPP";
00064
00065 private static final String DD_FLAG = "DD";
00066
00067 private static final String EXTRA_COMPONENT_HEADER = "COMPONENT";
00068
00069 private static final String EXTRA_CONNECTION_HEADER = "CONNECTION";
00070
00071 private static String EXTRA_CONNECTION_ID = "extra";
00072
00073 private static final String GD_FLAG = "GD";
00074
00075 private static final String UM_FLAG = "UM";
00076
00077 private static final String MG_FLAG = "MG";
00078
00079 private static final String JAVA_FLAG = "JAVA";
00080
00081 private static final String PYTHON_FLAG = "PYTHON";
00082
00083 private static ArchitectureConfiguration m_architecture;
00084
00085 private static String m_defaultHost;
00086
00087 private static int m_extraConnectionCount;
00088
00089 private static ArrayList<ComponentDescription> m_extraDescriptions;
00090
00091 public static ArrayList<SubarchitectureConfiguration> m_subarchitectures;
00092
00093 private static HashSet<String> m_componentNames;
00094
00095 private static HashSet<String> m_subarchNames;
00096
00097 private static final String TM_FLAG = "TM";
00098
00099 private static final String TRUE_VALUE = "true";
00100
00101 private static final String WM_FLAG = "WM";
00102
00103 public static final String ARCH_HEADER = "ARCHITECTURE";
00104
00105 public static final String COMMENT_CHAR = "#";
00106
00107 public static final String HOST_HEADER = "HOST";
00108
00109 public static final String SUBARCH_HEADER = "SUBARCHITECTURE";
00110
00111 private static String CMD_VARSET = "SETVAR";
00112 private static String CMD_VARDEFAULT = "VARDEFAULT";
00113
00114
00115
00116 private static String CMD_SETHOST = "HOSTNAME";
00117 private static String HOSTVAR_PREFIX = "host:";
00118 private static String HOSTVAR_LOCALHOST = HOSTVAR_PREFIX + "localhost";
00119
00120 public static final String VAR_CURRENT_DIR = "CURRENT_DIR";
00121
00122 public static final String VAR_CONFIG_DIR = "CONFIG_DIR";
00123
00124 public static final String ERROR_LABEL = "Parser ERROR: ";
00125 public static final String WARNING_LABEL = "Parser WARNING: ";
00126
00127 private static String m_lastParse = "";
00128
00129 private static String m_currentFile;
00130
00131 public static boolean m_bPrintHostInfo = false;
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00159 private static ComponentDescription getDescriptionForName(
00160 ComponentDescription[] _descriptions, String _string) {
00161
00162 for (int i = 0; i < _descriptions.length; i++) {
00163 if (_descriptions[i].componentName.equals(_string)) {
00164 return _descriptions[i];
00165 }
00166 }
00167 return null;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 private static void init() {
00292 m_subarchitectures = new ArrayList<SubarchitectureConfiguration>();
00293 m_componentNames = new HashSet<String>();
00294 m_subarchNames = new HashSet<String>();
00295 m_architecture = null;
00296 m_defaultHost = null;
00297 m_extraConnectionCount = 0;
00298 m_extraDescriptions = new ArrayList<ComponentDescription>();
00299 m_componentNumber = 0;
00300 }
00301
00306 private static boolean isHeader(String line) {
00307 return line.startsWith(SUBARCH_HEADER) || line.startsWith(ARCH_HEADER)
00308 || (line.startsWith(HOST_HEADER) && !line.startsWith(CMD_SETHOST))
00309 || line.startsWith(EXTRA_CONNECTION_HEADER)
00310 || line.startsWith(EXTRA_COMPONENT_HEADER);
00311 }
00312
00319 private static int parseArchitecture(ArrayList<String> _lines, int _i)
00320 throws ArchitectureConfigurationException {
00321
00322
00323
00324 String line;
00325
00326 String archLine = _lines.get(_i);
00327
00328
00329 m_architecture = parseArchitectureLine(archLine);
00330
00331 int i = 0;
00332 for (i = _i + 1; i < _lines.size(); i++) {
00333 line = _lines.get(i);
00334
00335 if (!(line.startsWith(COMMENT_CHAR) || line.length() == 0)) {
00336
00337 if (isHeader(line)) {
00338 break;
00339 } else {
00340
00341 parseArchitectureComponentLine(line, m_architecture);
00342 }
00343 }
00344 }
00345
00346
00347 return i - 1;
00348 }
00349
00355 private static void parseArchitectureComponentLine(String _line,
00356 ArchitectureConfiguration _m_architecture)
00357 throws ArchitectureConfigurationException {
00358
00359
00360 EnvVarTokenizer tokeniser = new EnvVarTokenizer(_line);
00361
00362 try {
00363
00364 String lang = tokeniser.nextToken();
00365 String componentHost;
00366
00367
00368 if (!isLanguageToken(lang)) {
00369 componentHost = lang;
00370 lang = tokeniser.nextToken();
00371 } else {
00372 componentHost = m_defaultHost;
00373 if (m_defaultHost == null) {
00374 throw new ArchitectureConfigurationException(
00375 "No host specified for component. Use either HOST flag at top level or component host specification: "
00376 + _line);
00377 }
00378 componentHost = m_defaultHost;
00379 }
00380 componentHost = expandComponentHost(componentHost);
00381
00382 ComponentLanguage procLang;
00383 if (lang.equals(CPP_FLAG)) {
00384 procLang = ComponentLanguage.CPP;
00385 } else if (lang.equals(JAVA_FLAG)) {
00386 procLang = ComponentLanguage.JAVA;
00387 } else if (lang.equals(PYTHON_FLAG)) {
00388 procLang = ComponentLanguage.PYTHON;
00389 } else {
00390 throw new ArchitectureConfigurationException(
00391 "Unknown language flag: " + lang + "\nUse one of "
00392 + CPP_FLAG + "|" + JAVA_FLAG + "|"
00393 + PYTHON_FLAG + "\n" + _line);
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 throw new ArchitectureConfigurationException(
00408 "Unknown component type flag: " + lang + "\nUse on of "
00409 + WM_FLAG + "|" + TM_FLAG + "|" + DD_FLAG + "|"
00410 + UM_FLAG + "|" + GD_FLAG + "|" + MG_FLAG);
00411
00412
00413 } catch (NoSuchElementException e) {
00414 throw new ArchitectureConfigurationException(
00415 "Malformed subarch component line: " + _line, e);
00416 }
00417
00418 }
00419
00424 private static boolean isLanguageToken(String lang) {
00425 return (lang.equals(CPP_FLAG) || lang.equals(JAVA_FLAG) || lang
00426 .equals(PYTHON_FLAG));
00427 }
00428
00433 private static ArchitectureConfiguration parseArchitectureLine(
00434 String _archLine) {
00435
00436 return new ArchitectureConfiguration();
00437 }
00438
00444 private static Map<String, String> parseCommandLine(
00445 EnvVarTokenizer _tokeniser)
00446 throws ArchitectureConfigurationException {
00447 Map<String, String> prop = defaultConfig();
00448
00449 String token;
00450 String key = null;
00451 String value = null;
00452 while (_tokeniser.hasMoreTokens()) {
00453 token = _tokeniser.nextToken();
00454
00455 if (token.startsWith(COMMENT_CHAR)) {
00456 if (key != null) {
00457 prop.put(key, TRUE_VALUE);
00458 }
00459 break;
00460 }
00461
00462 else if (token.startsWith("-")) {
00463
00464 if (key != null) {
00465 prop.put(key, TRUE_VALUE);
00466 }
00467
00468
00469 key = token;
00470
00471 } else {
00472
00473
00474
00475 if (token.startsWith("\"") && (!token.endsWith("\""))) {
00476
00477 value = token;
00478 while (_tokeniser.hasMoreTokens()) {
00479 token = _tokeniser.nextToken();
00480
00481
00482 if (token.endsWith("\"")) {
00483 value += " " + token;
00484
00485
00486 value = value.substring(1, value.length() - 1);
00487
00488 prop.put(key, value);
00489 key = null;
00490 break;
00491 }
00492
00493 else {
00494 value += " " + token;
00495 }
00496 }
00497
00498 } else {
00499 if (key != null) {
00500
00501 if (token.startsWith("\"") && token.endsWith("\"")) {
00502 token = token.substring(1, token.length() - 1);
00503 }
00504
00505 prop.put(key, token);
00506 key = null;
00507 } else {
00508 throw new ArchitectureConfigurationException(
00509 "Malformed command line args. Stray value: "
00510 + token);
00511 }
00512 }
00513
00514 }
00515
00516 }
00517
00518
00519 if (key != null) {
00520 prop.put(key, TRUE_VALUE);
00521 }
00522
00523
00524
00525 prop.put(COMPONENTNUMBERKEY.value, "" + m_componentNumber++);
00526
00527
00528
00529 return prop;
00530 }
00531
00532 private static int m_componentNumber;
00533
00534 public static ArrayList<ComponentDescription> m_extras;
00535
00541 private static Map<String, String> defaultConfig() {
00542 Map<String, String> prop = new HashMap<String, String>();
00543
00544 if (m_currentFile != null) {
00545 prop.put(CONFIGFILEKEY.value, m_currentFile);
00546 }
00547 return prop;
00548 }
00549
00556 private static void parseUnmanagedComponent(EnvVarTokenizer _tokeniser,
00557 String _componentHost, ComponentLanguage _procLang,
00558 SubarchitectureConfiguration _subarch)
00559 throws ArchitectureConfigurationException {
00560
00561 String componentName = _tokeniser.nextToken();
00562 checkComponentName(componentName);
00563
00564 String className = _tokeniser.nextToken();
00565
00566 Map<String, String> config = parseCommandLine(_tokeniser);
00567
00568 _subarch.addUnmanagedComponent(componentName, className, _procLang,
00569 _componentHost, config);
00570
00571 }
00572
00573 private static void checkComponentName(String _componentName)
00574 throws ArchitectureConfigurationException {
00575 if (m_componentNames.contains(_componentName)) {
00576 throw new ArchitectureConfigurationException(
00577 "Duplicate component names not allowed: " + _componentName);
00578 } else {
00579 m_componentNames.add(_componentName);
00580 }
00581 }
00582
00583 private static void checkSubarchitectureName(String _subarchName)
00584 throws ArchitectureConfigurationException {
00585 if (m_subarchNames.contains(_subarchName)) {
00586 throw new ArchitectureConfigurationException(
00587 "Duplicate subarchitecture names not allowed: "
00588 + _subarchName);
00589 } else {
00590 m_subarchNames.add(_subarchName);
00591 }
00592 }
00593
00599 private static ComponentDescription parseExtraComponent(String _line)
00600 throws ArchitectureConfigurationException {
00601 try {
00602
00603
00604
00605
00606
00607 EnvVarTokenizer tokeniser = new EnvVarTokenizer(_line);
00608
00609
00610 tokeniser.nextToken();
00611
00612 String lang = tokeniser.nextToken();
00613 String componentHost;
00614
00615
00616 if (!isLanguageToken(lang)) {
00617 componentHost = lang;
00618 lang = tokeniser.nextToken();
00619 } else {
00620 if (m_defaultHost == null) {
00621 throw new ArchitectureConfigurationException(
00622 "No host specified for component. Use either HOST flag at top level or component host specification: "
00623 + _line);
00624 }
00625 componentHost = m_defaultHost;
00626 }
00627 componentHost = expandComponentHost(componentHost);
00628
00629
00630
00631 ComponentLanguage procLang;
00632 if (lang.equals(CPP_FLAG)) {
00633 procLang = ComponentLanguage.CPP;
00634 } else if (lang.equals(JAVA_FLAG)) {
00635 procLang = ComponentLanguage.JAVA;
00636 } else if (lang.equals(PYTHON_FLAG)) {
00637 procLang = ComponentLanguage.PYTHON;
00638 } else {
00639 throw new ArchitectureConfigurationException(
00640 "Unknown language flag: " + lang + "\nUse on of "
00641 + CPP_FLAG + "|" + JAVA_FLAG + "|"
00642 + PYTHON_FLAG + "\n" + _line);
00643 }
00644
00645 String componentName = tokeniser.nextToken();
00646 checkComponentName(componentName);
00647
00648 String className = tokeniser.nextToken();
00649
00650 Map<String, String> config = parseCommandLine(tokeniser);
00651
00652
00653
00654
00655
00656 return new ComponentDescription(componentName, className, procLang,
00657 componentHost, config, false);
00658
00659 } catch (NoSuchElementException e) {
00660 throw new ArchitectureConfigurationException(
00661 "Malformed subarch component line: \"" + _line + "\"", e);
00662 }
00663 }
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00743 private static ArrayList<ComponentDescription> parseExtras(
00744 ArrayList<String> _lines) throws ArchitectureConfigurationException {
00745
00746 ArrayList<ComponentDescription> connections = new ArrayList<ComponentDescription>();
00747
00748 for (int i = 0; i < _lines.size(); i++) {
00749
00750 String line = (String) _lines.get(i);
00751
00752
00753
00754 if (!line.startsWith(COMMENT_CHAR)) {
00755
00756
00757
00758
00759
00760 if (line.startsWith(EXTRA_COMPONENT_HEADER)) {
00761 connections.add(parseExtraComponent(line));
00762 }
00763 }
00764 }
00765
00766 return connections;
00767
00768 }
00769
00776 private static void parseManagedComponent(EnvVarTokenizer _tokeniser,
00777 String _componentHost, ComponentLanguage _procLang,
00778 SubarchitectureConfiguration _subarch)
00779 throws ArchitectureConfigurationException {
00780
00781 String componentName = _tokeniser.nextToken();
00782 checkComponentName(componentName);
00783
00784 String className = _tokeniser.nextToken();
00785
00786 Map<String, String> config = parseCommandLine(_tokeniser);
00787
00788 _subarch.addManagedComponent(componentName, className, _procLang,
00789 _componentHost, config);
00790
00791 }
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00817 private static void parseHost(String _line)
00818 throws ArchitectureConfigurationException {
00819
00820 EnvVarTokenizer tokeniser = new EnvVarTokenizer(_line);
00821
00822
00823 tokeniser.nextToken();
00824
00825 try {
00826 String hostname = tokeniser.nextToken();
00827
00828 if (hostname.startsWith(COMMENT_CHAR)) {
00829 throw new ArchitectureConfigurationException(
00830 "Malformed host line: " + _line);
00831 } else {
00832 m_defaultHost = expandComponentHost(hostname);
00833 if (m_bPrintHostInfo) System.out.println("default host: " + m_defaultHost);
00834 }
00835 } catch (NoSuchElementException e) {
00836 throw new ArchitectureConfigurationException(
00837 "Malformed host line: " + _line, e);
00838 }
00839 }
00840
00841 private static HashMap<String, String> m_configVars = new HashMap<String, String>();
00842 private static Pattern m_regexConfigVar =
00843 Pattern.compile("^\\s*([A-Z]+)\\s+([a-zA-Z][a-zA-Z0-9_]*)\\s*=\\s*(.*)\\s*$");
00844 private static Pattern m_regexSethost =
00845 Pattern.compile("^\\s*([A-Z]+)\\s+([a-zA-Z][a-zA-Z0-9_]*)\\s+([^\\s#]+)\\s*$");
00846
00847
00848 private static int parseSetvarLine(ArrayList<String> _lines, int start) {
00849 int i = start;
00850 String line = (String) _lines.get(i);
00851 Matcher m = m_regexConfigVar.matcher(line);
00852 if (! m.matches()) {
00853 System.err.println(ERROR_LABEL + "Invalid expression: " + line);
00854 return i;
00855 }
00856
00857 String cmd = m.group(1);
00858 String token = m.group(2);
00859 String value = m.group(3);
00860
00861 if (value.startsWith("<multiline>")) {
00862 i++;
00863 if (value.length() < 12) value = "";
00864 else value = value.substring(11).trim();
00865 while(i < _lines.size()) {
00866 line = (String) _lines.get(i);
00867 line = line.trim();
00868 if (! line.startsWith(COMMENT_CHAR)) {
00869 if (line.equals("</multiline>")) break;
00870 if (value.length() == 0) value = line;
00871 else value = value + " " + line;
00872 }
00873 i++;
00874 }
00875 }
00876
00877 if (cmd.equals(CMD_VARDEFAULT)) {
00878 if (m_configVars.containsKey(token)) {
00879
00880 return i;
00881 }
00882 }
00883
00884 value = replaceVars(value);
00885
00886 m_configVars.put(token, value);
00887
00888 return i;
00889 }
00890
00891
00892 private static int parseSethostLine(ArrayList<String> _lines, int start) {
00893 int i = start;
00894 String line = (String) _lines.get(i);
00895 Matcher m = m_regexSethost.matcher(line);
00896 if (! m.matches()) {
00897 System.err.println(ERROR_LABEL + "Invalid expression: " + line);
00898 return i;
00899 }
00900
00901 String cmd = m.group(1);
00902 String token = m.group(2);
00903 String value = m.group(3);
00904
00905 token = HOSTVAR_PREFIX + token;
00906 value = expandComponentHost(value);
00907
00908 if (m_bPrintHostInfo) System.out.println(token + "=" + value);
00909
00910 m_configVars.put(token, value);
00911 return i;
00912 }
00913
00914 private static String replaceVars(String line) {
00915 int pos = line.indexOf("%(");
00916 if (pos < 0) {
00917 return line;
00918 }
00919 int lastpos = 0;
00920 String res = "";
00921 while (pos >= 0) {
00922 int end = line.indexOf(")", pos+1);
00923 if (end < 0) break;
00924 String token = line.substring(pos+2, end);
00925
00926
00927 if (token.startsWith(HOSTVAR_PREFIX)) {
00928 String value = expandHostVar(token);
00929 res = res + line.substring(lastpos, pos) + value;
00930 }
00931 else if (m_configVars.containsKey(token)) {
00932 String value = m_configVars.get(token);
00933 res = res + line.substring(lastpos, pos) + value;
00934 }
00935 else {
00936 System.err.println(WARNING_LABEL + "Variable %(" + token + ") not defined.");
00937 res = res + line.substring(lastpos, end+1);
00938 }
00939 lastpos = end + 1;
00940 pos = line.indexOf("%(", end+1);
00941 }
00942 if (lastpos < line.length()) {
00943 res = res + line.substring(lastpos);
00944 }
00945 return res;
00946 }
00947
00948 private static String expandComponentHost(String hostExpr) {
00949 if (hostExpr.equals("localhost") || hostExpr.equals("127.0.0.1") ) {
00950 return expandHostVar(HOSTVAR_LOCALHOST);
00951 }
00952 if (hostExpr.startsWith("[") && hostExpr.endsWith("]")) {
00953 return expandHostVar(HOSTVAR_PREFIX + hostExpr.substring(1, hostExpr.length()-1));
00954 }
00955 return hostExpr;
00956 }
00957
00958 private static String expandHostVar(String hostVarName) {
00959 if (! hostVarName.startsWith(HOSTVAR_PREFIX)) {
00960 throw new RuntimeException("Invalid host variable: " + hostVarName);
00961 }
00962
00963 String value;
00964 if (hostVarName.equals(HOSTVAR_LOCALHOST)) {
00965 if (m_configVars.containsKey(HOSTVAR_LOCALHOST)) {
00966 value = m_configVars.get(HOSTVAR_LOCALHOST);
00967 }
00968 else {
00969 value = "localhost";
00970 m_configVars.put(HOSTVAR_LOCALHOST, value);
00971 System.err.println(WARNING_LABEL + "No IP set for 'localhost'");
00972 }
00973 }
00974 else if (m_configVars.containsKey(hostVarName)) {
00975 value = m_configVars.get(hostVarName);
00976
00977
00978 if (value.equals("localhost") || value.equals("127.0.0.1")) {
00979 value = expandHostVar(HOSTVAR_LOCALHOST);
00980 }
00981 }
00982 else {
00983 System.err.println(WARNING_LABEL + "Undefined host: '" +
00984 hostVarName.substring(HOSTVAR_PREFIX.length()) +
00985 "'. The host 'localhost' will be used.");
00986 value = expandHostVar(HOSTVAR_LOCALHOST);
00987 m_configVars.put(hostVarName, value);
00988 }
00989
00990 return value;
00991 }
00992
00993 private static void expandVars(ArrayList<String> _lines) {
00994 ArrayList<String> orgLines = new ArrayList<String>(_lines);
00995 _lines.clear();
00996 boolean headerFound = false;
00997
00998 for (int i = 0; i < orgLines.size(); i++) {
00999 String line = (String) orgLines.get(i);
01000
01001 if (line.startsWith(COMMENT_CHAR)) {
01002 _lines.add(line);
01003 }
01004 else if (isHeader(line)) {
01005 headerFound = true;
01006 _lines.add(replaceVars(line));
01007 }
01008 else {
01009 if (line.startsWith(CMD_VARSET) || line.startsWith(CMD_VARDEFAULT)) {
01010 i = parseSetvarLine(orgLines, i);
01011 }
01012 else if (line.startsWith(CMD_SETHOST)) {
01013 if (headerFound) {
01014 System.err.println(ERROR_LABEL + CMD_SETHOST +
01015 " directives must preceede any other directives"
01016 + " except " + CMD_VARSET + " and " + CMD_VARDEFAULT + ".");
01017 }
01018 else
01019 i = parseSethostLine(orgLines, i);
01020 }
01021 else {
01022 _lines.add(replaceVars(line));
01023 }
01024 }
01025 }
01026 }
01027
01032 private static void parseLines(ArrayList<String> _lines)
01033 throws ArchitectureConfigurationException {
01034
01035 for (int i = 0; i < _lines.size(); i++) {
01036
01037 String line = (String) _lines.get(i);
01038
01039
01040
01041 if (!line.startsWith(COMMENT_CHAR)) {
01042
01043 if (line.startsWith(SUBARCH_HEADER)) {
01044 i = parseSubarchitecture(_lines, i);
01045 } else if (line.startsWith(ARCH_HEADER)) {
01046 i = parseArchitecture(_lines, i);
01047 } else if (line.startsWith(HOST_HEADER)) {
01048 parseHost(line);
01049 }
01050 }
01051 }
01052
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01081 private static int parseSubarchitecture(ArrayList<String> _lines, int _i)
01082 throws ArchitectureConfigurationException {
01083
01084
01085
01086 String line;
01087
01088 String subarchLine = _lines.get(_i);
01089
01090 SubarchitectureConfiguration subarch = parseSubarchitectureLine(subarchLine);
01091
01092 int i = _i + 1;
01093 for (i = _i + 1; i < _lines.size(); i++) {
01094 line = _lines.get(i);
01095
01096 if (!(line.startsWith(COMMENT_CHAR) || line.length() == 0)) {
01097
01098 if (isHeader(line)) {
01099 break;
01100 } else {
01101
01102 parseSubarchitectureComponentLine(line, subarch);
01103 }
01104 }
01105 }
01106
01107
01108
01109 m_subarchitectures.add(subarch);
01110
01111
01112
01113 return i - 1;
01114 }
01115
01121 private static void parseSubarchitectureComponentLine(String _line,
01122 SubarchitectureConfiguration _subarch)
01123 throws ArchitectureConfigurationException {
01124
01125
01126 EnvVarTokenizer tokeniser = new EnvVarTokenizer(_line);
01127
01128 try {
01129
01130 String lang = tokeniser.nextToken();
01131 String componentHost;
01132
01133
01134 if (!isLanguageToken(lang)) {
01135 componentHost = lang;
01136 lang = tokeniser.nextToken();
01137 } else {
01138 componentHost = _subarch.getHost();
01139 if (componentHost == null) {
01140 throw new ArchitectureConfigurationException(
01141 "No host specified for component. Use either HOST flag at top level, subarchitecture host specification or component host specification: "
01142 + _line);
01143 }
01144 }
01145 componentHost = expandComponentHost(componentHost);
01146
01147 ComponentLanguage procLang;
01148 if (lang.equals(CPP_FLAG)) {
01149 procLang = ComponentLanguage.CPP;
01150 } else if (lang.equals(JAVA_FLAG)) {
01151 procLang = ComponentLanguage.JAVA;
01152 } else if (lang.equals(PYTHON_FLAG)) {
01153 procLang = ComponentLanguage.PYTHON;
01154 } else {
01155 throw new ArchitectureConfigurationException(
01156 "Unknown language flag: " + lang + "\nUse on of "
01157 + CPP_FLAG + "|" + JAVA_FLAG + "\n" + _line);
01158 }
01159
01160 String componentType = tokeniser.nextToken();
01161
01162 if (componentType.equals(WM_FLAG)) {
01163 parseWorkingMemory(tokeniser, componentHost, procLang, _subarch);
01164 } else if (componentType.equals(TM_FLAG)) {
01165 parseTaskManager(tokeniser, componentHost, procLang, _subarch);
01166 } else if (componentType.equals(DD_FLAG)
01167 || componentType.equals(UM_FLAG)) {
01168 parseUnmanagedComponent(tokeniser, componentHost, procLang,
01169 _subarch);
01170 } else if (componentType.equals(GD_FLAG)
01171 || componentType.equals(MG_FLAG)) {
01172 parseManagedComponent(tokeniser, componentHost, procLang,
01173 _subarch);
01174 } else {
01175 throw new ArchitectureConfigurationException(
01176 "Unknown component type flag: " + lang + "\nUse on of "
01177 + WM_FLAG + "|" + TM_FLAG + "|" + DD_FLAG + "|"
01178 + UM_FLAG + "|" + GD_FLAG + "|" + MG_FLAG);
01179 }
01180
01181 } catch (NoSuchElementException e) {
01182 throw new ArchitectureConfigurationException(
01183 "Malformed subarch component line: \"" + _line + "\"", e);
01184 }
01185 }
01186
01192 private static SubarchitectureConfiguration parseSubarchitectureLine(
01193 String _subarchLine) throws ArchitectureConfigurationException {
01194
01195
01196 EnvVarTokenizer tokeniser = new EnvVarTokenizer(_subarchLine);
01197
01198
01199 tokeniser.nextToken();
01200
01201 try {
01202 String subarchName = tokeniser.nextToken();
01203 checkSubarchitectureName(subarchName);
01204
01205 if (subarchName.startsWith(COMMENT_CHAR)) {
01206 throw new ArchitectureConfigurationException(
01207 "Malformed subarch line: " + _subarchLine);
01208 }
01209
01210 String subarchHost;
01211 if (tokeniser.hasMoreTokens()) {
01212 subarchHost = tokeniser.nextToken();
01213 if (subarchHost.startsWith(COMMENT_CHAR)) {
01214 subarchHost = m_defaultHost;
01215 }
01216 } else {
01217 subarchHost = m_defaultHost;
01218 }
01219 subarchHost = expandComponentHost(subarchHost);
01220
01221 return new SubarchitectureConfiguration(subarchName, subarchHost);
01222
01223 } catch (NoSuchElementException e) {
01224 throw new ArchitectureConfigurationException(
01225 "Malformed subarch line: " + _subarchLine, e);
01226 }
01227 }
01228
01236 private static void parseTaskManager(EnvVarTokenizer _tokeniser,
01237 String _componentHost, ComponentLanguage _procLang,
01238 SubarchitectureConfiguration _subarch)
01239 throws ArchitectureConfigurationException {
01240
01241 String className = _tokeniser.nextToken();
01242 Map<String, String> config = parseCommandLine(_tokeniser);
01243
01244 _subarch.setTaskManager(className, _procLang, _componentHost, config);
01245 }
01246
01254 private static void parseWorkingMemory(EnvVarTokenizer _tokeniser,
01255 String _componentHost, ComponentLanguage _procLang,
01256 SubarchitectureConfiguration __subarch)
01257 throws ArchitectureConfigurationException {
01258 String className = _tokeniser.nextToken();
01259 Map<String, String> config = parseCommandLine(_tokeniser);
01260
01261 __subarch
01262 .setWorkingMemory(className, _procLang, _componentHost, config);
01263 }
01264
01271 private static void readFile(String _filename, ArrayList<String> _lines)
01272 throws FileNotFoundException, IOException {
01273
01274 File configFile = new File(_filename);
01275 FileReader fileRead = new FileReader(configFile);
01276 BufferedReader reader = new BufferedReader(fileRead);
01277 StringBuffer sb = new StringBuffer();
01278
01279 _lines.add("SETVAR " + VAR_CURRENT_DIR + "=" + configFile.getAbsoluteFile().getParent());
01280
01281 String line;
01282 while (reader.ready()) {
01283 line = reader.readLine().trim();
01284
01285 if (line.startsWith(INCLUDE_FLAG)) {
01286 String includeFile = parseInclude(line, configFile.getParent());
01287
01288 readFile(includeFile, _lines);
01289 _lines.add("SETVAR " + VAR_CURRENT_DIR + "=" + configFile.getAbsoluteFile().getParent());
01290 } else {
01291 _lines.add(line);
01292 sb.append(line);
01293 sb.append("\n");
01294 }
01295 }
01296
01297 m_lastParse = sb.toString();
01298
01299 }
01300
01301 private static String parseInclude(String _line, String _pathToParent) throws FileNotFoundException {
01302 String includeFile = _line.substring(INCLUDE_FLAG.length() + 1);
01303 includeFile = includeFile.trim();
01304
01305 File f = new File(includeFile);
01306
01307 if(f.isAbsolute()) {
01308 return includeFile;
01309 }
01310
01311 else {
01312 String relativeInclude = _pathToParent + "/" + includeFile;
01313 f = new File(relativeInclude);
01314 if(f.exists()) {
01315 return relativeInclude;
01316 }
01317 else {
01318 throw new FileNotFoundException("Cannot find included file: " + relativeInclude);
01319 }
01320 }
01321 }
01322
01329 private static ArrayList<String> readString(String _config)
01330 throws IOException {
01331
01332 StringReader stringRead = new StringReader(_config);
01333 BufferedReader reader = new BufferedReader(stringRead);
01334 ArrayList<String> lines = new ArrayList<String>();
01335 StringBuffer sb = new StringBuffer();
01336
01337 String line = reader.readLine();
01338 while (line != null) {
01339 line = line.trim();
01340
01341
01342 lines.add(line);
01343 sb.append(line);
01344 sb.append("\n");
01345
01346 line = reader.readLine();
01347 }
01348
01349 m_lastParse = sb.toString();
01350
01351 return lines;
01352 }
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368 public static void parseConfigFile(String _filename)
01369 throws ArchitectureConfigurationException {
01370
01371 try {
01372 init();
01373 ArrayList<String> lines = new ArrayList<String>();
01374 readFile(_filename, lines);
01375 m_currentFile = _filename;
01376
01377 m_architecture = new ArchitectureConfiguration();
01378
01379 File configFile = new File(_filename);
01380 m_configVars.put(VAR_CONFIG_DIR, configFile.getAbsoluteFile().getParent());
01381 expandVars(lines);
01382 System.out.println(VAR_CONFIG_DIR + "=" + m_configVars.get(VAR_CONFIG_DIR));
01383
01384 processLines(lines);
01385 m_extras = parseExtras(lines);
01386 } catch (FileNotFoundException e) {
01387 throw new ArchitectureConfigurationException(
01388 "Config file, or included file, does not exist: " + _filename, e);
01389 } catch (IOException e) {
01390 throw new ArchitectureConfigurationException(
01391 "Error parsing config file: " + _filename, e);
01392 }
01393
01394 }
01395
01396 public static ArchitectureConfiguration parseConfigString(String _config)
01397 throws ArchitectureConfigurationException {
01398 try {
01399
01400 init();
01401 m_architecture = new ArchitectureConfiguration();
01402 ArrayList<String> lines = readString(_config);
01403 expandVars(lines);
01404 return processLines(lines);
01405 } catch (IOException e) {
01406 throw new ArchitectureConfigurationException(
01407 "Error parsing config file: " + _config, e);
01408 }
01409 }
01410
01416 private static ArchitectureConfiguration processLines(
01417 ArrayList<String> lines) throws ArchitectureConfigurationException {
01418 parseLines(lines);
01419
01420 if (m_architecture == null) {
01421
01422 if (m_subarchitectures.isEmpty()) {
01423 throw new ArchitectureConfigurationException(
01424 "No architecture or subarchitecture configuration information found");
01425 }
01426
01427 SubarchitectureConfiguration singleSubarch = m_subarchitectures.get(0);
01428 System.err.println(WARNING_LABEL +
01429 "No full architecture information found,"
01430 + " configuring with first subarchitecture found"
01431 + " = '" + singleSubarch.getName() + "'");
01432
01433 ArchitectureConfiguration singleSAArch = new ArchitectureConfiguration();
01434 singleSAArch.addSubarchitectureConfiguration(singleSubarch);
01435
01436 return singleSAArch;
01437
01438 } else {
01439
01440
01441
01442
01443
01444
01445
01446 for (SubarchitectureConfiguration subarch : m_subarchitectures) {
01447 m_architecture.addSubarchitectureConfiguration(subarch);
01448 }
01449
01450 additionalConfiguration(m_architecture);
01451
01452 return m_architecture;
01453 }
01454 }
01455
01461 private static void additionalConfiguration(
01462 ArchitectureConfiguration _architecture) {
01463
01464 Map<String, String> props = new HashMap<String, String>();
01465 addIDs(_architecture, props);
01466
01467 ArrayList<SubarchitectureConfiguration> subarchs = _architecture
01468 .getSubarchitectures();
01469 for (SubarchitectureConfiguration subarch : subarchs) {
01470 subarch.addConfigurationInformation(props);
01471 }
01472
01473 }
01474
01475 private static void addIDs(ArchitectureConfiguration _architecture,
01476 Map<String, String> _props) {
01477 ArrayList<SubarchitectureConfiguration> subarchs = _architecture
01478 .getSubarchitectures();
01479 String wmIDs = "";
01480 String componentIDs = "";
01481
01482 for (SubarchitectureConfiguration subarch : subarchs) {
01483 wmIDs += "," + subarch.getWorkingMemoryConfig().componentName;
01484 ArrayList<ComponentDescription> umcs = subarch
01485 .getUnmanagedComponents();
01486 for (ComponentDescription desc : umcs) {
01487 componentIDs += "," + desc.componentName;
01488 }
01489 ArrayList<ComponentDescription> mcs = subarch
01490 .getManagedComponents();
01491 for (ComponentDescription desc : mcs) {
01492 componentIDs += "," + desc.componentName;
01493 }
01494 componentIDs += "," + subarch.getTaskManagerConfig().componentName;
01495 }
01496
01497 _props.put(WMIDSKEY.value, wmIDs);
01498 _props.put(COMPONENTIDSKEY.value, componentIDs);
01499
01500 }
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01527 public static String getLastParse() {
01528 return m_lastParse;
01529 }
01530
01531 }