/** * (C) Copyright 2013 Jabylon (http://www.jabylon.org) and others. * * 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 */ package org.jabylon.common.review.internal; import java.util.Collections; import java.util.Locale; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.Service; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.net4j.CDONet4jSession; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.common.util.EList; import org.jabylon.cdo.connector.RepositoryConnector; import org.jabylon.cdo.server.ServerConstants; import org.jabylon.common.review.TerminologyProvider; import org.jabylon.properties.ProjectLocale; import org.jabylon.properties.ProjectVersion; import org.jabylon.properties.Property; import org.jabylon.properties.PropertyFile; import org.jabylon.properties.PropertyFileDescriptor; import org.jabylon.properties.Workspace; import org.jabylon.resources.persistence.PropertyPersistenceService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @Component(enabled=true, immediate=true) @Service(value=TerminologyProvider.class) public class TerminologyProviderImpl extends CacheLoader<Locale, Map<String, Property>> implements TerminologyProvider, Supplier<ProjectVersion> { private LoadingCache<Locale, Map<String, Property>> terminologyCache; private CDONet4jSession session; private CDOView view; private Supplier<ProjectVersion> version; private Logger logger = LoggerFactory.getLogger(getClass()); @Reference(referenceInterface=PropertyPersistenceService.class,bind="setPersistenceService",unbind="unsetPersistenceService",cardinality=ReferenceCardinality.MANDATORY_UNARY) private PropertyPersistenceService propertyPersistence; @Reference(cardinality=ReferenceCardinality.MANDATORY_UNARY) private RepositoryConnector repositoryConnector; @Activate public void activate() { terminologyCache = CacheBuilder.newBuilder().expireAfterAccess(60, TimeUnit.SECONDS).concurrencyLevel(2).build(this); version = Suppliers.memoize((Supplier<ProjectVersion>) this); } protected void setPersistenceService(PropertyPersistenceService persistence) { this.propertyPersistence = persistence; } protected void unsetPersistenceService(PropertyPersistenceService persistence) { this.propertyPersistence = null; } @Override public Map<String, Property> getTerminology(Locale locale) { try { return terminologyCache.get(locale == null ? ProjectLocale.TEMPLATE_LOCALE : locale); } catch (ExecutionException e) { logger.error("Failed to retrieve termininology from cache. Skipping check.",e); return Collections.emptyMap(); } } @Override public Map<String, Property> load(Locale locale) throws Exception { if(version.get()==null){ //recreate the supplier in case we have terminology later version = Suppliers.memoize((Supplier<ProjectVersion>) this); } ProjectVersion projectVersion = version.get(); if(projectVersion!=null){ ProjectLocale projectLocale = projectVersion.getProjectLocale(locale); if(projectLocale!=null) { EList<PropertyFileDescriptor> descriptors = projectLocale.getDescriptors(); if(!descriptors.isEmpty()) { PropertyFileDescriptor descriptor = descriptors.get(0); PropertyFile properties = propertyPersistence.loadProperties(descriptor); return properties.asMap(); } } } return Collections.emptyMap(); } @Override public ProjectVersion get() { if(view==null) return null; CDOResource resource = view.getResource(ServerConstants.WORKSPACE_RESOURCE); Workspace workspace = (Workspace) resource.getContents().get(0); return workspace.getTerminology(); } public void bindRepositoryConnector(RepositoryConnector connector) { session = connector.createSession(); view = connector.openView(session); } public void unbindRepositoryConnector(RepositoryConnector connector) { view.close(); view = null; session.close(); session = null; } @Deactivate public void deactivate() { if(view!=null) view.close(); if(session!=null) session.close(); } }