mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-15 08:18:55 +00:00
[eclipse/xtext#1679] Refactor more Xtend to Java (#1428)
* [eclipse/xtext#1679] Refactor more Xtend to Java
This commit is contained in:
parent
adf0e9c491
commit
12a21c9114
22 changed files with 675 additions and 1424 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014 itemis AG (http://www.itemis.eu) and others.
|
||||
* 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.
|
||||
|
@ -84,7 +84,7 @@ class PortableURIsTest extends AbstractXtextTests {
|
|||
try {
|
||||
checkFragmentBothDirections(EcorePackage.eINSTANCE.EAnnotation_EModelElement, EcorePackage.eINSTANCE.EAttribute_EAttributeType)
|
||||
Assert.fail();
|
||||
} catch (IllegalStateException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2014 itemis AG (http://www.itemis.eu) and others.
|
||||
* 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.
|
||||
|
@ -22,6 +22,7 @@ import org.eclipse.xtext.linking.langATestLanguage.Main;
|
|||
import org.eclipse.xtext.linking.langATestLanguage.Type;
|
||||
import org.eclipse.xtext.resource.IReferenceDescription;
|
||||
import org.eclipse.xtext.resource.XtextResourceSet;
|
||||
import org.eclipse.xtext.resource.persistence.IResourceStorageFacade;
|
||||
import org.eclipse.xtext.resource.persistence.PortableURIs;
|
||||
import org.eclipse.xtext.resource.persistence.ResourceStorageLoadable;
|
||||
import org.eclipse.xtext.resource.persistence.ResourceStorageWritable;
|
||||
|
@ -96,9 +97,10 @@ public class PortableURIsTest extends AbstractXtextTests {
|
|||
final ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
final ResourceStorageWritable writable = resourceA.getResourceStorageFacade().createResourceStorageWritable(bout);
|
||||
writable.writeResource(resourceA);
|
||||
IResourceStorageFacade _resourceStorageFacade = resourceA.getResourceStorageFacade();
|
||||
byte[] _byteArray = bout.toByteArray();
|
||||
ByteArrayInputStream _byteArrayInputStream = new ByteArrayInputStream(_byteArray);
|
||||
final ResourceStorageLoadable loadable = resourceA.getResourceStorageFacade().createResourceStorageLoadable(_byteArrayInputStream);
|
||||
final ResourceStorageLoadable loadable = _resourceStorageFacade.createResourceStorageLoadable(_byteArrayInputStream);
|
||||
Resource _createResource_2 = resourceSet.createResource(URI.createURI("hubba:/bubba3.langatestlanguage"));
|
||||
final StorageAwareResource resourceC = ((StorageAwareResource) _createResource_2);
|
||||
resourceC.loadFromStorage(loadable);
|
||||
|
@ -120,7 +122,7 @@ public class PortableURIsTest extends AbstractXtextTests {
|
|||
this.checkFragmentBothDirections(EcorePackage.eINSTANCE.getEAnnotation_EModelElement(), EcorePackage.eINSTANCE.getEAttribute_EAttributeType());
|
||||
Assert.fail();
|
||||
} catch (final Throwable _t) {
|
||||
if (_t instanceof IllegalStateException) {
|
||||
if (_t instanceof IllegalArgumentException) {
|
||||
} else {
|
||||
throw Exceptions.sneakyThrow(_t);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* Copyright (c) 2018, 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.naming;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.util.PolymorphicDispatcher;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function1;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link ICopyQualifiedNameService}. Clients might use this implementation as base class.
|
||||
*
|
||||
* @author Anton Kosyakov - Initial contribution and API
|
||||
* @author Arne Deutsch - Moved to new package
|
||||
* @since 2.14
|
||||
*/
|
||||
public class DefaultCopyQualifiedNameService implements ICopyQualifiedNameService {
|
||||
@Inject
|
||||
private IQualifiedNameProvider qualifiedNameProvider;
|
||||
|
||||
@Inject
|
||||
private IQualifiedNameConverter qualifiedNameConverter;
|
||||
|
||||
private PolymorphicDispatcher<String> dispatchGetQualifiedName = PolymorphicDispatcher
|
||||
.createForSingleTarget("_getQualifiedName", 2, 2, this);
|
||||
|
||||
public String getQualifiedName(EObject it, EObject context) {
|
||||
return dispatchGetQualifiedName.invoke(it, context);
|
||||
}
|
||||
|
||||
protected String _getQualifiedName(EObject object, EObject context) {
|
||||
return toFullyQualifiedName(object);
|
||||
}
|
||||
|
||||
protected String _getQualifiedName(EObject object, Void context) {
|
||||
return toFullyQualifiedName(object);
|
||||
}
|
||||
|
||||
protected String _getQualifiedName(Void nullObject, EObject context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String _getQualifiedName(Void nullObject, Void context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected <T> CharSequence toQualifiedNames(List<T> list,
|
||||
Function1<? super T, ? extends String> toQualifiedNameFunction) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return Joiner.on(", ").skipNulls().join(Lists.transform(list, toQualifiedNameFunction::apply));
|
||||
}
|
||||
|
||||
protected String toFullyQualifiedName(EObject object) {
|
||||
return toString(object, getFullyQualifiedName(object));
|
||||
}
|
||||
|
||||
protected QualifiedName getFullyQualifiedName(EObject object) {
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
return qualifiedNameProvider.getFullyQualifiedName(object);
|
||||
}
|
||||
|
||||
protected String toString(EObject it, QualifiedName fullyQualifiedName) {
|
||||
if (fullyQualifiedName == null) {
|
||||
return null;
|
||||
}
|
||||
return qualifiedNameConverter.toString(fullyQualifiedName);
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2018 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.naming
|
||||
|
||||
import com.google.inject.Inject
|
||||
import java.util.List
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.xtext.naming.IQualifiedNameConverter
|
||||
import org.eclipse.xtext.naming.IQualifiedNameProvider
|
||||
import org.eclipse.xtext.naming.QualifiedName
|
||||
|
||||
/**
|
||||
* Default implementation for {@link ICopyQualifiedNameService}. Clients might use this implementation as base class.
|
||||
*
|
||||
* @author Anton Kosyakov - Initial contribution and API
|
||||
* @author Arne Deutsch - Moved to new package
|
||||
* @since 2.14
|
||||
*/
|
||||
class DefaultCopyQualifiedNameService implements ICopyQualifiedNameService {
|
||||
|
||||
@Inject
|
||||
IQualifiedNameProvider qualifiedNameProvider
|
||||
|
||||
@Inject
|
||||
IQualifiedNameConverter qualifiedNameConverter
|
||||
|
||||
def dispatch getQualifiedName(EObject it, EObject context) {
|
||||
toFullyQualifiedName
|
||||
}
|
||||
|
||||
def dispatch getQualifiedName(EObject it, Void context) {
|
||||
toFullyQualifiedName
|
||||
}
|
||||
|
||||
def protected dispatch getQualifiedName(Void it, EObject context) {
|
||||
null
|
||||
}
|
||||
|
||||
def protected dispatch getQualifiedName(Void it, Void context) {
|
||||
null
|
||||
}
|
||||
|
||||
def protected <T> toQualifiedNames(List<T> it, (T)=>String toQualifiedNameFunction) {
|
||||
if (it === null || size == 0) {
|
||||
return ""
|
||||
}
|
||||
'''«FOR element : it SEPARATOR ', '»«toQualifiedNameFunction.apply(element)»«ENDFOR»'''
|
||||
}
|
||||
|
||||
def protected toFullyQualifiedName(EObject it) {
|
||||
if (eIsProxy) {
|
||||
return null
|
||||
}
|
||||
toString(fullyQualifiedName)
|
||||
}
|
||||
|
||||
def protected getFullyQualifiedName(EObject it) {
|
||||
if (it === null) {
|
||||
return null
|
||||
}
|
||||
qualifiedNameProvider.getFullyQualifiedName(it)
|
||||
}
|
||||
|
||||
def protected toString(EObject it, QualifiedName fullyQualifiedName) {
|
||||
if (fullyQualifiedName === null) {
|
||||
return null
|
||||
}
|
||||
qualifiedNameConverter.toString(fullyQualifiedName)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2014 itemis AG (http://www.itemis.eu) and others.
|
||||
* 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.
|
||||
|
@ -10,11 +10,9 @@ package org.eclipse.xtext.resource.persistence;
|
|||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.xtext.generator.IFileSystemAccessExtension3;
|
||||
import org.eclipse.xtext.resource.persistence.ResourceStorageLoadable;
|
||||
import org.eclipse.xtext.resource.persistence.ResourceStorageWritable;
|
||||
import org.eclipse.xtext.resource.persistence.StorageAwareResource;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
|
@ -23,17 +21,16 @@ import org.eclipse.xtext.resource.persistence.StorageAwareResource;
|
|||
* @noextend
|
||||
* @since 2.8
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public interface IResourceStorageFacade {
|
||||
/**
|
||||
* @return whether the given resource should and can be loaded from stored resource state
|
||||
*/
|
||||
boolean shouldLoadFromStorage(final StorageAwareResource resource);
|
||||
boolean shouldLoadFromStorage(StorageAwareResource resource);
|
||||
|
||||
/**
|
||||
* @return whether storage data exists for the given URI
|
||||
*/
|
||||
boolean hasStorageFor(final URI uri);
|
||||
boolean hasStorageFor(URI uri);
|
||||
|
||||
/**
|
||||
* Finds or creates a ResourceStorageLoadable for the given resource.
|
||||
|
@ -42,20 +39,20 @@ public interface IResourceStorageFacade {
|
|||
*
|
||||
* @return an IResourceStorageLoadable
|
||||
*/
|
||||
ResourceStorageLoadable getOrCreateResourceStorageLoadable(final StorageAwareResource resource);
|
||||
ResourceStorageLoadable getOrCreateResourceStorageLoadable(StorageAwareResource resource);
|
||||
|
||||
/**
|
||||
* Saves the resource using the given file system access.
|
||||
*/
|
||||
void saveResource(final StorageAwareResource resource, final IFileSystemAccessExtension3 fsa);
|
||||
void saveResource(StorageAwareResource resource, IFileSystemAccessExtension3 fsa);
|
||||
|
||||
/**
|
||||
* Creates a fresh ResourceStorageWritable wrapping the given OutputStream
|
||||
*/
|
||||
ResourceStorageWritable createResourceStorageWritable(final OutputStream outputStream);
|
||||
ResourceStorageWritable createResourceStorageWritable(OutputStream outputStream);
|
||||
|
||||
/**
|
||||
* Creates a fresh ResourceStorageLoadable wrapping the given InputStream
|
||||
*/
|
||||
ResourceStorageLoadable createResourceStorageLoadable(final InputStream inputStream);
|
||||
ResourceStorageLoadable createResourceStorageLoadable(InputStream inputStream);
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014 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 org.eclipse.xtext.generator.IFileSystemAccessExtension3
|
||||
import java.io.OutputStream
|
||||
import java.io.InputStream
|
||||
import org.eclipse.emf.common.util.URI
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @noimplement
|
||||
* @noextend
|
||||
* @since 2.8
|
||||
*/
|
||||
interface IResourceStorageFacade {
|
||||
|
||||
/**
|
||||
* @return whether the given resource should and can be loaded from stored resource state
|
||||
*/
|
||||
def boolean shouldLoadFromStorage(StorageAwareResource resource)
|
||||
|
||||
/**
|
||||
* @return whether storage data exists for the given URI
|
||||
*/
|
||||
def boolean hasStorageFor(URI uri)
|
||||
|
||||
/**
|
||||
* Finds or creates a ResourceStorageLoadable for the given resource.
|
||||
* Clients should first call shouldLoadFromStorage to check whether there exists a storage version
|
||||
* of the given resource.
|
||||
*
|
||||
* @return an IResourceStorageLoadable
|
||||
*/
|
||||
def ResourceStorageLoadable getOrCreateResourceStorageLoadable(StorageAwareResource resource)
|
||||
|
||||
/**
|
||||
* Saves the resource using the given file system access.
|
||||
*/
|
||||
def void saveResource(StorageAwareResource resource, IFileSystemAccessExtension3 fsa)
|
||||
|
||||
/**
|
||||
* Creates a fresh ResourceStorageWritable wrapping the given OutputStream
|
||||
*/
|
||||
def ResourceStorageWritable createResourceStorageWritable(OutputStream outputStream)
|
||||
|
||||
/**
|
||||
* Creates a fresh ResourceStorageLoadable wrapping the given InputStream
|
||||
*/
|
||||
def ResourceStorageLoadable createResourceStorageLoadable(InputStream inputStream)
|
||||
|
||||
}
|
|
@ -0,0 +1,302 @@
|
|||
/**
|
||||
* 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 java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.EClass;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.emf.ecore.EPackage;
|
||||
import org.eclipse.emf.ecore.EReference;
|
||||
import org.eclipse.emf.ecore.EcoreFactory;
|
||||
import org.eclipse.emf.ecore.EcorePackage;
|
||||
import org.eclipse.emf.ecore.resource.Resource;
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil;
|
||||
import org.eclipse.xtext.naming.QualifiedName;
|
||||
import org.eclipse.xtext.resource.IEObjectDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider;
|
||||
import org.eclipse.xtext.scoping.IGlobalScopeProvider;
|
||||
import org.eclipse.xtext.scoping.IScope;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Portable URIs are based on names and therefore are independent of the concrete file pathes and fuile names the of
|
||||
* resources.
|
||||
*
|
||||
* A portable URI is really a resource URI to the client URI and a fragment that contains the information to retrieve
|
||||
* the referenced element using the global scoping. That is it contains
|
||||
* <ul>
|
||||
* <li>the qualified name of a container of the target element
|
||||
* <li>the type of that container
|
||||
* <li>the path from that container to the actual target element
|
||||
* </ul>
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
public class PortableURIs {
|
||||
|
||||
public static class PortableFragmentDescription {
|
||||
private final EClass descriptionEClass;
|
||||
|
||||
private final QualifiedName descriptionQualifiedName;
|
||||
|
||||
private final String descriptionRelativeFragment;
|
||||
|
||||
public PortableFragmentDescription(EClass descriptionEClass, QualifiedName descriptionQualifiedName,
|
||||
String descriptionRelativeFragment) {
|
||||
this.descriptionEClass = descriptionEClass;
|
||||
this.descriptionQualifiedName = descriptionQualifiedName;
|
||||
this.descriptionRelativeFragment = descriptionRelativeFragment;
|
||||
}
|
||||
|
||||
public EClass getDescriptionEClass() {
|
||||
return descriptionEClass;
|
||||
}
|
||||
|
||||
public QualifiedName getDescriptionQualifiedName() {
|
||||
return descriptionQualifiedName;
|
||||
}
|
||||
|
||||
public String getDescriptionRelativeFragment() {
|
||||
return descriptionRelativeFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((descriptionEClass == null) ? 0 : descriptionEClass.hashCode());
|
||||
result = prime * result + ((descriptionQualifiedName == null) ? 0 : descriptionQualifiedName.hashCode());
|
||||
result = prime * result
|
||||
+ ((descriptionRelativeFragment == null) ? 0 : descriptionRelativeFragment.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PortableFragmentDescription other = (PortableFragmentDescription) obj;
|
||||
if (descriptionEClass == null) {
|
||||
if (other.descriptionEClass != null)
|
||||
return false;
|
||||
} else if (!descriptionEClass.equals(other.descriptionEClass))
|
||||
return false;
|
||||
if (descriptionQualifiedName == null) {
|
||||
if (other.descriptionQualifiedName != null)
|
||||
return false;
|
||||
} else if (!descriptionQualifiedName.equals(other.descriptionQualifiedName))
|
||||
return false;
|
||||
if (descriptionRelativeFragment == null) {
|
||||
if (other.descriptionRelativeFragment != null)
|
||||
return false;
|
||||
} else if (!descriptionRelativeFragment.equals(other.descriptionRelativeFragment))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PortableFragmentDescription [descriptionEClass=" + descriptionEClass + ", descriptionQualifiedName="
|
||||
+ descriptionQualifiedName + ", descriptionRelativeFragment=" + descriptionRelativeFragment + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final String PORTABLE_SCHEME = "portable";
|
||||
|
||||
@Inject
|
||||
private IGlobalScopeProvider globalScopeProvider;
|
||||
|
||||
@Inject
|
||||
private EPackage.Registry packageRegistry;
|
||||
|
||||
@Inject
|
||||
private ResourceDescriptionsProvider resourceDescriptionsProvider;
|
||||
|
||||
/**
|
||||
* @return whether the given string is a portable URI fragment
|
||||
*/
|
||||
public boolean isPortableURIFragment(String uriFragment) {
|
||||
return uriFragment.startsWith(PortableURIs.PORTABLE_SCHEME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a given portable URI fragment against the given resource.
|
||||
*
|
||||
* @param resource
|
||||
* the resource from which global scope to look up the EObject
|
||||
* @param portableFragment
|
||||
* the portable fragment pointing to the to be resolved EObject
|
||||
*
|
||||
* @return the EObject for the given portableURIFragment
|
||||
*/
|
||||
public EObject resolve(StorageAwareResource resource, String portableFragment) {
|
||||
PortableURIs.PortableFragmentDescription desc = fromFragmentString(portableFragment);
|
||||
EReference mock = EcoreFactory.eINSTANCE.createEReference();
|
||||
mock.setEType(desc.descriptionEClass);
|
||||
IScope scope = globalScopeProvider.getScope(resource, mock, Predicates.<IEObjectDescription>alwaysTrue());
|
||||
Optional<IEObjectDescription> description = Streams.stream( //
|
||||
scope.getElements(desc.descriptionQualifiedName)).findFirst();
|
||||
return description.map(d -> {
|
||||
EObject container = EcoreUtil.resolve(d.getEObjectOrProxy(), resource);
|
||||
return getEObject(container, desc.descriptionRelativeFragment);
|
||||
}).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a portable URI from the given resource to the targetURI. Returns <code>null</code> if no
|
||||
* portable URI can be constructed, which is the case if the targetObject is not itself exported or is a child of an
|
||||
* exported EObject.
|
||||
*
|
||||
* @param sourceResource
|
||||
* the resource from which the EObject should later be resolved
|
||||
* @param targetURI
|
||||
* the target URI that should be resolvable by the created portable URI
|
||||
*
|
||||
* @return a portable URI or <code>null</code>
|
||||
*/
|
||||
public URI toPortableURI(StorageAwareResource sourceResource, URI targetURI) {
|
||||
EObject object = sourceResource.getResourceSet().getEObject(targetURI, false);
|
||||
// if it points to some registered ecore, there's no resourceSet and the result is not portable
|
||||
if (object == null || object.eResource().getResourceSet() != null) {
|
||||
return toPortableURI(sourceResource, object);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a portable URI from the global scope. Returns <code>null</code> if no portable URI can be
|
||||
* constructed, which is the case if the targetObject is not itself exported or is a child of an exported EObject.
|
||||
*
|
||||
* @param sourceResource
|
||||
* the resource from which the EObject should later be resolved
|
||||
* @param targetObject
|
||||
* the target object that should be resolvable by the created portable URI
|
||||
*
|
||||
* @return a portable URI or <code>null</code>
|
||||
*/
|
||||
public URI toPortableURI(StorageAwareResource sourceResource, EObject targetObject) {
|
||||
if (targetObject == null || targetObject.eIsProxy()) {
|
||||
return sourceResource.getURI().appendFragment(StorageAwareResource.UNRESOLVABLE_FRAGMENT);
|
||||
}
|
||||
String portableFragment = getPortableURIFragment(targetObject);
|
||||
if (portableFragment != null) {
|
||||
return sourceResource.getURI().appendFragment(portableFragment);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a portable URI fragment, or <code>null</code> if the give EObject isn't itself or is not contained in an
|
||||
* exported EObjectDescription
|
||||
*/
|
||||
protected String getPortableURIFragment(EObject obj) {
|
||||
IResourceDescriptions descriptions = resourceDescriptionsProvider.getResourceDescriptions(obj.eResource());
|
||||
IResourceDescription desc = descriptions.getResourceDescription(obj.eResource().getURI());
|
||||
if (desc == null) {
|
||||
return null;
|
||||
}
|
||||
return Streams.stream(desc.getExportedObjects()).filter(description -> {
|
||||
EObject possibleContainer = EcoreUtil.resolve(description.getEObjectOrProxy(), obj.eResource());
|
||||
return EcoreUtil.isAncestor(obj, possibleContainer);
|
||||
}).map(containerDesc -> {
|
||||
PortableFragmentDescription fragmentDescription = createPortableFragmentDescription(containerDesc, obj);
|
||||
return toFragmentString(fragmentDescription);
|
||||
}).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
protected PortableURIs.PortableFragmentDescription createPortableFragmentDescription(IEObjectDescription desc,
|
||||
EObject target) {
|
||||
EObject possibleContainer = EcoreUtil.resolve(desc.getEObjectOrProxy(), target);
|
||||
String fragmentToTarget = getFragment(target, possibleContainer);
|
||||
return new PortableURIs.PortableFragmentDescription(desc.getEClass(), desc.getQualifiedName(),
|
||||
fragmentToTarget);
|
||||
}
|
||||
|
||||
protected String toFragmentString(PortableURIs.PortableFragmentDescription desc) {
|
||||
String eclassUriAsString = URI.encodeFragment(EcoreUtil.getURI(desc.descriptionEClass).toString(), false);
|
||||
List<String> segments = desc.descriptionQualifiedName.getSegments();
|
||||
String uriFragment = PortableURIs.PORTABLE_SCHEME + "#" + eclassUriAsString + "#"
|
||||
+ URI.encodeFragment(Joiner.on(':').join(segments), false);
|
||||
if (desc.descriptionRelativeFragment != null) {
|
||||
uriFragment += "#" + URI.encodeFragment(desc.descriptionRelativeFragment, false);
|
||||
}
|
||||
return uriFragment;
|
||||
}
|
||||
|
||||
protected PortableURIs.PortableFragmentDescription fromFragmentString(String fragmentString) {
|
||||
Iterator<String> segments = Splitter.on("#").split(fragmentString).iterator();
|
||||
segments.next(); // skip first
|
||||
URI eClassURI = URI.createURI(URI.decode(segments.next()));
|
||||
EPackage ePackage = this.packageRegistry.getEPackage(eClassURI.trimFragment().toString());
|
||||
EClass eClass = EcorePackage.Literals.EOBJECT;
|
||||
if (ePackage != null) {
|
||||
Resource resource = ePackage.eResource();
|
||||
if (resource != null) {
|
||||
eClass = (EClass) resource.getEObject(eClassURI.fragment());
|
||||
}
|
||||
}
|
||||
QualifiedName qname = QualifiedName.create(Splitter.on(":").splitToList(URI.decode(segments.next())));
|
||||
String fragment = segments.hasNext() ? URI.decode(segments.next()) : null;
|
||||
return new PortableURIs.PortableFragmentDescription(eClass, qname, fragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a fragment to the child relative from the given container.
|
||||
*
|
||||
* @param fromContainer
|
||||
* the container EObject from which the fragment path is computed
|
||||
* @param toChild
|
||||
* the target EObject which can be found using the fromContainer and resulting fragment path
|
||||
*
|
||||
* @return a fragment path from the given container to the child, or <code>null</null> is fromContainer == toChild
|
||||
*
|
||||
* @see #getEObject(EObject,String)
|
||||
* @throws IllegalArgumentException if the child is not a child of the given container.
|
||||
*/
|
||||
public String getFragment(EObject fromContainer, EObject toChild) throws IllegalArgumentException {
|
||||
return Strings.emptyToNull(EcoreUtil.getRelativeURIFragmentPath(fromContainer, toChild));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an EObject for the given context EObject and fragment.
|
||||
*
|
||||
* @param from
|
||||
* the EObject from which the path should be resolved
|
||||
* @param toFragment
|
||||
* the fragment
|
||||
*
|
||||
* @return the resolved EObject based. If the given fragment is <code>null</null>, the given EObject itself will be
|
||||
* returned.
|
||||
*/
|
||||
public EObject getEObject(EObject from, String toFragment) {
|
||||
if (toFragment == null) {
|
||||
return from;
|
||||
}
|
||||
return EcoreUtil.getEObject(from, toFragment);
|
||||
}
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 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 com.google.common.base.Predicates
|
||||
import com.google.common.base.Splitter
|
||||
import com.google.inject.Inject
|
||||
import org.eclipse.emf.common.util.URI
|
||||
import org.eclipse.emf.ecore.EClass
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.EPackage
|
||||
import org.eclipse.emf.ecore.EcoreFactory
|
||||
import org.eclipse.emf.ecore.EcorePackage
|
||||
import org.eclipse.emf.ecore.InternalEObject
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil
|
||||
import org.eclipse.xtend.lib.annotations.Data
|
||||
import org.eclipse.xtext.naming.QualifiedName
|
||||
import org.eclipse.xtext.resource.IEObjectDescription
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider
|
||||
import org.eclipse.xtext.scoping.IGlobalScopeProvider
|
||||
|
||||
/**
|
||||
* Portable URIs are based on names and therefore are independent of the concrete file pathes and fuile names the
|
||||
* of resources.
|
||||
*
|
||||
* A portable URI is really a resource URI to the client URI and a fragment that contains the information to retrieve the
|
||||
* referenced element using the global scoping. That is it contains
|
||||
* <ul>
|
||||
* <li>the qualified name of a container of the target element
|
||||
* <li>the type of that container
|
||||
* <li>the path from that container to the actual target element
|
||||
* </ul>
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
class PortableURIs {
|
||||
|
||||
public static val PORTABLE_SCHEME = "portable"
|
||||
|
||||
@Inject IGlobalScopeProvider globalScopeProvider
|
||||
@Inject EPackage.Registry packageRegistry
|
||||
@Inject ResourceDescriptionsProvider resourceDescriptionsProvider
|
||||
|
||||
/**
|
||||
* @return whether the given string is a portable URI fragment
|
||||
*/
|
||||
def boolean isPortableURIFragment(String uriFragment) {
|
||||
uriFragment.startsWith(PORTABLE_SCHEME)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a given portable URI fragment against the given resource.
|
||||
*
|
||||
* @param resource the resource from which global scope to look up the EObject
|
||||
* @param portableFragment the portable fragment pointing to the to be resolved EObject
|
||||
*
|
||||
* @return the EObject for the given portableURIFragment
|
||||
*/
|
||||
def EObject resolve(StorageAwareResource resource, String portableFragment) {
|
||||
val desc = fromFragmentString(portableFragment)
|
||||
val mock = EcoreFactory.eINSTANCE.createEReference
|
||||
mock.EType = desc.descriptionEClass
|
||||
val scope = globalScopeProvider.getScope(resource, mock, Predicates.alwaysTrue)
|
||||
val description = scope.getElements(desc.descriptionQualifiedName).head
|
||||
if (description === null) {
|
||||
return null
|
||||
}
|
||||
val container = EcoreUtil.resolve(description.EObjectOrProxy, resource)
|
||||
return getEObject(container, desc.descriptionRelativeFragment)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a portable URI from the given resource to the targetURI.
|
||||
* Returns <code>null</code> is no portable URI can be constructed, which is the case if the
|
||||
* targetObject is not itself exported or is a child of an exported EObject.
|
||||
*
|
||||
* @param sourceResource the resource from which the EObject should later be resolved
|
||||
* @param targetURI the target URI that should be resolvable by the created portable URI
|
||||
*
|
||||
* @return a portable URI or <code>null</code>
|
||||
*/
|
||||
def URI toPortableURI(StorageAwareResource sourceResource, URI targetURI) {
|
||||
val to = sourceResource.resourceSet.getResource(targetURI.trimFragment, false)?.getEObject(targetURI.fragment)
|
||||
// if it points to some registered ecore, there's no resourceSet and the result is not portable
|
||||
if (to === null || to.eResource?.resourceSet !== null) {
|
||||
val result = toPortableURI(sourceResource, to);
|
||||
if (result !== null) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a portable URI from the global scope.
|
||||
* Returns <code>null</code> is no portable URI can be constructed, which is the case if the
|
||||
* targetObject is not itself exported or is a child of an exported EObject.
|
||||
*
|
||||
* @param sourceResource the resource from which the EObject should later be resolved
|
||||
* @param targetObject the target object that should be resolvable by the created portable URI
|
||||
*
|
||||
* @return a portable URI or <code>null</code>
|
||||
*/
|
||||
def URI toPortableURI(StorageAwareResource sourceResource, EObject targetObject) {
|
||||
if (targetObject === null || targetObject.eIsProxy) {
|
||||
return sourceResource.URI.appendFragment(StorageAwareResource.UNRESOLVABLE_FRAGMENT)
|
||||
}
|
||||
val portableFragment = getPortableURIFragment(targetObject)
|
||||
if (portableFragment !== null) {
|
||||
return sourceResource.URI.appendFragment(portableFragment)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a portable URI fragment, or <code>null</code> if the give EObject isn't itself or is not contained in an exported EObjectDescription
|
||||
*/
|
||||
protected def String getPortableURIFragment(EObject obj) {
|
||||
val descriptions = resourceDescriptionsProvider.getResourceDescriptions(obj.eResource)
|
||||
val desc = descriptions.getResourceDescription(obj.eResource.URI)
|
||||
if (desc === null) {
|
||||
return null
|
||||
}
|
||||
val containerDesc = desc.exportedObjects.findFirst [
|
||||
val possibleContainer = EcoreUtil.resolve(EObjectOrProxy, obj.eResource)
|
||||
obj==possibleContainer || EcoreUtil.isAncestor(obj, possibleContainer)
|
||||
]
|
||||
if (containerDesc !== null) {
|
||||
val fragmentDescription = createPortableFragmentDescription(containerDesc, obj)
|
||||
return toFragmentString(fragmentDescription)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
protected def PortableFragmentDescription createPortableFragmentDescription(IEObjectDescription desc, EObject target) {
|
||||
val possibleContainer = EcoreUtil.resolve(desc.EObjectOrProxy, target)
|
||||
val fragmentToTarget = getFragment(target, possibleContainer)
|
||||
return new PortableFragmentDescription(desc.EClass, desc.qualifiedName, fragmentToTarget)
|
||||
}
|
||||
|
||||
protected def String toFragmentString(PortableFragmentDescription desc) {
|
||||
val eclassUriAsString = URI.encodeFragment(EcoreUtil.getURI(desc.descriptionEClass).toString, false)
|
||||
val segments = desc.descriptionQualifiedName.segments
|
||||
var uriFragment = PORTABLE_SCHEME + '#' + eclassUriAsString + '#'+ URI.encodeFragment(segments.join(':'), false)
|
||||
if (desc.descriptionRelativeFragment !== null) {
|
||||
uriFragment += '#' + URI.encodeFragment(desc.descriptionRelativeFragment, false)
|
||||
}
|
||||
return uriFragment
|
||||
}
|
||||
|
||||
protected def PortableFragmentDescription fromFragmentString(String fragmentString) {
|
||||
val segments = Splitter.on('#').split(fragmentString).iterator
|
||||
segments.next // skip first
|
||||
val eClassURI = URI.createURI(URI.decode(segments.next))
|
||||
val ePackage = packageRegistry.getEPackage(eClassURI.trimFragment.toString)
|
||||
val eClass = ePackage?.eResource?.getEObject(eClassURI.fragment) as EClass
|
||||
val qname = QualifiedName.create(Splitter.on(':').split(URI.decode(segments.next)).toList)
|
||||
val fragment = if (segments.hasNext) {
|
||||
URI.decode(segments.next)
|
||||
}
|
||||
return new PortableFragmentDescription(eClass?:EcorePackage.Literals.EOBJECT, qname, fragment)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a fragment to the child relative from the given container.
|
||||
*
|
||||
* @param fromContainer the container EObject from which the fragment path is computed
|
||||
* @param toChild the target EObject which can be found using the fromContainer and resulting fragment path
|
||||
*
|
||||
* @return a fragment path from the given container to the child, or <code>null</null> is fromContainer == toChild
|
||||
*
|
||||
* @see #getEObject(EObject,String)
|
||||
*/
|
||||
def String getFragment(EObject fromContainer, EObject toChild) {
|
||||
if (fromContainer == toChild)
|
||||
return null
|
||||
var lastChild = toChild as InternalEObject
|
||||
var lastContainer = lastChild.eInternalContainer
|
||||
var result = lastContainer.eURIFragmentSegment(lastChild.eContainingFeature, lastChild)
|
||||
while (lastContainer !== null && fromContainer != lastContainer) {
|
||||
lastChild = lastContainer
|
||||
lastContainer = lastContainer.eInternalContainer
|
||||
if (lastContainer === null) {
|
||||
throw new IllegalStateException("No more containers for element "+lastChild)
|
||||
}
|
||||
result = lastContainer.eURIFragmentSegment(lastChild.eContainingFeature, lastChild)+'/'+result
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an EObject for the given context EObject and fragment.
|
||||
*
|
||||
* @param from the EObject from which the path should be resolved
|
||||
* @param toFragment the fragment
|
||||
*
|
||||
* @return the resolved EObject based. If the given fragment is <code>null</null>, the given EObject itself will be returned.
|
||||
*/
|
||||
def EObject getEObject(EObject from, String toFragment) {
|
||||
if (toFragment === null)
|
||||
return from
|
||||
val splitted = Splitter.on("/").split(toFragment)
|
||||
return splitted.fold(from) [
|
||||
($0 as InternalEObject).eObjectForURIFragmentSegment($1)
|
||||
]
|
||||
}
|
||||
|
||||
@Data static class PortableFragmentDescription {
|
||||
EClass descriptionEClass
|
||||
QualifiedName descriptionQualifiedName
|
||||
String descriptionRelativeFragment
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* 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 org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
|
||||
/**
|
||||
* An adapter that can be installed into a SerializableResource, to provide resource state. It is used with dirty
|
||||
* editors providing the dirty non persisted state to other editors.
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*/
|
||||
public class ResourceStorageProviderAdapter extends AdapterImpl {
|
||||
@Override
|
||||
public boolean isAdapterForType(Object type) {
|
||||
return ResourceStorageProviderAdapter.class.equals(type);
|
||||
}
|
||||
|
||||
public ResourceStorageLoadable getResourceStorageLoadable(StorageAwareResource resource) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014 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 org.eclipse.emf.common.notify.impl.AdapterImpl
|
||||
|
||||
/**
|
||||
* An adapter that can be installed into a SerializableResource,
|
||||
* to provide resource state. It is used with dirty editors providing the dirty non persisted
|
||||
* state to other editors.
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*/
|
||||
class ResourceStorageProviderAdapter extends AdapterImpl {
|
||||
|
||||
override isAdapterForType(Object type) {
|
||||
type == ResourceStorageProviderAdapter
|
||||
}
|
||||
|
||||
def ResourceStorageLoadable getResourceStorageLoadable(StorageAwareResource resource) {
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* 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 java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* An adapter to be installed into a ResourceSet.
|
||||
*
|
||||
* It's used as a protocol to tell whether a StorageAwareResource should load from source or could load from serialized
|
||||
* data.
|
||||
*
|
||||
* @see ResourceStorageProviderAdapter
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
public class SourceLevelURIsAdapter extends AdapterImpl {
|
||||
|
||||
public static void setSourceLevelUris(ResourceSet resourceSet, Collection<URI> uris) {
|
||||
SourceLevelURIsAdapter adapter = findOrCreateAdapter(resourceSet);
|
||||
adapter.sourceLevelURIs = ImmutableSet.copyOf(uris);
|
||||
}
|
||||
|
||||
protected static SourceLevelURIsAdapter findOrCreateAdapter(ResourceSet resourceSet) {
|
||||
SourceLevelURIsAdapter adapter = findInstalledAdapter(resourceSet);
|
||||
if (adapter != null) {
|
||||
return adapter;
|
||||
}
|
||||
adapter = new SourceLevelURIsAdapter();
|
||||
resourceSet.eAdapters().add(adapter);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the given set of URIs as the source level URIs. Does not copy the given set but uses it directly.
|
||||
*/
|
||||
public static void setSourceLevelUrisWithoutCopy(ResourceSet resourceSet, Set<URI> uris) {
|
||||
SourceLevelURIsAdapter adapter = findOrCreateAdapter(resourceSet);
|
||||
adapter.sourceLevelURIs = uris;
|
||||
}
|
||||
|
||||
public static SourceLevelURIsAdapter findInstalledAdapter(ResourceSet resourceSet) {
|
||||
for (Adapter adapter : resourceSet.eAdapters()) {
|
||||
if (adapter instanceof SourceLevelURIsAdapter) {
|
||||
return (SourceLevelURIsAdapter) adapter;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Set<URI> sourceLevelURIs;
|
||||
|
||||
public Set<URI> getSourceLevelURIs() {
|
||||
return Collections.unmodifiableSet(sourceLevelURIs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(Object type) {
|
||||
return SourceLevelURIsAdapter.class.equals(type);
|
||||
}
|
||||
|
||||
public void setSourceLevelURIs(Set<URI> sourceLevelURIs) {
|
||||
this.sourceLevelURIs = sourceLevelURIs;
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014 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 com.google.common.collect.ImmutableSet
|
||||
import java.util.Collection
|
||||
import java.util.Collections
|
||||
import java.util.Set
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl
|
||||
import org.eclipse.emf.common.util.URI
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
|
||||
/**
|
||||
* An adapter to be installed into a ResourceSet.
|
||||
*
|
||||
* It's used as a protocol to tell whether a StorageAwareResource
|
||||
* should load from source or could load from serialized data.
|
||||
*
|
||||
* @see ResourceStorageProviderAdapter
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
class SourceLevelURIsAdapter extends AdapterImpl {
|
||||
|
||||
@Accessors Set<URI> sourceLevelURIs
|
||||
|
||||
def Set<URI> getSourceLevelURIs() {
|
||||
return Collections.unmodifiableSet(this.sourceLevelURIs);
|
||||
}
|
||||
|
||||
override isAdapterForType(Object type) {
|
||||
return type == SourceLevelURIsAdapter
|
||||
}
|
||||
|
||||
def static void setSourceLevelUris(ResourceSet resourceSet, Collection<URI> uris) {
|
||||
val adapter = findOrCreateAdapter(resourceSet)
|
||||
adapter.sourceLevelURIs = ImmutableSet.copyOf(uris)
|
||||
}
|
||||
|
||||
protected def static SourceLevelURIsAdapter findOrCreateAdapter(ResourceSet resourceSet) {
|
||||
return findInstalledAdapter(resourceSet)
|
||||
?: (new SourceLevelURIsAdapter => [
|
||||
resourceSet.eAdapters += it
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the given set of URIs as the source level URIs. Does not copy the given
|
||||
* set but uses it directly.
|
||||
*/
|
||||
def static void setSourceLevelUrisWithoutCopy(ResourceSet resourceSet, Set<URI> uris) {
|
||||
val adapter = findOrCreateAdapter(resourceSet)
|
||||
adapter.sourceLevelURIs = uris;
|
||||
}
|
||||
|
||||
def static SourceLevelURIsAdapter findInstalledAdapter(ResourceSet resourceSet) {
|
||||
return resourceSet.eAdapters.filter(SourceLevelURIsAdapter).head
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* 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 java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.linking.lazy.LazyLinkingResource;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.util.internal.Stopwatches;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* A resource implementation that can load itself from ResourceStorage.
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*/
|
||||
public class StorageAwareResource extends LazyLinkingResource {
|
||||
public static final String UNRESOLVABLE_FRAGMENT = "UNRESOLVABLE";
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(StorageAwareResource.class);
|
||||
|
||||
@Inject(optional = true)
|
||||
private IResourceStorageFacade resourceStorageFacade;
|
||||
|
||||
@Inject
|
||||
private PortableURIs portableURIs;
|
||||
|
||||
private boolean isLoadedFromStorage = false;
|
||||
|
||||
private IResourceDescription resourceDescription = null;
|
||||
|
||||
@Override
|
||||
public void load(Map<?, ?> options) throws IOException {
|
||||
if (!isLoaded && !isLoading && resourceStorageFacade != null
|
||||
&& resourceStorageFacade.shouldLoadFromStorage(this)) {
|
||||
LOG.debug("Loading " + getURI() + " from storage.");
|
||||
try {
|
||||
ResourceStorageLoadable in = resourceStorageFacade.getOrCreateResourceStorageLoadable(this);
|
||||
loadFromStorage(in);
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
if (contents != null) {
|
||||
contents.clear();
|
||||
}
|
||||
if (eAdapters != null) {
|
||||
eAdapters.clear();
|
||||
}
|
||||
unload();
|
||||
}
|
||||
}
|
||||
super.load(options);
|
||||
}
|
||||
|
||||
public void loadFromStorage(ResourceStorageLoadable storageInputStream) throws IOException {
|
||||
// check the argument for null before the internal state is modified
|
||||
Preconditions.checkNotNull(storageInputStream, "storageInputStream");
|
||||
Stopwatches.StoppedTask task = Stopwatches.forTask("Loading from storage");
|
||||
task.start();
|
||||
isLoading = true;
|
||||
isLoadedFromStorage = true;
|
||||
try {
|
||||
storageInputStream.loadIntoResource(this);
|
||||
isLoaded = true;
|
||||
} finally {
|
||||
isLoading = false;
|
||||
task.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doUnload() {
|
||||
super.doUnload();
|
||||
isLoadedFromStorage = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearInternalState() {
|
||||
isLoadedFromStorage = false;
|
||||
super.clearInternalState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized EObject getEObject(String uriFragment) {
|
||||
if (portableURIs.isPortableURIFragment(uriFragment)) {
|
||||
return portableURIs.resolve(this, uriFragment);
|
||||
}
|
||||
return super.getEObject(uriFragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> getUnresolvableURIFragments() {
|
||||
if (isLoadedFromStorage) {
|
||||
return Collections.singleton(StorageAwareResource.UNRESOLVABLE_FRAGMENT);
|
||||
}
|
||||
return super.getUnresolvableURIFragments();
|
||||
}
|
||||
|
||||
public IResourceStorageFacade getResourceStorageFacade() {
|
||||
return resourceStorageFacade;
|
||||
}
|
||||
|
||||
public PortableURIs getPortableURIs() {
|
||||
return portableURIs;
|
||||
}
|
||||
|
||||
public boolean isLoadedFromStorage() {
|
||||
return isLoadedFromStorage;
|
||||
}
|
||||
|
||||
public void setIsLoadedFromStorage(boolean isLoadedFromStorage) {
|
||||
this.isLoadedFromStorage = isLoadedFromStorage;
|
||||
}
|
||||
|
||||
public IResourceDescription getResourceDescription() {
|
||||
return resourceDescription;
|
||||
}
|
||||
|
||||
public void setResourceDescription(IResourceDescription resourceDescription) {
|
||||
this.resourceDescription = resourceDescription;
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2017 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 com.google.inject.Inject
|
||||
import java.io.IOException
|
||||
import java.util.Map
|
||||
import org.apache.log4j.Logger
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.linking.lazy.LazyLinkingResource
|
||||
import org.eclipse.xtext.resource.IResourceDescription
|
||||
import org.eclipse.xtext.util.internal.Stopwatches
|
||||
|
||||
/**
|
||||
* A resource implementation that can load itself from ResourceStorage.
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*/
|
||||
class StorageAwareResource extends LazyLinkingResource {
|
||||
public static val UNRESOLVABLE_FRAGMENT = "UNRESOLVABLE"
|
||||
static val Logger LOG = Logger.getLogger(StorageAwareResource)
|
||||
|
||||
@Accessors(PUBLIC_GETTER) @Inject(optional=true) IResourceStorageFacade resourceStorageFacade
|
||||
|
||||
@Accessors(PUBLIC_GETTER) @Inject PortableURIs portableURIs
|
||||
|
||||
@Accessors boolean isLoadedFromStorage = false;
|
||||
|
||||
@Accessors IResourceDescription resourceDescription = null;
|
||||
|
||||
override load(Map<?, ?> options) throws IOException {
|
||||
if (!isLoaded && !isLoading && resourceStorageFacade !== null && resourceStorageFacade.shouldLoadFromStorage(this)) {
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("Loading "+URI+" from storage.")
|
||||
}
|
||||
try {
|
||||
val in = resourceStorageFacade.getOrCreateResourceStorageLoadable(this);
|
||||
loadFromStorage(in)
|
||||
return;
|
||||
} catch(IOException e) {
|
||||
// revert the resource into a clean state
|
||||
contents?.clear
|
||||
eAdapters?.clear
|
||||
unload
|
||||
}
|
||||
}
|
||||
super.load(options)
|
||||
}
|
||||
|
||||
def void loadFromStorage(ResourceStorageLoadable storageInputStream) throws IOException {
|
||||
if (storageInputStream === null) {
|
||||
throw new NullPointerException('storageInputStream')
|
||||
}
|
||||
val task = Stopwatches.forTask("Loading from storage")
|
||||
task.start
|
||||
isLoading = true;
|
||||
isLoadedFromStorage = true;
|
||||
try {
|
||||
storageInputStream.loadIntoResource(this);
|
||||
isLoaded = true;
|
||||
} finally {
|
||||
isLoading = false
|
||||
task.stop
|
||||
}
|
||||
}
|
||||
|
||||
override protected doUnload() {
|
||||
super.doUnload
|
||||
isLoadedFromStorage = false;
|
||||
}
|
||||
|
||||
override protected clearInternalState() {
|
||||
isLoadedFromStorage = false;
|
||||
super.clearInternalState();
|
||||
}
|
||||
|
||||
override synchronized getEObject(String uriFragment) {
|
||||
if (portableURIs.isPortableURIFragment(uriFragment)) {
|
||||
return portableURIs.resolve(this, uriFragment)
|
||||
}
|
||||
super.getEObject(uriFragment)
|
||||
}
|
||||
|
||||
override protected getUnresolvableURIFragments() {
|
||||
if (isLoadedFromStorage) {
|
||||
return #{UNRESOLVABLE_FRAGMENT}
|
||||
} else {
|
||||
return super.getUnresolvableURIFragments()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* 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 org.eclipse.emf.ecore.resource.Resource;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionManager;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
public class StorageAwareResourceDescriptionManager extends DefaultResourceDescriptionManager {
|
||||
@Override
|
||||
public IResourceDescription getResourceDescription(Resource resource) {
|
||||
if (resource instanceof StorageAwareResource) {
|
||||
IResourceDescription result = ((StorageAwareResource) resource).getResourceDescription();
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return super.getResourceDescription(resource);
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 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 org.eclipse.xtext.resource.impl.DefaultResourceDescriptionManager
|
||||
import org.eclipse.emf.ecore.resource.Resource
|
||||
import org.eclipse.xtext.resource.persistence.StorageAwareResource
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
class StorageAwareResourceDescriptionManager extends DefaultResourceDescriptionManager {
|
||||
|
||||
override getResourceDescription(Resource resource) {
|
||||
switch resource {
|
||||
StorageAwareResource case resource.resourceDescription !== null
|
||||
: resource.resourceDescription
|
||||
default : super.getResourceDescription(resource)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2018 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.naming;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtend2.lib.StringConcatenation;
|
||||
import org.eclipse.xtext.naming.ICopyQualifiedNameService;
|
||||
import org.eclipse.xtext.naming.IQualifiedNameConverter;
|
||||
import org.eclipse.xtext.naming.IQualifiedNameProvider;
|
||||
import org.eclipse.xtext.naming.QualifiedName;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function1;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link ICopyQualifiedNameService}. Clients might use this implementation as base class.
|
||||
*
|
||||
* @author Anton Kosyakov - Initial contribution and API
|
||||
* @author Arne Deutsch - Moved to new package
|
||||
* @since 2.14
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class DefaultCopyQualifiedNameService implements ICopyQualifiedNameService {
|
||||
@Inject
|
||||
private IQualifiedNameProvider qualifiedNameProvider;
|
||||
|
||||
@Inject
|
||||
private IQualifiedNameConverter qualifiedNameConverter;
|
||||
|
||||
protected String _getQualifiedName(final EObject it, final EObject context) {
|
||||
return this.toFullyQualifiedName(it);
|
||||
}
|
||||
|
||||
protected String _getQualifiedName(final EObject it, final Void context) {
|
||||
return this.toFullyQualifiedName(it);
|
||||
}
|
||||
|
||||
protected String _getQualifiedName(final Void it, final EObject context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String _getQualifiedName(final Void it, final Void context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected <T extends Object> CharSequence toQualifiedNames(final List<T> it, final Function1<? super T, ? extends String> toQualifiedNameFunction) {
|
||||
CharSequence _xblockexpression = null;
|
||||
{
|
||||
if (((it == null) || (it.size() == 0))) {
|
||||
return "";
|
||||
}
|
||||
StringConcatenation _builder = new StringConcatenation();
|
||||
{
|
||||
boolean _hasElements = false;
|
||||
for(final T element : it) {
|
||||
if (!_hasElements) {
|
||||
_hasElements = true;
|
||||
} else {
|
||||
_builder.appendImmediate(", ", "");
|
||||
}
|
||||
String _apply = toQualifiedNameFunction.apply(element);
|
||||
_builder.append(_apply);
|
||||
}
|
||||
}
|
||||
_xblockexpression = _builder;
|
||||
}
|
||||
return _xblockexpression;
|
||||
}
|
||||
|
||||
protected String toFullyQualifiedName(final EObject it) {
|
||||
String _xblockexpression = null;
|
||||
{
|
||||
boolean _eIsProxy = it.eIsProxy();
|
||||
if (_eIsProxy) {
|
||||
return null;
|
||||
}
|
||||
_xblockexpression = this.toString(it, this.getFullyQualifiedName(it));
|
||||
}
|
||||
return _xblockexpression;
|
||||
}
|
||||
|
||||
protected QualifiedName getFullyQualifiedName(final EObject it) {
|
||||
QualifiedName _xblockexpression = null;
|
||||
{
|
||||
if ((it == null)) {
|
||||
return null;
|
||||
}
|
||||
_xblockexpression = this.qualifiedNameProvider.getFullyQualifiedName(it);
|
||||
}
|
||||
return _xblockexpression;
|
||||
}
|
||||
|
||||
protected String toString(final EObject it, final QualifiedName fullyQualifiedName) {
|
||||
String _xblockexpression = null;
|
||||
{
|
||||
if ((fullyQualifiedName == null)) {
|
||||
return null;
|
||||
}
|
||||
_xblockexpression = this.qualifiedNameConverter.toString(fullyQualifiedName);
|
||||
}
|
||||
return _xblockexpression;
|
||||
}
|
||||
|
||||
public String getQualifiedName(final EObject it, final EObject context) {
|
||||
if (it != null
|
||||
&& context != null) {
|
||||
return _getQualifiedName(it, context);
|
||||
} else if (it != null
|
||||
&& context == null) {
|
||||
return _getQualifiedName(it, (Void)null);
|
||||
} else if (it == null
|
||||
&& context != null) {
|
||||
return _getQualifiedName((Void)null, context);
|
||||
} else if (it == null
|
||||
&& context == null) {
|
||||
return _getQualifiedName((Void)null, (Void)null);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unhandled parameter types: " +
|
||||
Arrays.<Object>asList(it, context).toString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,367 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2014, 2016 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 com.google.common.base.Objects;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.inject.Inject;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.EClass;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.emf.ecore.EPackage;
|
||||
import org.eclipse.emf.ecore.EReference;
|
||||
import org.eclipse.emf.ecore.EcoreFactory;
|
||||
import org.eclipse.emf.ecore.EcorePackage;
|
||||
import org.eclipse.emf.ecore.InternalEObject;
|
||||
import org.eclipse.emf.ecore.resource.Resource;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.emf.ecore.util.EcoreUtil;
|
||||
import org.eclipse.xtend.lib.annotations.Data;
|
||||
import org.eclipse.xtext.naming.QualifiedName;
|
||||
import org.eclipse.xtext.resource.IEObjectDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions;
|
||||
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider;
|
||||
import org.eclipse.xtext.resource.persistence.StorageAwareResource;
|
||||
import org.eclipse.xtext.scoping.IGlobalScopeProvider;
|
||||
import org.eclipse.xtext.scoping.IScope;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function1;
|
||||
import org.eclipse.xtext.xbase.lib.Functions.Function2;
|
||||
import org.eclipse.xtext.xbase.lib.IterableExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
|
||||
|
||||
/**
|
||||
* Portable URIs are based on names and therefore are independent of the concrete file pathes and fuile names the
|
||||
* of resources.
|
||||
*
|
||||
* A portable URI is really a resource URI to the client URI and a fragment that contains the information to retrieve the
|
||||
* referenced element using the global scoping. That is it contains
|
||||
* <ul>
|
||||
* <li>the qualified name of a container of the target element
|
||||
* <li>the type of that container
|
||||
* <li>the path from that container to the actual target element
|
||||
* </ul>
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class PortableURIs {
|
||||
@Data
|
||||
public static class PortableFragmentDescription {
|
||||
private final EClass descriptionEClass;
|
||||
|
||||
private final QualifiedName descriptionQualifiedName;
|
||||
|
||||
private final String descriptionRelativeFragment;
|
||||
|
||||
public PortableFragmentDescription(final EClass descriptionEClass, final QualifiedName descriptionQualifiedName, final String descriptionRelativeFragment) {
|
||||
super();
|
||||
this.descriptionEClass = descriptionEClass;
|
||||
this.descriptionQualifiedName = descriptionQualifiedName;
|
||||
this.descriptionRelativeFragment = descriptionRelativeFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.descriptionEClass== null) ? 0 : this.descriptionEClass.hashCode());
|
||||
result = prime * result + ((this.descriptionQualifiedName== null) ? 0 : this.descriptionQualifiedName.hashCode());
|
||||
return prime * result + ((this.descriptionRelativeFragment== null) ? 0 : this.descriptionRelativeFragment.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PortableURIs.PortableFragmentDescription other = (PortableURIs.PortableFragmentDescription) obj;
|
||||
if (this.descriptionEClass == null) {
|
||||
if (other.descriptionEClass != null)
|
||||
return false;
|
||||
} else if (!this.descriptionEClass.equals(other.descriptionEClass))
|
||||
return false;
|
||||
if (this.descriptionQualifiedName == null) {
|
||||
if (other.descriptionQualifiedName != null)
|
||||
return false;
|
||||
} else if (!this.descriptionQualifiedName.equals(other.descriptionQualifiedName))
|
||||
return false;
|
||||
if (this.descriptionRelativeFragment == null) {
|
||||
if (other.descriptionRelativeFragment != null)
|
||||
return false;
|
||||
} else if (!this.descriptionRelativeFragment.equals(other.descriptionRelativeFragment))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Pure
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this);
|
||||
b.add("descriptionEClass", this.descriptionEClass);
|
||||
b.add("descriptionQualifiedName", this.descriptionQualifiedName);
|
||||
b.add("descriptionRelativeFragment", this.descriptionRelativeFragment);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Pure
|
||||
public EClass getDescriptionEClass() {
|
||||
return this.descriptionEClass;
|
||||
}
|
||||
|
||||
@Pure
|
||||
public QualifiedName getDescriptionQualifiedName() {
|
||||
return this.descriptionQualifiedName;
|
||||
}
|
||||
|
||||
@Pure
|
||||
public String getDescriptionRelativeFragment() {
|
||||
return this.descriptionRelativeFragment;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String PORTABLE_SCHEME = "portable";
|
||||
|
||||
@Inject
|
||||
private IGlobalScopeProvider globalScopeProvider;
|
||||
|
||||
@Inject
|
||||
private EPackage.Registry packageRegistry;
|
||||
|
||||
@Inject
|
||||
private ResourceDescriptionsProvider resourceDescriptionsProvider;
|
||||
|
||||
/**
|
||||
* @return whether the given string is a portable URI fragment
|
||||
*/
|
||||
public boolean isPortableURIFragment(final String uriFragment) {
|
||||
return uriFragment.startsWith(PortableURIs.PORTABLE_SCHEME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a given portable URI fragment against the given resource.
|
||||
*
|
||||
* @param resource the resource from which global scope to look up the EObject
|
||||
* @param portableFragment the portable fragment pointing to the to be resolved EObject
|
||||
*
|
||||
* @return the EObject for the given portableURIFragment
|
||||
*/
|
||||
public EObject resolve(final StorageAwareResource resource, final String portableFragment) {
|
||||
final PortableURIs.PortableFragmentDescription desc = this.fromFragmentString(portableFragment);
|
||||
final EReference mock = EcoreFactory.eINSTANCE.createEReference();
|
||||
mock.setEType(desc.descriptionEClass);
|
||||
final IScope scope = this.globalScopeProvider.getScope(resource, mock, Predicates.<IEObjectDescription>alwaysTrue());
|
||||
final IEObjectDescription description = IterableExtensions.<IEObjectDescription>head(scope.getElements(desc.descriptionQualifiedName));
|
||||
if ((description == null)) {
|
||||
return null;
|
||||
}
|
||||
final EObject container = EcoreUtil.resolve(description.getEObjectOrProxy(), resource);
|
||||
return this.getEObject(container, desc.descriptionRelativeFragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a portable URI from the given resource to the targetURI.
|
||||
* Returns <code>null</code> is no portable URI can be constructed, which is the case if the
|
||||
* targetObject is not itself exported or is a child of an exported EObject.
|
||||
*
|
||||
* @param sourceResource the resource from which the EObject should later be resolved
|
||||
* @param targetURI the target URI that should be resolvable by the created portable URI
|
||||
*
|
||||
* @return a portable URI or <code>null</code>
|
||||
*/
|
||||
public URI toPortableURI(final StorageAwareResource sourceResource, final URI targetURI) {
|
||||
Resource _resource = sourceResource.getResourceSet().getResource(targetURI.trimFragment(), false);
|
||||
EObject _eObject = null;
|
||||
if (_resource!=null) {
|
||||
_eObject=_resource.getEObject(targetURI.fragment());
|
||||
}
|
||||
final EObject to = _eObject;
|
||||
boolean _or = false;
|
||||
if ((to == null)) {
|
||||
_or = true;
|
||||
} else {
|
||||
Resource _eResource = to.eResource();
|
||||
ResourceSet _resourceSet = null;
|
||||
if (_eResource!=null) {
|
||||
_resourceSet=_eResource.getResourceSet();
|
||||
}
|
||||
boolean _tripleNotEquals = (_resourceSet != null);
|
||||
_or = _tripleNotEquals;
|
||||
}
|
||||
if (_or) {
|
||||
final URI result = this.toPortableURI(sourceResource, to);
|
||||
if ((result != null)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a portable URI from the global scope.
|
||||
* Returns <code>null</code> is no portable URI can be constructed, which is the case if the
|
||||
* targetObject is not itself exported or is a child of an exported EObject.
|
||||
*
|
||||
* @param sourceResource the resource from which the EObject should later be resolved
|
||||
* @param targetObject the target object that should be resolvable by the created portable URI
|
||||
*
|
||||
* @return a portable URI or <code>null</code>
|
||||
*/
|
||||
public URI toPortableURI(final StorageAwareResource sourceResource, final EObject targetObject) {
|
||||
if (((targetObject == null) || targetObject.eIsProxy())) {
|
||||
return sourceResource.getURI().appendFragment(StorageAwareResource.UNRESOLVABLE_FRAGMENT);
|
||||
}
|
||||
final String portableFragment = this.getPortableURIFragment(targetObject);
|
||||
if ((portableFragment != null)) {
|
||||
return sourceResource.getURI().appendFragment(portableFragment);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a portable URI fragment, or <code>null</code> if the give EObject isn't itself or is not contained in an exported EObjectDescription
|
||||
*/
|
||||
protected String getPortableURIFragment(final EObject obj) {
|
||||
final IResourceDescriptions descriptions = this.resourceDescriptionsProvider.getResourceDescriptions(obj.eResource());
|
||||
final IResourceDescription desc = descriptions.getResourceDescription(obj.eResource().getURI());
|
||||
if ((desc == null)) {
|
||||
return null;
|
||||
}
|
||||
final Function1<IEObjectDescription, Boolean> _function = (IEObjectDescription it) -> {
|
||||
boolean _xblockexpression = false;
|
||||
{
|
||||
final EObject possibleContainer = EcoreUtil.resolve(it.getEObjectOrProxy(), obj.eResource());
|
||||
_xblockexpression = (Objects.equal(obj, possibleContainer) || EcoreUtil.isAncestor(obj, possibleContainer));
|
||||
}
|
||||
return Boolean.valueOf(_xblockexpression);
|
||||
};
|
||||
final IEObjectDescription containerDesc = IterableExtensions.<IEObjectDescription>findFirst(desc.getExportedObjects(), _function);
|
||||
if ((containerDesc != null)) {
|
||||
final PortableURIs.PortableFragmentDescription fragmentDescription = this.createPortableFragmentDescription(containerDesc, obj);
|
||||
return this.toFragmentString(fragmentDescription);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected PortableURIs.PortableFragmentDescription createPortableFragmentDescription(final IEObjectDescription desc, final EObject target) {
|
||||
final EObject possibleContainer = EcoreUtil.resolve(desc.getEObjectOrProxy(), target);
|
||||
final String fragmentToTarget = this.getFragment(target, possibleContainer);
|
||||
EClass _eClass = desc.getEClass();
|
||||
QualifiedName _qualifiedName = desc.getQualifiedName();
|
||||
return new PortableURIs.PortableFragmentDescription(_eClass, _qualifiedName, fragmentToTarget);
|
||||
}
|
||||
|
||||
protected String toFragmentString(final PortableURIs.PortableFragmentDescription desc) {
|
||||
final String eclassUriAsString = URI.encodeFragment(EcoreUtil.getURI(desc.descriptionEClass).toString(), false);
|
||||
final List<String> segments = desc.descriptionQualifiedName.getSegments();
|
||||
String _encodeFragment = URI.encodeFragment(IterableExtensions.join(segments, ":"), false);
|
||||
String uriFragment = ((((PortableURIs.PORTABLE_SCHEME + "#") + eclassUriAsString) + "#") + _encodeFragment);
|
||||
if ((desc.descriptionRelativeFragment != null)) {
|
||||
String _uriFragment = uriFragment;
|
||||
String _encodeFragment_1 = URI.encodeFragment(desc.descriptionRelativeFragment, false);
|
||||
String _plus = ("#" + _encodeFragment_1);
|
||||
uriFragment = (_uriFragment + _plus);
|
||||
}
|
||||
return uriFragment;
|
||||
}
|
||||
|
||||
protected PortableURIs.PortableFragmentDescription fromFragmentString(final String fragmentString) {
|
||||
final Iterator<String> segments = Splitter.on("#").split(fragmentString).iterator();
|
||||
segments.next();
|
||||
final URI eClassURI = URI.createURI(URI.decode(segments.next()));
|
||||
final EPackage ePackage = this.packageRegistry.getEPackage(eClassURI.trimFragment().toString());
|
||||
Resource _eResource = null;
|
||||
if (ePackage!=null) {
|
||||
_eResource=ePackage.eResource();
|
||||
}
|
||||
EObject _eObject = null;
|
||||
if (_eResource!=null) {
|
||||
_eObject=_eResource.getEObject(eClassURI.fragment());
|
||||
}
|
||||
final EClass eClass = ((EClass) _eObject);
|
||||
final QualifiedName qname = QualifiedName.create(IterableExtensions.<String>toList(Splitter.on(":").split(URI.decode(segments.next()))));
|
||||
String _xifexpression = null;
|
||||
boolean _hasNext = segments.hasNext();
|
||||
if (_hasNext) {
|
||||
_xifexpression = URI.decode(segments.next());
|
||||
}
|
||||
final String fragment = _xifexpression;
|
||||
EClass _elvis = null;
|
||||
if (eClass != null) {
|
||||
_elvis = eClass;
|
||||
} else {
|
||||
_elvis = EcorePackage.Literals.EOBJECT;
|
||||
}
|
||||
return new PortableURIs.PortableFragmentDescription(_elvis, qname, fragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a fragment to the child relative from the given container.
|
||||
*
|
||||
* @param fromContainer the container EObject from which the fragment path is computed
|
||||
* @param toChild the target EObject which can be found using the fromContainer and resulting fragment path
|
||||
*
|
||||
* @return a fragment path from the given container to the child, or <code>null</null> is fromContainer == toChild
|
||||
*
|
||||
* @see #getEObject(EObject,String)
|
||||
*/
|
||||
public String getFragment(final EObject fromContainer, final EObject toChild) {
|
||||
boolean _equals = Objects.equal(fromContainer, toChild);
|
||||
if (_equals) {
|
||||
return null;
|
||||
}
|
||||
InternalEObject lastChild = ((InternalEObject) toChild);
|
||||
InternalEObject lastContainer = lastChild.eInternalContainer();
|
||||
String result = lastContainer.eURIFragmentSegment(lastChild.eContainingFeature(), lastChild);
|
||||
while (((lastContainer != null) && (!Objects.equal(fromContainer, lastContainer)))) {
|
||||
{
|
||||
lastChild = lastContainer;
|
||||
lastContainer = lastContainer.eInternalContainer();
|
||||
if ((lastContainer == null)) {
|
||||
throw new IllegalStateException(("No more containers for element " + lastChild));
|
||||
}
|
||||
String _eURIFragmentSegment = lastContainer.eURIFragmentSegment(lastChild.eContainingFeature(), lastChild);
|
||||
String _plus = (_eURIFragmentSegment + "/");
|
||||
String _plus_1 = (_plus + result);
|
||||
result = _plus_1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds an EObject for the given context EObject and fragment.
|
||||
*
|
||||
* @param from the EObject from which the path should be resolved
|
||||
* @param toFragment the fragment
|
||||
*
|
||||
* @return the resolved EObject based. If the given fragment is <code>null</null>, the given EObject itself will be returned.
|
||||
*/
|
||||
public EObject getEObject(final EObject from, final String toFragment) {
|
||||
if ((toFragment == null)) {
|
||||
return from;
|
||||
}
|
||||
final Iterable<String> splitted = Splitter.on("/").split(toFragment);
|
||||
final Function2<EObject, String, EObject> _function = (EObject $0, String $1) -> {
|
||||
return ((InternalEObject) $0).eObjectForURIFragmentSegment($1);
|
||||
};
|
||||
return IterableExtensions.<String, EObject>fold(splitted, from, _function);
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2014 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 com.google.common.base.Objects;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.xtext.resource.persistence.ResourceStorageLoadable;
|
||||
import org.eclipse.xtext.resource.persistence.StorageAwareResource;
|
||||
|
||||
/**
|
||||
* An adapter that can be installed into a SerializableResource,
|
||||
* to provide resource state. It is used with dirty editors providing the dirty non persisted
|
||||
* state to other editors.
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class ResourceStorageProviderAdapter extends AdapterImpl {
|
||||
@Override
|
||||
public boolean isAdapterForType(final Object type) {
|
||||
return Objects.equal(type, ResourceStorageProviderAdapter.class);
|
||||
}
|
||||
|
||||
public ResourceStorageLoadable getResourceStorageLoadable(final StorageAwareResource resource) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2014 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 com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import org.eclipse.emf.common.notify.Adapter;
|
||||
import org.eclipse.emf.common.notify.impl.AdapterImpl;
|
||||
import org.eclipse.emf.common.util.EList;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.resource.ResourceSet;
|
||||
import org.eclipse.xtend.lib.annotations.Accessors;
|
||||
import org.eclipse.xtext.xbase.lib.IterableExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
|
||||
|
||||
/**
|
||||
* An adapter to be installed into a ResourceSet.
|
||||
*
|
||||
* It's used as a protocol to tell whether a StorageAwareResource
|
||||
* should load from source or could load from serialized data.
|
||||
*
|
||||
* @see ResourceStorageProviderAdapter
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class SourceLevelURIsAdapter extends AdapterImpl {
|
||||
@Accessors
|
||||
private Set<URI> sourceLevelURIs;
|
||||
|
||||
public Set<URI> getSourceLevelURIs() {
|
||||
return Collections.<URI>unmodifiableSet(this.sourceLevelURIs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdapterForType(final Object type) {
|
||||
return Objects.equal(type, SourceLevelURIsAdapter.class);
|
||||
}
|
||||
|
||||
public static void setSourceLevelUris(final ResourceSet resourceSet, final Collection<URI> uris) {
|
||||
final SourceLevelURIsAdapter adapter = SourceLevelURIsAdapter.findOrCreateAdapter(resourceSet);
|
||||
adapter.sourceLevelURIs = ImmutableSet.<URI>copyOf(uris);
|
||||
}
|
||||
|
||||
protected static SourceLevelURIsAdapter findOrCreateAdapter(final ResourceSet resourceSet) {
|
||||
SourceLevelURIsAdapter _elvis = null;
|
||||
SourceLevelURIsAdapter _findInstalledAdapter = SourceLevelURIsAdapter.findInstalledAdapter(resourceSet);
|
||||
if (_findInstalledAdapter != null) {
|
||||
_elvis = _findInstalledAdapter;
|
||||
} else {
|
||||
SourceLevelURIsAdapter _sourceLevelURIsAdapter = new SourceLevelURIsAdapter();
|
||||
final Procedure1<SourceLevelURIsAdapter> _function = (SourceLevelURIsAdapter it) -> {
|
||||
EList<Adapter> _eAdapters = resourceSet.eAdapters();
|
||||
_eAdapters.add(it);
|
||||
};
|
||||
SourceLevelURIsAdapter _doubleArrow = ObjectExtensions.<SourceLevelURIsAdapter>operator_doubleArrow(_sourceLevelURIsAdapter, _function);
|
||||
_elvis = _doubleArrow;
|
||||
}
|
||||
return _elvis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the given set of URIs as the source level URIs. Does not copy the given
|
||||
* set but uses it directly.
|
||||
*/
|
||||
public static void setSourceLevelUrisWithoutCopy(final ResourceSet resourceSet, final Set<URI> uris) {
|
||||
final SourceLevelURIsAdapter adapter = SourceLevelURIsAdapter.findOrCreateAdapter(resourceSet);
|
||||
adapter.sourceLevelURIs = uris;
|
||||
}
|
||||
|
||||
public static SourceLevelURIsAdapter findInstalledAdapter(final ResourceSet resourceSet) {
|
||||
return IterableExtensions.<SourceLevelURIsAdapter>head(Iterables.<SourceLevelURIsAdapter>filter(resourceSet.eAdapters(), SourceLevelURIsAdapter.class));
|
||||
}
|
||||
|
||||
public void setSourceLevelURIs(final Set<URI> sourceLevelURIs) {
|
||||
this.sourceLevelURIs = sourceLevelURIs;
|
||||
}
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2014, 2017 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 com.google.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtend.lib.annotations.AccessorType;
|
||||
import org.eclipse.xtend.lib.annotations.Accessors;
|
||||
import org.eclipse.xtext.linking.lazy.LazyLinkingResource;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.persistence.IResourceStorageFacade;
|
||||
import org.eclipse.xtext.resource.persistence.PortableURIs;
|
||||
import org.eclipse.xtext.resource.persistence.ResourceStorageLoadable;
|
||||
import org.eclipse.xtext.util.internal.Stopwatches;
|
||||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
import org.eclipse.xtext.xbase.lib.Pure;
|
||||
|
||||
/**
|
||||
* A resource implementation that can load itself from ResourceStorage.
|
||||
*
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class StorageAwareResource extends LazyLinkingResource {
|
||||
public static final String UNRESOLVABLE_FRAGMENT = "UNRESOLVABLE";
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(StorageAwareResource.class);
|
||||
|
||||
@Accessors(AccessorType.PUBLIC_GETTER)
|
||||
@Inject(optional = true)
|
||||
private IResourceStorageFacade resourceStorageFacade;
|
||||
|
||||
@Accessors(AccessorType.PUBLIC_GETTER)
|
||||
@Inject
|
||||
private PortableURIs portableURIs;
|
||||
|
||||
@Accessors
|
||||
private boolean isLoadedFromStorage = false;
|
||||
|
||||
@Accessors
|
||||
private IResourceDescription resourceDescription = null;
|
||||
|
||||
@Override
|
||||
public void load(final Map<?, ?> options) throws IOException {
|
||||
if (((((!this.isLoaded) && (!this.isLoading)) && (this.resourceStorageFacade != null)) && this.resourceStorageFacade.shouldLoadFromStorage(this))) {
|
||||
boolean _isDebugEnabled = StorageAwareResource.LOG.isDebugEnabled();
|
||||
if (_isDebugEnabled) {
|
||||
URI _uRI = this.getURI();
|
||||
String _plus = ("Loading " + _uRI);
|
||||
String _plus_1 = (_plus + " from storage.");
|
||||
StorageAwareResource.LOG.debug(_plus_1);
|
||||
}
|
||||
try {
|
||||
final ResourceStorageLoadable in = this.resourceStorageFacade.getOrCreateResourceStorageLoadable(this);
|
||||
this.loadFromStorage(in);
|
||||
return;
|
||||
} catch (final Throwable _t) {
|
||||
if (_t instanceof IOException) {
|
||||
if (this.contents!=null) {
|
||||
this.contents.clear();
|
||||
}
|
||||
if (this.eAdapters!=null) {
|
||||
this.eAdapters.clear();
|
||||
}
|
||||
this.unload();
|
||||
} else {
|
||||
throw Exceptions.sneakyThrow(_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.load(options);
|
||||
}
|
||||
|
||||
public void loadFromStorage(final ResourceStorageLoadable storageInputStream) throws IOException {
|
||||
if ((storageInputStream == null)) {
|
||||
throw new NullPointerException("storageInputStream");
|
||||
}
|
||||
final Stopwatches.StoppedTask task = Stopwatches.forTask("Loading from storage");
|
||||
task.start();
|
||||
this.isLoading = true;
|
||||
this.isLoadedFromStorage = true;
|
||||
try {
|
||||
storageInputStream.loadIntoResource(this);
|
||||
this.isLoaded = true;
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
task.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doUnload() {
|
||||
super.doUnload();
|
||||
this.isLoadedFromStorage = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearInternalState() {
|
||||
this.isLoadedFromStorage = false;
|
||||
super.clearInternalState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized EObject getEObject(final String uriFragment) {
|
||||
EObject _xblockexpression = null;
|
||||
{
|
||||
boolean _isPortableURIFragment = this.portableURIs.isPortableURIFragment(uriFragment);
|
||||
if (_isPortableURIFragment) {
|
||||
return this.portableURIs.resolve(this, uriFragment);
|
||||
}
|
||||
_xblockexpression = super.getEObject(uriFragment);
|
||||
}
|
||||
return _xblockexpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> getUnresolvableURIFragments() {
|
||||
if (this.isLoadedFromStorage) {
|
||||
return Collections.<String>unmodifiableSet(CollectionLiterals.<String>newHashSet(StorageAwareResource.UNRESOLVABLE_FRAGMENT));
|
||||
} else {
|
||||
return super.getUnresolvableURIFragments();
|
||||
}
|
||||
}
|
||||
|
||||
@Pure
|
||||
public IResourceStorageFacade getResourceStorageFacade() {
|
||||
return this.resourceStorageFacade;
|
||||
}
|
||||
|
||||
@Pure
|
||||
public PortableURIs getPortableURIs() {
|
||||
return this.portableURIs;
|
||||
}
|
||||
|
||||
@Pure
|
||||
public boolean isLoadedFromStorage() {
|
||||
return this.isLoadedFromStorage;
|
||||
}
|
||||
|
||||
public void setIsLoadedFromStorage(final boolean isLoadedFromStorage) {
|
||||
this.isLoadedFromStorage = isLoadedFromStorage;
|
||||
}
|
||||
|
||||
@Pure
|
||||
public IResourceDescription getResourceDescription() {
|
||||
return this.resourceDescription;
|
||||
}
|
||||
|
||||
public void setResourceDescription(final IResourceDescription resourceDescription) {
|
||||
this.resourceDescription = resourceDescription;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2014, 2016 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 org.eclipse.emf.ecore.resource.Resource;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionManager;
|
||||
import org.eclipse.xtext.resource.persistence.StorageAwareResource;
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
*
|
||||
* @since 2.8
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class StorageAwareResourceDescriptionManager extends DefaultResourceDescriptionManager {
|
||||
@Override
|
||||
public IResourceDescription getResourceDescription(final Resource resource) {
|
||||
IResourceDescription _switchResult = null;
|
||||
boolean _matched = false;
|
||||
if (resource instanceof StorageAwareResource) {
|
||||
IResourceDescription _resourceDescription = ((StorageAwareResource)resource).getResourceDescription();
|
||||
boolean _tripleNotEquals = (_resourceDescription != null);
|
||||
if (_tripleNotEquals) {
|
||||
_matched=true;
|
||||
_switchResult = ((StorageAwareResource)resource).getResourceDescription();
|
||||
}
|
||||
}
|
||||
if (!_matched) {
|
||||
_switchResult = super.getResourceDescription(resource);
|
||||
}
|
||||
return _switchResult;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue