View Javadoc
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 }