All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.xsemantics.runtime.XsemanticsCacheDefaultImpl Maven / Gradle / Ivy

There is a newer version: 1.12.1
Show newest version
package it.xsemantics.runtime;

import it.xsemantics.runtime.caching.util.XsemanticsCacheUtils;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.xtext.util.IResourceScopeCache;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.Pair;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

/**
 * Default implementation of {@link XsemanticsCache}, using a
 * {@link IResourceScopeCache}.
 * 
 * @author Lorenzo Bettini
 * 
 * @since 1.8
 */
@Singleton
public class XsemanticsCacheDefaultImpl implements XsemanticsCache {
	
	@Inject private IResourceScopeCache cache;
	
	@Inject private XsemanticsCacheUtils cacheUtils;
	
	/**
	 * @since 1.8
	 */
	protected String cachedString = "cached:";
	
	private List listeners = new ArrayList();

	@Override
	public  T get(String methodName, RuleEnvironment environment, RuleApplicationTrace trace, 
			XsemanticsProvider provider, Object...elements) {
		XsemanticsCachedData cached = internalGet(methodName, provider, elements);
		
		if (!provider.isCalled()) {
			for (XsemanticsCacheListener l : listeners) {
				l.cacheHit(cached);
			}

			// update the additional arguments with cached data
			if (environment != null && environment != cached.getEnvironment()) {
				environment.increment(cached.getEnvironment());
			}
			
			if (trace != null && trace != cached.getTrace()) {
				trace.addToTrace(cachedString);
				if (cached.getTrace() != null) {
					trace.addObjectAsSubtrace(lastElementNotTrace(cached.getTrace()));
				}
			}
		} else {
			cached.setName(methodName);

			for (XsemanticsCacheListener l : listeners) {
				l.cacheMissed(cached);
			}
		}

		return cached.getResult();
	}
	
	protected  T internalGet(String methodName, Provider provider,
			Object... elements) {
		return cache. get(
				Pair. of(methodName, cacheUtils.getKeys(elements)),
				cacheUtils.getResource(elements), provider);
	}

	@Override
	public void addListener(final XsemanticsCacheListener l) {
		this.listeners.add(l);
	}

	@Override
	public void removeListener(final XsemanticsCacheListener l) {
		this.listeners.remove(l);
	}
	
	private Object lastElementNotTrace(final RuleApplicationTrace trace) {
		// this is copied from TraceUtils, otherwise Sonarqube 5 reports
		// a dependency cycle because it uses source folders instead of
		// Java packages.
		return IterableExtensions. findLast(trace.trace, new Function1() {
			@Override
			public Boolean apply(final Object it) {
				return Boolean.valueOf(!(it instanceof RuleApplicationTrace));
			}
		});
	}
}