From d4922244deb21d864fa4bb50340bd6ffade384a2 Mon Sep 17 00:00:00 2001 From: Keith E Campbell Date: Tue, 1 Oct 2024 20:13:07 -0700 Subject: [PATCH] Implementation of ConceptEnumerationFacade, and related changes. --- .../tinkar/common/id/PublicIdStringKey.java | 2 +- .../tinkar/common/id/PublicIdWithString.java | 26 ++++++++ .../dev/ikm/tinkar/entity/ConceptEntity.java | 3 +- .../java/dev/ikm/tinkar/entity/Entity.java | 14 +++++ .../dev/ikm/tinkar/entity/EntityService.java | 4 ++ .../dev/ikm/tinkar/entity/IdentifierData.java | 3 +- .../dev/ikm/tinkar/entity/PatternRecord.java | 5 ++ .../dev/ikm/tinkar/entity/SemanticRecord.java | 5 ++ .../dev/ikm/tinkar/entity/StampEntity.java | 2 +- .../dev/ikm/tinkar/entity/StampRecord.java | 2 +- .../terms/ConceptEnumerationFacade.java | 63 +++++++++++++++++++ .../dev/ikm/tinkar/terms/EntityProxy.java | 63 +++++++++++-------- 12 files changed, 159 insertions(+), 33 deletions(-) create mode 100644 common/src/main/java/dev/ikm/tinkar/common/id/PublicIdWithString.java create mode 100644 terms/src/main/java/dev/ikm/tinkar/terms/ConceptEnumerationFacade.java diff --git a/common/src/main/java/dev/ikm/tinkar/common/id/PublicIdStringKey.java b/common/src/main/java/dev/ikm/tinkar/common/id/PublicIdStringKey.java index 1d176bac..c6b40fbc 100644 --- a/common/src/main/java/dev/ikm/tinkar/common/id/PublicIdStringKey.java +++ b/common/src/main/java/dev/ikm/tinkar/common/id/PublicIdStringKey.java @@ -33,7 +33,7 @@ *

