/*
* Copyright 2012 NGDATA nv
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lilyproject.indexer.model.indexerconf;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.lilyproject.repository.api.FieldType;
import org.lilyproject.repository.api.LRepository;
import org.lilyproject.repository.api.QName;
import org.lilyproject.repository.api.RepositoryException;
import org.lilyproject.util.repo.SystemFields;
import org.w3c.dom.Element;
public class NameTemplateParser {
private static Pattern varPattern = Pattern.compile("\\$\\{([^\\}]+)\\}");
private static Pattern exprPattern = Pattern.compile("([^\\?]+)\\?([^:]+)(?::(.+))?");
private static Pattern variantPropertyPattern = Pattern.compile("vprop:([^:]+)");
private static Pattern fieldPattern = Pattern.compile("([^:]+):([^:]+)?");
// used for parsing qnames
private LRepository repository;
private SystemFields systemFields;
public NameTemplateParser() {
this(null, null);
}
public NameTemplateParser(LRepository repository, SystemFields systemFields) {
this.repository = repository;
this.systemFields = systemFields;
}
public NameTemplate parse(String template, NameTemplateValidator validator)
throws IndexerConfException, NameTemplateException, InterruptedException, RepositoryException {
return parse(null, template, validator);
}
// FIXME: Not very clean that this can throw IndexerConfException
public NameTemplate parse(Element el, String template, NameTemplateValidator validator)
throws IndexerConfException, NameTemplateException, InterruptedException, RepositoryException {
List<TemplatePart> parts = new ArrayList<TemplatePart>();
int pos = 0;
Matcher matcher = varPattern.matcher(template);
while (pos < template.length()) {
if (matcher.find(pos)) {
int start = matcher.start();
if (start > pos) {
parts.add(new LiteralTemplatePart(template.substring(pos, start)));
}
String expr = matcher.group(1);
Matcher exprMatcher = exprPattern.matcher(expr);
Matcher atVariantPropMatcher = variantPropertyPattern.matcher(expr);
Matcher fieldMatcher = fieldPattern.matcher(expr);
if (exprMatcher.matches()) {
String condition = exprMatcher.group(1);
String trueValue = exprMatcher.group(2);
String falseValue = exprMatcher.group(3) != null ? exprMatcher.group(3) : "";
parts.add(new ConditionalTemplatePart(condition, trueValue, falseValue));
} else if (atVariantPropMatcher.matches()) {
parts.add(new VariantPropertyTemplatePart(atVariantPropMatcher.group(1)));
} else if (fieldMatcher.matches()) {
parts.add(buildFieldTemplatePart(el, template, expr));
} else {
parts.add(new VariableTemplatePart(expr));
}
pos = matcher.end();
} else {
parts.add(new LiteralTemplatePart(template.substring(pos)));
break;
}
}
final NameTemplate nameTemplate = new NameTemplate(template, parts);
if (validator != null) {
validator.validate(nameTemplate);
}
return nameTemplate;
}
private TemplatePart buildFieldTemplatePart(Element el, String template, String expr)
throws IndexerConfException, InterruptedException, RepositoryException {
QName field = ConfUtil.parseQName(expr, el);
FieldType fieldType = ConfUtil.getFieldType(field, systemFields, repository.getTypeManager());
return new FieldTemplatePart(fieldType, field);
}
}