blob: f83ccd28eef42af8da1397cc0bfaf1e7fd4ee06c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 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
* -------- -------- -----------------------------------------------------------
* 20060517 131582 mahutch@ca.ibm.com - Mark Hutchinson
* 20060906 141796 gilberta@ca.ibm.com - Gilbert Andrews
*******************************************************************************/
package org.eclipse.wst.ws.internal.registry;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.wst.ws.internal.model.v10.registry.Registry;
import org.eclipse.wst.ws.internal.model.v10.rtindex.Index;
import org.eclipse.wst.ws.internal.model.v10.rtindex.RTIndexFactory;
import org.eclipse.wst.ws.internal.model.v10.taxonomy.Taxonomy;
import org.eclipse.wst.ws.internal.plugin.WSPlugin;
/**
* A typical implementation of <code>IRegistryManager</code>.
* @author cbrealey
* @see IRegistryManager
*/
public class RegistryManager implements IRegistryManager
{
private static String REGISTRY = "Registry";
private static String TAXONOMY = "Taxonomy";
private static String XML = "xml";
private Hashtable taxonomyFinders_;
private Index index_;
private GenericResourceFactory resourceFactory_ = new GenericResourceFactory();
private URL registryURL_= null;
private String registryPathname_ = null;
/**
* Constructs a new RegistryManager for the index XML file
* at the given <code>url</code>.
* @param url The URL to the index XML file.
*/
RegistryManager ( URL url )
{
registryURL_ = url;
taxonomyFinders_ = new Hashtable();
}
/**
* Constructs a new RegistryManager for the index XML file
* at the given <code>pathname</code>.
* @param pathname The pathname to the index XML file.
*/
RegistryManager ( String pathname )
{
registryPathname_ = pathname;
taxonomyFinders_ = new Hashtable();
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#getURL()
*/
public URL getURL () throws MalformedURLException
{
if (registryURL_ == null)
{
registryURL_ = new File(registryPathname_).toURL();
}
return registryURL_;
}
/**
* Returns an absolute URL computed from the absolute URL of the
* index XML document managed by this <code>RegistryManager</code>
* and the given <code>id</code>. This method is used to determine
* a reasonable location URL for registry and taxonomy documents
* when references to them are first to be added to the index XML
* document. This method is idempotent insofar as it will always
* compute the same URL for a given <code>RegistryManager</code>
* and a given <code>id</code>.
*
* @param id The id of the referenced registry or taxonomy document.
* @return The absolute URL to the referenced document.
* @throws MalformedURLException If a viable absolute URL cannot
* be computed.
*/
private URL getURL ( String id ) throws MalformedURLException
{
String baseUrl = "";
URL indexUrl = getURL();
String indexString = indexUrl.toString();
int index = indexString.lastIndexOf("/");
baseUrl = indexString.substring(0,index + 1);
String urlString = baseUrl + id + "." + XML;
return new URL(urlString);
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#refreshManager()
*/
public void refreshManager ()
{
index_ = null;
}
/**
* Caches and returns the index model. On first call,
* if an index document exists, the index is loaded
* from it, otherwise, a new index is returned.
* @return The index.
* @throws CoreException If the index cannot be loaded for any reason.
*/
private Index getIndex () throws CoreException
{
if (index_ == null)
{
try
{
URL indexURL = getURL();
if (RegistryService.exists(indexURL))
{
Resource resource = resourceFactory_.createResource(URI.createURI("*.xml"));
resource.load(RegistryService.getInputStreamFor(indexURL),null);
org.eclipse.wst.ws.internal.model.v10.rtindex.DocumentRoot document = (org.eclipse.wst.ws.internal.model.v10.rtindex.DocumentRoot)resource.getContents().get(0);
index_ = document.getIndex();
}
else
{
index_ = RTIndexFactory.eINSTANCE.createIndex();
}
}
catch (IOException e)
{
//TODO: Need a message for this Status.
throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",e));
}
}
return index_;
}
/**
* Saves the index model to an XML document.
* @throws CoreException If the save fails for any reason.
*/
private void saveIndex () throws CoreException
{
org.eclipse.wst.ws.internal.model.v10.rtindex.DocumentRoot document = RTIndexFactory.eINSTANCE.createDocumentRoot();
document.setIndex(getIndex());
Resource resource = resourceFactory_.createResource(URI.createURI("*.xml"));
resource.getContents().add(document);
try
{
resource.save(RegistryService.getOutputStreamFor(getURL()),null);
}
catch (IOException e)
{
//TODO: Need a message for this Status.
throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",e));
}
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#addTaxonomyFinder(java.lang.String, org.eclipse.wst.ws.internal.registry.ITaxonomyFinder)
*/
public void addTaxonomyFinder(String className, ITaxonomyFinder taxonomyFinder)
{
taxonomyFinders_.put(className,taxonomyFinder);
}
/**
* Adds the given <code>registry</code> as-is, whether full model
* or reference, to the index only if a registry with the same ID
* or reference is not already stored there.
* @param registry The registry to add.
*/
private void addRegistryToIndex(Registry registry) throws CoreException
{
String id = registry.getId();
if (id == null) id = registry.getRef();
if (id != null && getRegistry(id) == null)
{
getIndex().getRegistry().add(registry);
}
}
/**
* Adds the given <code>taxonomy</code> as-is, whether full model
* or reference, to the index only if a taxonomy with the same ID
* or reference is not already stored there.
* @param taxonomy The taxonomy to add.
*/
private void addTaxonomyToIndex(Taxonomy taxonomy) throws CoreException
{
String id = taxonomy.getId();
if (id == null) id = taxonomy.getRef();
if (id != null && getTaxonomy(id) == null)
{
getIndex().getTaxonomy().add(taxonomy);
}
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#saveRegistry(org.eclipse.wst.ws.internal.model.v10.registry.Registry)
*/
public Registry saveRegistry ( Registry registry ) throws CoreException
{
RegistryService registryService = RegistryService.instance();
Registry registryRef = null;
try
{
URL url = getURL(REGISTRY + registry.getId());
registryService.saveRegistry(url,registry);
registryRef = registryService.newRegistryReference(registry);
registryRef.setLocation(url.toString());
addRegistryToIndex(registryRef);
saveIndex();
/*
* TODO: The following pile of code is commented out
* since there isn't a reliable way under the current
* design to save taxonomy models held in a registry model
*
ITaxonomyFinder finder = (ITaxonomyFinder)taxonomyFinders_.get(registry.getClass().getName());
if (finder != null)
{
Taxonomy[] taxonomies = finder.taxonomies(registry);
for (int i=0; i<taxonomies.length; i++)
{
String id = taxonomies[i].getId();
String ref = taxonomies[i].getRef();
if (id != null)
{
URL taxonomyURL = getURL(TAXONOMY + id);
registryService.saveTaxonomy(taxonomyURL,taxonomies[i]);
Taxonomy taxonomyRef = registryService.newTaxonomyReference(taxonomies[i]);
taxonomyRef.setLocation(taxonomyURL.toString());
addTaxonomyToIndex(taxonomyRef);
}
else if (ref != null)
{
if (taxonomies[i].getLocation() == null)
{
String location = null;
Taxonomy taxonomy = getTaxonomy(ref);
if (taxonomy != null) location = taxonomy.getLocation();
if (location == null) location = getURL(TAXONOMY + ref).toString();
taxonomies[i].setLocation(location);
if (taxonomy == null)
{
addTaxonomyToIndex(registryService.newTaxonomyReference(taxonomies[i]));
}
}
}
}
}
*/
}
catch ( MalformedURLException me )
{
//TODO: Message text required.
throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
}
return registryService.newRegistryReference(registryRef);
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadRegistry(java.lang.String)
*/
public Registry loadRegistry ( String uri ) throws CoreException
{
RegistryService registryService = RegistryService.instance();
try
{
Registry registry = getRegistry(uri);
if (registry == null) return null;
// If the Registry has an ID, it's a full model
// inlined within the Index and is returned as-is.
if (registry.getId() != null) return registry;
// Otherwise it's a reference to a full model
// which we load from the reference's location.
String urlString = registry.getLocation();
if (urlString == null) return null;
URL url = new URL(urlString);
return registryService.loadRegistry(url);
}
catch ( MalformedURLException me )
{
//TODO: Message text required.
throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
}
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadRegistries(java.lang.String[])
*/
public Registry[] loadRegistries ( String[] uris ) throws CoreException
{
List list = new ArrayList(uris.length);
for (int i=0; i<uris.length; i++)
{
Registry registry = loadRegistry(uris[i]);
if (registry != null)
{
list.add(registry);
}
}
return (Registry[])list.toArray(new Registry[0]);
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#getRegistryURIs()
*/
public String[] getRegistryURIs () throws CoreException
{
EList list = getIndex().getRegistry();
List registryURIs = new ArrayList(list.size());
Iterator iterator = list.iterator();
while(iterator.hasNext())
{
// Each Registry found in the index may be
// either a full model or a reference to one.
Registry registry = (Registry)iterator.next();
if (registry.getId() != null)
{
registryURIs.add(registry.getId());
}
else if (registry.getRef() != null)
{
registryURIs.add(registry.getRef());
}
}
return (String[])registryURIs.toArray(new String[0]);
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#removeRegistry(java.lang.String, boolean)
*/
public void removeRegistry ( String uri, boolean deleteDocument ) throws CoreException
{
EList list = getIndex().getRegistry();
Registry registry = getRegistry(uri);
if (registry != null)
{
list.remove(registry);
saveIndex();
// The identified Registry may be either a full model
// (ie. inlined in the Index) or a reference to one.
// Only in the latter case is there a file to delete.
if (deleteDocument && registry.getLocation() != null)
{
//TODO: Implement me.
}
}
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#saveTaxonomy(org.eclipse.wst.ws.internal.model.v10.taxonomy.Taxonomy)
*/
public Taxonomy saveTaxonomy ( Taxonomy taxonomy ) throws CoreException
{
RegistryService registryService = RegistryService.instance();
Taxonomy taxonomyRef = null;
try
{
URL url = getURL(TAXONOMY + taxonomy.getId());
registryService.saveTaxonomy(url,taxonomy);
taxonomyRef = registryService.newTaxonomyReference(taxonomy);
taxonomyRef.setLocation(url.toString());
addTaxonomyToIndex(taxonomyRef);
saveIndex();
}
catch ( MalformedURLException me )
{
//TODO: Message text required.
throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
}
return registryService.newTaxonomyReference(taxonomyRef);
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadTaxonomy(java.lang.String)
*/
public Taxonomy loadTaxonomy ( String uri ) throws CoreException
{
RegistryService registryService = RegistryService.instance();
try
{
Taxonomy taxonomy = getTaxonomy(uri);
if (taxonomy == null) return null;
// If the Taxonomy has an ID, it's a full model
// inlined within the Index and is returned as-is.
if (taxonomy.getId() != null) return taxonomy;
// Otherwise it's a reference to a full model
// which we load from the reference's location.
String urlString = taxonomy.getLocation();
if (urlString == null) return null;
URL url = new URL(urlString);
return registryService.loadTaxonomy(url);
}
catch ( MalformedURLException me )
{
//TODO: Message text required.
throw new CoreException(new Status(IStatus.ERROR,WSPlugin.ID,0,"",me));
}
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#loadTaxonomies(java.lang.String[])
*/
public Taxonomy[] loadTaxonomies ( String[] uris ) throws CoreException
{
List list = new ArrayList(uris.length);
for (int i=0; i<uris.length; i++)
{
Taxonomy taxonomy = loadTaxonomy(uris[i]);
if (taxonomy != null)
{
list.add(taxonomy);
}
}
return (Taxonomy[])list.toArray(new Taxonomy[0]);
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#getTaxonomyURIs()
*/
public String[] getTaxonomyURIs () throws CoreException
{
EList list = getIndex().getTaxonomy();
List taxonomyURIs = new ArrayList(list.size());
Iterator iterator = list.iterator();
while(iterator.hasNext())
{
// Each Taxonomy found in the index may be
// either a full model or a reference to one.
Taxonomy taxonomy = (Taxonomy)iterator.next();
if (taxonomy.getId() != null)
{
taxonomyURIs.add(taxonomy.getId());
}
else if (taxonomy.getRef() != null)
{
taxonomyURIs.add(taxonomy.getRef());
}
}
return (String[])taxonomyURIs.toArray(new String[0]);
}
/* (non-Javadoc)
* @see org.eclipse.wst.ws.internal.registry.IRegistryManager#removeTaxonomy(java.lang.String, boolean)
*/
public void removeTaxonomy ( String uri, boolean deleteDocument ) throws CoreException
{
EList list = getIndex().getTaxonomy();
Taxonomy taxonomy = getTaxonomy(uri);
if (taxonomy != null)
{
list.remove(taxonomy);
saveIndex();
// The identified Taxonomy may be either a full model
// (ie. inlined in the Index) or a reference to one.
// Only in the latter case is there a file to delete.
if (deleteDocument && taxonomy.getLocation() != null)
{
//TODO: Implement me.
}
}
}
/**
* Returns the Registry from the index whose ID or Reference
* matches the given URI. As such, this method may return a
* full model or a reference to a full model.
* @param uri The URI identifier of the Registry
* @return The <code>Registry</code> object whose ID or reference
* matches the given <code>uri</code>, or null if none match.
*/
private Registry getRegistry ( String uri ) throws CoreException
{
EList list = getIndex().getRegistry();
Iterator it = list.iterator();
while (it.hasNext()){
Registry registry = (Registry)it.next();
if (uri.equals(registry.getId()) || uri.equals(registry.getRef())){
return registry;
}
}
return null;
}
/**
* Returns the Taxonomy from the index whose ID or Reference
* matches the given URI. As such, this method may return a
* full model or a reference to a full model.
* @param uri The URI identifier of the Taxonomy
* @return The <code>Taxonomy</code> object whose ID or reference
* matches the given <code>uri</code>, or null if none match.
*/
private Taxonomy getTaxonomy ( String uri ) throws CoreException
{
EList list = getIndex().getTaxonomy();
Iterator it = list.iterator();
while (it.hasNext()){
Taxonomy taxonomy = (Taxonomy)it.next();
if (uri.equals(taxonomy.getId()) || uri.equals(taxonomy.getRef())){
return taxonomy;
}
}
return null;
}
}