private Model readModel()

in src/main/java/org/apache/sling/provisioning/model/io/ModelReader.java [103:340]


    private Model readModel(final Reader reader)
    throws IOException {

        boolean global = true;

        lineNumberReader = new LineNumberReader(reader);
        String line;
        while ( (line = lineNumberReader.readLine()) != null ) {
            // trim the line
            line = line.trim();

            // ignore empty line
            if ( line.isEmpty() ) {
                if ( this.mode == CATEGORY.ADDITIONAL ) {
                    if ( this.additionalSection.getContents() == null ) {
                        this.additionalSection.setContents(line);
                    } else {
                        this.additionalSection.setContents(this.additionalSection.getContents() + '\n' + line);
                    }
                    continue;
                }
                checkConfig();
                continue;
            }

            // comment?
            if ( line.startsWith("#") ) {
                if ( config != null ) {
                    configBuilder.append(line);
                    configBuilder.append('\n');

                    continue;
                }
                if ( this.mode == CATEGORY.ADDITIONAL ) {
                    if ( this.additionalSection.getContents() == null ) {
                        this.additionalSection.setContents(line);
                    } else {
                        this.additionalSection.setContents(this.additionalSection.getContents() + '\n' + line);
                    }
                    continue;
                }
                final String c = line.substring(1).trim();
                if ( comment == null ) {
                    comment = c;
                } else {
                    comment = comment + "\n" + c;
                }
                continue;
            }

            if ( global ) {
                global = false;
                if ( !line.startsWith("[feature ") ) {
                    throw new IOException(exceptionPrefix + " Model file must start with a feature category.");
                }
            }

            if ( line.startsWith("[") ) {
                additionalSection = null;
                if ( !line.endsWith("]") ) {
                    throw new IOException(exceptionPrefix + "Illegal category definition in line " + this.lineNumberReader.getLineNumber() + ": " + line);
                }
                int pos = 1;
                while ( line.charAt(pos) != ']' && !Character.isWhitespace(line.charAt(pos))) {
                    pos++;
                }
                final String category = line.substring(1, pos);
                CATEGORY found = null;
                for (CATEGORY c : CATEGORY.values()) {
                    if ( category.equals(c.name)) {
                        found = c;
                        break;
                    }
                }
                if ( found == null ) {
                    // additional section
                    if ( !category.startsWith(":") ) {
                        throw new IOException(exceptionPrefix + "Unknown category in line " + this.lineNumberReader.getLineNumber() + ": " + category);
                    }
                    found = CATEGORY.ADDITIONAL;
                }
                this.mode = found;
                Map<String, String> parameters = Collections.emptyMap();
                if (line.charAt(pos) != ']') {
                    final String parameterLine = line.substring(pos + 1, line.length() - 1).trim();
                    parameters = parseParameters(parameterLine, this.mode.parameters);
                }

                switch ( this.mode ) {
                    case NONE : break; // this can never happen
                    case CONFIG : break; // this can never happen
                    case FEATURE : final String name = parameters.get("name");
                                   if ( name == null ) {
                                       throw new IOException(exceptionPrefix + "Feature name missing in line " + this.lineNumberReader.getLineNumber() + ": " + line);
                                   }
                                   if ( model.getFeature(name) != null ) {
                                       throw new IOException(exceptionPrefix + "Duplicate feature in line " + this.lineNumberReader.getLineNumber() + ": " + line);
                                   }
                                   this.feature = model.getOrCreateFeature(name);
                                   this.feature.setType(parameters.get("type"));
                                   this.feature.setVersion(parameters.get("version"));
                                   this.init(this.feature);
                                   this.runMode = null;
                                   this.artifactGroup = null;
                                   break;
                    case VARIABLES : checkFeature();
                                     this.init(this.feature.getVariables());
                                     break;
                    case SETTINGS: checkFeature();
                                   checkRunMode(parameters);
                                   this.init(this.runMode.getSettings());
                                   break;
                    case ARTIFACTS: checkFeature();
                                    checkRunMode(parameters);
                                    int startLevel = 0;
                                    String level = parameters.get("startLevel");
                                    if ( level != null ) {
                                        try {
                                            startLevel = Integer.valueOf(level);
                                        } catch ( final NumberFormatException nfe) {
                                            throw new IOException(exceptionPrefix + "Invalid start level in line " + this.lineNumberReader.getLineNumber() + ": " + line + ":" + level);
                                        }
                                    }
                                    if ( this.runMode.getArtifactGroup(startLevel) != null ) {
                                        throw new IOException(exceptionPrefix + "Duplicate artifact group in line " + this.lineNumberReader.getLineNumber() + ": " + line);
                                    }
                                    this.artifactGroup = this.runMode.getOrCreateArtifactGroup(startLevel);
                                    this.init(this.artifactGroup);
                                    break;
                    case CONFIGURATIONS: checkFeature();
                                         checkRunMode(parameters);
                                         this.init(this.runMode.getConfigurations());
                                         break;
                    case ADDITIONAL: checkFeature();
                                     this.runMode = null;
                                     this.artifactGroup = null;
                                     this.additionalSection = new Section(category.substring(1));
                                     this.init(this.additionalSection);
                                     this.feature.getAdditionalSections().add(this.additionalSection);
                                     this.additionalSection.getAttributes().putAll(parameters);
                }
            } else {
                switch ( this.mode ) {
                    case NONE : break;
                    case VARIABLES : final String[] vars = parseProperty(line);
                                     feature.getVariables().put(vars[0], vars[1]);
                                     break;
                    case SETTINGS : final String[] settings = parseProperty(line);
                                    runMode.getSettings().put(settings[0], settings[1]);
                                    break;
                    case FEATURE:   this.runMode = this.feature.getOrCreateRunMode(null);
                                    this.artifactGroup = this.runMode.getOrCreateArtifactGroup(0);
                                    // no break, we continue with ARTIFACT
                    case ARTIFACTS : String artifactUrl = line;
                                     Map<String, String> parameters = Collections.emptyMap();
                                     if ( line.endsWith("]") ) {
                                         final int startPos = line.indexOf("[");
                                         if ( startPos != -1 ) {
                                             artifactUrl = line.substring(0, startPos).trim();
                                             parameters = parseParameters(line.substring(startPos + 1, line.length() - 1).trim(), null);
                                         }
                                     }
                                     try {
                                         final Artifact artifact = Artifact.fromMvnUrl("mvn:" + artifactUrl);
                                         this.init(artifact);
                                         this.artifactGroup.add(artifact);
                                         artifact.getMetadata().putAll(parameters);
                                     } catch ( final IllegalArgumentException iae) {
                                         throw new IOException(exceptionPrefix + iae.getMessage() + " in line " + this.lineNumberReader.getLineNumber(), iae);
                                     }
                                     break;
                    case CONFIGURATIONS : String configId = line;
                                          Map<String, String> cfgPars = Collections.emptyMap();
                                          if ( line.endsWith("]") ) {
                                              final int startPos = line.indexOf("[");
                                              if ( startPos != -1 ) {
                                                  configId = line.substring(0, startPos).trim();
                                                  cfgPars = parseParameters(line.substring(startPos + 1, line.length() - 1).trim(), new String[] {"format", "mode"});
                                              }
                                          }
                                          String format = cfgPars.get("format");
                                          if ( format != null ) {
                                              if ( !ModelConstants.CFG_FORMAT_FELIX_CA.equals(format)
                                                  && !ModelConstants.CFG_FORMAT_PROPERTIES.equals(format) ) {
                                                  throw new IOException(exceptionPrefix + "Unknown format configuration parameter in line " + this.lineNumberReader.getLineNumber() + ": " + line);
                                              }
                                          } else {
                                              format = ModelConstants.CFG_FORMAT_FELIX_CA;
                                          }
                                          String cfgMode= cfgPars.get("mode");
                                          if ( cfgMode != null ) {
                                              if ( !ModelConstants.CFG_MODE_OVERWRITE.equals(cfgMode)
                                                      && !ModelConstants.CFG_MODE_MERGE.equals(cfgMode) ) {
                                                      throw new IOException(exceptionPrefix + "Unknown mode configuration parameter in line " + this.lineNumberReader.getLineNumber() + ": " + line);
                                                  }
                                          } else {
                                              cfgMode = ModelConstants.CFG_MODE_OVERWRITE;
                                          }
                                          final String pid;
                                          final String factoryPid;
                                          final int factoryPos = configId.indexOf('-');
                                          if ( factoryPos == -1 ) {
                                              pid = configId;
                                              factoryPid = null;
                                          } else {
                                              pid = configId.substring(factoryPos + 1);
                                              factoryPid = configId.substring(0, factoryPos);
                                          }
                                          if ( runMode.getConfiguration(pid, factoryPid) != null ) {
                                              throw new IOException(exceptionPrefix + "Duplicate configuration in line " + this.lineNumberReader.getLineNumber());
                                          }
                                          config = runMode.getOrCreateConfiguration(pid, factoryPid);
                                          this.init(config);
                                          config.getProperties().put(ModelConstants.CFG_UNPROCESSED_FORMAT, format);
                                          config.getProperties().put(ModelConstants.CFG_UNPROCESSED_MODE, cfgMode);
                                          configBuilder = new StringBuilder();
                                          mode = CATEGORY.CONFIG;
                                          break;
                    case CONFIG : configBuilder.append(line);
                                  configBuilder.append('\n');
                                  break;
                    case ADDITIONAL : if ( this.additionalSection.getContents() == null ) {
                                          this.additionalSection.setContents(line);
                                      } else {
                                          this.additionalSection.setContents(this.additionalSection.getContents() + '\n' + line);
                                      }
                                      break;
                }
            }

        }
        checkConfig();
        if ( comment != null ) {
            throw new IOException(exceptionPrefix + "Comment not allowed at the end of file");
        }

        return model;
    }