/*
* 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 org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.seasar.mayaa.builder.library.LibraryDefinition;
import org.seasar.mayaa.builder.library.LibraryManager;
import org.seasar.mayaa.builder.library.ProcessorDefinition;
import org.seasar.mayaa.builder.library.PropertyDefinition;
import org.seasar.mayaa.builder.library.PropertySet;
import org.seasar.mayaa.builder.library.converter.PropertyConverter;
import org.seasar.mayaa.engine.processor.ProcessorProperty;
import org.seasar.mayaa.engine.processor.TemplateProcessor;
import org.seasar.mayaa.engine.processor.VirtualPropertyAcceptable;
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.CONST_IMPL;
import org.seasar.mayaa.impl.ParameterAwareImpl;
import org.seasar.mayaa.impl.engine.specification.NodeAttributeImpl;
import org.seasar.mayaa.impl.engine.specification.SpecificationUtil;
import org.seasar.mayaa.impl.provider.ProviderUtil;
import org.seasar.mayaa.impl.util.ObjectUtil;
import org.seasar.mayaa.impl.util.StringUtil;
/**
* @author Masataka Kurihara (Gluegent, Inc.)
*/
public class PropertyDefinitionImpl extends ParameterAwareImpl
implements PropertyDefinition, CONST_IMPL {
private static final long serialVersionUID = -9121229054380668801L;
private static final Log LOG =
LogFactory.getLog(PropertyDefinitionImpl.class);
private PropertySet _propertySet;
private String _name;
private String _implName;
private boolean _required;
private Class _expectedClass;
private String _defaultValue;
private String _finalValue;
private String _propertyConverterName;
private PropertyConverter _propertyConverter;
public void setPropertySet(PropertySet propertySet) {
if (propertySet == null) {
throw new IllegalArgumentException();
}
_propertySet = propertySet;
}
public PropertySet getPropertySet() {
if (_propertySet == null) {
throw new IllegalStateException();
}
return _propertySet;
}
public void setName(String name) {
if (StringUtil.isEmpty(name)) {
throw new IllegalArgumentException();
}
_name = name;
}
public String getName() {
if (StringUtil.isEmpty(_name)) {
throw new IllegalStateException();
}
return _name;
}
public void setImplName(String implName) {
_implName = implName;
}
public String getImplName() {
if (StringUtil.isEmpty(_implName)) {
return getName();
}
return _implName;
}
public void setRequired(boolean required) {
_required = required;
}
public boolean isRequired() {
return _required;
}
public void setExpectedClass(Class expectedClass) {
_expectedClass = expectedClass;
}
public Class getExpectedClass() {
if (_expectedClass == null) {
return Object.class;
}
return _expectedClass;
}
public void setDefaultValue(String defaultValue) {
_defaultValue = defaultValue;
}
public String getDefaultValue() {
return _defaultValue;
}
public void setFinalValue(String finalValue) {
_finalValue = finalValue;
}
public String getFinalValue() {
return _finalValue;
}
public void setPropertyConverterName(String propertyConverterName) {
_propertyConverterName = propertyConverterName;
}
public String getPropertyConverterName() {
return _propertyConverterName;
}
public void setPropertyConverter(PropertyConverter propertyConverter) {
if (propertyConverter == null) {
throw new IllegalArgumentException();
}
_propertyConverter = propertyConverter;
}
protected PropertyConverter getPropertyConverter(
ProcessorDefinition processorDef, TemplateProcessor processor) {
if (_propertyConverter != null) {
return _propertyConverter;
}
LibraryDefinition library = getPropertySet().getLibraryDefinition();
String converterName = getPropertyConverterName();
if (StringUtil.hasValue(converterName)) {
PropertyConverter converter =
library.getPropertyConverter(converterName);
if (converter == null) {
throw new ConverterNotFoundException(converterName,
getSystemID(), getLineNumber());
}
return converter;
}
Class propertyClass = getPropertyClass(processorDef, processor);
if (propertyClass != null) {
return library.getPropertyConverter(propertyClass);
}
return null;
}
protected Class getPropertyClass(
ProcessorDefinition processorDef, TemplateProcessor processor) {
Class processorClass = processorDef.getProcessorClass();
Class propertyClass = ObjectUtil.getPropertyClass(processorClass, getImplName());
if (propertyClass == null && processor instanceof VirtualPropertyAcceptable) {
VirtualPropertyAcceptable acceptable =
(VirtualPropertyAcceptable) processor;
propertyClass = acceptable.getVirtualPropertyClass();
}
return propertyClass;
}
protected QName getQName(SpecificationNode node) {
return SpecificationUtil.createQName(node.getQName().getNamespaceURI(),
_name);
}
public Object createProcessorProperty(ProcessorDefinition processorDef,
TemplateProcessor processor,
SpecificationNode original, SpecificationNode injected) {
if (injected == null) {
throw new IllegalArgumentException();
}
QName qName = getQName(injected);
String value = getFinalValue();
NodeAttribute attribute = injected.getAttribute(qName);
if (value == null) {
value = getDefaultValue();
if (attribute != null) {
value = attribute.getValue();
}
} else if (attribute != null) {
String processorName = processorDef.getName();
throw new FinalProcessorPropertyException(processorName, qName);
}
if (StringUtil.hasValue(value)) {
Class propertyClass = getPropertyClass(processorDef, processor);
if (propertyClass == null) {
// real property not found on the processor.
Class processorClass = processorDef.getProcessorClass();
if (VirtualPropertyAcceptable.class
.isAssignableFrom(processorClass) == false) {
if (LOG.isWarnEnabled()) {
LOG.warn(StringUtil.getMessage(
PropertyDefinitionImpl.class, 0, processorDef
.getName(), getName()));
}
return null;
}
}
PropertyConverter converter =
getPropertyConverter(processorDef, processor);
if (converter == null && propertyClass != null) {
LibraryManager manager = ProviderUtil.getLibraryManager();
converter = manager.getPropertyConverter(propertyClass);
}
if (converter == null) {
return value;
}
// converterがnullでなければattributeが必須
if (attribute == null) {
attribute = new NodeAttributeImpl(qName, value);
}
// expectedCheck
Object ret =
converter.convert(attribute, value, getExpectedClass());
if (ret instanceof ProcessorProperty) {
ProcessorProperty processorProperty = (ProcessorProperty) ret;
// 予測できるものは可能な限りここで型をチェックする
if (processorProperty.getValue().isLiteral()) {
if (getExpectedClass() == boolean.class
&& !ObjectUtil.canBooleanConvert(processorProperty
.getValue().getScriptText())) {
String processorName = processorDef.getName();
throw new ExpectedTypeMismatchValueException(
processorName, qName, getExpectedClass());
}
}
}
return ret;
} else if (_required) {
String processorName = processorDef.getName();
throw new NoRequiredPropertyException(processorName, qName);
}
return null;
}
}