"""
Load and save a set of chosen implementations.
@since: 0.27
"""
# Copyright (C) 2007, Thomas Leonard
# See the README file for details, or visit http://0install.net.
import os
from zeroinstall.injector import reader
from zeroinstall.injector.policy import Policy
from zeroinstall.injector.model import EnvironmentBinding, InterfaceDependency
from zeroinstall.injector.namespaces import XMLNS_IFACE
from zeroinstall.injector.qdom import Element
class Selection(object):
"""A single selected implementation in a L{Selections} set."""
__slots__ = ['interface', 'id', 'version', 'feed', 'dependencies', 'main']
def __init__(self, interface, id, version, feed, main, dependencies):
assert interface
assert id
assert version
assert feed
self.interface = interface
self.id = id
self.version = version
self.feed = feed
self.main = main
self.dependencies = dependencies
def __repr__(self):
return self.id
class Selections(object):
__slots__ = ['interface', 'selections']
def __init__(self, source):
self.selections = {}
if isinstance(source, Policy):
self._init_from_policy(source)
elif isinstance(source, Element):
self._init_from_qdom(source)
else:
raise Exception("Source not a Policy or qdom.Element!")
def _init_from_policy(self, policy):
"""Set the selections from a policy.
@param policy: the policy giving the selected implementations."""
self.interface = policy.root
for needed_iface in policy.implementation:
impl = policy.implementation[needed_iface]
assert impl
self.selections[needed_iface.uri] = Selection(needed_iface.uri, impl.id,
impl.get_version(), impl.interface.uri,
impl.main,
impl.requires)
def _init_from_qdom(self, root):
"""Parse and load a selections document.
@param root: a saved set of selections."""
self.interface = root.getAttribute('interface')
assert self.interface
for selection in root.childNodes:
if selection.uri != XMLNS_IFACE:
continue
if selection.name != 'selection':
continue
bindings = []
for dep_elem in selection.childNodes:
if dep_elem.uri != XMLNS_IFACE:
continue
if dep_elem.name != 'requires':
continue
dep = reader._process_depends(dep_elem)
bindings.append(dep)
iface_uri = selection.getAttribute('interface')
s = Selection(iface_uri,
selection.getAttribute('id'),
selection.getAttribute('version'),
selection.getAttribute('from-feed') or iface_uri,
selection.getAttribute('main'),
bindings)
self.selections[iface_uri] = s
def toDOM(self):
"""Create a DOM document for the selected implementations.
The document gives the URI of the root, plus each selected implementation.
For each selected implementation, we record the ID, the version, the URI and
(if different) the feed URL. We also record all the bindings needed.
@return: a new DOM Document"""
from xml.dom import minidom, XMLNS_NAMESPACE
assert self.interface
impl = minidom.getDOMImplementation()
doc = impl.createDocument(XMLNS_IFACE, "selections", None)
root = doc.documentElement
root.setAttributeNS(XMLNS_NAMESPACE, 'xmlns', XMLNS_IFACE)
root.setAttributeNS(None, 'interface', self.interface)
for selection in self.selections.values():
selection_elem = doc.createElementNS(XMLNS_IFACE, 'selection')
selection_elem.setAttributeNS(None, 'interface', selection.interface)
root.appendChild(selection_elem)
selection_elem.setAttributeNS(None, 'id', selection.id)
selection_elem.setAttributeNS(None, 'version', selection.version)
if selection.main:
selection_elem.setAttributeNS(None, 'main', selection.main)
if selection.interface != selection.feed:
selection_elem.setAttributeNS(None, 'from-feed', selection.feed)
for dep in selection.dependencies:
dep_elem = doc.createElementNS(XMLNS_IFACE, 'requires')
dep_elem.setAttributeNS(None, 'interface', dep.interface)
selection_elem.appendChild(dep_elem)
for m in dep.metadata:
parts = m.split(' ', 1)
if len(parts) == 1:
ns = None
localName = parts[0]
else:
ns, localName = parts
if not ns: ns = None
dep_elem.setAttributeNS(ns, localName, dep.metadata[m])
for b in dep.bindings:
dep_elem.appendChild(b._toxml(doc))
return doc
def __repr__(self):
return "Selections for " + self.interface
syntax highlighted by Code2HTML, v. 0.9.1