This is an automated email from the ASF dual-hosted git repository.

xiaokang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-graphar.git


The following commit(s) were added to refs/heads/main by this push:
     new bb4a1d33 feat(java,info): support multi-labels in yaml (#781)
bb4a1d33 is described below

commit bb4a1d335c9f8f50a534ccf08432b101aa493ae9
Author: Xiaokang Yang <[email protected]>
AuthorDate: Mon Dec 8 20:30:12 2025 +0800

    feat(java,info): support multi-labels in yaml (#781)
    
    * add multi labels
    
    * fix
    
    * format
    
    * update
    
    * fix
    
    * update
---
 .../java/org/apache/graphar/info/VertexInfo.java   |  63 +++++++-
 .../graphar/info/loader/BaseGraphInfoLoader.java   |   1 +
 .../org/apache/graphar/info/yaml/VertexYaml.java   |   4 +
 .../org/apache/graphar/info/GraphInfoTest.java     |   1 +
 .../apache/graphar/info/TestVerificationUtils.java |   2 +
 .../apache/graphar/info/VertexInfoLabelsTest.java  | 178 +++++++++++++++++++++
 6 files changed, 246 insertions(+), 3 deletions(-)

diff --git 
a/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java 
b/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java
index 5821216f..c6f4603d 100644
--- a/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java
+++ b/maven-projects/info/src/main/java/org/apache/graphar/info/VertexInfo.java
@@ -22,6 +22,7 @@ package org.apache.graphar.info;
 import java.io.Writer;
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
@@ -36,6 +37,7 @@ public class VertexInfo {
     private final String type;
     private final long chunkSize;
     private final PropertyGroups propertyGroups;
+    private final List<String> labels;
     private final URI baseUri;
     private final VersionInfo version;
 
@@ -49,6 +51,7 @@ public class VertexInfo {
         private PropertyGroups propertyGroups;
         private URI baseUri;
         private VersionInfo version;
+        private List<String> labels;
         private List<PropertyGroup> propertyGroupsAsListTemp;
 
         private VertexInfoBuilder() {}
@@ -87,6 +90,19 @@ public class VertexInfo {
             return this;
         }
 
+        public VertexInfoBuilder labels(List<String> labels) {
+            this.labels = labels;
+            return this;
+        }
+
+        public VertexInfoBuilder addLabel(String label) {
+            if (labels == null) {
+                labels = new ArrayList<>();
+            }
+            labels.add(label);
+            return this;
+        }
+
         public VertexInfoBuilder addPropertyGroup(PropertyGroup propertyGroup) 
{
             if (propertyGroupsAsListTemp == null) {
                 propertyGroupsAsListTemp = new ArrayList<>();
@@ -109,6 +125,14 @@ public class VertexInfo {
         }
 
         public VertexInfo build() {
+            if (type == null || type.isEmpty()) {
+                throw new IllegalArgumentException("Type cannot be null or 
empty");
+            }
+
+            if (labels == null) {
+                labels = Collections.emptyList();
+            }
+
             if (propertyGroups == null && propertyGroupsAsListTemp != null) {
                 propertyGroups = new PropertyGroups(propertyGroupsAsListTemp);
             } else if (propertyGroupsAsListTemp != null) {
@@ -127,6 +151,7 @@ public class VertexInfo {
             if (baseUri == null) {
                 throw new IllegalArgumentException("Base URI cannot be null");
             }
+
             return new VertexInfo(this);
         }
     }
@@ -134,6 +159,7 @@ public class VertexInfo {
     private VertexInfo(VertexInfoBuilder builder) {
         this.type = builder.type;
         this.chunkSize = builder.chunkSize;
+        this.labels = builder.labels;
         this.propertyGroups = builder.propertyGroups;
         this.baseUri = builder.baseUri;
         this.version = builder.version;
@@ -145,7 +171,17 @@ public class VertexInfo {
             List<PropertyGroup> propertyGroups,
             String prefix,
             String version) {
-        this(type, chunkSize, propertyGroups, URI.create(prefix), version);
+        this(type, chunkSize, propertyGroups, Collections.emptyList(), 
URI.create(prefix), version);
+    }
+
+    public VertexInfo(
+            String type,
+            long chunkSize,
+            List<PropertyGroup> propertyGroups,
+            List<String> labels,
+            String prefix,
+            String version) {
+        this(type, chunkSize, propertyGroups, labels, URI.create(prefix), 
version);
     }
 
     public VertexInfo(
@@ -154,13 +190,24 @@ public class VertexInfo {
             List<PropertyGroup> propertyGroups,
             URI baseUri,
             String version) {
-        this(type, chunkSize, propertyGroups, baseUri, 
VersionParser.getVersion(version));
+        this(type, chunkSize, propertyGroups, Collections.emptyList(), 
baseUri, version);
     }
 
     public VertexInfo(
             String type,
             long chunkSize,
             List<PropertyGroup> propertyGroups,
+            List<String> labels,
+            URI baseUri,
+            String version) {
+        this(type, chunkSize, propertyGroups, labels, baseUri, 
VersionParser.getVersion(version));
+    }
+
+    public VertexInfo(
+            String type,
+            long chunkSize,
+            List<PropertyGroup> propertyGroups,
+            List<String> labels,
             URI baseUri,
             VersionInfo version) {
         if (chunkSize < 0) {
@@ -169,6 +216,7 @@ public class VertexInfo {
         this.type = type;
         this.chunkSize = chunkSize;
         this.propertyGroups = new PropertyGroups(propertyGroups);
+        this.labels = labels == null ? Collections.emptyList() : 
List.copyOf(labels);
         this.baseUri = baseUri;
         this.version = version;
     }
@@ -180,7 +228,12 @@ public class VertexInfo {
                 .map(
                         newPropertyGroups ->
                                 new VertexInfo(
-                                        type, chunkSize, newPropertyGroups, 
baseUri, version));
+                                        type,
+                                        chunkSize,
+                                        newPropertyGroups,
+                                        labels,
+                                        baseUri,
+                                        version));
     }
 
     public int getPropertyGroupNum() {
@@ -255,6 +308,10 @@ public class VertexInfo {
         return chunkSize;
     }
 
+    public List<String> getLabels() {
+        return labels;
+    }
+
     public List<PropertyGroup> getPropertyGroups() {
         return propertyGroups.getPropertyGroupList();
     }
diff --git 
a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/BaseGraphInfoLoader.java
 
b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/BaseGraphInfoLoader.java
index 50463373..e5767b94 100644
--- 
a/maven-projects/info/src/main/java/org/apache/graphar/info/loader/BaseGraphInfoLoader.java
+++ 
b/maven-projects/info/src/main/java/org/apache/graphar/info/loader/BaseGraphInfoLoader.java
@@ -76,6 +76,7 @@ public abstract class BaseGraphInfoLoader implements 
GraphInfoLoader {
                 vertexYaml.getProperty_groups().stream()
                         .map(PropertyGroupYaml::toPropertyGroup)
                         .collect(Collectors.toList()),
+                vertexYaml.getLabels(),
                 vertexYaml.getPrefix(),
                 vertexYaml.getVersion());
     }
diff --git 
a/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/VertexYaml.java
 
b/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/VertexYaml.java
index 42d5a3fc..77342324 100644
--- 
a/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/VertexYaml.java
+++ 
b/maven-projects/info/src/main/java/org/apache/graphar/info/yaml/VertexYaml.java
@@ -50,6 +50,7 @@ public class VertexYaml {
                 vertexInfo.getPropertyGroups().stream()
                         .map(PropertyGroupYaml::new)
                         .collect(Collectors.toList());
+        this.labels = vertexInfo.getLabels();
         this.prefix = vertexInfo.getPrefix();
         this.version =
                 Optional.of(vertexInfo)
@@ -86,6 +87,9 @@ public class VertexYaml {
         if (labels == null) {
             return null;
         }
+        // Returns the labels list, or null if the list is null or empty. 
Returning null for empty
+        // lists ensures that the labels field is omitted from YAML output 
when no labels are
+        // defined.
         return labels.isEmpty() ? null : labels;
     }
 
diff --git 
a/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoTest.java 
b/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoTest.java
index 77efdc6b..0ba983ab 100644
--- 
a/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoTest.java
+++ 
b/maven-projects/info/src/test/java/org/apache/graphar/info/GraphInfoTest.java
@@ -116,6 +116,7 @@ public class GraphInfoTest {
     public void testPersonVertexInfoBasics() {
         VertexInfo personVertexInfo = graphInfo.getVertexInfos().get(0);
         Assert.assertEquals("person", personVertexInfo.getType());
+        Assert.assertTrue(personVertexInfo.getLabels().isEmpty());
         Assert.assertEquals(100, personVertexInfo.getChunkSize());
         Assert.assertEquals("vertex/person/", personVertexInfo.getPrefix());
         Assert.assertEquals(URI.create("vertex/person/"), 
personVertexInfo.getBaseUri());
diff --git 
a/maven-projects/info/src/test/java/org/apache/graphar/info/TestVerificationUtils.java
 
b/maven-projects/info/src/test/java/org/apache/graphar/info/TestVerificationUtils.java
index ddf66067..b9687787 100644
--- 
a/maven-projects/info/src/test/java/org/apache/graphar/info/TestVerificationUtils.java
+++ 
b/maven-projects/info/src/test/java/org/apache/graphar/info/TestVerificationUtils.java
@@ -234,6 +234,8 @@ public class TestVerificationUtils {
             return false;
         }
 
+        Assert.assertEquals("VertexInfo labels mismatch", 
expected.getLabels(), actual.getLabels());
+
         Assert.assertEquals("VertexInfo type mismatch", expected.getType(), 
actual.getType());
         Assert.assertEquals(
                 "VertexInfo chunk size mismatch", expected.getChunkSize(), 
actual.getChunkSize());
diff --git 
a/maven-projects/info/src/test/java/org/apache/graphar/info/VertexInfoLabelsTest.java
 
b/maven-projects/info/src/test/java/org/apache/graphar/info/VertexInfoLabelsTest.java
new file mode 100644
index 00000000..ed331b90
--- /dev/null
+++ 
b/maven-projects/info/src/test/java/org/apache/graphar/info/VertexInfoLabelsTest.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.graphar.info;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.apache.graphar.info.loader.GraphInfoLoader;
+import 
org.apache.graphar.info.loader.impl.LocalFileSystemStringGraphInfoLoader;
+import org.apache.graphar.info.saver.GraphInfoSaver;
+import org.apache.graphar.info.saver.impl.LocalFileSystemYamlGraphSaver;
+import org.apache.graphar.info.type.DataType;
+import org.apache.graphar.info.type.FileType;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class VertexInfoLabelsTest extends BaseFileSystemTest {
+
+    private String testSaveDirectory;
+    private GraphInfoSaver graphInfoSaver;
+    private GraphInfoLoader graphInfoLoader;
+
+    @Before
+    public void setUp() {
+        testSaveDirectory = 
createCleanTestDirectory("ldbc_multi_labels_sample/");
+        graphInfoSaver = new LocalFileSystemYamlGraphSaver();
+        graphInfoLoader = new LocalFileSystemStringGraphInfoLoader();
+    }
+
+    @After
+    public void tearDown() {
+        // Test data will be preserved for debugging - cleanup happens before 
next test run
+        System.out.println("Test data saved in: " + testSaveDirectory);
+    }
+
+    @Test
+    public void testVertexInfoWithLabels() throws IOException {
+        // Create property group
+        Property property = new Property("id", DataType.INT32, true, false);
+        PropertyGroup propertyGroup =
+                new PropertyGroup(Collections.singletonList(property), 
FileType.PARQUET, "test/");
+
+        // Create labels
+        List<String> labels = Arrays.asList("Person", "Employee", "User");
+
+        // Create vertex info with labels
+        VertexInfo vertexInfo =
+                new VertexInfo(
+                        "person",
+                        100L,
+                        Collections.singletonList(propertyGroup),
+                        labels,
+                        "vertex/person/",
+                        "gar/v1");
+
+        // Test getters
+        Assert.assertEquals("person", vertexInfo.getType());
+        Assert.assertEquals(100L, vertexInfo.getChunkSize());
+        Assert.assertEquals(labels, vertexInfo.getLabels());
+        Assert.assertEquals("vertex/person/", vertexInfo.getPrefix());
+        Assert.assertEquals("gar/v1", vertexInfo.getVersion().toString());
+
+        // Test property group related methods
+        Assert.assertEquals(1, vertexInfo.getPropertyGroupNum());
+        Assert.assertTrue(vertexInfo.hasProperty("id"));
+        Assert.assertTrue(vertexInfo.isPrimaryKey("id"));
+        Assert.assertFalse(vertexInfo.isNullableKey("id"));
+
+        // Test validation
+        Assert.assertTrue(vertexInfo.isValidated());
+
+        // Test dump
+        graphInfoSaver.save(URI.create(testSaveDirectory), vertexInfo);
+        // test load
+        VertexInfo loadedVertexInfo =
+                graphInfoLoader.loadVertexInfo(URI.create(testSaveDirectory + 
"person.vertex.yml"));
+        Assert.assertTrue(TestVerificationUtils.equalsVertexInfo(vertexInfo, 
loadedVertexInfo));
+    }
+
+    @Test
+    public void testVertexInfoWithoutLabels() throws IOException {
+        // Create property group
+        Property property = new Property("id", DataType.INT32, true, false);
+        PropertyGroup propertyGroup =
+                new PropertyGroup(Collections.singletonList(property), 
FileType.PARQUET, "test/");
+
+        // Create vertex info without labels (using old constructor)
+        VertexInfo vertexInfo =
+                new VertexInfo(
+                        "person",
+                        100L,
+                        Collections.singletonList(propertyGroup),
+                        "vertex/person/",
+                        "gar/v1");
+
+        // Test that labels list is empty but not null
+        Assert.assertEquals("person", vertexInfo.getType());
+        Assert.assertEquals(100L, vertexInfo.getChunkSize());
+        Assert.assertNotNull(vertexInfo.getLabels());
+        Assert.assertTrue(vertexInfo.getLabels().isEmpty());
+        Assert.assertEquals("vertex/person/", vertexInfo.getPrefix());
+
+        // Test validation
+        Assert.assertTrue(vertexInfo.isValidated());
+        // Test dump
+        graphInfoSaver.save(URI.create(testSaveDirectory), vertexInfo);
+        // test load
+        VertexInfo loadedVertexInfo =
+                graphInfoLoader.loadVertexInfo(URI.create(testSaveDirectory + 
"person.vertex.yml"));
+        Assert.assertTrue(TestVerificationUtils.equalsVertexInfo(vertexInfo, 
loadedVertexInfo));
+    }
+
+    @Test
+    public void testVertexInfoWithEmptyLabels() throws IOException {
+        // Create property group
+        Property property = new Property("id", DataType.INT32, true, false);
+        PropertyGroup propertyGroup =
+                new PropertyGroup(Collections.singletonList(property), 
FileType.PARQUET, "test/");
+
+        // Create vertex info with empty labels
+        VertexInfo vertexInfo =
+                new VertexInfo(
+                        "person",
+                        100L,
+                        Collections.singletonList(propertyGroup),
+                        Collections.emptyList(),
+                        "vertex/person/",
+                        "gar/v1");
+
+        // Test that labels list is empty but not null
+        Assert.assertEquals("person", vertexInfo.getType());
+        Assert.assertEquals(100L, vertexInfo.getChunkSize());
+        Assert.assertNotNull(vertexInfo.getLabels());
+        Assert.assertTrue(vertexInfo.getLabels().isEmpty());
+        Assert.assertEquals("vertex/person/", vertexInfo.getPrefix());
+
+        // Test validation
+        Assert.assertTrue(vertexInfo.isValidated());
+        // Test dump
+        graphInfoSaver.save(URI.create(testSaveDirectory), vertexInfo);
+        // test load
+        VertexInfo loadedVertexInfo =
+                graphInfoLoader.loadVertexInfo(URI.create(testSaveDirectory + 
"person.vertex.yml"));
+        Assert.assertTrue(TestVerificationUtils.equalsVertexInfo(vertexInfo, 
loadedVertexInfo));
+    }
+
+    @Test
+    public void testLoadFromTestData() throws IOException {
+        URI GRAPH_PATH_URI = TestUtil.getLdbcGraphURI();
+        GraphInfo graphInfo = graphInfoLoader.loadGraphInfo(GRAPH_PATH_URI);
+        VertexInfo placeInfo = graphInfo.getVertexInfo("place");
+        VertexInfo organisationInfo = graphInfo.getVertexInfo("organisation");
+        Assert.assertEquals(List.of("city", "country", "continent"), 
placeInfo.getLabels());
+        Assert.assertEquals(
+                List.of("university", "company", "public"), 
organisationInfo.getLabels());
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to