diff --git a/infra/axiom/src/main/java/com/evolveum/axiom/api/AxiomName.java b/infra/axiom/src/main/java/com/evolveum/axiom/api/AxiomName.java index 7f4b56d5b41..f05b3d27256 100644 --- a/infra/axiom/src/main/java/com/evolveum/axiom/api/AxiomName.java +++ b/infra/axiom/src/main/java/com/evolveum/axiom/api/AxiomName.java @@ -6,9 +6,13 @@ */ package com.evolveum.axiom.api; +import java.util.Iterator; + import org.jetbrains.annotations.NotNull; +import com.google.common.base.CharMatcher; import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; import com.google.common.base.Strings; public class AxiomName { @@ -17,6 +21,8 @@ public class AxiomName { private final String namespace; private final String localName; + private static final Splitter HASH_SYMBOL = Splitter.on('#'); + public AxiomName(String namespace, String localName) { this.namespace = Preconditions.checkNotNull(namespace, "namespace"); this.localName = Preconditions.checkNotNull(localName, "localName"); @@ -95,4 +101,9 @@ public static AxiomName local(@NotNull String localName) { return from("", localName); } + public static AxiomName parse(String item) { + Iterator nsLocalName = HASH_SYMBOL.split("#").iterator(); + return from(nsLocalName.next(), nsLocalName.next()); + } + } diff --git a/infra/axiom/src/main/java/com/evolveum/axiom/api/AxiomPrefixedName.java b/infra/axiom/src/main/java/com/evolveum/axiom/api/AxiomPrefixedName.java new file mode 100644 index 00000000000..d04ae6dab11 --- /dev/null +++ b/infra/axiom/src/main/java/com/evolveum/axiom/api/AxiomPrefixedName.java @@ -0,0 +1,79 @@ +package com.evolveum.axiom.api; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; + +public class AxiomPrefixedName { + + private final @Nullable String prefix; + private final @NotNull String localName; + + private AxiomPrefixedName(@Nullable String prefix, @NotNull String localName) { + this.prefix = Strings.emptyToNull(prefix); + this.localName = Preconditions.checkNotNull(localName, "localName"); + } + + + public static AxiomPrefixedName from(String prefix, String localName) { + return new AxiomPrefixedName(prefix, localName); + } + + public static final boolean isPrefixed(String maybePrefixed) { + // FIXME: Add matching + return maybePrefixed.contains(":"); + } + + public String getPrefix() { + return prefix; + } + + public String getLocalName() { + return localName; + } + + @Override + public String toString() { + return prefix != null ? prefix + ":" + localName : localName; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((localName == null) ? 0 : localName.hashCode()); + result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AxiomPrefixedName other = (AxiomPrefixedName) obj; + if (localName == null) { + if (other.localName != null) + return false; + } else if (!localName.equals(other.localName)) + return false; + if (prefix == null) { + if (other.prefix != null) + return false; + } else if (!prefix.equals(other.prefix)) + return false; + return true; + } + + + public static AxiomPrefixedName parse(String item) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/AxiomItemStream.java b/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/AxiomItemStream.java index bee876e3de4..4712ddc363b 100644 --- a/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/AxiomItemStream.java +++ b/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/AxiomItemStream.java @@ -23,7 +23,7 @@ interface TargetWithResolver extends Target { AxiomNameResolver valueResolver(); default AxiomStreamTarget asPrefixed(AxiomNameResolver sourceLocal) { - return new PrefixedToQualifiedNameAdapter(this, () -> itemResolver().or(sourceLocal), () -> valueResolver().or(sourceLocal)); + return new PrefixedToQNameTarget(this, () -> itemResolver().or(sourceLocal), () -> valueResolver().or(sourceLocal)); } } diff --git a/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/AxiomStreamTarget.java b/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/AxiomStreamTarget.java new file mode 100644 index 00000000000..f987b22b9c2 --- /dev/null +++ b/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/AxiomStreamTarget.java @@ -0,0 +1,16 @@ +package com.evolveum.axiom.api.stream; + +import com.evolveum.axiom.concepts.SourceLocation; + +public interface AxiomStreamTarget { + + void startItem(N item, SourceLocation loc); + void endItem(SourceLocation loc); + + void startValue(Object value, SourceLocation loc); + void endValue(SourceLocation loc); + + default void startInfra(N item, SourceLocation loc) {}; + default void endInfra(SourceLocation loc) {}; + +} diff --git a/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/PrefixedToQNameTarget.java b/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/PrefixedToQNameTarget.java new file mode 100644 index 00000000000..ea6c313e60f --- /dev/null +++ b/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/PrefixedToQNameTarget.java @@ -0,0 +1,61 @@ +package com.evolveum.axiom.api.stream; + +import java.util.function.Supplier; + +import com.evolveum.axiom.api.AxiomName; +import com.evolveum.axiom.api.AxiomPrefixedName; +import com.evolveum.axiom.api.stream.AxiomItemStream.Target; +import com.evolveum.axiom.concepts.SourceLocation; +import com.evolveum.axiom.lang.spi.AxiomNameResolver; +import com.evolveum.axiom.lang.spi.AxiomSemanticException; +import com.google.common.base.Preconditions; + +public class PrefixedToQNameTarget implements AxiomStreamTarget { + + private final AxiomItemStream.Target target; + + private final Supplier argumentResolver; + private final Supplier itemResolver; + + public PrefixedToQNameTarget(Target target, Supplier itemResolver, + Supplier valueResolver) { + super(); + this.target = target; + this.itemResolver = itemResolver; + this.argumentResolver = valueResolver; + } + + protected AxiomName convertItemName(AxiomPrefixedName prefixed, SourceLocation loc) { + AxiomName result = itemResolver.get().resolve(prefixed); + AxiomSemanticException.check(result != null, loc, "Unknown item '%s'.", prefixed); + return result; + } + + public void startItem(AxiomPrefixedName item, SourceLocation loc) { + target.startItem(convertItemName(item, loc), loc); + } + public void endItem(SourceLocation loc) { + target.endItem(loc); + } + public void startValue(Object value, SourceLocation loc) { + // FIXME: Do we want to do this? + if(value instanceof AxiomPrefixedName) { + value = Preconditions.checkNotNull(argumentResolver.get().resolve((AxiomPrefixedName) value)); + } + target.startValue(value, loc); + } + public void endValue(SourceLocation loc) { + target.endValue(loc); + } + public void startInfra(AxiomPrefixedName item, SourceLocation loc) { + target.startInfra(convertItemName(item, loc), loc); + } + public void endInfra(SourceLocation loc) { + target.endInfra(loc); + } + + AxiomItemStream.Target qnameTarget() { + return target; + } + +} diff --git a/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/StringToQNameTarget.java b/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/StringToQNameTarget.java new file mode 100644 index 00000000000..c5f11efb327 --- /dev/null +++ b/infra/axiom/src/main/java/com/evolveum/axiom/api/stream/StringToQNameTarget.java @@ -0,0 +1,49 @@ +package com.evolveum.axiom.api.stream; + +import java.util.function.Supplier; + +import com.evolveum.axiom.api.AxiomName; +import com.evolveum.axiom.api.AxiomPrefixedName; +import com.evolveum.axiom.api.stream.AxiomItemStream.Target; +import com.evolveum.axiom.concepts.SourceLocation; +import com.evolveum.axiom.lang.spi.AxiomNameResolver; +import com.evolveum.axiom.lang.spi.AxiomSemanticException; +import com.google.common.base.Preconditions; + +public class StringToQNameTarget implements AxiomStreamTarget { + + private PrefixedToQNameTarget target; + + public StringToQNameTarget(Target target, Supplier itemResolver, + Supplier valueResolver) { + super(); + this.target = new PrefixedToQNameTarget(target, itemResolver, valueResolver); + } + + public void endItem(SourceLocation loc) { + target.endItem(loc); + } + public void startValue(Object value, SourceLocation loc) { + // FIXME: Do we want to do this? + /*if(value instanceof AxiomPrefixedName) { + value = Preconditions.checkNotNull(argumentResolver.get().resolve((AxiomPrefixedName) value)); + }*/ + target.startValue(value, loc); + } + public void endValue(SourceLocation loc) { + target.endValue(loc); + } + + @Override + public void startItem(String item, SourceLocation loc) { + if(AxiomPrefixedName.isPrefixed(item)) { + target.startItem(AxiomPrefixedName.parse(item), loc); + } + target.qnameTarget().startItem(AxiomName.parse(item), loc); + } + + public void startInfra(String item, SourceLocation loc) { + + } + +} diff --git a/infra/axiom/src/main/java/com/evolveum/axiom/lang/antlr/AxiomAntlrStatementSource.java b/infra/axiom/src/main/java/com/evolveum/axiom/lang/antlr/AxiomAntlrStatementSource.java index 98e15674c42..352ddd262e0 100644 --- a/infra/axiom/src/main/java/com/evolveum/axiom/lang/antlr/AxiomAntlrStatementSource.java +++ b/infra/axiom/src/main/java/com/evolveum/axiom/lang/antlr/AxiomAntlrStatementSource.java @@ -73,8 +73,11 @@ public void stream(AxiomItemStream.TargetWithResolver target, Optional> emitOnly, AxiomNameResolver resolver) { - AxiomStreamTarget prefixedTarget = target.asPrefixed(resolver); - AxiomAntlrVisitor2 visitor = new AxiomAntlrVisitor2<>(sourceName, prefixedTarget); + stream(target.asPrefixed(resolver)); + } + + public final void stream(AxiomStreamTarget target) { + AxiomAntlrVisitor2 visitor = new AxiomAntlrVisitor2<>(sourceName, target); visitor.visit(root); }