/**
* <copyright>
* </copyright>
*
*
*/
package ssl.resource.ssl.analysis;
public class SslDefaultResolverDelegate<ContainerType extends org.eclipse.emf.ecore.EObject, ReferenceType extends org.eclipse.emf.ecore.EObject> {
private static class ReferenceCache implements ssl.resource.ssl.ISslReferenceCache, org.eclipse.emf.common.notify.Adapter {
private java.util.Map<String, Object> cache = new java.util.LinkedHashMap<String, Object>();
private org.eclipse.emf.common.notify.Notifier target;
public org.eclipse.emf.common.notify.Notifier getTarget() {
return target;
}
public boolean isAdapterForType(Object arg0) {
return false;
}
public void notifyChanged(org.eclipse.emf.common.notify.Notification arg0) {
}
public void setTarget(org.eclipse.emf.common.notify.Notifier arg0) {
target = arg0;
}
public Object get(String identifier) {
return cache.get(identifier);
}
public void put(String identifier, Object newObject) {
cache.put(identifier, newObject);
}
}
public final static String NAME_FEATURE = "name";
/**
* This standard implementation searches the tree for objects of the correct type
* with a name attribute matching the identifier.
*/
protected void resolve(String identifier, ContainerType container, org.eclipse.emf.ecore.EReference reference, int position, boolean resolveFuzzy, ssl.resource.ssl.ISslReferenceResolveResult<ReferenceType> result) {
try {
org.eclipse.emf.ecore.EClass type = reference.getEReferenceType();
org.eclipse.emf.ecore.EObject root = ssl.resource.ssl.util.SslEObjectUtil.findRootContainer(container);
// first check whether the root element matches
boolean continueSearch = checkElement(root, type, identifier, resolveFuzzy, true, result);
if (!continueSearch) {
return;
}
// then check the contents
for (java.util.Iterator<org.eclipse.emf.ecore.EObject> iterator = root.eAllContents(); iterator.hasNext(); ) {
org.eclipse.emf.ecore.EObject element = iterator.next();
continueSearch = checkElement(element, type, identifier, resolveFuzzy, true, result);
if (!continueSearch) {
return;
}
}
org.eclipse.emf.ecore.resource.Resource resource = container.eResource();
if (resource != null) {
org.eclipse.emf.common.util.URI uri = getURI(identifier, resource.getURI());
if (uri != null) {
org.eclipse.emf.ecore.EObject element = loadResource(container.eResource().getResourceSet(), uri);
if (element == null) {
return;
}
checkElement(element, type, identifier, resolveFuzzy, false, result);
}
}
} catch (java.lang.RuntimeException rte) {
// catch exception here to prevent EMF proxy resolution from swallowing it
rte.printStackTrace();
}
}
private boolean checkElement(org.eclipse.emf.ecore.EObject element, org.eclipse.emf.ecore.EClass type, String identifier, boolean resolveFuzzy, boolean checkStringWise, ssl.resource.ssl.ISslReferenceResolveResult<ReferenceType> result) {
if (element.eIsProxy()) {
return true;
}
boolean hasCorrectType = hasCorrectType(element, type.getInstanceClass());
if (!hasCorrectType) {
return true;
}
String match;
// do not compare string-wise if identifier is a URI
if (checkStringWise) {
match = matches(element, identifier, resolveFuzzy);
} else {
match = identifier;
}
if (match == null) {
return true;
}
// we can safely cast 'element' to 'ReferenceType' here, because we've checked the
// type of 'element' against the type of the reference. unfortunately the compiler
// does not know that this is sufficient, so we must call cast(), which is not
// type safe by itself.
result.addMapping(match, cast(element));
if (!resolveFuzzy) {
return false;
}
return true;
}
/**
* This method encapsulates an unchecked cast from EObject to ReferenceType. We
* cannot do this cast strictly type safe, because type parameters are erased by
* compilation. Thus, an instanceof check cannot be performed at runtime.
*/
@SuppressWarnings("unchecked")
private ReferenceType cast(org.eclipse.emf.ecore.EObject element) {
return (ReferenceType) element;
}
protected String produceDeResolveErrorMessage(org.eclipse.emf.ecore.EObject refObject, org.eclipse.emf.ecore.EObject container, org.eclipse.emf.ecore.EReference reference, ssl.resource.ssl.ISslTextResource resource) {
String msg = getClass().getSimpleName() + ": " + reference.getEType().getName() + " \"" + refObject.toString() + "\" not de-resolveable";
return msg;
}
protected String deResolve(ReferenceType element, ContainerType container, org.eclipse.emf.ecore.EReference reference) {
return getName(element);
}
private String matches(org.eclipse.emf.ecore.EObject element, String identifier, boolean matchFuzzy) {
// first check for attributes that have set the ID flag to true
java.util.List<org.eclipse.emf.ecore.EStructuralFeature> features = element.eClass().getEStructuralFeatures();
for (org.eclipse.emf.ecore.EStructuralFeature feature : features) {
if (feature instanceof org.eclipse.emf.ecore.EAttribute) {
org.eclipse.emf.ecore.EAttribute attribute = (org.eclipse.emf.ecore.EAttribute) feature;
if (attribute.isID()) {
Object attributeValue = element.eGet(attribute);
String match = matches(identifier, attributeValue, matchFuzzy);
if (match != null) {
return match;
}
}
}
}
// then check for an attribute that is called 'name'
org.eclipse.emf.ecore.EStructuralFeature nameAttr = element.eClass().getEStructuralFeature(NAME_FEATURE);
if (nameAttr instanceof org.eclipse.emf.ecore.EAttribute) {
Object attributeValue = element.eGet(nameAttr);
return matches(identifier, attributeValue, matchFuzzy);
} else {
// try any other string attribute found
for (org.eclipse.emf.ecore.EAttribute stringAttribute : element.eClass().getEAllAttributes()) {
if ("java.lang.String".equals(stringAttribute.getEType().getInstanceClassName())) {
Object attributeValue = element.eGet(stringAttribute);
String match = matches(identifier, attributeValue, matchFuzzy);
if (match != null) {
return match;
}
}
}
for (org.eclipse.emf.ecore.EOperation o : element.eClass().getEAllOperations()) {
if (o.getName().toLowerCase().endsWith(NAME_FEATURE) && o.getEParameters().size() == 0 ) {
String result = (String) ssl.resource.ssl.util.SslEObjectUtil.invokeOperation(element, o);
String match = matches(identifier, result, matchFuzzy);
if (match != null) {
return match;
}
}
}
}
return null;
}
private String matches(String identifier, Object attributeValue, boolean matchFuzzy) {
if (attributeValue != null && attributeValue instanceof String) {
String name = (String) attributeValue;
if (name.equals(identifier) || matchFuzzy) {
return name;
}
}
return null;
}
private String getName(ReferenceType element) {
org.eclipse.emf.ecore.EStructuralFeature nameAttr = element.eClass().getEStructuralFeature(NAME_FEATURE);
if(element.eIsProxy()) {
String fragment = ((org.eclipse.emf.ecore.InternalEObject) element).eProxyURI().fragment();
if (fragment != null && fragment.startsWith(ssl.resource.ssl.ISslContextDependentURIFragment.INTERNAL_URI_FRAGMENT_PREFIX)) {
fragment = fragment.substring(ssl.resource.ssl.ISslContextDependentURIFragment.INTERNAL_URI_FRAGMENT_PREFIX.length());
fragment = fragment.substring(fragment.indexOf("_") + 1);
}
return fragment;
}
else if (nameAttr instanceof org.eclipse.emf.ecore.EAttribute) {
return (String) element.eGet(nameAttr);
} else {
// try any other string attribute found
for (org.eclipse.emf.ecore.EAttribute strAttribute : element.eClass().getEAllAttributes()) {
if (!strAttribute.isMany() && strAttribute.getEType().getInstanceClassName().equals("String")) {
return (String) element.eGet(strAttribute);
}
}
for (org.eclipse.emf.ecore.EOperation o : element.eClass().getEAllOperations()) {
if (o.getName().toLowerCase().endsWith(NAME_FEATURE) && o.getEParameters().size() == 0 ) {
String result = (String) ssl.resource.ssl.util.SslEObjectUtil.invokeOperation(element, o);
if (result != null) {
return result;
}
}
}
}
return null;
}
private boolean hasCorrectType(org.eclipse.emf.ecore.EObject element, Class<?> expectedTypeClass) {
return expectedTypeClass.isInstance(element);
}
private org.eclipse.emf.ecore.EObject loadResource(org.eclipse.emf.ecore.resource.ResourceSet resourceSet, org.eclipse.emf.common.util.URI uri) {
try {
org.eclipse.emf.ecore.resource.Resource resource = resourceSet.getResource(uri, true);
org.eclipse.emf.common.util.EList<org.eclipse.emf.ecore.EObject> contents = resource.getContents();
if (contents.size() > 0) {
return contents.get(0);
}
} catch (java.lang.RuntimeException re) {
// do nothing here. if no resource can be loaded the uriString is probably not a
// valid resource URI
}
return null;
}
private org.eclipse.emf.common.util.URI getURI(String identifier, org.eclipse.emf.common.util.URI baseURI) {
if (identifier == null) {
return null;
}
try {
org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createURI(identifier);
if (uri.isRelative()) {
uri = uri.resolve(baseURI);
}
return uri;
} catch (java.lang.IllegalArgumentException iae) {
// the identifier string is not a valid URI
return null;
}
}
protected ssl.resource.ssl.ISslReferenceCache getCache(org.eclipse.emf.ecore.EObject object) {
org.eclipse.emf.ecore.EObject root = ssl.resource.ssl.util.SslEObjectUtil.findRootContainer(object);
java.util.List<org.eclipse.emf.common.notify.Adapter> eAdapters = root.eAdapters();
for (org.eclipse.emf.common.notify.Adapter adapter : eAdapters) {
if (adapter instanceof ReferenceCache) {
ReferenceCache cache = (ReferenceCache) adapter;
return cache;
}
}
ReferenceCache cache = new ReferenceCache();
root.eAdapters().add(cache);
return cache;
}
}