summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBWrapperHelper.java
blob: 5f90aa4d7a660bf04371742f9fada477220cf259 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
 * 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.
 */

package org.apache.tuscany.sca.databinding.jaxb;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * The JAXBWrapper tool is used to create a JAXB Object from a series of child objects (wrap) or get
 * the child objects from a JAXB Object (unwrap)
 */
public class JAXBWrapperHelper {

    /**
     * unwrap Returns the list of child objects of the jaxb object
     *
     * @param jaxbObject that represents the type
     * @param childNames list of xml child names as String
     * @param pdMap      PropertyDescriptor map for this jaxbObject
     * @return list of Objects in the same order as the element names.
     */
    public Object[] unwrap(Object jaxbObject, List<String> childNames, Map<String, JAXBPropertyDescriptor> pdMap)
        throws JAXBWrapperException {

        // Get the object that will have the property descriptors (i.e. the object representing the complexType)
        Object jaxbComplexTypeObj = jaxbObject;

        // Get the PropertyDescriptorPlus map.
        // The method makes sure that each child name has a matching jaxb property
        // checkPropertyDescriptorMap(jaxbComplexTypeObj.getClass(), childNames, pdMap);

        // Get the corresponsing objects from the jaxb bean
        ArrayList<Object> objList = new ArrayList<Object>();
        int index = 0;
        for (String childName : childNames) {
            JAXBPropertyDescriptor propInfo = getPropertyDescriptor(pdMap, childName, index);

            Object object = null;
            try {
                object = propInfo.get(jaxbComplexTypeObj);
            } catch (Throwable e) {
                throw new JAXBWrapperException(e);
            }

            objList.add(object);
            index++;
        }
        Object[] jaxbObjects = objList.toArray();
        objList = null;
        return jaxbObjects;

    }

    private JAXBPropertyDescriptor getPropertyDescriptor(Map<String, JAXBPropertyDescriptor> pdMap,
                                                         String childName,
                                                         int index) {
        JAXBPropertyDescriptor propInfo = pdMap.get(childName);
        if (propInfo == null) {
            // FIXME: [rfeng] Sometimes the child element names don't match. Get chilld by location?
            List<JAXBPropertyDescriptor> props = new ArrayList<JAXBPropertyDescriptor>(pdMap.values());
            // Sort the properties by index. We might need to take propOrder into consideration
            Collections.sort(props);
            propInfo = props.get(index);
        }
        return propInfo;
    }

    /**
     * wrap Creates a jaxb object that is initialized with the child objects.
     * <p/>
     * Note that the jaxbClass must be the class the represents the complexType. (It should never be
     * JAXBElement)
     *
     * @param jaxbClass
     * @param childNames    list of xml child names as String
     * @param childObjects, component type objects
     * @param pdMap         PropertyDescriptor map for this jaxbObject
     */
    public Object wrap(Class<?> jaxbClass,
                       List<String> childNames,
                       Map<String, Object> childObjects,
                       Map<String, JAXBPropertyDescriptor> pdMap) throws JAXBWrapperException {

        // Just like unWrap, get the property info map
        // checkPropertyDescriptorMap(jaxbClass, childNames, pdMap);

        // The jaxb object always has a default constructor.  Create the object
        Object jaxbObject = null;
        try {
            jaxbObject = jaxbClass.newInstance();
        } catch (Throwable t) {
            throw new JAXBWrapperException(t);
        }

        wrap(jaxbObject, childNames, childObjects, pdMap);

        // Return the jaxb object 
        return jaxbObject;
    }

    public void wrap(Object jaxbObject,
                     List<String> childNames,
                     Map<String, Object> childObjects,
                     Map<String, JAXBPropertyDescriptor> pdMap) {
        // Now set each object onto the jaxb object
        int index = 0;
        for (String childName : childNames) {
            JAXBPropertyDescriptor propInfo = getPropertyDescriptor(pdMap, childName, index);
            Object value = childObjects.get(childName);
            try {
                propInfo.set(jaxbObject, value);
            } catch (Throwable t) {
                throw new JAXBWrapperException(t);
            }
            index++;
        }
    }

    public Object[] unwrap(Object jaxbObject, List<String> childNames) throws JAXBWrapperException {
        // Get the property descriptor map for this JAXBClass
        Class<?> jaxbClass = jaxbObject.getClass();
        Map<String, JAXBPropertyDescriptor> pdMap = null;
        try {
            pdMap = XMLRootElementUtil.createPropertyDescriptorMap(jaxbClass);
        } catch (Throwable t) {
            throw new JAXBWrapperException(t);
        }

        // Delegate
        return unwrap(jaxbObject, childNames, pdMap);
    }

    public Object wrap(Class<?> jaxbClass, List<String> childNames, Map<String, Object> childObjects)
        throws JAXBWrapperException {
        // Get the property descriptor map
        Map<String, JAXBPropertyDescriptor> pdMap = null;
        try {
            pdMap = XMLRootElementUtil.createPropertyDescriptorMap(jaxbClass);
        } catch (Throwable t) {
            throw new JAXBWrapperException(t);
        }

        // Delegate
        return wrap(jaxbClass, childNames, childObjects, pdMap);
    }

}