/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available 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. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * HUMBOLDT EU Integrated Project #030962 * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.common.align.io.impl.internal; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import eu.esdihumboldt.hale.common.align.model.ChildContext; import eu.esdihumboldt.hale.common.align.model.Condition; import eu.esdihumboldt.hale.common.align.model.Entity; import eu.esdihumboldt.hale.common.align.model.Property; import eu.esdihumboldt.hale.common.align.model.impl.DefaultProperty; import eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition; import eu.esdihumboldt.hale.common.instance.extension.filter.FilterDefinitionManager; import eu.esdihumboldt.hale.common.instance.model.Filter; import eu.esdihumboldt.hale.common.schema.SchemaSpaceID; import eu.esdihumboldt.hale.common.schema.model.ChildDefinition; import eu.esdihumboldt.hale.common.schema.model.DefinitionGroup; import eu.esdihumboldt.hale.common.schema.model.DefinitionUtil; import eu.esdihumboldt.hale.common.schema.model.GroupPropertyDefinition; import eu.esdihumboldt.hale.common.schema.model.TypeDefinition; import eu.esdihumboldt.hale.common.schema.model.TypeIndex; import eu.esdihumboldt.util.Pair; /** * Represents a {@link Property}. * * @author Simon Templer */ public class PropertyBean extends EntityBean<PropertyEntityDefinition> { private List<ChildContextBean> properties = new ArrayList<ChildContextBean>(); /** * Default constructor */ public PropertyBean() { super(); } /** * Create a property entity bean based on the given property entity * * @param property the property entity */ public PropertyBean(Property property) { super(); setTypeName(property.getDefinition().getType().getName()); setFilter(FilterDefinitionManager.getInstance().asString( property.getDefinition().getFilter())); for (ChildContext child : property.getDefinition().getPropertyPath()) { properties.add(new ChildContextBean(child)); } } /** * @see EntityBean#createEntity(TypeIndex, SchemaSpaceID) */ @Override public Entity createEntity(TypeIndex types, SchemaSpaceID schemaSpace) { return new DefaultProperty(createEntityDefinition(types, schemaSpace)); } /** * @see EntityBean#createEntityDefinition(TypeIndex, SchemaSpaceID) */ @Override protected PropertyEntityDefinition createEntityDefinition(TypeIndex index, SchemaSpaceID schemaSpace) { TypeDefinition typeDef = index.getType(getTypeName()); if (typeDef == null) { throw new IllegalStateException(MessageFormat.format( "TypeDefinition for type {0} not found", getTypeName())); } List<ChildContext> path = new ArrayList<ChildContext>(); DefinitionGroup parent = typeDef; for (ChildContextBean childContext : properties) { if (parent == null) { throw new IllegalStateException( "Could not resolve property entity definition: child not present"); } Pair<ChildDefinition<?>, List<ChildDefinition<?>>> childs = findChild(parent, childContext.getChildName()); ChildDefinition<?> child = childs.getFirst(); // if the child is still null throw an exception if (child == null) { throw new IllegalStateException( "Could not resolve property entity definition: child not found"); } if (childs.getSecond() != null) { for (ChildDefinition<?> pathElems : childs.getSecond()) { path.add(new ChildContext(childContext.getContextName(), childContext .getContextIndex(), createCondition(childContext.getConditionFilter()), pathElems)); } } path.add(new ChildContext(childContext.getContextName(), childContext.getContextIndex(), createCondition(childContext .getConditionFilter()), child)); if (child instanceof DefinitionGroup) { parent = (DefinitionGroup) child; } else if (child.asProperty() != null) { parent = child.asProperty().getPropertyType(); } else { parent = null; } } return new PropertyEntityDefinition(typeDef, path, schemaSpace, FilterDefinitionManager .getInstance().parse(getFilter())); } /** * The function to look for a child as ChildDefinition or as Group * * @param parent the starting point to traverse from * @param childName the name of the parent's child * @return a pair of child and a list with the full path from parent to the * child or <code>null</code> if no such child was found */ public static Pair<ChildDefinition<?>, List<ChildDefinition<?>>> findChild( DefinitionGroup parent, QName childName) { ChildDefinition<?> child = parent.getChild(childName); if (child == null) { // if the child is null there can be still a childname // if the namespace is not null if (childName.getNamespaceURI().equals(XMLConstants.NULL_NS_URI)) { // get all children and iterate over them Collection<? extends ChildDefinition<?>> children = DefinitionUtil .getAllChildren(parent); for (ChildDefinition<?> _child : children) { // try to find another child with the same local part, // if we find a child with the same local part but // different namespace we overwrite child if (_child.getName().getLocalPart().equals(childName.getLocalPart())) { child = _child; break; } } } } if (child != null) { return new Pair<ChildDefinition<?>, List<ChildDefinition<?>>>(child, null); } Collection<? extends ChildDefinition<?>> children = DefinitionUtil.getAllChildren(parent); for (ChildDefinition<?> groupChild : children) { if (groupChild.asGroup() != null) { GroupPropertyDefinition temp = groupChild.asGroup(); if (findChild(temp, childName) != null) { Pair<ChildDefinition<?>, List<ChildDefinition<?>>> recTemp = findChild(temp, childName); if (recTemp.getSecond() == null) { List<ChildDefinition<?>> second = new ArrayList<ChildDefinition<?>>(); second.add(temp); ChildDefinition<?> first = recTemp.getFirst(); return new Pair<ChildDefinition<?>, List<ChildDefinition<?>>>(first, second); } else { recTemp.getSecond().add(0, temp); } } } } return null; } /** * Create a condition. * * @param conditionFilter the condition filter * @return the condition or <code>null</code> */ private Condition createCondition(String conditionFilter) { Filter filter = FilterDefinitionManager.getInstance().parse(conditionFilter); if (filter != null) { return new Condition(filter); } return null; } /** * Get the property names * * @return the property names */ public List<ChildContextBean> getProperties() { return properties; } /** * Set the property names * * @param properties the property names to set */ public void setProperties(List<ChildContextBean> properties) { this.properties = properties; } }