Skip to content

Commit

Permalink
Serializ and deserialize InfraItemName as @localPart in Item Paths
Browse files Browse the repository at this point in the history
  - this serialization format is consistent with JSON / YAML serialization
    of items.
  • Loading branch information
tonydamage committed Apr 23, 2024
1 parent eb7e1a1 commit 3b5aaa1
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pathValue: SQUARE_BRACKET_LEFT argument SQUARE_BRACKET_RIGHT;

itemPathComponent: SHARP #IdentifierComponent
| AT_SIGN #DereferenceComponent
| prefixedName #ItemComponent
| itemName #ItemComponent
;

path: DOT #SelfPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
*/
package com.evolveum.midpoint.prism.path;

import java.util.AbstractMap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.PrismConstants;

import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -44,6 +48,16 @@ public class InfraItemName extends ItemName {
public static final InfraItemName METADATA = InfraItemName.of(PrismConstants.NS_METADATA,"metadata").intern();


private static final BiMap<InfraItemName, QName> SERIALIZATION_MAPPING = ImmutableBiMap.<InfraItemName, QName>builder()
.put(serializationEntry(ID))
.put(serializationEntry(TYPE))
.put(serializationEntry(PATH))
.put(serializationEntry(METADATA))
.build();

private static final BiMap<QName, InfraItemName> DESERIALIZATION_MAPPING = SERIALIZATION_MAPPING.inverse();



public InfraItemName(String namespaceURI, String localPart) {
super(namespaceURI, localPart);
Expand All @@ -53,6 +67,24 @@ public static InfraItemName of(String namespace, String localPart) {
return new InfraItemName(namespace, localPart);
}

public static InfraItemName fromQName(QName name) {
if (name == null) {
return null;
} else if (name instanceof InfraItemName infra) {
return infra;
} else {
return of(name.getNamespaceURI(), name.getLocalPart());
}
}

public static boolean isSerializedForm(QName qname) {
return DESERIALIZATION_MAPPING.containsKey(qname);
}

public static InfraItemName fromSerialized(QName qname) {
return DESERIALIZATION_MAPPING.get(qname);
}

public InfraItemName intern() {
return INTERNER.intern(this);
}
Expand Down Expand Up @@ -103,76 +135,21 @@ public ItemPath rest(int n) {
}
}

@Override
public Long firstToIdOrNull() {
return null;
}

@NotNull
@Override
public ItemPath namedSegmentsOnly() {
return this;
}

@NotNull
@Override
public ItemPath removeIds() {
return this;
}

@Override
public ItemName asSingleName() {
return null;
}

@Override
public boolean isSingleName() {
return true;
}

@Override
public ItemName lastName() {
return null;
}

@Override
public Object last() {
return this;
}

@Override
public ItemPath firstAsPath() {
return this;
}

@NotNull
@Override
public ItemPath allExceptLast() {
return EMPTY_PATH;
}

@Override
public String toString() {
return "@" + this.getLocalPart();
}

@Override
public void shortDump(StringBuilder sb) {
sb.append(this);

public boolean matches(QName other) {
throw new UnsupportedOperationException();
}

@Override
public ItemPath subPath(int from, int to) {
if (from > 0) {
return EMPTY_PATH;
} else if (to == 0) {
return EMPTY_PATH;
} else {
return this;
}
public QName asSerializationForm() {
return SERIALIZATION_MAPPING.get(this);
}

public boolean matches(QName other) {
throw new UnsupportedOperationException();
private static Map.Entry<InfraItemName,QName> serializationEntry(InfraItemName infraItem) {
return new AbstractMap.SimpleEntry<>(infraItem, new QName("@" + infraItem.getLocalPart()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ static ItemPath fromString(@NotNull String value) {
return PrismContext.get().itemPathParser().asItemPath(value);
}

static boolean isInfraItem(QName name) {
// FIXME: Maybe also add check for namespace, localName? - this could cause problems now with ID segment
return name instanceof InfraItemName;
}

/**
* Returns true if the path is empty i.e. has no components.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@ public NameItemPathSegment(@NotNull QName name) {
this.name = ItemName.fromQName(name);
}

public NameItemPathSegment(@NotNull InfraItemName name) {
this.name = name;
}

@NotNull
public ItemName getName() {
return name;
}

@Override
public String toString() {
return DebugUtil.formatElementName(name);
return name.toString();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ static UniformItemPath create(Object... segments) {
}

static ItemPathSegment createSegment(QName qname, boolean variable) {
if (InfraItemName.isSerializedForm(qname)) {
return new NameItemPathSegment(InfraItemName.fromSerialized(qname));
}
if (ParentPathSegment.QNAME.equals(qname)) {
return new ParentPathSegment();
} else if (ObjectReferencePathSegment.QNAME.equals(qname)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ public <ID extends ItemDefinition<?>> ID findItemDefinition(@NotNull ItemPath pa
throw new IllegalArgumentException("Cannot resolve empty path on complex type definition "+this);
}
Object first = path.first();
if (first instanceof InfraItemName infraItem) {
if (ItemPath.toNameOrNull(first) instanceof InfraItemName infraItem) {
return findInfraItemDefinition(infraItem, path.rest(), clazz);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ private static QName assignPrefix(@NotNull QName name, PrismNamespaceContext glo
Map<String, String> localNamespaceToPrefix, Map<String, String> prefixToNs, boolean overrideNs) {
String namespace = name.getNamespaceURI();
String explicitPrefix = name.getPrefix();

if(ItemPath.isInfraItem(name)) {

return InfraItemName.fromQName(name).asSerializationForm();
}

if (Strings.isNullOrEmpty(namespace)) {
if (Strings.isNullOrEmpty(explicitPrefix)) {
/*
Expand Down

0 comments on commit 3b5aaa1

Please sign in to comment.