001 /*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements. See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership. The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied. See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 *
020 */
021 package org.apache.qpid.management.wsdm.muse.serializer;
022
023 import java.net.URI;
024 import java.util.Date;
025 import java.util.HashMap;
026 import java.util.Map;
027 import java.util.UUID;
028
029 import javax.xml.XMLConstants;
030 import javax.xml.namespace.QName;
031
032 import org.apache.muse.core.serializer.Serializer;
033 import org.apache.muse.core.serializer.SerializerRegistry;
034 import org.apache.muse.ws.addressing.soap.SoapFault;
035 import org.apache.qpid.management.Names;
036 import org.w3c.dom.Attr;
037 import org.w3c.dom.Element;
038
039 /**
040 * Generic Serializer for objects.
041 * It is a general-purpose serializer used for encoding Object values.
042 */
043 public class ObjectSerializer implements Serializer
044 {
045 /**
046 * Mapping between xsd and java types.
047 */
048 private Map<String, Class<?>> xml2Java = new HashMap<String, Class<?>>();
049 {
050 xml2Java.put("xsd:long", Long.class);
051 xml2Java.put("xsd:boolean",Boolean.class);
052 xml2Java.put("xsd:double",Double.class);
053 xml2Java.put("xsd:float",Float.class);
054 xml2Java.put("xsd:integer",Integer.class);
055 xml2Java.put("xsd:int",Integer.class);
056 xml2Java.put("xsd:short",Short.class);
057 xml2Java.put("xsd:string",String.class);
058 xml2Java.put("xsd:anyURI",URI.class);
059 xml2Java.put("xsd:dateTime",Date.class);
060 xml2Java.put("xsd:QName",QName.class);
061 xml2Java.put("xsd:element",Element.class);
062 xml2Java.put("xsd:base64Binary",byte[].class);
063 xml2Java.put("qman:arrayOfLong",Long[].class);
064 xml2Java.put("qman:arrayOfBoolean",Boolean[].class);
065 xml2Java.put("qman:arrayOfDouble",Double[].class);
066 xml2Java.put("qman:arrayOfFloat",Float[].class);
067 xml2Java.put("qman:arrayOfInteger",Integer[].class);
068 xml2Java.put("qman:arrayOfShort",Short[].class);
069 xml2Java.put("qman:arrayOfString",String[].class);
070 xml2Java.put("qman:arrayOfURI",URI[].class);
071 xml2Java.put("qman:arrayOfDate",Date[].class);
072 xml2Java.put("qman:uuid",UUID.class);
073 xml2Java.put("qman:map",Map.class);
074 xml2Java.put("qman:map",HashMap.class);
075 }
076
077 private Map<Class<?>, String> java2Xml = new HashMap<Class<?>, String>();
078 {
079 java2Xml.put(UUID.class,"qman:uuid");
080 java2Xml.put(Long.class,"xsd:long");
081 java2Xml.put(long.class,"xsd:long");
082 java2Xml.put(Boolean.class,"xsd:boolean");
083 java2Xml.put(boolean.class,"xsd:boolean");
084 java2Xml.put(Double.class,"xsd:double");
085 java2Xml.put(double.class,"xsd:double");
086 java2Xml.put(Float.class,"xsd:float");
087 java2Xml.put(float.class,"xsd:float");
088 java2Xml.put(Integer.class,"xsd:integer");
089 java2Xml.put(int.class,"xsd:integer");
090 java2Xml.put(Short.class,"xsd:short");
091 java2Xml.put(short.class,"xsd:short");
092 java2Xml.put(String.class,"xsd:string");
093 java2Xml.put(URI.class,"xsd:anyURI");
094 java2Xml.put(Date.class,"xsd:dateTime");
095 java2Xml.put(QName.class,"xsd:QName");
096 java2Xml.put(Element.class,"xsd:element");
097 java2Xml.put(byte[].class,"xsd:base64Binary");
098 java2Xml.put(Long[].class,"qman:arrayOfLong");
099 java2Xml.put(long[].class,"qman:arrayOfLong");
100 java2Xml.put(Boolean[].class,"qman:arrayOfBoolean");
101 java2Xml.put(boolean[].class,"qman:arrayOfBoolean");
102 java2Xml.put(Double[].class,"qman:arrayOfDouble");
103 java2Xml.put(double[].class,"qman:arrayOfDouble");
104 java2Xml.put(Float[].class,"qman:arrayOfFloat");
105 java2Xml.put(float[].class,"qman:arrayOfFloat");
106 java2Xml.put(Integer[].class,"qman:arrayOfInteger");
107 java2Xml.put(int[].class,"qman:arrayOfInteger");
108 java2Xml.put(Short[].class,"qman:arrayOfShort");
109 java2Xml.put(short[].class,"qman:arrayOfShort");
110 java2Xml.put(String[].class,"qman:arrayOfString");
111 java2Xml.put(URI[].class,"qman:arrayOfURI");
112 java2Xml.put(Date[].class,"qman:arrayOfDate");
113 java2Xml.put(Map.class,"qman:map");
114 java2Xml.put(HashMap.class,"qman:map");
115 }
116
117 /**
118 * Converts the incoming element into the appropriate Java type.
119 * The method will fail if :
120 *
121 * <br>1) The element has no xsi:type attribute;
122 * <br>2) The xsi:type attribute has no corresponding java type on this serializer mappings.
123 *
124 * @param elementData the xml element containing data to be unmarshalled.l
125 * @return the java object as result of xml element unmarshalling.
126 * @throws SoapFault when the marshalling fails.
127 */
128 public Object fromXML(Element elementData) throws SoapFault
129 {
130 Attr typeAttribute = elementData.getAttributeNodeNS(
131 XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
132 Names.TYPE);
133
134 if (typeAttribute == null)
135 {
136 throw new SoapFault(
137 "No type attribute was found for the current element. " +
138 "If you are using this serializer, in order to unmarshal the" +
139 " opportune type the xsi:type must be specified.");
140 }
141
142 Class<?> clazz = xml2Java.get(typeAttribute.getValue());
143
144 if (clazz == null)
145 {
146 throw new SoapFault(
147 String.format(
148 "No corresponding class was found on this serializer mappings for xsi:type %s.",
149 typeAttribute));
150 }
151
152 if (clazz == byte[].class) {
153 return new ByteArraySerializer().fromXML(elementData);
154 }
155
156 return SerializerRegistry.getInstance().getSerializer(clazz).fromXML(elementData);
157 }
158
159 /**
160 * As this serializer is supposed to deal with generic object types, this method returns Object.class.
161 *
162 * @return Object.class
163 */
164 public Class<?> getSerializableType()
165 {
166 return Object.class;
167 }
168
169 /**
170 * Converts the given object (with the given qname) in XML format.
171 * This method fails if there's no corresponding xml type for the given runtime type of the input object.
172 *
173 * @param obj the object to be marshalled.
174 * @param qname the qualified name that will be used in encoding.
175 */
176 public Element toXML(Object obj, QName qname) throws SoapFault
177 {
178 Class<?> clazz = obj.getClass();
179
180 Element result = null;
181
182 if (clazz == byte[].class) {
183 result = new ByteArraySerializer().toXML(obj,qname);
184 }
185 else {
186 result = SerializerRegistry.getInstance().getSerializer(clazz).toXML(obj,qname);
187 }
188 result.setAttribute(Names.XSI_TYPE, java2Xml.get(clazz));
189 return result;
190 }
191
192 /**
193 * Returns the xml type associated with the given class.
194 *
195 * @param clazz the class.
196 * @return the xml type associated with the given class.
197 */
198 public String getXmlType(Class<?> clazz)
199 {
200 return java2Xml.get(clazz);
201 }
202 }
|