* T is the class this is a key for, to help code comprehension */ -public class PublicIdStringKey implements Comparable, Encodable { +public class PublicIdStringKey implements PublicIdWithString { final PublicId publicId; String string; diff --git a/common/src/main/java/dev/ikm/tinkar/common/id/PublicIdWithString.java b/common/src/main/java/dev/ikm/tinkar/common/id/PublicIdWithString.java new file mode 100644 index 00000000..fec35c5a --- /dev/null +++ b/common/src/main/java/dev/ikm/tinkar/common/id/PublicIdWithString.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2015 Integrated Knowledge Management (support@ikm.dev) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package dev.ikm.tinkar.common.id; + +import dev.ikm.tinkar.common.binary.Encodable; + +/** + * An interface that can be implemented by an enum, and can also be made compatible + * with a future concept binding that may exist in a starter set or elsewhere. + * @param + */ +public interface PublicIdWithString extends Comparable, Encodable { +} diff --git a/entity/src/main/java/dev/ikm/tinkar/entity/ConceptEntity.java b/entity/src/main/java/dev/ikm/tinkar/entity/ConceptEntity.java index 3a8a059f..fb491596 100644 --- a/entity/src/main/java/dev/ikm/tinkar/entity/ConceptEntity.java +++ b/entity/src/main/java/dev/ikm/tinkar/entity/ConceptEntity.java @@ -23,8 +23,7 @@ public interface ConceptEntity extends Entity, ConceptChronology, - ConceptFacade, - IdentifierData { + ConceptFacade { @Override ImmutableList versions(); diff --git a/entity/src/main/java/dev/ikm/tinkar/entity/Entity.java b/entity/src/main/java/dev/ikm/tinkar/entity/Entity.java index 6e4e08d9..160f55c3 100644 --- a/entity/src/main/java/dev/ikm/tinkar/entity/Entity.java +++ b/entity/src/main/java/dev/ikm/tinkar/entity/Entity.java @@ -132,6 +132,20 @@ default T getVersionFast(int stampNid) { return null; } + default Optional getVersion(PublicId stampId) { + return Optional.ofNullable(getVersionFast(stampId)); + } + + default T getVersionFast(PublicId stampId) { + int stampNid = nid(stampId); + for (T version : versions()) { + if (version.stampNid() == stampNid) { + return version; + } + } + return null; + } + default IntIdSet stampNids() { MutableIntList stampNids = IntLists.mutable.withInitialCapacity(versions().size()); for (EntityVersion version : versions()) { diff --git a/entity/src/main/java/dev/ikm/tinkar/entity/EntityService.java b/entity/src/main/java/dev/ikm/tinkar/entity/EntityService.java index 96f288cc..4e1e973d 100644 --- a/entity/src/main/java/dev/ikm/tinkar/entity/EntityService.java +++ b/entity/src/main/java/dev/ikm/tinkar/entity/EntityService.java @@ -104,6 +104,9 @@ default int nidForUuids(UUID... uuids) { default , V extends EntityVersion> Optional getEntity(Component component) { return getEntity(nidForPublicId(component.publicId())); } + default , V extends EntityVersion> Optional getEntity(PublicId publicId) { + return getEntity(nidForPublicId(publicId)); + } default , V extends EntityVersion> Optional getEntity(int nid) { T entity = getEntityFast(nid); @@ -119,6 +122,7 @@ default , V extends EntityVersion> Optional getEntity(Imm return getEntity(nidForUuids(uuidList)); } + default int nidForUuids(ImmutableList uuidList) { return nidForPublicId(PublicIds.of(uuidList.toArray(new UUID[uuidList.size()]))); } diff --git a/entity/src/main/java/dev/ikm/tinkar/entity/IdentifierData.java b/entity/src/main/java/dev/ikm/tinkar/entity/IdentifierData.java index bfb6ac91..417e8210 100644 --- a/entity/src/main/java/dev/ikm/tinkar/entity/IdentifierData.java +++ b/entity/src/main/java/dev/ikm/tinkar/entity/IdentifierData.java @@ -16,6 +16,7 @@ package dev.ikm.tinkar.entity; import dev.ikm.tinkar.common.id.PublicId; +import dev.ikm.tinkar.common.id.PublicIds; import java.util.UUID; import java.util.function.LongConsumer; @@ -60,6 +61,6 @@ default void forEach(LongConsumer consumer) { } default PublicId publicId() { - return this; + return PublicIds.of(asUuidArray()); } } diff --git a/entity/src/main/java/dev/ikm/tinkar/entity/PatternRecord.java b/entity/src/main/java/dev/ikm/tinkar/entity/PatternRecord.java index bf0a39a9..817a0434 100644 --- a/entity/src/main/java/dev/ikm/tinkar/entity/PatternRecord.java +++ b/entity/src/main/java/dev/ikm/tinkar/entity/PatternRecord.java @@ -16,6 +16,7 @@ package dev.ikm.tinkar.entity; import dev.ikm.tinkar.common.id.PublicId; +import dev.ikm.tinkar.common.id.PublicIds; import dev.ikm.tinkar.common.util.Validator; import io.soabase.recordbuilder.core.RecordBuilder; import org.eclipse.collections.api.list.ImmutableList; @@ -98,4 +99,8 @@ public PatternAnalogueBuilder analogueBuilder() { public PatternAnalogueBuilder without(PatternEntityVersion versionToAdd) { return analogueBuilder().remove(versionToAdd); } + + public PublicId publicId() { + return PublicIds.of(asUuidArray()); + } } diff --git a/entity/src/main/java/dev/ikm/tinkar/entity/SemanticRecord.java b/entity/src/main/java/dev/ikm/tinkar/entity/SemanticRecord.java index 81147558..d1878658 100644 --- a/entity/src/main/java/dev/ikm/tinkar/entity/SemanticRecord.java +++ b/entity/src/main/java/dev/ikm/tinkar/entity/SemanticRecord.java @@ -16,6 +16,7 @@ package dev.ikm.tinkar.entity; import dev.ikm.tinkar.common.id.PublicId; +import dev.ikm.tinkar.common.id.PublicIds; import dev.ikm.tinkar.common.service.PrimitiveData; import dev.ikm.tinkar.common.util.Validator; import dev.ikm.tinkar.terms.PatternFacade; @@ -141,4 +142,8 @@ public SemanticAnalogueBuilder without(SemanticVersionRecord versionToAdd) { return analogueBuilder().remove(versionToAdd); } + public PublicId publicId() { + return PublicIds.of(asUuidArray()); + } + } diff --git a/entity/src/main/java/dev/ikm/tinkar/entity/StampEntity.java b/entity/src/main/java/dev/ikm/tinkar/entity/StampEntity.java index bfb20f23..53537404 100644 --- a/entity/src/main/java/dev/ikm/tinkar/entity/StampEntity.java +++ b/entity/src/main/java/dev/ikm/tinkar/entity/StampEntity.java @@ -28,7 +28,7 @@ import static dev.ikm.tinkar.common.util.time.DateTimeUtil.SEC_FORMATTER; public interface StampEntity extends Entity, - Stamp, Component, Version, IdentifierData { + Stamp, Component, Version { @Override default State state() { return lastVersion().state(); diff --git a/entity/src/main/java/dev/ikm/tinkar/entity/StampRecord.java b/entity/src/main/java/dev/ikm/tinkar/entity/StampRecord.java index 008ed4ed..761a365b 100644 --- a/entity/src/main/java/dev/ikm/tinkar/entity/StampRecord.java +++ b/entity/src/main/java/dev/ikm/tinkar/entity/StampRecord.java @@ -33,7 +33,7 @@ public record StampRecord( long mostSignificantBits, long leastSignificantBits, long[] additionalUuidLongs, int nid, ImmutableList versions) - implements StampEntity, ImmutableEntity, StampRecordBuilder.With { + implements StampEntity, ImmutableEntity, IdentifierData, StampRecordBuilder.With { private static StampRecord nonExistentStamp; public StampRecord { diff --git a/terms/src/main/java/dev/ikm/tinkar/terms/ConceptEnumerationFacade.java b/terms/src/main/java/dev/ikm/tinkar/terms/ConceptEnumerationFacade.java new file mode 100644 index 00000000..e8de7715 --- /dev/null +++ b/terms/src/main/java/dev/ikm/tinkar/terms/ConceptEnumerationFacade.java @@ -0,0 +1,63 @@ +/* + * Copyright © 2015 Integrated Knowledge Management (support@ikm.dev) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package dev.ikm.tinkar.terms; + +import dev.ikm.tinkar.common.binary.DecoderInput; +import dev.ikm.tinkar.common.binary.Encodable; +import dev.ikm.tinkar.common.binary.EncoderOutput; +import dev.ikm.tinkar.common.id.PublicId; +import dev.ikm.tinkar.common.id.PublicIds; +import dev.ikm.tinkar.common.service.PrimitiveData; +import dev.ikm.tinkar.common.util.uuid.UuidUtil; + +public interface ConceptEnumerationFacade> + extends ConceptFacade, Encodable { + ConceptFacade conceptForEnum(); + + String name(); + + default PublicId publicId() { + return this.conceptForEnum().publicId(); + } + + default int nid() { + return PrimitiveData.nid(this.conceptForEnum().publicId()); + } + + default E enumValue() { + return (E) this; + } + + static > E decode(DecoderInput in, Class enumClass) { + switch (Encodable.checkVersion(in)) { + default: + String encodedName = in.readString(); + PublicId encodedId = PublicIds.of(UuidUtil.fromString(in.readString())); + ConceptEnumerationFacade enumElement = (ConceptEnumerationFacade) Enum.valueOf(enumClass, encodedName); + if (enumElement.conceptForEnum().publicId().equals(encodedId)) { + return enumElement.enumValue(); + } + throw new IllegalStateException("Unknown enum concept " + encodedName + "with id " + encodedId); + } + } + + @Override + default void encode(EncoderOutput out) { + out.writeString(this.name()); + out.writeString(UuidUtil.toString(this.conceptForEnum().publicId())); + } + +} diff --git a/terms/src/main/java/dev/ikm/tinkar/terms/EntityProxy.java b/terms/src/main/java/dev/ikm/tinkar/terms/EntityProxy.java index b67af4cf..b55baf9f 100644 --- a/terms/src/main/java/dev/ikm/tinkar/terms/EntityProxy.java +++ b/terms/src/main/java/dev/ikm/tinkar/terms/EntityProxy.java @@ -16,8 +16,10 @@ package dev.ikm.tinkar.terms; import dev.ikm.tinkar.common.id.PublicId; +import dev.ikm.tinkar.common.id.PublicIds; import dev.ikm.tinkar.common.service.PrimitiveData; import dev.ikm.tinkar.component.Component; +import org.eclipse.collections.api.list.ImmutableList; import java.util.Arrays; import java.util.UUID; @@ -67,9 +69,8 @@ public static EntityProxy make(String description, UUID[] uuids) { return new EntityProxy(description, uuids); } - @Override - public final PublicId publicId() { - return this; + public PublicId publicId() { + return PublicIds.of(uuids); } @Override @@ -85,14 +86,14 @@ public boolean equals(Object o) { return Arrays.equals(this.uuids, other.uuids); } } - if (o instanceof ComponentWithNid) { - return this.nid() == ((ComponentWithNid) o).nid(); + if (o instanceof ComponentWithNid componentWithNid) { + return this.nid() == componentWithNid.nid(); } - if (o instanceof PublicId) { - return PublicId.equals(this, (PublicId) o); + if (o instanceof PublicId publicId) { + return PublicId.equals(this.publicId(), publicId); } - if (o instanceof Component) { - return PublicId.equals(this, ((Component) o).publicId()); + if (o instanceof Component component) { + return PublicId.equals(this.publicId(), component.publicId()); } return false; } @@ -101,7 +102,7 @@ public boolean equals(Object o) { public String toString() { return this.getClass().getSimpleName() + "{" + description() + - " " + Arrays.toString(asUuidArray()) + + " " + Arrays.toString(uuids) + "<" + cachedNid + ">}"; } @@ -114,36 +115,44 @@ public final String description() { } @Override - public UUID[] asUuidArray() { - if (this.uuids == null) { - this.uuids = PrimitiveData.publicId(nid()).asUuidArray(); + public final int nid() { + if (cachedNid == 0) { + cachedNid = PrimitiveData.get().nidForUuids(uuids); } - return this.uuids; + return cachedNid; } @Override - public int uuidCount() { - return asUuidArray().length; + public ImmutableList asUuidList() { + return PublicId.super.asUuidList(); } @Override - public void forEach(LongConsumer consumer) { - for (UUID uuid : asUuidArray()) { - consumer.accept(uuid.getMostSignificantBits()); - consumer.accept(uuid.getLeastSignificantBits()); - } + public UUID[] asUuidArray() { + return publicId().asUuidArray(); + } + @Override + public int compareTo(PublicId o) { + return publicId().compareTo(o); } @Override - public final int nid() { - if (cachedNid == 0) { - cachedNid = PrimitiveData.get().nidForUuids(uuids); - } - return cachedNid; + public boolean contains(UUID uuid) { + return publicId().contains(uuid); + } + + @Override + public int uuidCount() { + return publicId().uuidCount(); + } + + @Override + public void forEach(LongConsumer consumer) { + publicId().forEach(consumer); } - public static class Concept extends EntityProxy implements ConceptFacade, PublicId { + public static class Concept extends EntityProxy implements ConceptFacade { private Concept(int conceptNid) {