From 69d8f2b115a832560eca0d56903c8977178b71ab Mon Sep 17 00:00:00 2001 From: Antti Villberg Date: Fri, 16 Mar 2018 16:55:52 +0200 Subject: [PATCH] Fixed various bugs in TG readers Added primary install-location based relative path resolution to database baselining logic. Secondary relative baseline resolution logic still uses working directory. refs #7825 Change-Id: I154528e674e6d478ea4bdb1de4d38c38d5097fdf --- .../StreamingTransferableGraphFileReader.java | 88 +++++++++++-------- .../graph/db/TransferableGraphs.java | 9 +- .../graph/representation/ByteFileReader.java | 42 ++++----- .../TransferableGraphFileReader.java | 16 ++-- .../project/management/PlatformUtil.java | 6 +- .../simantics/BaselineCreatorApplication.java | 7 +- .../src/org/simantics/SimanticsPlatform.java | 46 ++++++++-- 7 files changed, 129 insertions(+), 85 deletions(-) diff --git a/bundles/org.simantics.graph.db/src/org/simantics/graph/db/StreamingTransferableGraphFileReader.java b/bundles/org.simantics.graph.db/src/org/simantics/graph/db/StreamingTransferableGraphFileReader.java index 86c3d2fcb..68a94e304 100644 --- a/bundles/org.simantics.graph.db/src/org/simantics/graph/db/StreamingTransferableGraphFileReader.java +++ b/bundles/org.simantics.graph.db/src/org/simantics/graph/db/StreamingTransferableGraphFileReader.java @@ -135,9 +135,9 @@ final public class StreamingTransferableGraphFileReader extends ByteFileReader { Extensions extensions; int resourceCount; - private int identities; - private int stmLength; - private int valueLength; + private int identities = -1; + private int stmLength = -1; + private int valueLength = -1; public FileTransferableGraphSource() throws Exception { init(); @@ -176,33 +176,41 @@ final public class StreamingTransferableGraphFileReader extends ByteFileReader { @Override public int getIdentityCount() throws Exception { - identities = safeInt(); + if(identities == -1) { + identities = safeInt(); + } return identities; } @Override public int getStatementCount() throws Exception { - stmLength = safeInt(); + if(stmLength == -1) { + stmLength = safeInt(); + } return stmLength; } @Override public int getValueCount() throws Exception { - valueLength = safeInt(); + if(valueLength == -1) { + valueLength = safeInt(); + } return valueLength; } @Override public void forStatements(ReadGraph graph, TransferableGraphSourceProcedure procedure) throws Exception { - + int[] value = new int[4]; + int stmLength = getStatementCount(); + for(int stmIndex=0;stmIndex> 2; int allowed = Math.min(stmLength-stmIndex, avail); @@ -213,94 +221,100 @@ final public class StreamingTransferableGraphFileReader extends ByteFileReader { // statements[stmIndex++] = ((bytes[index++]&0xff)<<24) | ((bytes[index++]&0xff)<<16) | ((bytes[index++]&0xff)<<8) | ((bytes[index++]&0xff)); } byteIndex += allowed<<2; - + } - + } @Override public void forIdentities(ReadGraph graph, TransferableGraphSourceProcedure procedure) throws Exception { - + + int identities = getIdentityCount(); + for(int i=0;i procedure) throws Exception { - + + int valueLength = getValueCount(); + Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT); - + List idcontext = new ArrayList<>(); - + for(int i=0;i idContext = new ArrayList<>(); - + for(int i=0;i values = new ArrayList<>(); - final ArrayList identities = new ArrayList<>(); - try { + ArrayList identities = new ArrayList<>(source.getIdentityCount()); + source.forIdentities(graph, i -> identities.add(i)); + TIntArrayList statements = new TIntArrayList(source.getStatementCount()); source.forStatements(graph, r -> statements.addAll(r)); + ArrayList values = new ArrayList<>(source.getValueCount()); source.forValues(graph, v -> values.add(v)); - source.forIdentities(graph, i -> identities.add(i)); return new TransferableGraph1(source.getResourceCount(), identities.toArray(new Identity[identities.size()]), diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/representation/ByteFileReader.java b/bundles/org.simantics.graph/src/org/simantics/graph/representation/ByteFileReader.java index 4c14bded6..e930a00fc 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/representation/ByteFileReader.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/representation/ByteFileReader.java @@ -69,9 +69,7 @@ public class ByteFileReader implements Closeable { } final protected byte[] safeBytes(int amount) throws IOException { - byte[] result = new byte[amount]; - int has = size-byteIndex; if(amount >= has) { ReadableByteChannel c = channel; @@ -86,6 +84,9 @@ public class ByteFileReader implements Closeable { int got = c.read(bb2); if(got == -1) throw new IOException("Unexpected end-of-file"); has += got; + // For some unknown reason this is needed! + // Spec indicates that read would increment position but it does not. + bb2.position(has); } size = c.read(bb); bb.position(0); @@ -104,7 +105,7 @@ public class ByteFileReader implements Closeable { int result; if(has == 0) { ReadableByteChannel c = channel; - ByteBuffer bb = byteBuffer; + ByteBuffer bb = byteBuffer; size = c.read(bb); if(size == -1) { throw new EOFException("Unexpected end-of-file"); @@ -114,43 +115,40 @@ public class ByteFileReader implements Closeable { if(size == 0) return -1; } - result = bytes[byteIndex]; - if(result < 0) - result += 256; - ++byteIndex; + result = bytes[byteIndex++] & 0xff; return result; } public int getDynamicUInt32() throws IOException { - int length = getByte()&0xff; + int length = getByte(); if(length >= 0x80) { if(length >= 0xc0) { if(length >= 0xe0) { if(length >= 0xf0) { length &= 0x0f; - length += ((getByte()&0xff)<<3); - length += ((getByte()&0xff)<<11); - length += ((getByte()&0xff)<<19); + length += (getByte()<<3); + length += (getByte()<<11); + length += (getByte()<<19); length += 0x10204080; } else { length &= 0x1f; - length += ((getByte()&0xff)<<4); - length += ((getByte()&0xff)<<12); - length += ((getByte()&0xff)<<20); + length += (getByte()<<4); + length += (getByte()<<12); + length += (getByte()<<20); length += 0x204080; } } else { length &= 0x3f; - length += ((getByte()&0xff)<<5); - length += ((getByte()&0xff)<<13); + length += (getByte()<<5); + length += (getByte()<<13); length += 0x4080; } } else { length &= 0x7f; - length += ((getByte()&0xff)<<6); + length += (getByte()<<6); length += 0x80; } } @@ -159,10 +157,12 @@ public class ByteFileReader implements Closeable { final protected int safeInt() throws IOException { + byte[] bytes = this.bytes; + if(byteIndex >= (size-5)) { int result = 0; ReadableByteChannel c = channel; - ByteBuffer bb = byteBuffer; + ByteBuffer bb = byteBuffer; if(byteIndex == size) { size = c.read(bb); if(size == -1) throw new EOFException("Unexpected end-of-file"); @@ -190,7 +190,7 @@ public class ByteFileReader implements Closeable { bb.position(0); byteIndex = 0; } - result |= ((int)(bytes[byteIndex++]&0xff)<<0); + result |= ((int)(bytes[byteIndex++]&0xff)); if(byteIndex == size) { size = c.read(bb); bb.position(0); @@ -200,9 +200,9 @@ public class ByteFileReader implements Closeable { } else { return ((bytes[byteIndex++]&0xff)<<24) | ((bytes[byteIndex++]&0xff)<<16) | ((bytes[byteIndex++]&0xff)<<8) | ((bytes[byteIndex++]&0xff)); } - + } - + final protected int getSize() { return size; } diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphFileReader.java b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphFileReader.java index ae1ec711c..077eb6617 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphFileReader.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphFileReader.java @@ -161,7 +161,7 @@ final public class TransferableGraphFileReader extends ByteFileReader { int resourceCount = safeInt(); - List idcontext = new ArrayList(); + List idcontext = new ArrayList<>(); dis = new DataInputStream(in); Extensions extensions = (Extensions)Bindings.getSerializerUnchecked(Extensions.class).deserialize((DataInput)dis, idcontext); @@ -174,27 +174,27 @@ final public class TransferableGraphFileReader extends ByteFileReader { // long duration = System.nanoTime() - start; // LOGGER.warn("start in " + 1e-9*duration + "s."); // start = System.nanoTime(); - + for(int i=0;i(); dis = new DataInputStream(in); for(int i=0;i graphSource = () -> { try { @@ -443,7 +445,7 @@ public class PlatformUtil { // For an unknown reason this is totally broken when running the TestSCLOsgi // in the SDK Tycho build. It returns incomplete results because the // ReadableByteChannel used by ByteFileReader starts returning 0 unexpectedly. -// try (TransferableGraphFileReader reader = new TransferableGraphFileReader(is)) { +// try (TransferableGraphFileReader reader = new TransferableGraphFileReader(is)) { // return reader.readTG(); // } return DataContainers.readFile(new DataInputStream(is), handlers); diff --git a/bundles/org.simantics/src/org/simantics/BaselineCreatorApplication.java b/bundles/org.simantics/src/org/simantics/BaselineCreatorApplication.java index d0b8e6949..a3b409027 100644 --- a/bundles/org.simantics/src/org/simantics/BaselineCreatorApplication.java +++ b/bundles/org.simantics/src/org/simantics/BaselineCreatorApplication.java @@ -61,12 +61,7 @@ public class BaselineCreatorApplication implements IApplication { private static Path getInstanceLocation() throws CoreException, IOException { Location l = Platform.getInstanceLocation(); - if (l == null) - throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - "Workspace not defined. Use -data argument to define where to place the baselining workspace.")); - - Location instanceLoc = Platform.getInstanceLocation(); - if (instanceLoc == null || instanceLoc.isReadOnly()) + if (l == null || l.isReadOnly()) throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Workspace not defined. Use -data argument to define where to place the baselining workspace.")); diff --git a/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java b/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java index 3638d3407..ad3b86d9c 100644 --- a/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java +++ b/bundles/org.simantics/src/org/simantics/SimanticsPlatform.java @@ -41,6 +41,7 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.osgi.service.datalocation.Location; import org.eclipse.osgi.service.resolver.BundleDescription; import org.ini4j.Ini; import org.ini4j.InvalidFileFormatException; @@ -696,7 +697,42 @@ public class SimanticsPlatform implements LifecycleListener { resetDatabase(monitor); } - public boolean handleBaselineDatabase() throws PlatformException { + private static Path tryGetInstallLocation() { + Location l = Platform.getInstallLocation(); + return l == null ? null : new File(l.getURL().getPath()).toPath(); + } + + private Path resolveBaselineFile() throws PlatformException { + String dbBaselineArchive = System.getProperty("org.simantics.db.baseline", null); + if (dbBaselineArchive == null) + return null; + + Path baseline = Paths.get(dbBaselineArchive); + if (baseline.isAbsolute()) { + if (!Files.isRegularFile(baseline)) + throw new PlatformException("Specified database baseline archive " + baseline + + " does not exist. Cannot initialize workspace database from baseline."); + return baseline; + } + + // Relative path resolution order: + // 1. from the platform "install location" + // 2. from working directory + Path installLocation = tryGetInstallLocation(); + if (installLocation != null) { + Path installedBaseline = installLocation.resolve(dbBaselineArchive); + if (Files.isRegularFile(installedBaseline)) + return installedBaseline; + } + if (!Files.isRegularFile(baseline)) + throw new PlatformException("Specified database baseline archive " + baseline + + " does not exist in either the install location (" + installLocation + + ") or the working directory (" + Paths.get(".").toAbsolutePath() + + "). Cannot initialize workspace database."); + return null; + } + + private boolean handleBaselineDatabase() throws PlatformException { Path workspaceLocation = Platform.getLocation().toFile().toPath(); Path baselineIndicatorFile = workspaceLocation.resolve(".baselined"); if (Files.isRegularFile(baselineIndicatorFile)) { @@ -705,14 +741,10 @@ public class SimanticsPlatform implements LifecycleListener { return true; } - String dbBaselineArchive = System.getProperty("org.simantics.db.baseline", null); - if (dbBaselineArchive == null) + Path baseline = resolveBaselineFile(); + if (baseline == null) return false; - Path baseline = Paths.get(dbBaselineArchive); - if (!Files.isRegularFile(baseline)) - throw new PlatformException("Specified database baseline archive " + baseline + " does not exist. Cannot initialize workspace database."); - DatabaseBaselines.validateBaselineFile(baseline); DatabaseBaselines.validateWorkspaceForBaselineInitialization(workspaceLocation); DatabaseBaselines.initializeWorkspaceWithBaseline(baseline, workspaceLocation, baselineIndicatorFile); -- 2.43.2