/* * Copyright 2009-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.groovy.eclipse.dsl; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.codehaus.jdt.groovy.model.GroovyNature; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.IJavaProject; /** * Singleton class that holds the {@link DSLDStore}s for all Groovy projects. * * @author andrew * @created Nov 17, 2010 */ public class DSLDStoreManager { private final Map<String, DSLDStore> projectDSLDMap; private final Set<String> inProgress = new HashSet<String>(); public DSLDStoreManager() { projectDSLDMap = new HashMap<String, DSLDStore>(); } public DSLDStore getDSLDStore(IJavaProject project) { return getDSLDStore(project.getElementName()); } public DSLDStore getDSLDStore(IProject project) { return getDSLDStore(project.getName()); } public DSLDStore getDSLDStore(String projectName) { DSLDStore contextStore = projectDSLDMap.get(projectName); if (contextStore == null) { contextStore = new DSLDStore(); projectDSLDMap.put(projectName, contextStore); } return contextStore; } public void clearDSLDStore(IProject project) { projectDSLDMap.remove(project.getName()); } public void clearDSLDStore(IJavaProject project) { projectDSLDMap.remove(project.getElementName()); } public void reset() { projectDSLDMap.clear(); } public boolean hasDSLDStoreFor(IProject project) { return projectDSLDMap.containsKey(project.getName()); } public List<String> getAllStores() { return new ArrayList<String>(projectDSLDMap.keySet()); } public void initializeAll(boolean synchronous) { if (GroovyDSLCoreActivator.getDefault().isDSLDDisabled()) { return; } IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); initialize(allProjects, synchronous); } public void initialize(IProject[] projects, boolean synchronous) { initialize(Arrays.asList(projects), synchronous); } public void initialize(IProject project, boolean synchronous) { initialize(Collections.singletonList(project), synchronous); } public void initialize(List<IProject> projects, boolean synchronous) { List<IProject> groovyProjects = new ArrayList<IProject>(projects.size()); for (IProject project : projects) { if (GroovyNature.hasGroovyNature(project)) { groovyProjects.add(project); } } @SuppressWarnings("deprecation") Job refreshJob = new RefreshDSLDJob(groovyProjects); refreshJob.setPriority(synchronous ? Job.INTERACTIVE : Job.LONG); refreshJob.schedule(); if (synchronous) { waitForFinish(); } } public void ensureInitialized(IProject project, boolean synchronous) { if (!hasDSLDStoreFor(project) && !isInProgress(project)) { initialize(project, synchronous); } } private final static int TIME_LIMIT = 30000; synchronized void waitForFinish() { long end = System.currentTimeMillis() + TIME_LIMIT; while (!inProgress.isEmpty()) { try { long timeLeft = end - System.currentTimeMillis(); if (timeLeft > 0) { wait(timeLeft); } else { // GroovyDSLCoreActivator.logException("Avoiding potential deadlock", new RuntimeException()); break; } } catch (InterruptedException e) { } } } synchronized boolean isInProgress(IProject project) { return inProgress.contains(project.getName()); } private synchronized boolean addInProgress(IProject project) { return inProgress.add(project.getName()); } synchronized List<IProject> addInProgress(List<IProject> projects) { List<IProject> addedProjects = new ArrayList<IProject>(projects.size()); for (IProject project : projects) { if (addInProgress(project)) { addedProjects.add(project); } } return addedProjects; } synchronized void removeInProgress(IProject project) { inProgress.remove(project.getName()); notifyAll(); } }