package org.wiztools.restclient.persistence; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import nu.xom.Element; import nu.xom.Elements; import org.wiztools.appupdate.Version; import org.wiztools.appupdate.VersionImpl; import org.wiztools.commons.StringUtil; import org.wiztools.restclient.bean.ContentType; import org.wiztools.restclient.bean.ContentTypeBean; import org.wiztools.restclient.bean.MultipartMode; import org.wiztools.restclient.bean.MultipartSubtype; import org.wiztools.restclient.bean.ReqEntity; import org.wiztools.restclient.bean.ReqEntityBasePart; import org.wiztools.restclient.bean.ReqEntityByteArrayBean; import org.wiztools.restclient.bean.ReqEntityFileBean; import org.wiztools.restclient.bean.ReqEntityFilePartBean; import org.wiztools.restclient.bean.ReqEntityMultipartBean; import org.wiztools.restclient.bean.ReqEntityPart; import org.wiztools.restclient.bean.ReqEntityStringBean; import org.wiztools.restclient.bean.ReqEntityStringPartBean; import org.wiztools.restclient.bean.ReqEntityUrlStreamBean; import org.wiztools.restclient.util.Util; /** * * @author subwiz */ public class XmlBodyRead { private final Version readVersion; private static final Version VERSION_SINCE_PART_CONTENT = new VersionImpl("3.5"); XmlBodyRead(String version) { readVersion = new VersionImpl(version); } ReqEntity getReqEntity(Element eEntity) { Elements eChildren = eEntity.getChildElements(); for(int i=0; i<eChildren.size(); i++) { Element e = eChildren.get(i); final String name = e.getLocalName(); if("string".equals(name)) { ContentType ct = getContentType(e); String body = e.getValue(); return new ReqEntityStringBean(body, ct); } else if("file".equals(name)) { ContentType ct = getContentType(e); String filePath = e.getValue(); return new ReqEntityFileBean(new File(filePath), ct); } else if("byte-array".equals(name)) { ContentType ct = getContentType(e); byte[] body = Util.base64decodeByteArray(e.getValue()); return new ReqEntityByteArrayBean(body, ct); } else if("url-stream".equals(name)) { try { ContentType ct = getContentType(e); URL url = new URL(e.getValue()); return new ReqEntityUrlStreamBean(ct, url); } catch(MalformedURLException ex) { throw new RuntimeException(ex); } } else if("multipart".equals(name)) { return getMultipart(e); } else { throw new XMLException("Unsupported element encountered inside <body>: " + name); } } return null; } private ReqEntityMultipartBean getMultipart(Element e) { final String subTypeStr = e.getAttributeValue("subtype"); final MultipartSubtype subType = subTypeStr!=null? MultipartSubtype.valueOf(subTypeStr): MultipartSubtype.FORM_DATA; final String mode = e.getAttributeValue("mode"); MultipartMode format = StringUtil.isNotEmpty(mode)? MultipartMode.valueOf(mode): null; List<ReqEntityPart> parts = getMultipartParts(e); return new ReqEntityMultipartBean(parts, format, subType); } private List<ReqEntityPart> getMultipartParts(Element e) { List<ReqEntityPart> parts = new ArrayList<>(); Elements children = e.getChildElements(); for(int i=0; i<children.size(); i++) { ReqEntityPart part = getMultipartPart(children.get(i)); parts.add(part); } return parts; } private String getPartValue(Element e) { if(readVersion.isLessThan(VERSION_SINCE_PART_CONTENT)) { return e.getValue(); } else { Element eContent = e.getChildElements("content").get(0); return eContent.getValue(); } } private ReqEntityPart getMultipartPart(Element e) { final String name = e.getLocalName(); final String partName = e.getAttributeValue("name"); final ContentType ct = getContentType(e); Elements eFields = null; if(e.getChildElements("fields").size() > 0) { eFields = e.getChildElements("fields").get(0).getChildElements("field"); } if("string".equals(name)) { String partBody = getPartValue(e); ReqEntityStringPartBean out = new ReqEntityStringPartBean(partName, ct, partBody); addFields(eFields, out); return out; } else if("file".equals(name)) { File file = new File(getPartValue(e)); String fileName = e.getAttributeValue("filename"); // filename: backward-compatibility: fileName = StringUtil.isEmpty(fileName)? file.getName(): fileName; return new ReqEntityFilePartBean(partName, fileName, ct, file); } else { throw new XMLException("Unsupported element encountered inside <multipart>: " + name); } } private void addFields(Elements eFields, ReqEntityBasePart part) { if(eFields == null) { return; } for(int i=0; i<eFields.size(); i++) { Element eField = eFields.get(i); String name = eField.getChildElements("name").get(0).getValue(); String value = eField.getChildElements("value").get(0).getValue(); part.addField(name, value); } } private static ContentType getContentType(Element e) { String contentType = e.getAttributeValue("content-type"); String charsetStr = e.getAttributeValue("charset"); if(StringUtil.isNotEmpty(contentType)) { return new ContentTypeBean(contentType, (charsetStr!=null? Charset.forName(charsetStr): null)); } else { return null; } } }