1 package org.kuali.mobility.util.mapper;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.net.URL;
6 import java.net.URLConnection;
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import org.apache.log4j.Logger;
11 import org.kuali.mobility.util.mapper.entity.DataMapping;
12 import org.kuali.mobility.util.mapper.entity.MappingElement;
13
14 import com.thoughtworks.xstream.XStream;
15 import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
16 import com.thoughtworks.xstream.mapper.MapperWrapper;
17
18 public class DataMapperImpl implements DataMapper {
19
20 private static final Logger LOG = Logger.getLogger(DataMapperImpl.class);
21
22 private Integer connectionTimeoutMs = new Integer(5000);
23
24 private Integer readTimeoutMs = new Integer(10000);;
25
26 @Override
27 public <B extends Object> B mapData(B responseObject, final URL source, final String mappingFile) throws ClassNotFoundException, IOException {
28 return mapData(responseObject, source, mappingFile, null);
29 }
30
31 @Override
32 public <B extends Object> B mapData(B responseObject, final URL source, final URL mappingFileUrl) throws ClassNotFoundException, IOException {
33 return mapData(responseObject, source, mappingFileUrl, null);
34 }
35
36 @Override
37 public <B extends Object> B mapData(B responseObject, final String dataFile, final String mappingFile) throws ClassNotFoundException {
38 return mapData(responseObject, dataFile, mappingFile, null);
39 }
40
41 @SuppressWarnings("unchecked")
42 @Override
43 public <B> B mapData(B responseObject, URL source, String mappingFile, String listName) throws ClassNotFoundException, IOException {
44 DataConfig dc = new DataConfig();
45 DataMapping mapping = null;
46 try {
47 mapping = dc.loadConfiguation(mappingFile);
48 } catch (IOException ioe) {
49 LOG.error(ioe);
50 }
51 XStream xstream = loadMapper(mapping, listName);
52 if (xstream != null) {
53 URLConnection con = source.openConnection();
54 con.setConnectTimeout(connectionTimeoutMs);
55 con.setReadTimeout(readTimeoutMs);
56 InputStream in = con.getInputStream();
57
58 responseObject = (B) xstream.fromXML(in);
59 }
60 return responseObject;
61 }
62
63 @SuppressWarnings("unchecked")
64 @Override
65 public <B> B mapData(B responseObject, String dataFile, String mappingFile, String listName) throws ClassNotFoundException {
66 DataConfig dc = new DataConfig();
67 DataMapping mapping = null;
68 try {
69 mapping = dc.loadConfiguation(mappingFile);
70 } catch (IOException ioe) {
71 LOG.error(ioe);
72 }
73 XStream xstream = loadMapper(mapping, listName);
74 if (xstream != null) {
75 try {
76 responseObject = (B) xstream.fromXML(this.getClass().getClassLoader().getResourceAsStream(dataFile));
77 }
78 catch( NullPointerException npe ) {
79 LOG.error( npe.getLocalizedMessage(), npe );
80 }
81 }
82 return responseObject;
83 }
84
85 @SuppressWarnings("unchecked")
86 @Override
87 public <B extends Object> B mapData(B responseObject, final URL source, final URL mappingFileUrl, String listName) throws ClassNotFoundException, IOException {
88 DataConfig dc = new DataConfig();
89 DataMapping mapping = null;
90 try {
91 mapping = dc.loadConfiguation(mappingFileUrl, connectionTimeoutMs, readTimeoutMs);
92 } catch (IOException ioe) {
93 LOG.error(ioe);
94 }
95 XStream xstream = loadMapper(mapping, listName);
96 if (xstream != null) {
97 URLConnection con = source.openConnection();
98 con.setConnectTimeout(connectionTimeoutMs);
99 con.setReadTimeout(readTimeoutMs);
100 InputStream in = con.getInputStream();
101 responseObject = (B) xstream.fromXML(in);
102 }
103 return responseObject;
104 }
105
106 private XStream loadMapper(DataMapping mapping, String listName) throws ClassNotFoundException {
107 if (mapping != null) {
108 final List<String> fields = new ArrayList<String>();
109
110 for (MappingElement map : mapping.getMappings()) {
111 fields.add(map.getMapTo());
112 }
113 final String objectClass = mapping.getClassName();
114
115 XStream xstream;
116 if( mapping.getMimeType() != null && "application/json".equalsIgnoreCase(mapping.getMimeType()) )
117 {
118 LOG.debug( "Loading xstream jettison mapped xml driver.");
119 xstream = new XStream(new JettisonMappedXmlDriver()) {
120 @Override
121 protected MapperWrapper wrapMapper(MapperWrapper next) {
122 return new MapperWrapper(next) {
123 @Override
124 public boolean shouldSerializeMember(Class definedIn, String fieldName) {
125 try {
126 if (!fields.contains(fieldName) && definedIn == Class.forName(objectClass)) {
127 return false;
128 }
129 } catch (ClassNotFoundException e) {
130 return false;
131 }
132 return super.shouldSerializeMember(definedIn, fieldName);
133 }
134 };
135 }
136 };
137 }
138 else
139 {
140 xstream = new XStream() {
141 @Override
142 protected MapperWrapper wrapMapper(MapperWrapper next) {
143 return new MapperWrapper(next) {
144 @Override
145 public boolean shouldSerializeMember(Class definedIn, String fieldName) {
146 try {
147 if (!fields.contains(fieldName) && definedIn == Class.forName(objectClass)) {
148 return false;
149 }
150 } catch (ClassNotFoundException e) {
151 return false;
152 }
153 return super.shouldSerializeMember(definedIn, fieldName);
154 }
155 };
156 }
157 };
158 }
159 xstream.alias(mapping.getId(), Class.forName(mapping.getClassName()));
160 if (mapping.getRootElement() != null && !"".equalsIgnoreCase(mapping.getRootElement())) {
161 if (mapping.getRootElementClassName() != null && !"".equals(mapping.getRootElementClassName().trim())) {
162 if (listName != null && !"".equals(listName.trim())) {
163 xstream.addImplicitCollection(Class.forName(mapping.getRootElementClassName()), listName);
164 }
165 xstream.alias(mapping.getRootElement(), Class.forName(mapping.getRootElementClassName()));
166 } else {
167 xstream.alias(mapping.getRootElement(), (mapping.isList() ? List.class : Object.class));
168 }
169 }
170 for (MappingElement map : mapping.getMappings()) {
171 if (map.isAttribute()) {
172 xstream.aliasAttribute(Class.forName(mapping.getClassName()), map.getMapTo(), map.getMapFrom());
173 } else {
174 xstream.aliasField(map.getMapFrom(), Class.forName(mapping.getClassName()), map.getMapTo());
175 }
176 }
177 return xstream;
178 } else {
179 return null;
180 }
181 }
182
183 public Integer getConnectionTimeoutMs() {
184 return connectionTimeoutMs;
185 }
186
187 public void setConnectionTimeoutMs(Integer connectionTimeoutMs) {
188 this.connectionTimeoutMs = connectionTimeoutMs;
189 }
190
191 public Integer getReadTimeoutMs() {
192 return readTimeoutMs;
193 }
194
195 public void setReadTimeoutMs(Integer readTimeoutMs) {
196 this.readTimeoutMs = readTimeoutMs;
197 }
198
199 }