Search in sources :

Example 1 with ChildDefinition

use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.

the class CustomTypeContentHelper method applyConfiguration.

/**
 * Apply a custom type configuration to the given schema.
 *
 * @param index the XML schema
 * @param association the custom type configuration for an individual
 *            property
 */
public static void applyConfiguration(XmlIndex index, CustomTypeContentAssociation association) {
    CustomTypeContent config = association.getConfig();
    // property identified by a list of qualified names
    List<QName> property = association.getProperty();
    PropertyDefinition propDef = null;
    DefinitionGroup propParent = null;
    if (property != null && property.size() > 1) {
        QName typeName = property.get(0);
        TypeDefinition type = index.getType(typeName);
        if (type != null) {
            LinkedList<QName> nameQueue = new LinkedList<>(property.subList(1, property.size()));
            Definition<?> parent = null;
            Definition<?> child = type;
            while (!nameQueue.isEmpty() && child != null) {
                parent = child;
                QName name = nameQueue.pollFirst();
                child = DefinitionUtil.getChild(parent, name);
            }
            if (nameQueue.isEmpty() && child instanceof PropertyDefinition) {
                propDef = (PropertyDefinition) child;
                if (parent instanceof TypeDefinition) {
                    propParent = (DefinitionGroup) parent;
                } else if (parent instanceof ChildDefinition<?>) {
                    ChildDefinition<?> pc = (ChildDefinition<?>) parent;
                    if (pc.asProperty() != null) {
                        propParent = pc.asProperty().getPropertyType();
                    } else if (pc.asGroup() != null) {
                        propParent = pc.asGroup();
                    }
                } else {
                    log.error("Illegal parent for custom type content property");
                    return;
                }
            } else {
                log.warn("Cannot apply custom type content configuration due to invalid property path");
                return;
            }
        } else {
            log.warn("Cannot apply custom type content configuration due because the type {} starting the property path could not be found", typeName);
            return;
        }
    } else {
        log.warn("Cannot apply custom type content configuration due to missing property path");
        return;
    }
    switch(config.getMode()) {
        case simple:
            applySimpleMode(propDef, propParent, config);
        case elements:
            applyElementsMode(propDef, propParent, config, index);
        default:
            log.error("Unrecognized custom type content mode {}", config.getMode().name());
    }
}
Also used : QName(javax.xml.namespace.QName) ChildDefinition(eu.esdihumboldt.hale.common.schema.model.ChildDefinition) DefaultPropertyDefinition(eu.esdihumboldt.hale.common.schema.model.impl.DefaultPropertyDefinition) DefaultGroupPropertyDefinition(eu.esdihumboldt.hale.common.schema.model.impl.DefaultGroupPropertyDefinition) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition) DefinitionGroup(eu.esdihumboldt.hale.common.schema.model.DefinitionGroup) LinkedList(java.util.LinkedList) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) DefaultTypeDefinition(eu.esdihumboldt.hale.common.schema.model.impl.DefaultTypeDefinition)

Example 2 with ChildDefinition

use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.

the class OptionalPropertiesFilter method areChildrenOptional.

/**
 * Determines if the given (nillable) entity can be considered optional in
 * respect to its children.
 *
 * @param entityDef the entity definition which children to check
 * @param alreadyChecked the set of definitions that have already been
 *            checked (excluding the given entity)
 * @return if all children are optional
 */
private boolean areChildrenOptional(EntityDefinition entityDef, Set<Definition<?>> alreadyChecked) {
    // get children without contexts
    Collection<? extends EntityDefinition> children = AlignmentUtil.getChildrenWithoutContexts(entityDef);
    if (children == null || children.isEmpty()) {
        return true;
    }
    for (EntityDefinition child : children) {
        Set<Definition<?>> checked = new HashSet<>(alreadyChecked);
        checked.add(entityDef.getDefinition());
        ChildDefinition<?> childDef = (ChildDefinition<?>) child.getDefinition();
        /*
			 * XML: We only need to check children that are attributes, if they
			 * are optional.
			 */
        if (childDef.asProperty() != null && childDef.asProperty().getConstraint(XmlAttributeFlag.class).isEnabled()) {
            // need to check if it is optional
            if (!isOptional(child, checked)) {
                return false;
            }
        }
    /*
			 * XXX does other special handling need to be done for other kinds
			 * of schemas?
			 */
    }
    return true;
}
Also used : EntityDefinition(eu.esdihumboldt.hale.common.align.model.EntityDefinition) GroupPropertyDefinition(eu.esdihumboldt.hale.common.schema.model.GroupPropertyDefinition) Definition(eu.esdihumboldt.hale.common.schema.model.Definition) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition) ChildDefinition(eu.esdihumboldt.hale.common.schema.model.ChildDefinition) EntityDefinition(eu.esdihumboldt.hale.common.align.model.EntityDefinition) ChildDefinition(eu.esdihumboldt.hale.common.schema.model.ChildDefinition) HashSet(java.util.HashSet)

