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 }