/**
* Copyright (c) 2011 - 2015, Lunifera GmbH (Gross Enzersdorf), Loetz KG (Heidelberg)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.lunifera.dsl.xtext.lazyresolver;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.xtext.common.types.JvmTypeReference;
/**
* A helper class to register jvmLinkingReferences.
*/
public class LazyJvmTypeLinkingHelper {
private Map<EReference, Set<EReference>> linkMappings = new HashMap<EReference, Set<EReference>>();
private Map<EReference, IJvmLinkCrossRefStringEnhancer> jvmLinkToEnhancers = new HashMap<EReference, IJvmLinkCrossRefStringEnhancer>();
private Map<EReference, IJvmTypeRefFinisher> jvmLinkToFinisher = new HashMap<EReference, IJvmTypeRefFinisher>();
private Set<EReference> jvmLinks = new HashSet<EReference>();
public LazyJvmTypeLinkingHelper() {
}
/**
* Registers a jvmTypeReference for a given semanticReference.
*
* @param semanticReference
* @param jvmTypeReference
* @return
*/
public EReference register(EReference semanticReference,
EReference jvmTypeReference) {
return register(semanticReference, jvmTypeReference, null, null);
}
/**
* Registers a jvmTypeReference for a given semanticReference.
*
* @param semanticReference
* @param jvmTypeReference
* @param enhancer
* @return
*/
public EReference register(EReference semanticReference,
EReference jvmTypeReference,
IJvmLinkCrossRefStringEnhancer enhancer,
IJvmTypeRefFinisher finisher) {
Set<EReference> links = linkMappings.get(semanticReference);
if (links == null) {
links = new HashSet<EReference>();
linkMappings.put(semanticReference, links);
}
links.add(jvmTypeReference);
jvmLinks.add(jvmTypeReference);
if (enhancer != null) {
jvmLinkToEnhancers.put(jvmTypeReference, enhancer);
}
if (finisher != null) {
jvmLinkToFinisher.put(jvmTypeReference, finisher);
}
return jvmTypeReference;
}
/**
* Returns true, if the semanticReference needs jvmLinking
*
* @param semanticReference
* @return
*/
public boolean needsJvmLinking(EReference semanticReference) {
return linkMappings.containsKey(semanticReference);
}
/**
* Returns true, if the given reference is a jvmLink
*
* @param reference
* @return
*/
public boolean isJvmLink(EStructuralFeature feature) {
if (feature instanceof EReference) {
return jvmLinks.contains(feature);
} else {
return false;
}
}
/**
* Returns the enhancer for the given feature.
*
* @param feature
* @return
*/
public IJvmLinkCrossRefStringEnhancer getEnhancer(EStructuralFeature feature) {
return jvmLinkToEnhancers.get(feature);
}
/**
* Returns the finisher for the given feature.
*
* @param feature
* @return
*/
public IJvmTypeRefFinisher getFinisher(EStructuralFeature feature) {
return jvmLinkToFinisher.get(feature);
}
/**
* Returns the jvmLinkingReference for the given semanticReference.
*
* @param semanticReference
* @return
*/
public Set<EReference> getJvmLinkingReferences(EReference semanticReference) {
return linkMappings.get(semanticReference);
}
/**
* The JvmLinks are a helper construct to provide proper proxies. But in
* some cases the cross reference String that is used for scoping needs to
* be enhanced. For instance if a DTO mapper is queried. The naming
* convention defines, that a mapper is called "{DTO-FQN}Mapper". So the
* jvmLink-proxy from LDto#mapperJvmType needs to become resolved with the
* name of the mapper.
*/
public interface IJvmLinkCrossRefStringEnhancer {
/**
* Returns the crossRefString to be used.
* <p>
* Example: given "ItemDTO" and returned "ItemDTOMapper".
*
* @param context
* @param feature
* @param crossRefString
* @return
*/
String enhance(EObject context, EStructuralFeature feature,
String crossRefString);
}
/**
* The JvmHelperProxies will be validated by Xbase. So it is necessary to
* add type arguments to raw types. This finisher gives access to the
* created {@link JvmTypeReference}.
*/
public interface IJvmTypeRefFinisher {
/**
* Allows to manipulate the created type reference.
*
* @param jvmLinkFeature
* @param typeRef
*/
void finish(EStructuralFeature jvmLinkFeature, JvmTypeReference typeRef);
}
}