Example 3 with ChildDefinition

use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.

the class StyledDefinitionLabelProvider method update.

/**
 * @see StyledCellLabelProvider#update(ViewerCell)
 */
@Override
public void update(ViewerCell cell) {
    Object element = cell.getElement();
    element = extractElement(element);
    StyledString text = new StyledString(defaultLabels.getText(element));
    cell.setImage(defaultLabels.getImage(element));
    String contextText = null;
    String countText = null;
    if (element instanceof EntityDefinition) {
        PopulationService ps = PlatformUI.getWorkbench().getService(PopulationService.class);
        if (ps != null) {
            Population pop = ps.getPopulation((EntityDefinition) element);
            int count = pop.getOverallCount();
            int parents = pop.getParentsCount();
            switch(count) {
                case Population.UNKNOWN:
                    countText = "\u00d7?";
                    break;
                case 0:
                    break;
                default:
                    countText = "\u00d7" + count;
                    if (parents != count) {
                        countText += " (" + parents + ")";
                    }
            }
        }
        contextText = AlignmentUtil.getContextText((EntityDefinition) element);
        element = ((EntityDefinition) element).getDefinition();
    }
    // append cardinality
    if (!suppressCardinality && element instanceof ChildDefinition<?>) {
        Cardinality cardinality = null;
        if (((ChildDefinition<?>) element).asGroup() != null) {
            cardinality = ((ChildDefinition<?>) element).asGroup().getConstraint(Cardinality.class);
        } else if (((ChildDefinition<?>) element).asProperty() != null) {
            cardinality = ((ChildDefinition<?>) element).asProperty().getConstraint(Cardinality.class);
        }
        if (cardinality != null) {
            // only append cardinality if it isn't 1/1
            if (cardinality.getMinOccurs() != 1 || cardinality.getMaxOccurs() != 1) {
                String card = " " + MessageFormat.format("({0}..{1})", new Object[] { Long.valueOf(cardinality.getMinOccurs()), (cardinality.getMaxOccurs() == Cardinality.UNBOUNDED) ? ("n") : (Long.valueOf(cardinality.getMaxOccurs())) });
                text.append(card, StyledString.COUNTER_STYLER);
            }
        }
    }
    if (contextText != null) {
        contextText = " " + contextText;
        text.append(contextText, StyledString.DECORATIONS_STYLER);
    }
    if (countText != null) {
        countText = " " + countText;
        text.append(countText, StyledString.QUALIFIER_STYLER);
    }
    cell.setText(text.toString());
    cell.setStyleRanges(text.getStyleRanges());
    Color foreground = getForeground(cell.getElement());
    cell.setForeground(foreground);
    Color background = getBackground(cell.getElement());
    cell.setBackground(background);
    super.update(cell);
}
Also used : EntityDefinition(eu.esdihumboldt.hale.common.align.model.EntityDefinition) Cardinality(eu.esdihumboldt.hale.common.schema.model.constraint.property.Cardinality) Color(org.eclipse.swt.graphics.Color) PopulationService(eu.esdihumboldt.hale.ui.common.service.population.PopulationService) ChildDefinition(eu.esdihumboldt.hale.common.schema.model.ChildDefinition) Population(eu.esdihumboldt.hale.ui.common.service.population.Population) StyledString(org.eclipse.jface.viewers.StyledString) StyledString(org.eclipse.jface.viewers.StyledString)

