/*
* Copyright 2004-2012 the Seasar Foundation and the Others.
*
* 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.seasar.mayaa.impl.builder.library;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.seasar.mayaa.builder.library.TemplateAttributeReader;
import org.seasar.mayaa.engine.specification.NodeAttribute;
import org.seasar.mayaa.engine.specification.QName;
import org.seasar.mayaa.engine.specification.SpecificationNode;
import org.seasar.mayaa.impl.ParameterAwareImpl;
import org.seasar.mayaa.impl.engine.specification.SpecificationUtil;
import org.seasar.mayaa.impl.util.StringUtil;
/**
* @author Koji Suga (Gluegent, Inc.)
*/
public class TemplateAttributeReaderImpl
extends ParameterAwareImpl
implements TemplateAttributeReader {
private static final long serialVersionUID = -7340519771743083660L;
private Set _ignoreAttributes;
private Map _aliasAttributes;
private boolean _enabled;
public TemplateAttributeReaderImpl() {
_ignoreAttributes = new LinkedHashSet();
_aliasAttributes = new LinkedHashMap();
_enabled = false;
}
public void addIgnoreAttribute(String qName, String attribute) {
if (isQName(qName) == false || StringUtil.isEmpty(attribute)) {
throw new IllegalArgumentException();
}
synchronized (_ignoreAttributes) {
_ignoreAttributes.add(toKey(qName, attribute));
}
}
public void addAliasAttribute(
String qName, String attribute, String templateAttribute) {
if (isQName(qName) == false || StringUtil.isEmpty(attribute)
|| isQNameOrLocalName(templateAttribute) == false) {
throw new IllegalArgumentException();
}
synchronized (_aliasAttributes) {
_aliasAttributes.put(toKey(qName, attribute), templateAttribute);
}
}
public void setParameter(String name, String value) {
if ("enabled".equals(name)) {
_enabled = Boolean.valueOf(value).booleanValue();
}
super.setParameter(name, value);
}
public String getValue(
QName qName, String attributeName, SpecificationNode original) {
if (_enabled) {
AttributeKey key = qNameToKey(qName, attributeName);
if (isTarget(key)) {
for (Iterator it = _aliasAttributes.keySet().iterator(); it.hasNext(); ) {
AttributeKey aliasKey = (AttributeKey) it.next();
if (aliasKey.match(key)) {
QName attributeQName = getQName(original,
(String) _aliasAttributes.get(aliasKey));
NodeAttribute attribute =
original.getAttribute(attributeQName);
if (attribute != null) {
return StringUtil.resolveEntity(attribute.getValue());
}
}
}
NodeAttribute attribute =
original.getAttribute(getQName(original, attributeName));
if (attribute != null) {
return StringUtil.resolveEntity(attribute.getValue());
}
}
}
return null;
}
private boolean isTarget(AttributeKey key) {
for (Iterator it = _ignoreAttributes.iterator(); it.hasNext(); ) {
AttributeKey ignoreKey = (AttributeKey) it.next();
if (ignoreKey.match(key)) {
return false;
}
}
return true;
}
private QName getQName(SpecificationNode original, String attribute) {
if(attribute.startsWith("{")) {
String[] split = attribute.split("[\\{\\}]");
return SpecificationUtil.createQName(
SpecificationUtil.createURI(split[1]), split[2]);
}
return SpecificationUtil.createQName(
original.getQName().getNamespaceURI(), attribute);
}
private AttributeKey toKey(String qName, String attribute) {
if (StringUtil.isEmpty(qName) || StringUtil.isEmpty(attribute)) {
throw new IllegalArgumentException();
}
return new AttributeKey(qName, attribute);
}
private AttributeKey qNameToKey(QName qName, String attribute) {
if (qName == null || StringUtil.isEmpty(attribute)) {
throw new IllegalArgumentException();
}
return new AttributeKey(qName.toString(), attribute);
}
private static final Pattern QNAME_PATTERN =
Pattern.compile("^\\{[^\\{\\}]+\\}[^\\{\\}]+$");
private boolean isQName(String test) {
return StringUtil.hasValue(test) && QNAME_PATTERN.matcher(test).matches();
}
private boolean isQNameOrLocalName(String test) {
return StringUtil.hasValue(test)
&& (QNAME_PATTERN.matcher(test).matches()
|| (test.indexOf('{') == -1 && test.indexOf('}') == -1));
}
private static class AttributeKey {
private String _tagName;
private String _attributeName;
protected AttributeKey(String tagName, String attributeName) {
_tagName = tagName;
_attributeName = attributeName;
}
protected boolean match(AttributeKey other) {
return matchWildCard(_tagName, other._tagName)
&& matchWildCard(_attributeName, other._attributeName);
}
private boolean matchWildCard(String pattern, String test) {
if (pattern.charAt(pattern.length() - 1) == '*') {
return test.startsWith(pattern.substring(0, pattern.length() - 1));
}
return test.equals(pattern);
}
}
}