PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/rivoli-class-hierarchy-model/src/main/groovy/com/googlecode/rivoli/model/classhierarchy/ElementConverter.groovy

https://code.google.com/p/rivoli/
Groovy | 107 lines | 67 code | 25 blank | 15 comment | 10 complexity | d631d9960ff54daa1796c5274791460f MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Copyright 2011-2012 Rivoli team
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.googlecode.rivoli.model.classhierarchy
  17. import com.googlecode.rivoli.RivoliException
  18. import com.googlecode.rivoli.model.AttributeDescriptor
  19. import com.googlecode.rivoli.model.Element
  20. import com.googlecode.rivoli.model.ElementDescriptor
  21. import java.lang.reflect.Field
  22. class ElementConverter {
  23. static <T> T convert(Element element, Class<T> elementClass) {
  24. T object = createObject(element.descriptor, elementClass)
  25. setAttributes(object, element, element.descriptor)
  26. convertChildren(object, element)
  27. object
  28. }
  29. private static <T> T createObject(ElementDescriptor elementDescriptor, Class<T> elementClass) {
  30. T object = elementClass.newInstance()
  31. String elementClassName = elementClass.simpleName.humanize()
  32. Set<String> possibleElementClassNames = getPossibleElementClassNames(elementDescriptor)
  33. if (!(elementClassName in possibleElementClassNames)) {
  34. throw new RivoliException("unexpected element name '${elementClassName}', expected one of ${possibleElementClassNames}")
  35. }
  36. object
  37. }
  38. private static Set<String> getPossibleElementClassNames(ElementDescriptor elementDescriptor) {
  39. Set<String> possibleElementClassNames = []
  40. ElementDescriptor currentElementDescriptor = elementDescriptor
  41. while (currentElementDescriptor) {
  42. possibleElementClassNames << currentElementDescriptor.name
  43. currentElementDescriptor = currentElementDescriptor.parent
  44. }
  45. possibleElementClassNames
  46. }
  47. private static void setAttributes(Object object, Element element, ElementDescriptor elementDescriptor) {
  48. ElementDescriptor parentDescriptor = elementDescriptor.parent
  49. if (parentDescriptor) {
  50. setAttributes(object, element, parentDescriptor)
  51. }
  52. elementDescriptor.attributeDescriptors.each {AttributeDescriptor attributeDescriptor ->
  53. String attributeName = attributeDescriptor.name
  54. MetaProperty property = object.hasProperty(attributeName)
  55. if (!property) {
  56. throw new RivoliException("element class '${object.class.simpleName}' does not have a property named '${attributeName}'")
  57. } else if (property.type != attributeDescriptor.type) {
  58. throw new RivoliException("property '${attributeName}' of element class '${object.class.simpleName}' is not of type '${attributeDescriptor.type.simpleName}'")
  59. } else {
  60. object[attributeName] = element.getAttribute(attributeName)
  61. }
  62. }
  63. }
  64. private static void convertChildren(Object object, Element element) {
  65. if (element.descriptor.containerFor) {
  66. List<Object> children = []
  67. element.children.each {Element child ->
  68. children << convert(child, getClassBasedDescriptor(child).elementDescriptorClass)
  69. }
  70. Field containerField = Utilities.findContainerField(object.class, true)
  71. containerField.accessible = true
  72. containerField.set(object, children)
  73. }
  74. }
  75. private static ClassBasedElementDescriptor getClassBasedDescriptor(Element element) {
  76. ElementDescriptor descriptor = element.descriptor
  77. if (!(descriptor in ClassBasedElementDescriptor)) {
  78. throw new RivoliException("element descriptor '${descriptor.name}' is not class based")
  79. }
  80. descriptor
  81. }
  82. }