EmbeddingTPGMFactory.java
/*
* Copyright © 2014 - 2021 Leipzig University (Database Research Group)
*
* 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 org.gradoop.temporal.model.impl.operators.matching.single.cypher.pojos;
import org.gradoop.common.model.impl.properties.PropertyValue;
import org.gradoop.flink.model.impl.operators.matching.single.cypher.pojos.Embedding;
import org.gradoop.temporal.model.impl.pojo.TemporalEdge;
import org.gradoop.temporal.model.impl.pojo.TemporalGraphElement;
import org.gradoop.temporal.model.impl.pojo.TemporalVertex;
import org.gradoop.gdl.model.comparables.time.TimeSelector;
import java.util.List;
/**
* Utility class to convert an element ({@link TemporalVertex} and {@link TemporalEdge} into an
* {@link Embedding}.
* Analogous to
* {@link org.gradoop.flink.model.impl.operators.matching.single.cypher.pojos.EmbeddingFactory}
* but creating TPGMEmbeddings from TPGM elements
*/
public class EmbeddingTPGMFactory {
/**
* Converts a {@link TemporalVertex} into an {@link Embedding}.
* <p>
* The resulting embedding has one entry containing the vertex id and one entry for each property
* value associated with the specified property keys (ordered by list order). Note that missing
* property values are represented by a {@link PropertyValue#NULL_VALUE}.
* Furthermore, the time data of each element ({tx_from, tx_to, valid_from, valid_to}) is stored
* in the embedding, just like normal properties
*
* @param vertex vertex to create embedding from
* @param propertyKeys properties that will be stored in the embedding
* @return Embedding
*/
public static Embedding fromVertex(TemporalVertex vertex, List<String> propertyKeys) {
Embedding embedding = new Embedding();
embedding.add(vertex.getId(), project(vertex, propertyKeys));
return embedding;
}
/**
* Converts an {@link TemporalEdge} into an {@link Embedding}.
* <p>
* The resulting embedding has three entries containing the source vertex id, the edge id and the
* target vertex id. Furthermore, the embedding has one entry for each property value associated
* with the specified property keys (ordered by list order). Note that missing property values are
* represented by a {@link PropertyValue#NULL_VALUE}.
* Additionally, the time data of the edge ({tx_from, tx_to, valid_from, valid_to}) are stored
* in the embedding, just like properties
*
* @param edge edge to create embedding from
* @param propertyKeys properties that will be stored in the embedding
* @param isLoop indicates if the edges is a loop
* @return Embedding
*/
public static Embedding fromEdge(TemporalEdge edge, List<String> propertyKeys, boolean isLoop) {
Embedding embedding = new Embedding();
if (isLoop) {
embedding.addAll(edge.getSourceId(), edge.getId());
} else {
embedding.addAll(edge.getSourceId(), edge.getId(), edge.getTargetId());
}
embedding.addPropertyValues(project(edge, propertyKeys));
return embedding;
}
/**
* Projects the elements properties into a list of property values. Only those properties
* specified by their key will be kept. Properties that are specified but not present at the
* element will be adopted as {@link PropertyValue#NULL_VALUE}.
* Temporal properties are stored just like "normal" ones
*
* @param element element of which the properties will be projected
* @param propertyKeys properties that will be projected from the specified element
* @return projected property values
*/
private static PropertyValue[] project(TemporalGraphElement element, List<String> propertyKeys) {
PropertyValue[] propertyValues = new PropertyValue[propertyKeys.size()];
int i = 0;
for (String propertyKey : propertyKeys) {
if (propertyKey.equals("__label__")) {
propertyValues[i++] = PropertyValue.create(element.getLabel());
} else if (isProperty(propertyKey)) {
propertyValues[i++] = element.hasProperty(propertyKey) ?
element.getPropertyValue(propertyKey) : PropertyValue.NULL_VALUE;
} else {
if (propertyKey.equals(TimeSelector.TimeField.VAL_FROM.toString())) {
propertyValues[i++] = PropertyValue.create(element.getValidFrom());
} else if (propertyKey.equals(TimeSelector.TimeField.VAL_TO.toString())) {
propertyValues[i++] = PropertyValue.create(element.getValidTo());
} else if (propertyKey.equals(TimeSelector.TimeField.TX_FROM.toString())) {
propertyValues[i++] = PropertyValue.create(element.getTxFrom());
} else if (propertyKey.equals(TimeSelector.TimeField.TX_TO.toString())) {
propertyValues[i++] = PropertyValue.create(element.getTxTo());
} else {
propertyValues[i++] = PropertyValue.NULL_VALUE;
}
}
}
return propertyValues;
}
/**
* Checks if a string refers to an actual property or a time stamp
*
* @param key string to check
* @return true iff key refers to an actual property
*/
private static boolean isProperty(String key) {
return !key.equals(TimeSelector.TimeField.VAL_FROM.toString()) &&
!key.equals(TimeSelector.TimeField.VAL_TO.toString()) &&
!key.equals(TimeSelector.TimeField.TX_FROM.toString()) &&
!key.equals(TimeSelector.TimeField.TX_TO.toString());
}
}