/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.xml.util;
import java.util.HashMap;
import java.util.Map;
import org.whole.lang.bindings.IBindingManager;
import org.whole.lang.builders.IBuilder;
import org.whole.lang.builders.IBuilderOperation;
import org.whole.lang.commons.reflect.CommonsLanguageKit;
import org.whole.lang.model.IEntity;
import org.whole.lang.parsers.DataTypeParsers;
import org.whole.lang.parsers.IDataTypeParser;
import org.whole.lang.reflect.EntityDescriptor;
import org.whole.lang.reflect.EntityDescriptorEnum;
import org.whole.lang.reflect.ReflectionFactory;
import org.whole.lang.util.DataTypeUtils;
import org.whole.lang.xml.model.Attribute;
import org.whole.lang.xml.model.Document;
import org.whole.lang.xml.model.Element;
import org.whole.lang.xml.model.Name;
import org.whole.lang.xml.model.QualifiedName;
import org.whole.lang.xml.reflect.XmlEntityDescriptorEnum;
import org.whole.lang.xml.visitors.XmlTraverseAllVisitor;
/**
* @author Riccardo Solmi, Matteo Necci
*/
public class XmlStoreConsumerVisitor extends XmlTraverseAllVisitor {
private IBuilder targetBuilder;
private IBindingManager bindings;
private Map<String, EntityDescriptorEnum> entityDescriptorEnumMap = new HashMap<String, EntityDescriptorEnum>();
private EntityDescriptorEnum entityDescriptorEnumDefault = null;
private EntityDescriptor<?> entityDescriptor;
private String valueAttr = null;
private String initialCapacityAttr = null;
public XmlStoreConsumerVisitor(IBuilderOperation targetOperation) {
targetBuilder = targetOperation.wGetBuilder(CommonsLanguageKit.URI);//FIXME generic call
this.bindings = targetOperation.getBindings();
}
public String getContextURI() {
return bindings != null && bindings.wIsSet("contextURI") ?
bindings.wStringValue("contextURI") : null;
}
protected EntityDescriptorEnum getEntityDescriptorEnum(String uri) {
return ReflectionFactory.getLanguageKit(uri, true, getContextURI()).getEntityDescriptorEnum();
}
protected EntityDescriptor<?> getEntityDescriptor(String name) {
return getEntityDescriptor(entityDescriptorEnumDefault, name);
}
protected EntityDescriptor<?> getEntityDescriptor(EntityDescriptorEnum edEnum, String name) {
EntityDescriptor<?> ed = edEnum.valueOf(name);
if (ed == null)
throw new IllegalArgumentException("Missing entity type \""+name+"\" from \""+
edEnum.getLanguageKit().getName()+"\" language");
return ed;
}
public void visit(Document entity) {
entity.getElement().accept(this);
}
public void visit(Element entity) {
// bManager.enterScope();
entity.getAttributes().accept(this);
entity.getTag().accept(this);
if (entity.getContent().wIsEmpty() && initialCapacityAttr == null) {
if (valueAttr != null) {
buildLeaf(entity);
valueAttr = null;
} else
targetBuilder.wEntity(entityDescriptor);
} else {
buildStructure(entity);
}
// bManager.exitScope();
}
public void visit(QualifiedName entity) {
String nameSpace = entity.getNameSpace().wStringValue();
String qualifiedString = entity.getName().wStringValue();
EntityDescriptorEnum edEnum = (EntityDescriptorEnum) entityDescriptorEnumMap.get(nameSpace);
entityDescriptor = getEntityDescriptor(edEnum, qualifiedString);
}
public void visit(Name entity) {
entityDescriptor = getEntityDescriptor(entity.getValue());
}
public void visit(Attribute entity) {
IEntity name = entity.getName();
switch (name.wGetEntityDescriptor().getOrdinal()) {
case XmlEntityDescriptorEnum.Name_ord:
if (name.wStringValue().equals("value"))
valueAttr = entity.getValue().wStringValue();
if (name.wStringValue().equals("initialCapacity"))
initialCapacityAttr = entity.getValue().wStringValue();
if (name.wStringValue().equals("xmlns")) {
entityDescriptorEnumDefault = getEntityDescriptorEnum(entity.getValue().wStringValue());
}
break;
case XmlEntityDescriptorEnum.QualifiedName_ord:
QualifiedName qName = (QualifiedName)name;
if (qName.getNameSpace().wStringValue().equals("xmlns")) {
String descrString = qName.getName().wStringValue();
if (!entityDescriptorEnumMap.containsKey(descrString))
entityDescriptorEnumMap.put(descrString, getEntityDescriptorEnum(entity.getValue().wStringValue()));
}
break;
}
}
private void buildLeaf(Element entity) {
IDataTypeParser parser = DataTypeUtils.getDataTypeParser(entityDescriptor, DataTypeParsers.PERSISTENCE);
switch (entityDescriptor.getDataKind()) {
case BOOLEAN:
targetBuilder.wEntity(entityDescriptor, parser.parseBoolean(entityDescriptor, valueAttr));
break;
case BYTE:
targetBuilder.wEntity(entityDescriptor, parser.parseByte(entityDescriptor, valueAttr));
break;
case CHAR:
targetBuilder.wEntity(entityDescriptor, parser.parseChar(entityDescriptor, valueAttr));
break;
case DATE:
targetBuilder.wEntity(entityDescriptor, parser.parseDate(entityDescriptor, valueAttr));
break;
case DOUBLE:
targetBuilder.wEntity(entityDescriptor, parser.parseDouble(entityDescriptor, valueAttr));
break;
case FLOAT:
targetBuilder.wEntity(entityDescriptor, parser.parseFloat(entityDescriptor, valueAttr));
break;
case INT:
targetBuilder.wEntity(entityDescriptor, parser.parseInt(entityDescriptor, valueAttr));
break;
case LONG:
targetBuilder.wEntity(entityDescriptor, parser.parseLong(entityDescriptor, valueAttr));
break;
case SHORT:
targetBuilder.wEntity(entityDescriptor, parser.parseShort(entityDescriptor, valueAttr));
break;
case STRING:
targetBuilder.wEntity(entityDescriptor, parser.parseString(entityDescriptor, valueAttr));
break;
case OBJECT:
targetBuilder.wEntity(entityDescriptor, parser.parseObject(entityDescriptor, valueAttr));
break;
case ENUM_VALUE:
targetBuilder.wEntity(entityDescriptor, parser.parseEnumValue(entityDescriptor, valueAttr));
break;
}
}
private void buildStructure(Element entity) {
EntityDescriptor<?> ed = entityDescriptor;
if (initialCapacityAttr == null) {
targetBuilder.wEntity_(ed);
entity.getContent().accept(this);
targetBuilder._wEntity(ed);
} else {
int initialCapacity = Integer.valueOf(initialCapacityAttr).intValue();
initialCapacityAttr = null;
targetBuilder.wEntity_(ed, initialCapacity);
entity.getContent().accept(this);
targetBuilder._wEntity(ed);
}
}
}