Example 4 with ChildDefinition

use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.

the class Pattern method match.

/**
 * Matches the type against the encoding pattern.
 *
 * @param type the type definition
 * @param path the definition path
 * @param gmlNs the GML namespace
 * @param checkedTypes the type definitions that have already been checked
 *            (to prevent cycles)
 * @param remainingElements the remaining elements to match
 *
 * @return the new path if there is a match, <code>null</code> otherwise
 */
private static DefinitionPath match(TypeDefinition type, DefinitionPath path, String gmlNs, HashSet<TypeDefinition> checkedTypes, List<PatternElement> remainingElements) {
    if (remainingElements == null || remainingElements.isEmpty()) {
        return null;
    }
    if (checkedTypes.contains(type)) {
        return null;
    } else {
        checkedTypes.add(type);
    }
    PatternElement first = remainingElements.get(0);
    PatternElement checkAgainst;
    boolean allowAttributeDescent;
    boolean removeFirstForAttributeDescent = false;
    boolean allowSubtypeDescent = true;
    switch(first.getType()) {
        case ONE_ELEMENT:
            // only descend
            checkAgainst = null;
            allowAttributeDescent = true;
            // first element may not be
            removeFirstForAttributeDescent = true;
            // special case: was last element
            if (remainingElements.size() == 1) {
                return path;
            }
            break;
        case ANY_ELEMENTS:
            // check against the next named element
            PatternElement named = null;
            for (int i = 1; i < remainingElements.size() && named == null; i++) {
                PatternElement element = remainingElements.get(i);
                if (element.getType().equals(ElementType.NAMED_ELEMENT)) {
                    named = element;
                }
            }
            if (named == null) {
                // no named element
                return null;
            } else {
                checkAgainst = named;
            }
            allowAttributeDescent = true;
            break;
        case NAMED_ELEMENT:
            // check the current
            checkAgainst = first;
            // only allow sub-type descent
            allowAttributeDescent = false;
            break;
        default:
            // $NON-NLS-1$
            throw new IllegalStateException("Unknown pattern element type");
    }
    if (checkAgainst != null) {
        // get the last path element
        QName elementName = path.getLastName();
        QName name = checkAgainst.getName();
        // inject namespace if needed
        if (name.getNamespaceURI() == GML_NAMESPACE_PLACEHOLDER) {
            name = new QName(gmlNs, name.getLocalPart());
        }
        // check direct match
        if (name.equals(elementName)) {
            // match for the element name -> we are on the right track
            int index = remainingElements.indexOf(checkAgainst);
            if (index == remainingElements.size() - 1) {
                // is last - we have a full match
                return path;
            }
            // remove the element (and any leading wildcards) from the queue
            remainingElements = remainingElements.subList(index + 1, remainingElements.size());
            // for a name match, no sub-type descent is allowed
            allowSubtypeDescent = false;
            // but an attribute descent is ok
            allowAttributeDescent = true;
        } else {
        // no name match
        // sub-type descent is still allowed, don't remove element
        }
    }
    if (allowSubtypeDescent) {
    // step down sub-types
    // XXX now represented in choices
    // XXX sub-type must work through parent choice
    // for (SchemaElement element : type.getSubstitutions(path.getLastName())) {
    // DefinitionPath candidate = match(
    // element.getType(),
    // new DefinitionPath(path).addSubstitution(element),
    // gmlNs,
    // new HashSet<TypeDefinition>(checkedTypes),
    // new ArrayList<PatternElement>(remainingElements));
    // 
    // if (candidate != null) {
    // return candidate;
    // }
    // }
    }
    if (allowAttributeDescent) {
        if (removeFirstForAttributeDescent) {
            remainingElements.remove(0);
        }
        // step down properties
        @java.lang.SuppressWarnings("unchecked") Iterable<ChildDefinition<?>> children = (Iterable<ChildDefinition<?>>) ((path.isEmpty()) ? (type.getChildren()) : (type.getDeclaredChildren()));
        Iterable<DefinitionPath> childPaths = GmlWriterUtil.collectPropertyPaths(children, path, true);
        for (DefinitionPath childPath : childPaths) {
            DefinitionPath candidate = match(childPath.getLastType(), childPath, gmlNs, new HashSet<TypeDefinition>(checkedTypes), new ArrayList<PatternElement>(remainingElements));
            if (candidate != null) {
                return candidate;
            }
        }
    }
    return null;
}
Also used : QName(javax.xml.namespace.QName) ChildDefinition(eu.esdihumboldt.hale.common.schema.model.ChildDefinition) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) DefinitionPath(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath)

