-
Notifications
You must be signed in to change notification settings - Fork 316
/
ResourceStorageLoadable.java
127 lines (111 loc) · 4.72 KB
/
ResourceStorageLoadable.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**
* Copyright (c) 2014, 2020 itemis AG (http://www.itemis.eu) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.resource.persistence;
import static org.eclipse.xtext.xbase.lib.IterableExtensions.*;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.util.Collections;
import java.util.zip.ZipInputStream;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl;
import org.eclipse.xtext.nodemodel.impl.SerializableNodeModel;
import org.eclipse.xtext.nodemodel.serialization.DeserializationConversionContext;
import org.eclipse.xtext.parser.ParseResult;
import com.google.common.io.CharStreams;
/**
* @author Sven Efftinge - Initial contribution and API
*/
public class ResourceStorageLoadable {
private static final Logger LOG = Logger.getLogger(ResourceStorageLoadable.class);
private final InputStream in;
private final boolean storeNodeModel;
public ResourceStorageLoadable(InputStream in, boolean storeNodeModel) {
this.in = in;
this.storeNodeModel = storeNodeModel;
}
protected void loadIntoResource(StorageAwareResource resource) throws IOException {
if (!resource.isLoadedFromStorage())
throw new IllegalStateException("Please use StorageAwareResource#load(ResourceStorageLoadable).");
try (ZipInputStream zin = new ZipInputStream(in)) {
loadEntries(resource, zin);
}
}
/**
* Load entries from the storage. Overriding methods should first delegate to super before adding their own entries.
*/
protected void loadEntries(StorageAwareResource resource, ZipInputStream zipIn) throws IOException {
zipIn.getNextEntry();
readContents(resource, new BufferedInputStream(zipIn));
zipIn.getNextEntry();
readResourceDescription(resource, new BufferedInputStream(zipIn));
if (storeNodeModel) {
zipIn.getNextEntry();
readNodeModel(resource, new BufferedInputStream(zipIn));
}
}
protected void readContents(StorageAwareResource resource, InputStream inputStream) throws IOException {
new BinaryResourceImpl.EObjectInputStream(inputStream, Collections.emptyMap()) {
@Override
public int readCompressedInt() throws IOException {
//HACK! null resource set, to avoid usage of resourceSet's package registry
resourceSet = null;
return super.readCompressedInt();
}
@Override
public InternalEObject loadEObject() throws IOException {
InternalEObject result = super.loadEObject();
handleLoadEObject(result, this);
return result;
}
}.loadResource(resource);
}
protected void handleLoadEObject(InternalEObject loaded, BinaryResourceImpl.EObjectInputStream input)
throws IOException {
}
protected void readResourceDescription(StorageAwareResource resource, InputStream inputStream) throws IOException {
try {
@SuppressWarnings("resource")
SerializableResourceDescription description = (SerializableResourceDescription) new ObjectInputStream(
inputStream).readObject();
description.updateResourceURI(resource.getURI());
resource.setResourceDescription(description);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
protected void readNodeModel(StorageAwareResource resource, InputStream inputStream) throws IOException {
if (!resource.customReadNodeModel(inputStream)) {
SerializableNodeModel serializableNodeModel = new SerializableNodeModel(resource);
// if this is a synthetic resource (i.e. tests or so, don't load the node model)
URIConverter uriConverter = resource.getResourceSet().getURIConverter();
URI resourceUri = resource.getURI();
if (!uriConverter.exists(resourceUri, resource.getResourceSet().getLoadOptions())) {
LOG.info("Skipping loading node model for synthetic resource " + resourceUri);
return;
}
try (InputStreamReader reader = new InputStreamReader(
uriConverter.createInputStream(resourceUri),
resource.getEncoding())) {
String completeContent = CharStreams.toString(reader);
DeserializationConversionContext deserializationContext = new DeserializationConversionContext(resource,
completeContent);
serializableNodeModel.readObjectData(new DataInputStream(inputStream), deserializationContext);
resource.setParseResult(new ParseResult(head(resource.getContents()), serializableNodeModel.root,
deserializationContext.hasErrors()));
}
}
}
}