package com.abiquo.appliancemanager;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.JAXBException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.abiquo.appliancemanager.exceptions.DownloadException;
import com.abiquo.appliancemanager.exceptions.InvalidRepositorySpace;
import com.abiquo.appliancemanager.exceptions.XMLException;
import com.abiquo.appliancemanager.filesystems.FileFactory;
import com.abiquo.appliancemanager.util.RepositoryUtils;
import com.abiquo.appliancemanager.xml.OVFSerializer;
import com.abiquo.ovfindex.OVFPackage;
import com.abiquo.ovfindex.RepositorySpace;
/**
* Maintain a RespositorySpace resuming all the attached RepositorySpaces.<br/>
*
* @todo export OVFIndex XML document to be accessed (default http??).
*/
public class OVFIndex
{
private final static Logger log = LoggerFactory.getLogger(OVFIndex.class);
/** Allow read/write XML documents . */
// private final OVFSerializer xmlOvf;
/** Store all the OVFPackages on all RepositorySpaces . */
private RepositorySpace repository;
/** Index all the attached RepositorySpaces by its URI. */
private Map<URI, RepositorySpace> allSpaces = new HashMap<URI, RepositorySpace>();
/** Where the ovfindex.xml is persisted. */
// TODO use the correct path to expose index on the repositoryURI used on constructor
// private String repositoryUri = "state" + File.separatorChar + "ovfindex.xml";
private final URI repositoryURI;
/**
* Creates a new ReposiorySpace.
*
* @param repositoryURI, the repository URI to be used.
* @throws JAXBException can create OVF XML serializer. TODO restore from ????
*/
public OVFIndex(URI repositoryURI) throws JAXBException
{
this.repositoryURI = repositoryURI;
repository = new RepositorySpace();
repository.setRepositoriURI(repositoryURI.toASCIIString());
// xmlOvf = OVFSerializer.getInstance();
log.debug("Created repositor space on " + repositoryURI.toASCIIString());
}
/**
* Returns the RepositorySpace.
*
* @return the RepositorySpace resuming all the attached ReposiotrySpaces.
*/
public RepositorySpace getRepositorySpace()
{
return repository;
}
public void setRepositorySpace(RepositorySpace repo)
{
repository = repo;
}
public Set<URI> getAttachedRepositorySpaces()
{
return allSpaces.keySet();
}
/**
* Attach a new RepositorySpace, adding all its OVFPackages into the resume RS.
*
* @param repoURI, where the ovfindex.xml is read (@TODO check known protocol)
* @throws FileNotFoundException if the provided repositoryURI can not be reach.
*/
public void addRespositorySpace(URI repoURI) throws InvalidRepositorySpace //
{
RepositorySpace repo;
try
{
repo =
OVFSerializer.getInstance().readXMLRepositorySpace(
FileFactory.open(repoURI.toURL()));
}
catch (XMLException e) // XMLStreamException or JAXBException
{
final String msg =
"Invalid OVFIndex.xml on RepositorySpace: " + repoURI.toASCIIString();
throw new InvalidRepositorySpace(msg, e);
}
catch (MalformedURLException e)
{
final String msg = "Invalid repository space identifier : " + repoURI.toASCIIString();
throw new InvalidRepositorySpace(msg, e);
}
catch (DownloadException e)
{
final String msg =
"the OVFIndex.xml can not be downloaded from : " + repoURI.toASCIIString();
throw new InvalidRepositorySpace(msg, e);
}
allSpaces.put(repoURI, repo);
// TODO check for duplicatets
repository.getOVFPackage().addAll(repo.getOVFPackage());
log.debug("Attached repository space " + repoURI.toASCIIString());
}
/**
* Refresh the content on the RepositorySpace for the given repository URI.
*
* @param repoURI, what to update.
* @throws InvalidRepositorySpace, purge the ovfpackages (old OVFPackages can not be accessed
* anymore)
*/
public void updateIndex(URI repoURI) throws InvalidRepositorySpace
{
// TODO check it was already on 'allSpaces'
allSpaces.remove(repoURI);
RepositoryUtils.purgeRepositorySpace(repository.getOVFPackage(), repoURI.toASCIIString());
addRespositorySpace(repoURI);
log.debug("Updated repository " + repoURI.toASCIIString());
}
/**
* Get all the OVFPackages form the RepositorySpace.
*
* @param repositoryURI, the RepositorySpace to use, if null, use the resume (master)
* RepositorySpace (all of it).
* @param category, to filter the OVFPackages, if null, any filter.
* @return all the OVFPackages with provided category an on the given repositoryURI.
*/
public List<OVFPackage> listRepository(URI repositoryURI, String category)
throws InvalidRepositorySpace
{
List<OVFPackage> packages = new LinkedList<OVFPackage>();
if (repositoryURI == null)
{
packages = repository.getOVFPackage();
}
else if (this.repositoryURI.equals(repositoryURI))
{
packages = repository.getOVFPackage();
}
else if (allSpaces.keySet().contains(repositoryURI))
{
packages = allSpaces.get(repositoryURI).getOVFPackage();
}
else
{
final String msg =
"The reposioryURI " + repositoryURI + " is not attached to this index";
throw new InvalidRepositorySpace(msg);
}
if (category != null)
{
packages = RepositoryUtils.filterRepositorySpace(packages, category);
}
return packages;
}
}