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;
}