/* * 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.model.transformation.tree.impl; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import eu.esdihumboldt.hale.common.align.model.AlignmentUtil; import eu.esdihumboldt.hale.common.align.model.EntityDefinition; import eu.esdihumboldt.hale.common.align.model.transformation.tree.CellNode; import eu.esdihumboldt.hale.common.align.model.transformation.tree.Leftovers; import eu.esdihumboldt.hale.common.align.model.transformation.tree.SourceNode; import eu.esdihumboldt.hale.common.align.model.transformation.tree.TransformationNode; import eu.esdihumboldt.hale.common.align.model.transformation.tree.TransformationNodeVisitor; import eu.esdihumboldt.hale.common.align.model.transformation.tree.context.TransformationContext; import eu.esdihumboldt.hale.common.schema.model.Definition; /** * Default {@link SourceNode} implementation * * @author Simon Templer */ public class SourceNodeImpl extends AbstractTransformationNode implements SourceNode { private final EntityDefinition entityDefinition; private final SourceNode parent; private final Set<SourceNode> children = new HashSet<SourceNode>(); // private final SourceNodeFactory sourceNodeFactory; private final Set<CellNode> relations = new HashSet<CellNode>(); private TransformationContext context; /** * Constructor * * @param definition the associated entity definition * @param sourceNodeFactory the factory for creating new source nodes */ public SourceNodeImpl(EntityDefinition definition, SourceNodeFactory sourceNodeFactory) { this.entityDefinition = definition; // this.sourceNodeFactory = sourceNodeFactory; EntityDefinition parentDef = AlignmentUtil.getParent(definition); if (parentDef != null) { parent = sourceNodeFactory.getSourceNode(parentDef); parent.addChild(this); } else { parent = null; } } /** * Constructor for nodes not associated to a source node factory. * * @param definition the associated entity definition * @param parent the parent source node * @param addToParent if the created node should be added as a child to the * given parent */ public SourceNodeImpl(EntityDefinition definition, SourceNode parent, boolean addToParent) { this.entityDefinition = definition; // this.sourceNodeFactory = null; this.parent = parent; if (addToParent && parent != null) { parent.addChild(this); } } /** * @see SourceNode#getDefinition() */ @Override public Definition<?> getDefinition() { return entityDefinition.getDefinition(); } /** * @see SourceNode#getParent() */ @Override public SourceNode getParent() { return parent; } /** * @see SourceNode#getEntityDefinition() */ @Override public EntityDefinition getEntityDefinition() { return entityDefinition; } /** * @see SourceNode#addChild(SourceNode) */ @Override public void addChild(SourceNode child) { children.add(child); } /** * @see SourceNode#getChildren(boolean) */ @SuppressWarnings("unchecked") @Override public Collection<SourceNode> getChildren(boolean includeAnnotated) { if (!includeAnnotated || getAnnotation(ANNOTATION_CHILDREN) == null) { return Collections.unmodifiableCollection(children); } else { Collection<SourceNode> result = new ArrayList<SourceNode>(children); result.addAll((Collection<SourceNode>) getAnnotation(ANNOTATION_CHILDREN)); return result; } } /** * @see SourceNode#addRelation(CellNode) */ @Override public void addRelation(CellNode cellNode) { relations.add(cellNode); } /** * @see SourceNode#getRelations(boolean) */ @SuppressWarnings("unchecked") @Override public Collection<CellNode> getRelations(boolean includeAnnotated) { if (!includeAnnotated || getAnnotation(ANNOTATION_RELATIONS) == null) { return Collections.unmodifiableCollection(relations); } else { Collection<CellNode> result = new ArrayList<CellNode>(relations); result.addAll((Collection<CellNode>) getAnnotation(ANNOTATION_RELATIONS)); return result; } } /** * @see TransformationNode#accept(TransformationNodeVisitor) */ @SuppressWarnings("unchecked") @Override public void accept(TransformationNodeVisitor visitor) { if (visitor.visit(this)) { if (visitor.isFromTargetToSource()) { if (parent != null) { parent.accept(visitor); } } else { // visit children for (SourceNode child : children) { child.accept(visitor); } // visit annotated children if (visitor.includeAnnotatedNodes() && getAnnotation(ANNOTATION_CHILDREN) != null) { for (SourceNode child : (Iterable<SourceNode>) getAnnotation(ANNOTATION_CHILDREN)) { child.accept(visitor); } } // visit relations for (CellNode relation : getRelations(visitor.includeAnnotatedNodes())) { relation.accept(visitor); } } } visitor.leave(this); } /** * @see SourceNode#isDefined() */ @Override public boolean isDefined() { Object value = getAnnotation(ANNOTATION_VALUE_DEFINED); if (value instanceof Boolean) { return (Boolean) value; } return false; } /** * @see SourceNode#setDefined(boolean) */ @Override public void setDefined(boolean defined) { setAnnotation(ANNOTATION_VALUE_DEFINED, defined); } /** * @see SourceNode#getValue() */ @Override public Object getValue() { return getAnnotation(ANNOTATION_VALUE); } /** * @see SourceNode#setValue(java.lang.Object) */ @Override public void setValue(Object value) { setAnnotation(ANNOTATION_VALUE, value); setDefined(true); if (getAllValues() == null || getAllValues().length == 0) { setAllValues(value); } } @Override public void setAllValues(Object... values) { setAnnotation(ANNOTATION_ALL_VALUES, values); } @Override public Object[] getAllValues() { return (Object[]) getAnnotation(ANNOTATION_ALL_VALUES); } /** * @see SourceNode#setLeftovers(Leftovers) */ @Override public void setLeftovers(Leftovers leftovers) { setAnnotation(ANNOTATION_LEFTOVERS, leftovers); } /** * @see SourceNode#getLeftovers() */ @Override public Leftovers getLeftovers() { return (Leftovers) getAnnotation(ANNOTATION_LEFTOVERS); } /** * @see SourceNode#addAnnotatedChild(SourceNode) */ @Override public void addAnnotatedChild(SourceNode child) { @SuppressWarnings("unchecked") List<SourceNode> ac = (List<SourceNode>) getAnnotation(ANNOTATION_CHILDREN); if (ac == null) { ac = new ArrayList<SourceNode>(); setAnnotation(ANNOTATION_CHILDREN, ac); } ac.add(child); } /** * @see SourceNode#addAnnotatedRelation(CellNode) */ @Override public void addAnnotatedRelation(CellNode relation) { @SuppressWarnings("unchecked") List<CellNode> ar = (List<CellNode>) getAnnotation(ANNOTATION_RELATIONS); if (ar == null) { ar = new ArrayList<CellNode>(); setAnnotation(ANNOTATION_RELATIONS, ar); } ar.add(relation); } /** * @see SourceNode#setContext(TransformationContext) */ @Override public void setContext(TransformationContext context) { this.context = context; } /** * @see SourceNode#getContext() */ @Override public TransformationContext getContext() { return context; } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((entityDefinition == null) ? 0 : entityDefinition.hashCode()); return result; } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; SourceNodeImpl other = (SourceNodeImpl) obj; if (entityDefinition == null) { if (other.entityDefinition != null) return false; } else if (!entityDefinition.equals(other.entityDefinition)) return false; return true; } /** * @see SourceNode#setAnnotatedParent(SourceNode) */ @Override public void setAnnotatedParent(SourceNode parent) { setAnnotation(ANNOTATION_PARENT, parent); } /** * @see SourceNode#setAnnotatedParent(SourceNode) */ @Override public SourceNode getAnnotatedParent() { return (SourceNode) getAnnotation(ANNOTATION_PARENT); } }