return (T)tg;
}
- TransferableGraphFileReader reader = null;
try {
File modelFile = getProperty(MigrationStateKeys.MODEL_FILE);
- reader = new TransferableGraphFileReader(modelFile);
TimeLogger.log(MigrationStateImpl.class, "reading TG into memory from " + modelFile);
- TransferableGraph1 tg = reader.readTG();
+ TransferableGraph1 tg = TransferableGraphFileReader.read(modelFile);
TimeLogger.log(MigrationStateImpl.class, "read TG into memory from " + modelFile);
setProperty(MigrationStateKeys.CURRENT_TG, tg);
return (T)tg;
throw e;
} catch (Throwable t) {
throw new DatabaseException(t);
- } finally {
- uncheckedClose(reader);
}
} else if (MigrationStateKeys.CURRENT_TGS.equals(key)) {
public static Resource importModel(final Resource toLocation, File fromFile, String withName) throws Exception {
- TransferableGraphFileReader importer = new TransferableGraphFileReader(fromFile);
- TransferableGraph1 tg = importer.readTG();
- importer.close();
+ TransferableGraph1 tg = TransferableGraphFileReader.read(fromFile);
final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(toLocation) {
@Override
@Override
public Object deserialize(File file) throws IOException {
- TransferableGraphFileReader reader = new TransferableGraphFileReader(file);
- try {
- return reader.readTG();
- } finally {
- reader.close();
- }
+ return TransferableGraphFileReader.read(file);
}
public Object deserialize(InputStream in) throws IOException {
- TransferableGraphFileReader reader = new TransferableGraphFileReader(in);
- try {
- return reader.readTG();
- } finally {
- reader.close();
- }
+ return TransferableGraphFileReader.read(in);
}
@Override
import org.simantics.databoard.Datatypes;
import org.simantics.databoard.binding.error.RuntimeDatatypeConstructionException;
import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.databoard.container.DataContainer;
import org.simantics.databoard.container.DataContainers;
import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;
import org.simantics.databoard.serialization.Serializer;
import org.slf4j.LoggerFactory;
+/**
+ * It is recommended to use {@link #read(File)} and {@link #read(InputStream)}
+ * for reading to ensure proper resource handling.
+ */
final public class TransferableGraphFileReader extends ByteFileReader {
private static final Logger LOGGER = LoggerFactory.getLogger(TransferableGraphFileReader.class);
final static class InputChannel implements ReadableByteChannel {
final private InputStream stream;
-
+
public InputChannel(InputStream stream) {
this.stream = stream;
}
-
+
@Override
public boolean isOpen() {
return true;
@Override
public void close() throws IOException {
+ // NOTE: it is an intentional choice not to close the underlying stream here
+ // InputStreams given directly to TransferableGraphFileReader are expected to
+ // be closed outside of this implementation.
}
@Override
public int read(ByteBuffer dst) throws IOException {
- int pos = dst.position();
+ int nRead;
+ int size = 0;
+ int position = dst.position();
int limit = dst.limit();
- int i=stream.read(dst.array(), pos, limit-pos);
- //LOGGER.warn("Read " + i + " (expected " + dst.array().length + ")");
- return i;
+ // The users of this channel expect that the data is fully read at this point
+ while ((nRead = stream.read(dst.array(), position, limit - position)) != -1 && limit - position > 0) {
+ size += nRead;
+ position += nRead;
+ }
+ return size;
}
-
+
}
private static boolean init = true;
final private static int SIZE = 1<<18;
final private static int HEADER = headerSize();
final private int header;
-
+
+ /**
+ * Reads a {@link DataContainer} containing a {@link TransferableGraph1}
+ * structure from the specified {@link File}.
+ *
+ * @param file the file to read from
+ * @return the TG contained by the file
+ * @throws IOException
+ */
+ public static TransferableGraph1 read(File file) throws IOException {
+ try (TransferableGraphFileReader reader = new TransferableGraphFileReader(file)) {
+ return reader.readTG();
+ }
+ }
+
+ /**
+ * Reads a {@link DataContainer} containing a {@link TransferableGraph1}
+ * structure from the specified InputStream. Note that this implementation does
+ * not close the specified <code>input</code> stream, it is expected to be
+ * closed by the caller.
+ *
+ * @param input the input stream to read from
+ * @return the TG contained by the stream
+ * @throws IOException
+ */
+ public static TransferableGraph1 read(InputStream input) throws IOException {
+ try (TransferableGraphFileReader reader = new TransferableGraphFileReader(input)) {
+ return reader.readTG();
+ }
+ }
+
public TransferableGraphFileReader(File file) throws IOException {
super(file, SIZE);
if(init) {
for(int i=0;i<valueLength;i++) {
int resource = safeInt();
- idcontext.clear();
+ //idcontext.clear();
Variant value = (Variant)variantSerializer
.deserialize((DataInput)dis, idcontext);
values[i] = new Value(resource, value);
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
-import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import org.osgi.framework.Bundle;
import org.simantics.databoard.Bindings;
import org.simantics.databoard.adapter.AdaptException;
-import org.simantics.databoard.binding.Binding;
import org.simantics.databoard.binding.mutable.Variant;
import org.simantics.databoard.container.DataContainer;
import org.simantics.databoard.container.DataContainers;
-import org.simantics.databoard.container.FormatHandler;
import org.simantics.graph.compiler.CompilationResult;
import org.simantics.graph.compiler.GraphCompiler;
import org.simantics.graph.compiler.GraphCompilerPreferences;
import org.simantics.graph.compiler.ValidationMode;
import org.simantics.graph.representation.Extensions;
import org.simantics.graph.representation.TransferableGraph1;
+import org.simantics.graph.representation.TransferableGraphFileReader;
import org.simantics.ltk.FileSource;
import org.simantics.ltk.ISource;
import org.simantics.ltk.Problem;
import org.simantics.scl.reflection.OntologyVersions;
-import org.simantics.utils.datastructures.ArrayMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
throw new IOException("Problem loading graph.tg from bundle " + bundle.getSymbolicName(), e);
}
}
-
- private static FormatHandler<TransferableGraph1> FORMAT_HANDLER = new FormatHandler<TransferableGraph1>() {
- @Override
- public Binding getBinding() {
- return TransferableGraph1.BINDING;
- }
- @Override
- public TransferableGraph1 process(DataContainer container) throws Exception {
- return (TransferableGraph1) container.content.getValue(TransferableGraph1.BINDING);
- }
- };
-
- @SuppressWarnings("unchecked")
- private static Map<String, FormatHandler<TransferableGraph1>> handlers = ArrayMap.make(
- new String[] {
- "graph:1",
- "sharedLibrary:1"
- },
- FORMAT_HANDLER,
- FORMAT_HANDLER);
-
- private static TransferableGraph1 readTG(InputStream is) throws Exception {
- // 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)) {
-// return reader.readTG();
-// }
- return DataContainers.readFile(new DataInputStream(is), handlers);
- }
private static TransferableGraph1 readTG(URL url) throws Exception {
try (InputStream is = url.openStream()) {
- return readTG(is);
+ return TransferableGraphFileReader.read(is);
}
}