/rivoli-class-hierarchy-model/src/main/groovy/com/googlecode/rivoli/model/classhierarchy/ElementConverter.groovy
Groovy | 107 lines | 67 code | 25 blank | 15 comment | 10 complexity | d631d9960ff54daa1796c5274791460f MD5 | raw file
Possible License(s): Apache-2.0
- /*
- * Copyright 2011-2012 Rivoli team
- *
- * Licensed 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.
- */
- package com.googlecode.rivoli.model.classhierarchy
- import com.googlecode.rivoli.RivoliException
- import com.googlecode.rivoli.model.AttributeDescriptor
- import com.googlecode.rivoli.model.Element
- import com.googlecode.rivoli.model.ElementDescriptor
- import java.lang.reflect.Field
- class ElementConverter {
- static <T> T convert(Element element, Class<T> elementClass) {
- T object = createObject(element.descriptor, elementClass)
- setAttributes(object, element, element.descriptor)
- convertChildren(object, element)
- object
- }
- private static <T> T createObject(ElementDescriptor elementDescriptor, Class<T> elementClass) {
- T object = elementClass.newInstance()
- String elementClassName = elementClass.simpleName.humanize()
- Set<String> possibleElementClassNames = getPossibleElementClassNames(elementDescriptor)
- if (!(elementClassName in possibleElementClassNames)) {
- throw new RivoliException("unexpected element name '${elementClassName}', expected one of ${possibleElementClassNames}")
- }
- object
- }
- private static Set<String> getPossibleElementClassNames(ElementDescriptor elementDescriptor) {
- Set<String> possibleElementClassNames = []
- ElementDescriptor currentElementDescriptor = elementDescriptor
- while (currentElementDescriptor) {
- possibleElementClassNames << currentElementDescriptor.name
- currentElementDescriptor = currentElementDescriptor.parent
- }
- possibleElementClassNames
- }
- private static void setAttributes(Object object, Element element, ElementDescriptor elementDescriptor) {
- ElementDescriptor parentDescriptor = elementDescriptor.parent
- if (parentDescriptor) {
- setAttributes(object, element, parentDescriptor)
- }
- elementDescriptor.attributeDescriptors.each {AttributeDescriptor attributeDescriptor ->
- String attributeName = attributeDescriptor.name
- MetaProperty property = object.hasProperty(attributeName)
- if (!property) {
- throw new RivoliException("element class '${object.class.simpleName}' does not have a property named '${attributeName}'")
- } else if (property.type != attributeDescriptor.type) {
- throw new RivoliException("property '${attributeName}' of element class '${object.class.simpleName}' is not of type '${attributeDescriptor.type.simpleName}'")
- } else {
- object[attributeName] = element.getAttribute(attributeName)
- }
- }
- }
- private static void convertChildren(Object object, Element element) {
- if (element.descriptor.containerFor) {
- List<Object> children = []
- element.children.each {Element child ->
- children << convert(child, getClassBasedDescriptor(child).elementDescriptorClass)
- }
- Field containerField = Utilities.findContainerField(object.class, true)
- containerField.accessible = true
- containerField.set(object, children)
- }
- }
- private static ClassBasedElementDescriptor getClassBasedDescriptor(Element element) {
- ElementDescriptor descriptor = element.descriptor
- if (!(descriptor in ClassBasedElementDescriptor)) {
- throw new RivoliException("element descriptor '${descriptor.name}' is not class based")
- }
- descriptor
- }
- }