blob: c3e72ef803138aebcc955166a94767ace8dfc701 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 IBM Corporation 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
*
* Contributors:
* IBM Corporation - initial API and implementation
* yyyymmdd bug Email and other contact information
* -------- -------- -----------------------------------------------------------
* 20060131 121071 rsinha@ca.ibm.com - Rupam Kuehner (initial creation)
*******************************************************************************/
package org.eclipse.jst.ws.internal.consumption.ui.wsrt;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.ws.internal.consumption.common.FacetMatcher;
import org.eclipse.jst.ws.internal.consumption.common.FacetSetsByTemplateCache;
import org.eclipse.jst.ws.internal.consumption.common.FacetUtils;
import org.eclipse.jst.ws.internal.consumption.common.RequiredFacetVersion;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectTemplate;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
public class FacetMatchCache implements IResourceChangeListener
{
//single instance per workbench
private static FacetMatchCache instance_;
//Tables related to existing projects in the workspace
private Hashtable serviceFacetMatchTable_;
private Hashtable serviceTableKeysByProjectName_;
private Hashtable clientFacetMatchTable_;
private Hashtable clientTableKeysByProjectName_;
private List projectEntriesToDelete_;
//Tables related to templates
private Hashtable templatesByServiceRuntimeId_;
private Hashtable templatesByClientRuntimeId_;
/**
* Returns a singleton instance of this class.
*
* @return A singleton FacetMatchCache object.
*/
public static synchronized FacetMatchCache getInstance()
{
if (instance_ == null)
{
instance_ = new FacetMatchCache();
instance_.load();
}
return instance_;
}
private void load()
{
serviceFacetMatchTable_ = new Hashtable();
serviceTableKeysByProjectName_ = new Hashtable();
clientFacetMatchTable_ = new Hashtable();
clientTableKeysByProjectName_ = new Hashtable();
projectEntriesToDelete_ = new ArrayList();
templatesByClientRuntimeId_ = new Hashtable();
templatesByServiceRuntimeId_ = new Hashtable();
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_DELETE);
}
/*
* Returns the FacetMatcher resulting from matching a service/client runtime with an existing project.
* @param isClient
* @param runtimeId the id of a client runtime if isClient is true or the id of a service runtime if
* isClient is false.
* @param projectName the name of an existing project.
*
* @returns FacetMatcher resulting from calling FacetUtils.match(..) using the service/client runtime id
* and the project name. null if the project doesn't exist. Non-faceted existing projects will always result
* in a FacetMatcher with isMatch() equal to false (with the exception of Java projects are a special case
* - see FacetUtils.getFacetsForProject()).
*/
public synchronized FacetMatcher getMatchForProject(boolean isClient, String runtimeId, String projectName)
{
//Delete entries from table if there are deletions pending.
if (projectEntriesToDelete_.size() > 0)
{
Iterator projectItr = projectEntriesToDelete_.iterator();
while(projectItr.hasNext())
{
String projectNameToDelete = (String)projectItr.next();
//Delete entries from client table
removeTableEntriesForProject(true, projectNameToDelete);
//Delete entries from service table
removeTableEntriesForProject(false, projectNameToDelete);
}
//Clear the projectEntriesToDelete list
projectEntriesToDelete_.clear();
}
IProject project = ProjectUtilities.getProject(projectName);
FacetMatcher fm = null;
if (project != null && project.exists())
{
String key = getKey(runtimeId, projectName);
if (isClient)
{
fm = (FacetMatcher) clientFacetMatchTable_.get(key);
}
else
{
fm = (FacetMatcher) serviceFacetMatchTable_.get(key);
}
if (fm == null)
{
// This combination has not yet been calculated and cached so calculate it and cache it.
fm = calculateFacetMatcher(isClient, runtimeId, projectName);
if (isClient)
{
clientFacetMatchTable_.put(key,fm);
}
else
{
serviceFacetMatchTable_.put(key, fm);
}
updateTableOfKeys(isClient, key, projectName);
} else
{
// If the project's facets have changed since the last time the
// facets were calculated, refresh the facetMatcher.
Set currentFacetVersions = FacetUtils.getFacetsForProject(projectName);
Set previousFacetVersions = fm.getFacetsTested();
if (!currentFacetVersions.equals(previousFacetVersions))
{
//recalculate and cache the FacetMatcher
fm = calculateFacetMatcher(isClient, runtimeId, projectName);
if (isClient)
{
clientFacetMatchTable_.put(key,fm);
}
else
{
serviceFacetMatchTable_.put(key, fm);
}
}
}
}
return fm;
}
private void updateTableOfKeys(boolean isClient, String key, String projectName)
{
Set setOfKeysForProjectName = null;
if (isClient)
{
setOfKeysForProjectName = (Set)clientTableKeysByProjectName_.get(projectName);
}
else
{
setOfKeysForProjectName = (Set)serviceTableKeysByProjectName_.get(projectName);
}
if (setOfKeysForProjectName == null)
{
//Add an entry in the table for this project.
Set keys = new HashSet();
keys.add(key);
if (isClient)
{
clientTableKeysByProjectName_.put(projectName, keys);
}
else
{
serviceTableKeysByProjectName_.put(projectName, keys);
}
}
else
{
//Update the entry in the table for this project.
setOfKeysForProjectName.add(key);
}
}
private FacetMatcher calculateFacetMatcher(boolean isClient, String runtimeId, String projectName)
{
FacetMatcher fm = null;
RequiredFacetVersion[] rfvs = null;
if (isClient)
{
ClientRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(runtimeId);
rfvs = desc.getRequiredFacetVersions();
}
else
{
ServiceRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(runtimeId);
rfvs = desc.getRequiredFacetVersions();
}
Set facetVersions = FacetUtils.getFacetsForProject(projectName);
if (facetVersions != null)
{
fm = FacetUtils.match(rfvs, facetVersions);
} else
{
fm = new FacetMatcher();
fm.setMatch(false);
}
return fm;
}
private String getKey(String a, String b)
{
StringBuffer keysb = new StringBuffer();
keysb.append(a);
keysb.append("/");
keysb.append(b);
return keysb.toString();
}
private void removeTableEntriesForProject(boolean isClient, String projectName)
{
//First remove the entries from clientFacetMatchTable_ or serviceFacetMatchTable_
//that have keys containing this project name.
Set setOfKeysForProjectName = null;
if (isClient)
{
setOfKeysForProjectName = (Set)clientTableKeysByProjectName_.get(projectName);
}
else
{
setOfKeysForProjectName = (Set)serviceTableKeysByProjectName_.get(projectName);
}
if (setOfKeysForProjectName != null)
{
Iterator keysItr = setOfKeysForProjectName.iterator();
while (keysItr.hasNext())
{
String key = (String)keysItr.next();
if (isClient)
{
clientFacetMatchTable_.remove(key);
}
else
{
serviceFacetMatchTable_.remove(key);
}
}
//Second, remove the entry in clientTableKeysByProjectName_ or serviceTableKeysByProjectName_
//with this projectName as the key.
if (isClient)
{
clientTableKeysByProjectName_.remove(projectName);
}
else
{
serviceTableKeysByProjectName_.remove(projectName);
}
}
}
/*
* Returns a set of templates supported by th given client runtime
* @returns Set (type: IFacetedProjectTemplate)
*/
public synchronized Set getTemplatesForClientRuntime(String clientRuntimeId)
{
Set templates = (Set)templatesByClientRuntimeId_.get(clientRuntimeId);
if (templates != null)
{
//Return the cached set of templates.
return templates;
}
else
{
//Calculate the templates, cache them for later use, and return them.
ClientRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(clientRuntimeId);
Set validTemplates = getTemplates(desc.getRequiredFacetVersions());
templatesByClientRuntimeId_.put(clientRuntimeId, validTemplates);
return validTemplates;
}
}
public synchronized Set getTemplatesForServiceRuntime(String serviceRuntimeId)
{
Set templates = (Set)templatesByServiceRuntimeId_.get(serviceRuntimeId);
if (templates != null)
{
//Return the cached set of templates.
return templates;
}
else
{
//Calculate the templates, cache them for later use, and return them.
ServiceRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(serviceRuntimeId);
Set validTemplates = getTemplates(desc.getRequiredFacetVersions());
templatesByServiceRuntimeId_.put(serviceRuntimeId, validTemplates);
return validTemplates;
}
}
private Set getTemplates(RequiredFacetVersion[] requiredFacetVersions)
{
//Get the templates that support the actions
Set templates = new HashSet();
for( Iterator itr = ProjectFacetsManager.getTemplates().iterator(); itr.hasNext(); )
{
final IFacetedProjectTemplate template = (IFacetedProjectTemplate) itr.next();
String templateId = template.getId();
if (templateId.indexOf("ear") == -1 && templateId.indexOf("wst.web") == -1) //Don't include the EARs!!
{
Set[] combinations = FacetSetsByTemplateCache.getInstance().getFacetVersionCombinationsFromTemplate(templateId);
for (int i=0; i<combinations.length; i++)
{
FacetMatcher fm = FacetUtils.match(requiredFacetVersions, combinations[i]);
if (fm.isMatch())
{
//Found a combination that worked. Add the template to the list and move on.
templates.add(template);
break;
}
}
}
}
return templates;
}
public synchronized void resourceChanged(IResourceChangeEvent event)
{
if (event.getType() == IResourceChangeEvent.PRE_DELETE)
{
IResource projectResource = event.getResource();
if (projectResource!=null)
{
String projectName = projectResource.getName();
//Add this project name to the list of project entries
//to delete.
projectEntriesToDelete_.add(projectName);
}
}
}
}