Example 5 with ChildDefinition

use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.

the class TypeStructureTray method createSourceSample.

/**
 * Create sample code for a single tree path specifying a source property.
 *
 * @param path the tree path
 * @param types the types serving as input
 * @return the sample code or <code>null</code>
 */
private String createSourceSample(TreePath path, Collection<? extends TypeDefinition> types) {
    DefinitionGroup parent;
    int startIndex = 0;
    boolean hasPropDef = false;
    StringBuilder access = new StringBuilder();
    // determine parent type
    if (path.getFirstSegment() instanceof TypeDefinition) {
        // types are the top level elements
        parent = (DefinitionGroup) path.getFirstSegment();
        startIndex = 1;
        access.append(GroovyConstants.BINDING_SOURCE);
    } else {
        // types are not in the tree, single type must be root
        TypeDefinition type = types.iterator().next();
        parent = type;
        if (VARIABLES_TYPE_NAME.equals(type.getName())) {
            // Groovy property transformation
            // first segment is variable name
            Definition<?> def = (Definition<?>) path.getFirstSegment();
            startIndex++;
            access.append(def.getName().getLocalPart());
            // XXX add namespace if necessary
            // XXX currently groovy transformation does not support multiple
            // variables with the same name
            parent = DefinitionUtil.getDefinitionGroup(def);
        } else {
            // assuming Retype/Merge
            access.append(GroovyConstants.BINDING_SOURCE);
        }
    }
    // is a property or list of inputs referenced -> use accessor
    boolean propertyOrList = path.getSegmentCount() > startIndex || (path.getLastSegment() instanceof ChildDefinition<?> && canOccureMultipleTimes((ChildDefinition<?>) path.getLastSegment()));
    if (!propertyOrList) {
        if (parent instanceof TypeDefinition && canHaveValue((TypeDefinition) parent)) {
            if (!DefinitionUtil.hasChildren((Definition<?>) path.getLastSegment())) {
                // variable w/o children referenced
                return "// access variable\ndef value = " + access;
            } else {
                // variable w/ children referenced
                return "// access instance variable value\ndef value = " + access + ".value";
            }
        } else {
        // return null;
        }
    }
    if (path.getFirstSegment() instanceof TypeDefinition) {
        access.append(".links." + ((TypeDefinition) path.getFirstSegment()).getDisplayName());
    } else {
        access.append(".p");
        // check for encountering property definition, so that there should
        // not be 2 'p's appended.
        hasPropDef = true;
    }
    for (int i = startIndex; i < path.getSegmentCount(); i++) {
        Definition<?> def = (Definition<?>) path.getSegment(i);
        if (def instanceof PropertyDefinition) {
            for (int j = i - 1; j >= 0; j--) {
                Definition<?> def1 = (Definition<?>) path.getSegment(j);
                if (def1 instanceof TypeDefinition) {
                // do nothing
                } else {
                    hasPropDef = true;
                }
            }
            if (!hasPropDef) {
                access.append(".p");
            }
            // property name
            access.append('.');
            access.append(def.getName().getLocalPart());
            // test if uniquely accessible from parent
            boolean useNamespace = true;
            if (parent instanceof Definition<?>) {
                useNamespace = namespaceNeeded((Definition<?>) parent, def);
            }
            // add namespace if necessary
            if (useNamespace) {
                access.append("('");
                access.append(def.getName().getNamespaceURI());
                access.append("')");
            }
        } else if (def instanceof TypeDefinition) {
            access.append("." + ((TypeDefinition) def).getDisplayName());
        }
        // set the new parent
        parent = DefinitionUtil.getDefinitionGroup(def);
    }
    if (parent instanceof TypeDefinition) {
        // only properties at the end of the path are supported
        TypeDefinition propertyType = (TypeDefinition) parent;
        StringBuilder example = new StringBuilder();
        boolean canOccurMultipleTimes = false;
        if (path.getFirstSegment() instanceof TypeDefinition) {
            canOccurMultipleTimes = true;
        }
        /*
			 * Instances/values may occur multiple times if any element in the
			 * path may occur multiple times.
			 */
        for (int i = path.getSegmentCount() - 1; i >= 0 && !canOccurMultipleTimes; i--) {
            if (path.getSegment(i) instanceof ChildDefinition<?>) {
                canOccurMultipleTimes = canOccureMultipleTimes((ChildDefinition<?>) path.getSegment(i));
            }
        }
        if (canHaveValue(propertyType)) {
            // single value
            if (canOccurMultipleTimes) {
                example.append("// access first value\n");
            } else {
                example.append("// access value\n");
            }
            example.append("def value = ");
            example.append(access);
            example.append(".value()\n\n");
            // multiple values
            if (canOccurMultipleTimes) {
                example.append("// access all values as list\n");
                example.append("def valueList = ");
                example.append(access);
                example.append(".values()\n\n");
            }
        }
        if (DefinitionUtil.hasChildren(propertyType)) {
            // single instance
            if (canOccurMultipleTimes) {
                example.append("// access first instance\n");
            } else {
                example.append("// access instance\n");
            }
            example.append("def instance = ");
            example.append(access);
            example.append(".first()\n\n");
            if (canOccurMultipleTimes) {
                // multiple values
                example.append("// access all instances as list\n");
                example.append("def instanceList = ");
                example.append(access);
                example.append(".list()\n\n");
                // iterate over instances
                example.append("// iterate over instances\n");
                example.append(access);
                example.append(".each {\n");
                example.append("\tinstance ->\n");
                example.append("}\n\n");
            }
        } else if (canOccurMultipleTimes && propertyType.getConstraint(HasValueFlag.class).isEnabled()) {
            // iterate over values
            example.append("// iterate over values\n");
            example.append(access);
            example.append(".each {\n");
            example.append("\tvalue ->\n");
            example.append("}\n\n");
        }
        return example.toString();
    }
    return null;
}
Also used : HasValueFlag(eu.esdihumboldt.hale.common.schema.model.constraint.type.HasValueFlag) ChildDefinition(eu.esdihumboldt.hale.common.schema.model.ChildDefinition) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition) Definition(eu.esdihumboldt.hale.common.schema.model.Definition) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) ChildDefinition(eu.esdihumboldt.hale.common.schema.model.ChildDefinition) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition) DefinitionGroup(eu.esdihumboldt.hale.common.schema.model.DefinitionGroup) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition)

