http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/loading/file.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/loading/file.py b/apache-ariatosca-0.1.1/aria/parser/loading/file.py deleted file mode 100644 index a02bd69..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/loading/file.py +++ /dev/null @@ -1,64 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -import codecs - -from .loader import Loader -from .exceptions import LoaderException, DocumentNotFoundException - - -class FileTextLoader(Loader): - """ - ARIA file text loader. - - Extracts a text document from a file. The default encoding is UTF-8, but other supported - encoding can be specified instead. - """ - - def __init__(self, context, path, encoding='utf-8'): - self.context = context - self.path = path - self.encoding = encoding - self._file = None - - def open(self): - try: - self._file = codecs.open(self.path, mode='r', encoding=self.encoding, buffering=1) - except IOError as e: - if e.errno == 2: - raise DocumentNotFoundException('file not found: "%s"' % self.path, cause=e) - else: - raise LoaderException('file I/O error: "%s"' % self.path, cause=e) - except Exception as e: - raise LoaderException('file error: "%s"' % self.path, cause=e) - - def close(self): - if self._file is not None: - try: - self._file.close() - except IOError as e: - raise LoaderException('file I/O error: "%s"' % self.path, cause=e) - except Exception as e: - raise LoaderException('file error: "%s"' % self.path, cause=e) - - def load(self): - if self._file is not None: - try: - return self._file.read() - except IOError as e: - raise LoaderException('file I/O error: "%s"' % self.path, cause=e) - except Exception as e: - raise LoaderException('file error %s' % self.path, cause=e) - return None
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/loading/literal.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/loading/literal.py b/apache-ariatosca-0.1.1/aria/parser/loading/literal.py deleted file mode 100644 index 7865008..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/loading/literal.py +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - - -from .loader import Loader - - -class LiteralLoader(Loader): - """ - ARIA literal loader. - - See :class:`~aria.parser.loading.LiteralLocation`. - """ - - def __init__(self, location): - self.location = location - - def load(self): - return self.location.content http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/loading/loader.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/loading/loader.py b/apache-ariatosca-0.1.1/aria/parser/loading/loader.py deleted file mode 100644 index e1abfbf..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/loading/loader.py +++ /dev/null @@ -1,34 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - - -class Loader(object): - """ - Base class for ARIA loaders. - - Loaders extract a document by consuming a document source. - - Though the extracted document is often textual (a string or string-like - data), loaders may provide any format. - """ - - def open(self): - pass - - def close(self): - pass - - def load(self): - raise NotImplementedError http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/loading/location.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/loading/location.py b/apache-ariatosca-0.1.1/aria/parser/loading/location.py deleted file mode 100644 index 902e856..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/loading/location.py +++ /dev/null @@ -1,82 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - - -import os - -from ...utils.uris import as_file - - -class Location(object): - """ - Base class for ARIA locations. - - Locations are used by :class:`~aria.parser.loading.LoaderSource` to delegate to - an appropriate :class:`~aria.parser.loading.Loader`. - """ - - def is_equivalent(self, location): - raise NotImplementedError - - @property - def prefix(self): - return None - - -class UriLocation(Location): - """ - A URI location can be absolute or relative, and can include a scheme or not. - - If no scheme is included, it should be treated as a filesystem path. - - See :class:`~aria.parser.loading.UriTextLoader`. - """ - - def __init__(self, uri): - self.uri = uri - - def is_equivalent(self, location): - return isinstance(location, UriLocation) and (location.uri == self.uri) - - @property - def prefix(self): - prefix = os.path.dirname(self.uri) - if prefix and (as_file(prefix) is None): - # Yes, it's weird, but dirname handles URIs, - # too: http://stackoverflow.com/a/35616478/849021 - # We just need to massage it with a trailing slash - prefix += '/' - return prefix - - def __str__(self): - return self.uri - - -class LiteralLocation(Location): - """ - A location that embeds content. - - See :class:`~aria.parser.loading.LiteralLoader`. - """ - - def __init__(self, content, name='literal'): - self.content = content - self.name = name - - def is_equivalent(self, location): - return isinstance(location, LiteralLocation) and (location.content == self.content) - - def __str__(self): - return '<%s>' % self.name http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/loading/request.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/loading/request.py b/apache-ariatosca-0.1.1/aria/parser/loading/request.py deleted file mode 100644 index a809347..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/loading/request.py +++ /dev/null @@ -1,88 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -import os -import tempfile - -from requests import Session -from requests.exceptions import (ConnectionError, InvalidSchema) -from cachecontrol import CacheControl -from cachecontrol.caches import FileCache - -from .exceptions import LoaderException, DocumentNotFoundException -from .loader import Loader - -SESSION = None -SESSION_CACHE_PATH = os.path.join(tempfile.gettempdir(), 'aria_requests') - - -class RequestLoader(Loader): - """ - Base class for ARIA request-based loaders. - - Extracts a document from a URI by performing a request. - - Note that the "file:" schema is not supported: :class:`FileTextLoader` should - be used instead. - """ - - def __init__(self, context, uri, headers=None): - if headers is None: - headers = {} - self.context = context - self.uri = uri - self.headers = headers - self._response = None - - def load(self): - pass - - def open(self): - global SESSION - if SESSION is None: - SESSION = CacheControl(Session(), cache=FileCache(SESSION_CACHE_PATH)) - - try: - self._response = SESSION.get(self.uri, headers=self.headers) - except InvalidSchema as e: - raise DocumentNotFoundException('document not found: "%s"' % self.uri, cause=e) - except ConnectionError as e: - raise LoaderException('request connection error: "%s"' % self.uri, cause=e) - except Exception as e: - raise LoaderException('request error: "%s"' % self.uri, cause=e) - - status = self._response.status_code - if status == 404: - self._response = None - raise DocumentNotFoundException('document not found: "%s"' % self.uri) - elif status != 200: - self._response = None - raise LoaderException('request error %d: "%s"' % (status, self.uri)) - - -class RequestTextLoader(RequestLoader): - """ - ARIA request-based text loader. - """ - - def load(self): - if self._response is not None: - try: - if self._response.encoding is None: - self._response.encoding = 'utf8' - return self._response.text - except Exception as e: - raise LoaderException('request error: %s' % self.uri, cause=e) - return None http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/loading/source.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/loading/source.py b/apache-ariatosca-0.1.1/aria/parser/loading/source.py deleted file mode 100644 index bcd6dd1..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/loading/source.py +++ /dev/null @@ -1,44 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -from .location import LiteralLocation, UriLocation -from .literal import LiteralLoader -from .uri import UriTextLoader - - -class LoaderSource(object): - """ - Base class for ARIA loader sources. - - Loader sources provide appropriate :class:`Loader` instances for locations. - """ - - def get_loader(self, context, location, origin_location): - raise NotImplementedError - - -class DefaultLoaderSource(LoaderSource): - """ - The default ARIA loader source will generate a :class:`UriTextLoader` for - :class:`UriLocation` and a :class:`LiteralLoader` for a :class:`LiteralLocation`. - """ - - def get_loader(self, context, location, origin_location): - if isinstance(location, UriLocation): - return UriTextLoader(context, location, origin_location) - elif isinstance(location, LiteralLocation): - return LiteralLoader(location) - - return super(DefaultLoaderSource, self).get_loader(context, location, origin_location) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/loading/uri.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/loading/uri.py b/apache-ariatosca-0.1.1/aria/parser/loading/uri.py deleted file mode 100644 index a5a18e6..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/loading/uri.py +++ /dev/null @@ -1,97 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -import os -from urlparse import urljoin - -from ...extension import parser -from ...utils.collections import StrictList -from ...utils.uris import as_file -from .loader import Loader -from .file import FileTextLoader -from .request import RequestTextLoader -from .exceptions import DocumentNotFoundException - - -class UriTextLoader(Loader): - """ - Base class for ARIA URI loaders. - - See :class:`~aria.parser.loading.UriLocation`. - - Supports a list of search prefixes that are tried in order if the URI cannot be found. - They will be: - - * If ``origin_location`` is provided its prefix will come first. - * Then the prefixes in the :class:`LoadingContext` will be added. - * Finally, the parser can supply a ``uri_loader_prefix`` function with extra prefixes. - """ - - def __init__(self, context, location, origin_location=None): - self.context = context - self.location = location - self._prefixes = StrictList(value_class=basestring) - self._loader = None - - def add_prefix(prefix): - if prefix and (prefix not in self._prefixes): - self._prefixes.append(prefix) - - def add_prefixes(prefixes): - for prefix in prefixes: - add_prefix(prefix) - - if origin_location is not None: - add_prefix(origin_location.prefix) - - add_prefixes(context.prefixes) - add_prefixes(parser.uri_loader_prefix()) - - def open(self): - try: - self._open(self.location.uri) - return - except DocumentNotFoundException: - # Try prefixes in order - for prefix in self._prefixes: - prefix_as_file = as_file(prefix) - if prefix_as_file is not None: - uri = os.path.join(prefix_as_file, self.location.uri) - else: - uri = urljoin(prefix, self.location.uri) - try: - self._open(uri) - return - except DocumentNotFoundException: - pass - raise DocumentNotFoundException('document not found at URI: "%s"' % self.location) - - def close(self): - if self._loader is not None: - self._loader.close() - - def load(self): - return self._loader.load() if self._loader is not None else None - - def _open(self, uri): - the_file = as_file(uri) - if the_file is not None: - uri = the_file - loader = FileTextLoader(self.context, uri) - else: - loader = RequestTextLoader(self.context, uri) - loader.open() # might raise an exception - self._loader = loader - self.location.uri = uri http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/modeling/context.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/modeling/context.py b/apache-ariatosca-0.1.1/aria/parser/modeling/context.py deleted file mode 100644 index 3d75617..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/modeling/context.py +++ /dev/null @@ -1,103 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -import itertools - -from ...utils.collections import StrictDict, prune -from ...utils.uuid import generate_uuid - - -class IdType(object): - LOCAL_SERIAL = 0 - """ - Locally unique serial ID: a running integer. - """ - - LOCAL_RANDOM = 1 - """ - Locally unique ID: 6 random safe characters. - """ - - UNIVERSAL_RANDOM = 2 - """ - Universally unique ID (UUID): 22 random safe characters. - """ - - -class ModelingContext(object): - """ - Modeling context. - - :ivar template: generated service template - :vartype template: aria.modeling.models.ServiceTemplate - :ivar instance: generated service instance - :vartype instance: aria.modeling.models.Service - :ivar node_id_format: format for node instance IDs - :vartype node_id_format: basestring - :ivar id_type: type of IDs to use for instances - :vartype id_type: basestring - :ivar id_max_length: maximum allowed instance ID length - :vartype id_max_length: int - :ivar inputs: inputs values - :vartype inputs: {:obj:`basestring`, object} - """ - - def __init__(self): - self.template = None - self.instance = None - self.node_id_format = '{template}_{id}' - #self.id_type = IdType.LOCAL_SERIAL - #self.id_type = IdType.LOCAL_RANDOM - self.id_type = IdType.UNIVERSAL_RANDOM - self.id_max_length = 63 # See: http://www.faqs.org/rfcs/rfc1035.html - self.inputs = StrictDict(key_class=basestring) - - self._serial_id_counter = itertools.count(1) - self._locally_unique_ids = set() - - def store(self, model_storage): - if self.template is not None: - model_storage.service_template.put(self.template) - if self.instance is not None: - model_storage.service.put(self.instance) - - def generate_id(self): - if self.id_type == IdType.LOCAL_SERIAL: - return self._serial_id_counter.next() - - elif self.id_type == IdType.LOCAL_RANDOM: - the_id = generate_uuid(6) - while the_id in self._locally_unique_ids: - the_id = generate_uuid(6) - self._locally_unique_ids.add(the_id) - return the_id - - return generate_uuid() - - def set_input(self, name, value): - self.inputs[name] = value - # TODO: coerce to validate type - - @property - def template_as_raw(self): - raw = self.template.as_raw - prune(raw) - return raw - - @property - def instance_as_raw(self): - raw = self.instance.as_raw - prune(raw) - return raw http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/presentation/context.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/presentation/context.py b/apache-ariatosca-0.1.1/aria/parser/presentation/context.py deleted file mode 100644 index 44a6f82..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/presentation/context.py +++ /dev/null @@ -1,65 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - - -from .source import DefaultPresenterSource - - -class PresentationContext(object): - """ - Presentation context. - - :ivar presenter: the generated presenter instance - :vartype presenter: ~aria.parser.presentation.Presenter - :ivar location: from where we will generate the presenter - :vartype location: ~aria.parser.loading.Location - :ivar presenter_source: for finding presenter classes - :vartype presenter_source: ~aria.parser.presentation.PresenterSource - :ivar presenter_class: overrides ``presenter_source`` with a specific class - :vartype presenter_class: type - :ivar import_profile: whether to import the profile by default (defaults to ``True``) - :vartype import_profile: bool - :ivar threads: number of threads to use when reading data - :vartype threads: int - :ivar timeout: timeout in seconds for loading data - :vartype timeout: float - :ivar print_exceptions: whether to print exceptions while reading data - :vartype print_exceptions: bool - """ - - def __init__(self): - self.presenter = None - self.location = None - self.presenter_source = DefaultPresenterSource() - self.presenter_class = None # overrides - self.import_profile = True - self.threads = 8 # reasonable default for networking multithreading - self.timeout = 10 # in seconds - self.print_exceptions = False - - def get(self, *names): - """ - Gets attributes recursively from the presenter. - """ - - return self.presenter._get(*names) if self.presenter is not None else None - - def get_from_dict(self, *names): - """ - Gets attributes recursively from the presenter, except for the last name which is used - to get a value from the last dict. - """ - - return self.presenter._get_from_dict(*names) if self.presenter is not None else None http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/presentation/exceptions.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/presentation/exceptions.py b/apache-ariatosca-0.1.1/aria/parser/presentation/exceptions.py deleted file mode 100644 index cd7eb07..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/presentation/exceptions.py +++ /dev/null @@ -1,29 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - - -from ...exceptions import AriaException - - -class PresenterException(AriaException): - """ - ARIA presenter exception. - """ - - -class PresenterNotFoundError(PresenterException): - """ - ARIA presenter error: presenter not found for raw. - """ http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/presentation/field_validators.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/presentation/field_validators.py b/apache-ariatosca-0.1.1/aria/parser/presentation/field_validators.py deleted file mode 100644 index aa04913..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/presentation/field_validators.py +++ /dev/null @@ -1,164 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - - -from ..validation import Issue -from .utils import (parse_types_dict_names, report_issue_for_unknown_type, - report_issue_for_parent_is_self, report_issue_for_unknown_parent_type, - report_issue_for_circular_type_hierarchy) - - -def type_validator(type_name, *types_dict_names): - """ - Makes sure that the field refers to an existing type defined in the root presenter. - - The arguments from the second onwards are used to locate a nested field under - ``service_template`` under the root presenter. The first of these can optionally be a function, - in which case it will be called to convert type names. This can be used to support shorthand - type names, aliases, etc. - - Can be used with the :func:`field_validator` decorator. - """ - - types_dict_names, convert = parse_types_dict_names(types_dict_names) - - def validator_fn(field, presentation, context): - field.default_validate(presentation, context) - - # Make sure type exists - value = getattr(presentation, field.name) - if value is not None: - types_dict = context.presentation.get('service_template', *types_dict_names) or {} - - if convert: - value = convert(context, value, types_dict) - - if value not in types_dict: - report_issue_for_unknown_type(context, presentation, type_name, field.name) - - return validator_fn - - -def list_type_validator(type_name, *types_dict_names): - """ - Makes sure that the field's elements refer to existing types defined in the root presenter. - - Assumes that the field is a list. - - The arguments from the second onwards are used to locate a nested field under - ``service_template`` under the root presenter. The first of these can optionally be a function, - in which case it will be called to convert type names. This can be used to support shorthand - type names, aliases, etc. - - Can be used with the :func:`field_validator` decorator. - """ - - types_dict_names, convert = parse_types_dict_names(types_dict_names) - - def validator_fn(field, presentation, context): - field.default_validate(presentation, context) - - # Make sure types exist - values = getattr(presentation, field.name) - if values is not None: - types_dict = context.presentation.get('service_template', *types_dict_names) or {} - - for value in values: - if convert: - value = convert(context, value, types_dict) - - if value not in types_dict: - report_issue_for_unknown_type(context, presentation, type_name, field.name) - - return validator_fn - - -def list_length_validator(length): - """ - Makes sure the field has exactly a specific number of elements. - - Assumes that the field is a list. - - Can be used with the :func:`field_validator` decorator. - """ - - def validator_fn(field, presentation, context): - field.default_validate(presentation, context) - - # Make sure list has exactly the length - values = getattr(presentation, field.name) - if isinstance(values, list): - if len(values) != length: - context.validation.report('field "%s" does not have exactly %d elements in "%s"' - % (field.name, length, presentation._fullname), - locator=presentation._get_child_locator(field.name), - level=Issue.FIELD) - - return validator_fn - - -def derived_from_validator(*types_dict_names): - """ - Makes sure that the field refers to a valid parent type defined in the root presenter. - - Checks that we do not derive from ourselves and that we do not cause a circular hierarchy. - - The arguments are used to locate a nested field under ``service_template`` under the root - presenter. The first of these can optionally be a function, in which case it will be called to - convert type names. This can be used to support shorthand type names, aliases, etc. - - Can be used with the :func:`field_validator` decorator. - """ - - types_dict_names, convert = parse_types_dict_names(types_dict_names) - - def validator_fn(field, presentation, context): - field.default_validate(presentation, context) - - value = getattr(presentation, field.name) - if value is not None: - types_dict = context.presentation.get('service_template', *types_dict_names) or {} - - if convert: - value = convert(context, value, types_dict) - - # Make sure not derived from self - if value == presentation._name: - report_issue_for_parent_is_self(context, presentation, field.name) - # Make sure derived from type exists - elif value not in types_dict: - report_issue_for_unknown_parent_type(context, presentation, field.name) - else: - # Make sure derivation hierarchy is not circular - hierarchy = [presentation._name] - presentation_tmp = presentation - while presentation_tmp.derived_from is not None: - derived_from = presentation_tmp.derived_from - if convert: - derived_from = convert(context, derived_from, types_dict) - - if derived_from == presentation_tmp._name: - # This should cause a validation issue at that type - break - elif derived_from not in types_dict: - # This should cause a validation issue at that type - break - presentation_tmp = types_dict[derived_from] - if presentation_tmp._name in hierarchy: - report_issue_for_circular_type_hierarchy(context, presentation, field.name) - break - hierarchy.append(presentation_tmp._name) - - return validator_fn http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/presentation/fields.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/presentation/fields.py b/apache-ariatosca-0.1.1/aria/parser/presentation/fields.py deleted file mode 100644 index 959bad1..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/presentation/fields.py +++ /dev/null @@ -1,756 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -import threading -from functools import wraps -from types import MethodType - -from ...exceptions import AriaException -from ...utils.collections import FrozenDict, FrozenList, deepcopy_with_locators, merge, OrderedDict -from ...utils.caching import cachedmethod -from ...utils.console import puts -from ...utils.formatting import as_raw, safe_repr -from ...utils.type import full_type_name -from ...utils.exceptions import print_exception -from ..exceptions import InvalidValueError - -from .null import NULL -from .utils import validate_primitive - -# -# Class decorators -# - -# pylint: disable=unused-argument - -def has_fields(cls): - """ - Class decorator for validated field support. - - 1. Adds a ``FIELDS`` class property that is a dict of all the fields. Will inherit and merge - ``FIELDS`` properties from base classes if they have them. - - 2. Generates automatic ``@property`` implementations for the fields with the help of a set of - special function decorators. - - The class also works with the Python dict protocol, so that fields can be accessed via dict - semantics. The functionality is identical to that of using attribute access. - - The class will also gain two utility methods, ``_iter_field_names`` and ``_iter_fields``. - """ - - # Make sure we have FIELDS - if 'FIELDS' not in cls.__dict__: - setattr(cls, 'FIELDS', OrderedDict()) - - # Inherit FIELDS from base classes - for base in cls.__bases__: - if hasattr(base, 'FIELDS'): - cls.FIELDS.update(base.FIELDS) - - # We could do this: - # - # for name, field in cls.__dict__.iteritems(): - # - # But dir() is better because it has a deterministic order (alphabetical) - - for name in dir(cls): - field = getattr(cls, name) - - if isinstance(field, Field): - # Accumulate - cls.FIELDS[name] = field - - field.name = name - field.container_cls = cls - - # This function is here just to create an enclosed scope for "field" - def closure(field): - - # By convention, we have the getter wrap the original function. - # (It is, for example, where the Python help() function will look for - # docstrings when encountering a property.) - @cachedmethod - @wraps(field.func) - def getter(self): - return field.get(self, None) - - def setter(self, value): - field.set(self, None, value) - - # Convert to Python property - return property(fget=getter, fset=setter) - - setattr(cls, name, closure(field)) - - # Bind methods - setattr(cls, '_iter_field_names', MethodType(has_fields_iter_field_names, None, cls)) - setattr(cls, '_iter_fields', MethodType(has_fields_iter_fields, None, cls)) - - # Behave like a dict - setattr(cls, '__len__', MethodType(has_fields_len, None, cls)) - setattr(cls, '__getitem__', MethodType(has_fields_getitem, None, cls)) - setattr(cls, '__setitem__', MethodType(has_fields_setitem, None, cls)) - setattr(cls, '__delitem__', MethodType(has_fields_delitem, None, cls)) - setattr(cls, '__iter__', MethodType(has_fields_iter, None, cls)) - setattr(cls, '__contains__', MethodType(has_fields_contains, None, cls)) - - return cls - - -def short_form_field(name): - """ - Class decorator for specifying the short form field. - - The class must be decorated with :func:`has_fields`. - """ - - def decorator(cls): - if hasattr(cls, name) and hasattr(cls, 'FIELDS') and (name in cls.FIELDS): - setattr(cls, 'SHORT_FORM_FIELD', name) - return cls - else: - raise AttributeError('@short_form_field must be used with ' - 'a Field name in @has_fields class') - return decorator - - -def allow_unknown_fields(cls): - """ - Class decorator specifying that the class allows unknown fields. - - The class must be decorated with :func:`has_fields`. - """ - - if hasattr(cls, 'FIELDS'): - setattr(cls, 'ALLOW_UNKNOWN_FIELDS', True) - return cls - else: - raise AttributeError('@allow_unknown_fields must be used with a @has_fields class') - -# -# Method decorators -# - - -def primitive_field(cls=None, default=None, allowed=None, required=False): - """ - Method decorator for primitive fields. - - The function must be a method in a class decorated with :func:`has_fields`. - """ - - def decorator(func): - return Field(field_variant='primitive', func=func, cls=cls, default=default, - allowed=allowed, required=required) - return decorator - - -def primitive_list_field(cls=None, default=None, allowed=None, required=False): - """ - Method decorator for list of primitive fields. - - The function must be a method in a class decorated with :func:`has_fields`. - """ - - def decorator(func): - return Field(field_variant='primitive_list', func=func, cls=cls, default=default, - allowed=allowed, required=required) - return decorator - - -def primitive_dict_field(cls=None, default=None, allowed=None, required=False): - """ - Method decorator for dict of primitive fields. - - The function must be a method in a class decorated with :func:`has_fields`. - """ - def decorator(func): - return Field(field_variant='primitive_dict', func=func, cls=cls, default=default, - allowed=allowed, required=required) - return decorator - - -def primitive_dict_unknown_fields(cls=None, default=None, allowed=None, required=False): - """ - Method decorator for dict of primitive fields, for all the fields that are - not already decorated. - - The function must be a method in a class decorated with :func:`has_fields`. - """ - - def decorator(func): - return Field(field_variant='primitive_dict_unknown_fields', func=func, cls=cls, - default=default, allowed=allowed, required=required) - return decorator - - -def object_field(cls, default=None, allowed=None, required=False): - """ - Method decorator for object fields. - - The function must be a method in a class decorated with :func:`has_fields`. - """ - def decorator(func): - return Field(field_variant='object', func=func, cls=cls, default=default, allowed=allowed, - required=required) - return decorator - - -def object_list_field(cls, default=None, allowed=None, required=False): - """ - Method decorator for list of object fields. - - The function must be a method in a class decorated with :func:`has_fields`. - """ - - def decorator(func): - return Field(field_variant='object_list', func=func, cls=cls, default=default, - allowed=allowed, required=required) - return decorator - - -def object_dict_field(cls, default=None, allowed=None, required=False): - """ - Method decorator for dict of object fields. - - The function must be a method in a class decorated with :func:`has_fields`. - """ - - def decorator(func): - return Field(field_variant='object_dict', func=func, cls=cls, default=default, - allowed=allowed, required=required) - return decorator - - -def object_sequenced_list_field(cls, default=None, allowed=None, required=False): - """ - Method decorator for sequenced list of object fields. - - The function must be a method in a class decorated with :func:`has_fields`. - """ - - def decorator(func): - return Field(field_variant='sequenced_object_list', func=func, cls=cls, default=default, - allowed=allowed, required=required) - return decorator - - -def object_dict_unknown_fields(cls, default=None, allowed=None, required=False): - """ - Method decorator for dict of object fields, for all the fields that are not already decorated. - - The function must be a method in a class decorated with :func:`has_fields`. - """ - def decorator(func): - return Field(field_variant='object_dict_unknown_fields', func=func, cls=cls, - default=default, allowed=allowed, required=required) - return decorator - - -def field_getter(getter_func): - """ - Method decorator for overriding the getter function of a field. - - The signature of the getter function must be: ``f(field, presentation, context)``. - The default getter can be accessed as ```field.default_get(presentation, context)``. - - The function must already be decorated with a field decorator. - """ - - def decorator(field): - if isinstance(field, Field): - field.get = MethodType(getter_func, field, Field) - return field - else: - raise AttributeError('@field_getter must be used with a Field') - return decorator - - -def field_setter(setter_func): - """ - Method decorator for overriding the setter function of a field. - - The signature of the setter function must be: ``f(field, presentation, context, value)``. - The default setter can be accessed as ``field.default_set(presentation, context, value)``. - - The function must already be decorated with a field decorator. - """ - - def decorator(field): - if isinstance(field, Field): - field.set = MethodType(setter_func, field, Field) - return field - else: - raise AttributeError('@field_setter must be used with a Field') - return decorator - - -def field_validator(validator_fn): - """ - Method decorator for overriding the validator function of a field. - - The signature of the validator function must be: ``f(field, presentation, context)``. - The default validator can be accessed as ``field.default_validate(presentation, context)``. - - The function must already be decorated with a field decorator. - """ - - def decorator(field): - if isinstance(field, Field): - field.validate = MethodType(validator_fn, field, Field) - return field - else: - raise AttributeError('@field_validator must be used with a Field') - return decorator - -# -# Utils -# - - -def has_fields_iter_field_names(self): - for name in self.__class__.FIELDS: - yield name - - -def has_fields_iter_fields(self): - return self.FIELDS.iteritems() - - -def has_fields_len(self): - return len(self.__class__.FIELDS) - - -def has_fields_getitem(self, key): - if not isinstance(key, basestring): - raise TypeError('key must be a string') - if key not in self.__class__.FIELDS: - raise KeyError('no \'%s\' property' % key) - return getattr(self, key) - - -def has_fields_setitem(self, key, value): - if not isinstance(key, basestring): - raise TypeError('key must be a string') - if key not in self.__class__.FIELDS: - raise KeyError('no \'%s\' property' % key) - return setattr(self, key, value) - - -def has_fields_delitem(self, key): - if not isinstance(key, basestring): - raise TypeError('key must be a string') - if key not in self.__class__.FIELDS: - raise KeyError('no \'%s\' property' % key) - return setattr(self, key, None) - - -def has_fields_iter(self): - return self.__class__.FIELDS.iterkeys() - - -def has_fields_contains(self, key): - if not isinstance(key, basestring): - raise TypeError('key must be a string') - return key in self.__class__.FIELDS - - -class Field(object): - """ - Field handler used by ``@has_fields`` decorator. - """ - - def __init__(self, field_variant, func, cls=None, default=None, allowed=None, required=False): - if cls == str: - # Use "unicode" instead of "str" - cls = unicode - - self.container_cls = None - self.name = None - self.field_variant = field_variant - self.func = func - self.cls = cls - self.default = default - self.allowed = allowed - self.required = required - - @property - def full_name(self): - return 'field "%s" in "%s"' % (self.name, full_type_name(self.container_cls)) - - @property - def full_cls_name(self): - name = full_type_name(self.cls) - if name == 'unicode': - # For simplicity, display "unicode" as "str" - name = 'str' - return name - - def get(self, presentation, context): - return self.default_get(presentation, context) - - def set(self, presentation, context, value): - return self.default_set(presentation, context, value) - - def validate(self, presentation, context): - self.default_validate(presentation, context) - - def get_locator(self, raw): - if hasattr(raw, '_locator'): - locator = raw._locator - if locator is not None: - return locator.get_child(self.name) - return None - - def dump(self, presentation, context): - value = getattr(presentation, self.name) - if value is None: - return - - dumper = getattr(self, '_dump_%s' % self.field_variant) - dumper(context, value) - - def default_get(self, presentation, context): - # Handle raw - - default_raw = (presentation._get_default_raw() - if hasattr(presentation, '_get_default_raw') - else None) - - if default_raw is None: - raw = presentation._raw - else: - # Handle default raw value - raw = deepcopy_with_locators(default_raw) - merge(raw, presentation._raw) - - # Handle unknown fields - - if self.field_variant == 'primitive_dict_unknown_fields': - return self._get_primitive_dict_unknown_fields(presentation, raw, context) - elif self.field_variant == 'object_dict_unknown_fields': - return self._get_object_dict_unknown_fields(presentation, raw, context) - - is_short_form_field = (self.container_cls.SHORT_FORM_FIELD == self.name - if hasattr(self.container_cls, 'SHORT_FORM_FIELD') - else False) - is_dict = isinstance(raw, dict) - - # Find value - - value = self._find_value(is_short_form_field, is_dict, raw) - - # Handle required - - if value is None: - if self.required: - raise InvalidValueError('required %s does not have a value' % self.full_name, - locator=self.get_locator(raw)) - else: - return None - - # Handle allowed values - - if self.allowed is not None: - if value not in self.allowed: - raise InvalidValueError('%s is not %s' - % (self.full_name, ' or '.join([safe_repr(v) - for v in self.allowed])), - locator=self.get_locator(raw)) - - # Handle get according to variant - - getter = getattr(self, '_get_%s' % self.field_variant, None) - - if getter is None: - locator = self.get_locator(raw) - location = (' @%s' % locator) if locator is not None else '' - raise AttributeError('%s has unsupported field variant: "%s"%s' - % (self.full_name, self.field_variant, location)) - - return getter(presentation, raw, value, context) - - def _find_value(self, is_short_form_field, is_dict, raw): - value = None - if is_short_form_field and not is_dict: - # Handle short form - value = raw - elif is_dict: - if self.name in raw: - value = raw[self.name] - if value is None: - # An explicit null - value = NULL - else: - value = self.default - return value - - def default_set(self, presentation, context, value): - raw = presentation._raw - old = self.get(presentation, context) - raw[self.name] = value - try: - self.validate(presentation, context) - except Exception as e: - raw[self.name] = old - raise e - return old - - def default_validate(self, presentation, context): - value = None - - try: - value = self.get(presentation, context) - except AriaException as e: - if e.issue: - context.validation.report(issue=e.issue) - except Exception as e: - context.validation.report(exception=e) - print_exception(e) - - self.validate_value(value, context) - - def validate_value(self, value, context): - if isinstance(value, list): - if self.field_variant == 'object_list': - for element in value: - if hasattr(element, '_validate'): - element._validate(context) - elif self.field_variant == 'sequenced_object_list': - for _, element in value: - if hasattr(element, '_validate'): - element._validate(context) - elif isinstance(value, dict): - if self.field_variant in ('object_dict', 'object_dict_unknown_fields'): - for inner_value in value.itervalues(): - if hasattr(inner_value, '_validate'): - inner_value._validate(context) - - if hasattr(value, '_validate'): - value._validate(context) - - @staticmethod - def _get_context(): - thread_locals = threading.local() - return getattr(thread_locals, 'aria_consumption_context', None) - - def _coerce_primitive(self, value, context): - if context is None: - context = Field._get_context() - allow_primitive_coercion = (context.validation.allow_primitive_coersion - if context is not None - else True) - return validate_primitive(value, self.cls, allow_primitive_coercion) - - # primitive - - def _get_primitive(self, presentation, raw, value, context): - if (self.cls is not None and not isinstance(value, self.cls) - and value is not None and value is not NULL): - try: - return self._coerce_primitive(value, context) - except ValueError as e: - raise InvalidValueError('%s is not a valid "%s": %s' % - (self.full_name, self.full_cls_name, safe_repr(value)), - locator=self.get_locator(raw), cause=e) - return value - - def _dump_primitive(self, context, value): - if hasattr(value, 'as_raw'): - value = as_raw(value) - puts('%s: %s' % (self.name, context.style.literal(value))) - - # primitive list - - def _get_primitive_list(self, presentation, raw, value, context): - if not isinstance(value, list): - raise InvalidValueError('%s is not a list: %s' % (self.full_name, safe_repr(value)), - locator=self.get_locator(raw)) - primitive_list = value - if self.cls is not None: - if context is None: - context = Field._get_context() - primitive_list = [] - for i, _ in enumerate(value): - primitive = value[i] - try: - primitive = self._coerce_primitive(primitive, context) - except ValueError as e: - raise InvalidValueError('%s is not a list of "%s": element %d is %s' - % (self.full_name, - self.full_cls_name, - i, - safe_repr(primitive)), - locator=self.get_locator(raw), cause=e) - if primitive in primitive_list: - raise InvalidValueError('%s has a duplicate "%s": %s' - % (self.full_name, - self.full_cls_name, - safe_repr(primitive)), - locator=self.get_locator(raw)) - primitive_list.append(primitive) - return FrozenList(primitive_list) - - def _dump_primitive_list(self, context, value): - puts('%s:' % self.name) - with context.style.indent: - for primitive in value: - if hasattr(primitive, 'as_raw'): - primitive = as_raw(primitive) - puts(context.style.literal(primitive)) - - # primitive dict - - def _get_primitive_dict(self, presentation, raw, value, context): - if not isinstance(value, dict): - raise InvalidValueError('%s is not a dict: %s' % (self.full_name, safe_repr(value)), - locator=self.get_locator(raw)) - primitive_dict = value - if self.cls is not None: - if context is None: - context = Field._get_context() - primitive_dict = OrderedDict() - for k, v in value.iteritems(): - try: - primitive_dict[k] = self._coerce_primitive(v, context) - except ValueError as e: - raise InvalidValueError('%s is not a dict of "%s" values: entry "%d" is %s' - % (self.full_name, self.full_cls_name, k, safe_repr(v)), - locator=self.get_locator(raw), - cause=e) - return FrozenDict(primitive_dict) - - def _dump_primitive_dict(self, context, value): - puts('%s:' % self.name) - with context.style.indent: - for v in value.itervalues(): - if hasattr(v, 'as_raw'): - v = as_raw(v) - puts(context.style.literal(v)) - - # object - - def _get_object(self, presentation, raw, value, context): - try: - return self.cls(name=self.name, raw=value, container=presentation) - except TypeError as e: - raise InvalidValueError('%s cannot not be initialized to an instance of "%s": %s' - % (self.full_name, self.full_cls_name, safe_repr(value)), - cause=e, - locator=self.get_locator(raw)) - - def _dump_object(self, context, value): - puts('%s:' % self.name) - with context.style.indent: - if hasattr(value, '_dump'): - value._dump(context) - - # object list - - def _get_object_list(self, presentation, raw, value, context): - if not isinstance(value, list): - raise InvalidValueError('%s is not a list: %s' - % (self.full_name, safe_repr(value)), - locator=self.get_locator(raw)) - return FrozenList((self.cls(name=self.name, raw=v, container=presentation) for v in value)) - - def _dump_object_list(self, context, value): - puts('%s:' % self.name) - with context.style.indent: - for v in value: - if hasattr(v, '_dump'): - v._dump(context) - - # object dict - - def _get_object_dict(self, presentation, raw, value, context): - if not isinstance(value, dict): - raise InvalidValueError('%s is not a dict: %s' % (self.full_name, safe_repr(value)), - locator=self.get_locator(raw)) - return FrozenDict(((k, self.cls(name=k, raw=v, container=presentation)) - for k, v in value.iteritems())) - - def _dump_object_dict(self, context, value): - puts('%s:' % self.name) - with context.style.indent: - for v in value.itervalues(): - if hasattr(v, '_dump'): - v._dump(context) - - # sequenced object list - - def _get_sequenced_object_list(self, presentation, raw, value, context): - if not isinstance(value, list): - raise InvalidValueError('%s is not a sequenced list (a list of dicts, ' - 'each with exactly one key): %s' - % (self.full_name, safe_repr(value)), - locator=self.get_locator(raw)) - sequence = [] - for v in value: - if not isinstance(v, dict): - raise InvalidValueError('%s list elements are not all dicts with ' - 'exactly one key: %s' % (self.full_name, safe_repr(value)), - locator=self.get_locator(raw)) - if len(v) != 1: - raise InvalidValueError('%s list elements do not all have exactly one key: %s' - % (self.full_name, safe_repr(value)), - locator=self.get_locator(raw)) - key, value = v.items()[0] - sequence.append((key, self.cls(name=key, raw=value, container=presentation))) - return FrozenList(sequence) - - def _dump_sequenced_object_list(self, context, value): - puts('%s:' % self.name) - for _, v in value: - if hasattr(v, '_dump'): - v._dump(context) - - # primitive dict for unknown fields - - def _get_primitive_dict_unknown_fields(self, presentation, raw, context): - if isinstance(raw, dict): - primitive_dict = raw - if self.cls is not None: - if context is None: - context = Field._get_context() - primitive_dict = OrderedDict() - for k, v in raw.iteritems(): - if k not in presentation.FIELDS: - try: - primitive_dict[k] = self._coerce_primitive(v, context) - except ValueError as e: - raise InvalidValueError('%s is not a dict of "%s" values:' - ' entry "%d" is %s' - % (self.full_name, self.full_cls_name, - k, safe_repr(v)), - locator=self.get_locator(raw), - cause=e) - return FrozenDict(primitive_dict) - return None - - def _dump_primitive_dict_unknown_fields(self, context, value): - self._dump_primitive_dict(context, value) - - # object dict for unknown fields - - def _get_object_dict_unknown_fields(self, presentation, raw, context): - if isinstance(raw, dict): - return FrozenDict(((k, self.cls(name=k, raw=v, container=presentation)) - for k, v in raw.iteritems() if k not in presentation.FIELDS)) - return None - - def _dump_object_dict_unknown_fields(self, context, value): - self._dump_object_dict(context, value) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/presentation/null.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/presentation/null.py b/apache-ariatosca-0.1.1/aria/parser/presentation/null.py deleted file mode 100644 index 287d2ba..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/presentation/null.py +++ /dev/null @@ -1,67 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -from ...utils.collections import deepcopy_with_locators - - -class Null(object): - """ - Represents an explicit null value provided by the user, which is different from - not supplying a value at all. - - It is a singleton. - """ - - @property - def as_raw(self): - return None - -NULL = Null() - - -def none_to_null(value): - """ - Convert ``None`` to ``NULL``, recursively. - """ - - if value is None: - return NULL - if isinstance(value, list): - value = deepcopy_with_locators(value) - for i, _ in enumerate(value): - value[i] = none_to_null(value[i]) - elif isinstance(value, dict): - value = deepcopy_with_locators(value) - for k, v in value.iteritems(): - value[k] = none_to_null(v) - return value - - -def null_to_none(value): - """ - Convert ``NULL`` to ``None``, recursively. - """ - - if value is NULL: - return None - if isinstance(value, list): - value = deepcopy_with_locators(value) - for i, _ in enumerate(value): - value[i] = none_to_null(value[i]) - elif isinstance(value, dict): - value = deepcopy_with_locators(value) - for k, v in value.iteritems(): - value[k] = none_to_null(v) - return value http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/presentation/presentation.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/presentation/presentation.py b/apache-ariatosca-0.1.1/aria/parser/presentation/presentation.py deleted file mode 100644 index 7292562..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/presentation/presentation.py +++ /dev/null @@ -1,235 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -from ...utils.caching import HasCachedMethods -from ...utils.collections import deepcopy_with_locators -from ...utils.formatting import safe_repr -from ...utils.type import full_type_name -from ...utils.console import puts -from ..validation import Issue -from .null import none_to_null -from .utils import (get_locator, validate_no_short_form, validate_no_unknown_fields, - validate_known_fields, validate_primitive) - - -class Value(object): - """ - Encapsulates a typed value assignment. - """ - - def __init__(self, type_name, value, description): - self.type = deepcopy_with_locators(type_name) - self.value = deepcopy_with_locators(value) - self.description = deepcopy_with_locators(description) - - -class PresentationBase(HasCachedMethods): - """ - Base class for ARIA presentation classes. - """ - - def __init__(self, name=None, raw=None, container=None): - self._name = name - self._raw = raw - self._container = container - super(PresentationBase, self).__init__() - - @property - def as_raw(self): - return self._raw - - def _validate(self, context): - """ - Validates the presentation while reporting errors in the validation context but *not* - raising exceptions. - - The base class does not thing, but subclasses may override this for specialized validation. - """ - - @property - def _fullname(self): - """ - Always returns a usable full name of the presentation, whether it itself is named, or - recursing to its container, and finally defaulting to the class name. - """ - - if self._name is not None: - return self._name - elif self._container is not None: - return self._container._fullname - return full_type_name(self) - - @property - def _locator(self): - """ - Attempts to return the most relevant locator, whether we have one, or recursing to our - container. - - :rtype: :class:`aria.parser.reading.Locator` - """ - - return get_locator(self._raw, self._container) - - def _get(self, *names): - """ - Gets attributes recursively. - """ - - obj = self - if (obj is not None) and names: - for name in names: - obj = getattr(obj, name, None) - if obj is None: - break - return obj - - def _get_from_dict(self, *names): - """ - Gets attributes recursively, except for the last name which is used to get a value from the - last dict. - """ - - if names: - obj = self._get(*names[:-1]) - if isinstance(obj, dict): - return obj.get(names[-1]) # pylint: disable=no-member - return None - - def _get_child_locator(self, *names): - """ - Attempts to return the locator of one our children. Will default to our locator if not - found. - - :rtype: :class:`aria.parser.reading.Locator` - """ - - if hasattr(self._raw, '_locator'): - locator = self._raw._locator - if locator is not None: - return locator.get_child(*names) - return self._locator - - def _dump(self, context): - """ - Emits a colorized representation. - - The base class will emit a sensible default representation of the fields, (by calling - ``_dump_content``), but subclasses may override this for specialized dumping. - """ - - if self._name: - puts(context.style.node(self._name)) - with context.style.indent: - self._dump_content(context) - else: - self._dump_content(context) - - def _dump_content(self, context, field_names=None): - """ - Emits a colorized representation of the contents. - - The base class will call ``_dump_field`` on all the fields, but subclasses may override - this for specialized dumping. - """ - - if field_names: - for field_name in field_names: - self._dump_field(context, field_name) - elif hasattr(self, '_iter_field_names'): - for field_name in self._iter_field_names(): # pylint: disable=no-member - self._dump_field(context, field_name) - else: - puts(context.style.literal(self._raw)) - - def _dump_field(self, context, field_name): - """ - Emits a colorized representation of the field. - - According to the field type, this may trigger nested recursion. The nested types will - delegate to their ``_dump`` methods. - """ - - field = self.FIELDS[field_name] # pylint: disable=no-member - field.dump(self, context) - - def _clone(self, container=None): - """ - Creates a clone of this presentation, optionally allowing for a new container. - """ - - raw = deepcopy_with_locators(self._raw) - if container is None: - container = self._container - return self.__class__(name=self._name, raw=raw, container=container) - - -class Presentation(PresentationBase): - """ - Base class for ARIA presentations. A presentation is a Pythonic wrapper around agnostic raw - data, adding the ability to read and modify the data with proper validation. - - ARIA presentation classes will often be decorated with :func:`has_fields`, as that mechanism - automates a lot of field-specific validation. However, that is not a requirement. - - Make sure that your utility property and method names begin with a ``_``, because those names - without a ``_`` prefix are normally reserved for fields. - """ - - def _validate(self, context): - validate_no_short_form(context, self) - validate_no_unknown_fields(context, self) - validate_known_fields(context, self) - - -class AsIsPresentation(PresentationBase): - """ - Base class for trivial ARIA presentations that provide the raw value as is. - """ - - def __init__(self, name=None, raw=None, container=None, cls=None): - super(AsIsPresentation, self).__init__(name, raw, container) - self.cls = cls - - @property - def value(self): - return none_to_null(self._raw) - - @value.setter - def value(self, value): - self._raw = value - - @property - def _full_cls_name(self): - name = full_type_name(self.cls) if self.cls is not None else None - if name == 'unicode': - # For simplicity, display "unicode" as "str" - name = 'str' - return name - - def _validate(self, context): - try: - validate_primitive(self._raw, self.cls, context.validation.allow_primitive_coersion) - except ValueError as e: - context.validation.report('"%s" is not a valid "%s": %s' - % (self._fullname, self._full_cls_name, safe_repr(self._raw)), - locator=self._locator, - level=Issue.FIELD, - exception=e) - - def _dump(self, context): - if hasattr(self._raw, '_dump'): - self._raw._dump(context) - else: - super(AsIsPresentation, self)._dump(context) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/presentation/presenter.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/presentation/presenter.py b/apache-ariatosca-0.1.1/aria/parser/presentation/presenter.py deleted file mode 100644 index 9fd296f..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/presentation/presenter.py +++ /dev/null @@ -1,70 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -from ...utils.collections import merge -from ...utils.formatting import safe_repr -from ..validation import Issue -from .presentation import Presentation - - -class Presenter(Presentation): - """ - Base class for ARIA presenters. - - Presenters provide a robust API over agnostic raw data. - """ - - DSL_VERSIONS = None - ALLOWED_IMPORTED_DSL_VERSIONS = None - - @classmethod - def can_present(cls, raw): - dsl = raw.get('tosca_definitions_version') - assert cls.DSL_VERSIONS - return dsl in cls.DSL_VERSIONS - - def _validate_import(self, context, presentation): - tosca_definitions_version = presentation.service_template.tosca_definitions_version - assert self.ALLOWED_IMPORTED_DSL_VERSIONS - if tosca_definitions_version is not None \ - and tosca_definitions_version not in self.__class__.ALLOWED_IMPORTED_DSL_VERSIONS: - context.validation.report( - 'import "tosca_definitions_version" is not one of %s: %s' - % (' or '.join([safe_repr(v) - for v in self.__class__.ALLOWED_IMPORTED_DSL_VERSIONS]), - presentation.service_template.tosca_definitions_version), - locator=presentation._get_child_locator('inputs'), - level=Issue.BETWEEN_TYPES) - return False - return True - - def _merge_import(self, presentation): - merge(self._raw, presentation._raw) - if hasattr(self._raw, '_locator') and hasattr(presentation._raw, '_locator'): - self._raw._locator.merge(presentation._raw._locator) - - def _link_locators(self): - if hasattr(self._raw, '_locator'): - locator = self._raw._locator - delattr(self._raw, '_locator') - locator.link(self._raw) - - @staticmethod - def _get_import_locations(context): - raise NotImplementedError - - @staticmethod - def _get_deployment_template(context): - raise NotImplementedError http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/presentation/source.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/presentation/source.py b/apache-ariatosca-0.1.1/aria/parser/presentation/source.py deleted file mode 100644 index 4bfb8e1..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/presentation/source.py +++ /dev/null @@ -1,55 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - - -from ...extension import parser - -from .exceptions import PresenterNotFoundError - - -class PresenterSource(object): - """ - Base class for ARIA presenter sources. - - Presenter sources provide appropriate :class:`Presenter` classes for agnostic raw data. - """ - - def get_presenter(self, raw): # pylint: disable=unused-argument,no-self-use - raise PresenterNotFoundError('presenter not found') - - -class DefaultPresenterSource(PresenterSource): - """ - The default ARIA presenter source. - """ - - def __init__(self, classes=None): - if classes is None: - classes = parser.presenter_class() - self.classes = classes - - def get_presenter(self, raw): - for cls in self.classes: - if cls.can_present(raw): - return cls - - if 'tosca_definitions_version' in raw: - if raw['tosca_definitions_version'] is None: - raise PresenterNotFoundError("'tosca_definitions_version' is not specified") - if not isinstance(raw['tosca_definitions_version'], basestring): - raise PresenterNotFoundError("'tosca_definitions_version' is not a string") - if not raw['tosca_definitions_version']: - raise PresenterNotFoundError("'tosca_definitions_version' is not specified") - return super(DefaultPresenterSource, self).get_presenter(raw) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca-website/blob/23d6ba76/apache-ariatosca-0.1.1/aria/parser/presentation/utils.py ---------------------------------------------------------------------- diff --git a/apache-ariatosca-0.1.1/aria/parser/presentation/utils.py b/apache-ariatosca-0.1.1/aria/parser/presentation/utils.py deleted file mode 100644 index f0fd390..0000000 --- a/apache-ariatosca-0.1.1/aria/parser/presentation/utils.py +++ /dev/null @@ -1,187 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. - -from types import FunctionType - -from ...utils.formatting import safe_repr -from ...utils.type import full_type_name -from ..validation import Issue -from .null import NULL - - -def get_locator(*values): - """ - Gets the first available locator. - - :rtype: :class:`aria.parser.reading.Locator` - """ - - for v in values: - if hasattr(v, '_locator'): - locator = v._locator - if locator is not None: - return locator - return None - - -def parse_types_dict_names(types_dict_names): - """ - If the first element in the array is a function, extracts it out. - """ - - convert = None - if isinstance(types_dict_names[0], FunctionType): - convert = types_dict_names[0] - types_dict_names = types_dict_names[1:] - return types_dict_names, convert - - -def validate_primitive(value, cls, coerce=False): - """ - Checks if the value is of the primitive type, optionally attempting to coerce it - if it is not. - - :raises ValueError: if not a primitive type or if coercion failed. - """ - - if (cls is not None) and (value is not None) and (value is not NULL): - if (cls is unicode) or (cls is str): # These two types are interchangeable - valid = isinstance(value, basestring) - elif cls is int: - # In Python, a bool is an int - valid = isinstance(value, int) and not isinstance(value, bool) - else: - valid = isinstance(value, cls) - if not valid: - if coerce: - value = cls(value) - else: - raise ValueError('not a "%s": %s' % (full_type_name(cls), safe_repr(value))) - return value - - -def validate_no_short_form(context, presentation): - """ - Makes sure that we can use short form definitions only if we allowed it. - """ - - if not hasattr(presentation, 'SHORT_FORM_FIELD') and not isinstance(presentation._raw, dict): - context.validation.report('short form not allowed for field "%s"' % presentation._fullname, - locator=presentation._locator, - level=Issue.BETWEEN_FIELDS) - - -def validate_no_unknown_fields(context, presentation): - """ - Make sure that we can use unknown fields only if we allowed it. - """ - - if not getattr(presentation, 'ALLOW_UNKNOWN_FIELDS', False) \ - and not context.validation.allow_unknown_fields \ - and isinstance(presentation._raw, dict) \ - and hasattr(presentation, 'FIELDS'): - for k in presentation._raw: - if k not in presentation.FIELDS: - context.validation.report('field "%s" is not supported in "%s"' - % (k, presentation._fullname), - locator=presentation._get_child_locator(k), - level=Issue.BETWEEN_FIELDS) - - -def validate_known_fields(context, presentation): - """ - Validates all known fields. - """ - - if hasattr(presentation, '_iter_fields'): - for _, field in presentation._iter_fields(): - field.validate(presentation, context) - - -def get_parent_presentation(context, presentation, *types_dict_names): - """ - Returns the parent presentation according to the ``derived_from`` field, or ``None`` if invalid. - - Checks that we do not derive from ourselves and that we do not cause a circular hierarchy. - - The arguments from the third onwards are used to locate a nested field under - ``service_template`` under the root presenter. The first of these can optionally be a function, - in which case it will be called to convert type names. This can be used to support shorthand - type names, aliases, etc. - """ - - type_name = presentation.derived_from - - if type_name is None: - return None - - types_dict_names, convert = parse_types_dict_names(types_dict_names) - types_dict = context.presentation.get('service_template', *types_dict_names) or {} - - if convert: - type_name = convert(context, type_name, types_dict) - - # Make sure not derived from self - if type_name == presentation._name: - return None - # Make sure derived from type exists - elif type_name not in types_dict: - return None - else: - # Make sure derivation hierarchy is not circular - hierarchy = [presentation._name] - presentation_copy = presentation - while presentation_copy.derived_from is not None: - derived_from = presentation_copy.derived_from - if convert: - derived_from = convert(context, derived_from, types_dict) - - if derived_from == presentation_copy._name or derived_from not in types_dict: - return None - presentation_copy = types_dict[derived_from] - if presentation_copy._name in hierarchy: - return None - hierarchy.append(presentation_copy._name) - - return types_dict[type_name] - - -def report_issue_for_unknown_type(context, presentation, type_name, field_name, value=None): - if value is None: - value = getattr(presentation, field_name) - context.validation.report('"%s" refers to an unknown %s in "%s": %s' - % (field_name, type_name, presentation._fullname, safe_repr(value)), - locator=presentation._get_child_locator(field_name), - level=Issue.BETWEEN_TYPES) - - -def report_issue_for_parent_is_self(context, presentation, field_name): - context.validation.report('parent type of "%s" is self' % presentation._fullname, - locator=presentation._get_child_locator(field_name), - level=Issue.BETWEEN_TYPES) - - -def report_issue_for_unknown_parent_type(context, presentation, field_name): - context.validation.report('unknown parent type "%s" in "%s"' - % (getattr(presentation, field_name), presentation._fullname), - locator=presentation._get_child_locator(field_name), - level=Issue.BETWEEN_TYPES) - - -def report_issue_for_circular_type_hierarchy(context, presentation, field_name): - context.validation.report('"%s" of "%s" creates a circular type hierarchy' - % (getattr(presentation, field_name), presentation._fullname), - locator=presentation._get_child_locator(field_name), - level=Issue.BETWEEN_TYPES)
