*******************************************************************************/
package org.simantics.project.management;
+import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.simantics.databoard.Bindings;
-import org.simantics.databoard.binding.Binding;
import org.simantics.databoard.binding.error.BindingException;
import org.simantics.databoard.binding.error.RuntimeBindingException;
import org.simantics.db.ReadGraph;
import org.simantics.db.exception.DatabaseException;
import org.simantics.graph.representation.TransferableGraph1;
import org.simantics.layer0.DatabaseManagementResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* GraphBundle represents a bundle graph that may exist in memory
*/
public class GraphBundle implements Comparable<GraphBundle> {
+ private static final Logger LOGGER = LoggerFactory.getLogger(GraphBundle.class);
+
/** Versioned Id pattern */
static String ID_PATTERN_STRING = "[a-zA-Z_0-9\\-]+(?:\\.[a-zA-Z_0-9\\-]+)*";
static String VERSION_PATTERN_STRING = "(\\d+).(\\d+).(\\d+).([a-zA-Z_0-9\\-]+)";
/** User-friendly name */
String name;
+ /** If {@link #graph} is null then this may be defined to fetch the data on-demand */
+ Supplier<TransferableGraph1> graphSource;
+
/** Actual graph */
TransferableGraph1 graph;
boolean immutable = true;
GraphBundle() {}
-
+
public GraphBundle(String name, TransferableGraph1 data, String versionedId)
- throws RuntimeBindingException {
- try {
+ throws RuntimeBindingException {
+ try {
// Assert version id is correct
Matcher m = VERSIONED_ID_PATTERN.matcher(versionedId);
if (!m.matches()) {
throw new IllegalArgumentException("Illegal VersionId \""+versionedId+"\", <id>/<major.minor.micro.qualifier> is expected.");
}
-
- Binding binding = Bindings.getBindingUnchecked( TransferableGraph1.class );
-
+
this.name = name;
- this.graph = data;
- this.hashcode = data != null ? binding.hashValue( data ) : 0;
+ this.graph = data;
+ this.hashcode = hash(data);
this.id = m.group(1);
this.major = Integer.valueOf( m.group(2) );
this.minor = Integer.valueOf( m.group(3) );
} catch (BindingException e) {
// Unexpected
throw new RuntimeBindingException(e);
- }
+ }
}
-
+
public GraphBundle(String name, TransferableGraph1 data, String id, String version)
- throws RuntimeBindingException {
+ throws RuntimeBindingException {
Matcher m = ID_PATTERN.matcher(id);
if (!m.matches())
throw new IllegalArgumentException("Illegal Id, got \""+id+"\"");
m = VERSION_PATTERN.matcher(version);
if (!m.matches())
throw new IllegalArgumentException("Illegal Version, got \""+id+"\", <id>/<major.minor.micro.qualifier> is expected.");
- try {
- Binding binding = Bindings.getBindingUnchecked( TransferableGraph1.class );
+ try {
this.name = name;
- this.graph = data;
- this.hashcode = binding.hashValue( data );
+ this.graph = data;
+ this.hashcode = hash(data);
this.id = id;
this.major = Integer.valueOf( m.group(1) );
this.minor = Integer.valueOf( m.group(2) );
throw new RuntimeBindingException(e);
}
}
-
+
+ public GraphBundle(String name, Supplier<TransferableGraph1> source, int hashCode, String id, String version) {
+ Matcher m = ID_PATTERN.matcher(id);
+ if (!m.matches())
+ throw new IllegalArgumentException("Illegal Id, got \""+id+"\"");
+ m = VERSION_PATTERN.matcher(version);
+ if (!m.matches())
+ throw new IllegalArgumentException("Illegal Version, got \""+id+"\", <id>/<major.minor.micro.qualifier> is expected.");
+ this.name = name;
+ this.graphSource = source;
+ this.hashcode = hashCode;
+ this.id = id;
+ this.major = Integer.valueOf( m.group(1) );
+ this.minor = Integer.valueOf( m.group(2) );
+ this.service = Integer.valueOf( m.group(3) );
+ if (m.group(4) != null) {
+ this.qualifier = m.group(4);
+ }
+ }
+
+ private int hash(TransferableGraph1 data) throws BindingException {
+ return data == null ? 0 : TransferableGraph1.BINDING.hashValue( data );
+ }
+
public String getName() {
return name;
}
*/
public TransferableGraph1 getGraph() {
if (graph == null) {
- ReadGraph g = Transaction.readGraph();
- if (g == null)
- throw new IllegalStateException("No read transaction available");
- try {
- Binding tg_binding = Bindings.getBindingUnchecked( TransferableGraph1.class );
- DatabaseManagementResource DatabaseManagement = DatabaseManagementResource.getInstance(g);
- graph = g.getRelatedValue(resource, DatabaseManagement.HasFile, tg_binding);
- } catch (DatabaseException e) {
- e.printStackTrace();
+ if (graphSource != null) {
+ graph = graphSource.get();
+ }
+ if (graph == null) {
+ ReadGraph g = Transaction.readGraph();
+ if (g == null)
+ throw new IllegalStateException("No read transaction available");
+ try {
+ graph = readTg(g);
+ } catch (DatabaseException e) {
+ LOGGER.error("Failed to read transferable graph from " + resource, e);
+ }
}
}
return graph;
graph = processor.syncRequest(new ResourceRead<TransferableGraph1>(resource) {
@Override
public TransferableGraph1 perform(ReadGraph graph) throws DatabaseException {
- Binding tg_binding = Bindings.getBindingUnchecked( TransferableGraph1.class );
- DatabaseManagementResource DatabaseManagement = DatabaseManagementResource.getInstance(graph);
- return graph.getRelatedValue(resource, DatabaseManagement.HasFile, tg_binding);
+ return readTg(graph);
}
});
} catch (DatabaseException e) {
- e.printStackTrace();
+ LOGGER.error("Failed to read transferable graph from " + resource, e);
}
}
return graph;
}
-
+
+ private TransferableGraph1 readTg(ReadGraph graph) throws DatabaseException {
+ DatabaseManagementResource DatabaseManagement = DatabaseManagementResource.getInstance(graph);
+ return graph.getRelatedValue(resource, DatabaseManagement.HasFile, TransferableGraph1.BINDING);
+ }
+
public int getHashcode() {
return hashcode;
}