Aggregations

ChildDefinition (eu.esdihumboldt.hale.common.schema.model.ChildDefinition)32 ArrayList (java.util.ArrayList)20 QName (javax.xml.namespace.QName)19 TypeDefinition (eu.esdihumboldt.hale.common.schema.model.TypeDefinition)11 ChildContext (eu.esdihumboldt.hale.common.align.model.ChildContext)6 Definition (eu.esdihumboldt.hale.common.schema.model.Definition)6 EntityDefinition (eu.esdihumboldt.hale.common.align.model.EntityDefinition)5 PropertyEntityDefinition (eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition)5 DefinitionGroup (eu.esdihumboldt.hale.common.schema.model.DefinitionGroup)5 List (java.util.List)5 PropertyDefinition (eu.esdihumboldt.hale.common.schema.model.PropertyDefinition)4 Pair (eu.esdihumboldt.util.Pair)3 LinkedList (java.util.LinkedList)3 IStructuredSelection (org.eclipse.jface.viewers.IStructuredSelection)3 TreePath (org.eclipse.jface.viewers.TreePath)3 TypeEntityDefinition (eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition)2 InstanceValidationMessage (eu.esdihumboldt.hale.common.instance.extension.validation.report.InstanceValidationMessage)2 InstanceValidationReport (eu.esdihumboldt.hale.common.instance.extension.validation.report.InstanceValidationReport)2 Group (eu.esdihumboldt.hale.common.instance.model.Group)2 Instance (eu.esdihumboldt.hale.common.instance.model.Instance)2