Java tutorial
/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.suren.autotest.web.framework.code; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.VisitorSupport; import org.dom4j.XPath; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.dom4j.xpath.DefaultXPath; import org.jaxen.SimpleNamespaceContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.stereotype.Component; import org.suren.autotest.web.framework.core.Callback; import org.suren.autotest.web.framework.util.StringUtils; import org.xml.sax.SAXException; /** * ??xml????xml??? * @author suren * @date 20161214 ?8:21:27 */ @Component("xml_to_datasource") public class DefaultXmlDataSourceGenerator implements Generator { private static final Logger logger = LoggerFactory.getLogger(DefaultXmlDataSourceGenerator.class); private String outputDir; private Map<String, Document> docMap; @SuppressWarnings("rawtypes") private Callback callback; @Override public void generate(String srcCoding, String outputDir) { this.outputDir = outputDir; ClassLoader classLoader = this.getClass().getClassLoader(); //?? try (InputStream confInput = classLoader.getResourceAsStream(srcCoding)) { generate(confInput, outputDir, null); } catch (DocumentException | IOException e) { logger.error(String.format("Main config [%s] parse process error.", srcCoding), e); } catch (SAXException e) { e.printStackTrace(); } finally { for (String resPath : docMap.keySet()) { Document doc = docMap.get(resPath); write(doc, resPath); } } } /** * @param input ???? * @param outputDir * @param callback ??java.io.File */ @Override public void generate(InputStream input, String outputDir, Callback<?> callback) throws DocumentException, SAXException { this.callback = callback; this.outputDir = outputDir; docMap = new HashMap<String, Document>(); //?? try { read(input); } catch (IOException e) { logger.error(String.format("Main config parse process error."), e); } finally { for (String resPath : docMap.keySet()) { Document doc = docMap.get(resPath); write(doc, resPath); } } } /** * ??? * * @param inputStream * @throws DocumentException * @throws IOException * @throws SAXException */ private void read(InputStream inputStream) throws DocumentException, IOException, SAXException { Document document = new SAXReader().read(inputStream); parse(document); } /** * @param document */ private void parse(Document doc) { SimpleNamespaceContext simpleNamespaceContext = new SimpleNamespaceContext(); simpleNamespaceContext.addNamespace("ns", "http://surenpi.com"); XPath xpath = new DefaultXPath("/ns:autotest/ns:includePage"); xpath.setNamespaceContext(simpleNamespaceContext); @SuppressWarnings("unchecked") List<Element> includePageList = xpath.selectNodes(doc); if (includePageList != null && includePageList.size() > 0) { for (Element includePage : includePageList) { String pageConfig = includePage.attributeValue("pageConfig"); generate(pageConfig, outputDir); } } xpath = new DefaultXPath("/ns:autotest/ns:pages"); xpath.setNamespaceContext(simpleNamespaceContext); Element pagesEle = (Element) xpath.selectSingleNode(doc); String pagePackage = pagesEle.attributeValue("pagePackage", ""); if (StringUtils.isNotBlank(pagePackage)) { pagePackage = pagePackage.trim(); } // pages parse progress xpath = new DefaultXPath("/ns:autotest/ns:pages/ns:page"); xpath.setNamespaceContext(simpleNamespaceContext); @SuppressWarnings("unchecked") List<Element> pageNodes = xpath.selectNodes(doc); if (pageNodes != null) { for (Element ele : pageNodes) { String pageClsStr = ele.attributeValue("class"); if (pageClsStr == null) { logger.warn("can not found class attribute."); continue; } String dataSrc = ele.attributeValue("dataSource"); try { parse(doc, pagePackage, pageClsStr, dataSrc, ele); } catch (NoSuchBeanDefinitionException e) { logger.error("Page element [{}] parse error, in document [{}].", "pageClsStr", doc); throw e; } catch (Exception e) { logger.error("Page element parse error.", e); } } } } /** * ??Page * * @param pageClsStr * @param dataSrc * @param dataSrc2 * @param ele */ private void parse(Document doc, String pagePackage, final String pageClsStr, String dataSrc, Element ele) throws Exception { SimpleNamespaceContext simpleNamespaceContext = new SimpleNamespaceContext(); simpleNamespaceContext.addNamespace("ns", "http://surenpi.com"); XPath xpath = new DefaultXPath("/ns:autotest/ns:dataSources/ns:dataSource[@name='" + dataSrc + "']"); xpath.setNamespaceContext(simpleNamespaceContext); Element dataSourceEle = (Element) xpath.selectSingleNode(doc); if (dataSourceEle == null) { logger.error("Can not found dataSource element by {}.", dataSrc); return; } String dsType = dataSourceEle.attributeValue("type"); String dsResource = dataSourceEle.attributeValue("resource"); logger.debug("DataSource type is {}, resource is {}.", dsType, dsResource); updateXmlDataSourceByEle(ele, dsResource, pagePackage, pageClsStr); } /** * @param ele * @param pageClsStr2 */ private void updateXmlDataSourceByEle(Element ele, String dsResource, String pagePackage, String pageClsStr) { Document doc = docMap.get(dsResource); if (doc == null) { doc = prepareDoc(dsResource); docMap.put(dsResource, doc); } SimpleNamespaceContext simpleNamespaceContext = new SimpleNamespaceContext(); simpleNamespaceContext.addNamespace("ns", "http://datasource.surenpi.com"); XPath xpath = new DefaultXPath("/ns:dataSources"); xpath.setNamespaceContext(simpleNamespaceContext); Element dataSourcesEle = doc.getRootElement(); dataSourcesEle.addAttribute("pagePackage", pagePackage); //? if (StringUtils.isNotBlank(pagePackage)) { pagePackage = (pagePackage.trim()); xpath = new DefaultXPath("/ns:dataSources[@pagePackage='" + pagePackage + "']/ns:dataSource[@pageClass='" + pageClsStr + "']"); xpath.setNamespaceContext(simpleNamespaceContext); } else { xpath = new DefaultXPath("/ns:dataSources/ns:dataSource[@pageClass='" + pageClsStr + "']"); xpath.setNamespaceContext(simpleNamespaceContext); } Element dataSourceEle = (Element) xpath.selectSingleNode(doc); if (dataSourceEle == null) { String prefix = dataSourcesEle.getNamespacePrefix(); if (StringUtils.isBlank("")) { String parentName = dataSourcesEle.getName(); if (parentName.contains(":")) { prefix = parentName.split(":")[0]; } } if (StringUtils.isNotBlank(prefix)) { prefix = prefix + ":"; } dataSourceEle = dataSourcesEle.addElement(prefix + "dataSource"); dataSourceEle.addAttribute("pageClass", pageClsStr); } //?? if (StringUtils.isNotBlank(pagePackage)) { pagePackage = (pagePackage.trim()); xpath = new DefaultXPath("/ns:dataSources[@pagePackage='" + pagePackage + "']/ns:dataSource[@pageClass='" + pageClsStr + "']/ns:page[1]"); xpath.setNamespaceContext(simpleNamespaceContext); } else { xpath = new DefaultXPath("/ns:dataSources/ns:dataSource[@pageClass='" + pageClsStr + "']/ns:page[1]"); xpath.setNamespaceContext(simpleNamespaceContext); } Element pageEle = (Element) xpath.selectSingleNode(dataSourceEle); if (pageEle == null) { String prefix = dataSourceEle.getNamespacePrefix(); if (StringUtils.isNotBlank(prefix)) { prefix = prefix + ":"; } pageEle = dataSourceEle.addElement(prefix + "page"); } ele.accept(new PageFieldVisitor(pageEle, pagePackage, pageClsStr)); } /** * ?xmldocument * @param resPath * @return */ private Document prepareDoc(final String resPath) { ClassLoader clsLoader = this.getClass().getClassLoader(); URL url = clsLoader.getResource(resPath); InputStream dsInput = null; try { if (url != null) { dsInput = url.openStream(); } } catch (IOException e1) { e1.printStackTrace(); } Document doc = null; if (dsInput != null) { try { doc = new SAXReader().read(dsInput); } catch (DocumentException e) { e.printStackTrace(); } } else { doc = DocumentHelper.createDocument(); } SimpleDateFormat dateFormat = new SimpleDateFormat(); doc.addComment("Auto created by AutoTest, " + dateFormat.format(new Date())); SimpleNamespaceContext simpleNamespaceContext = new SimpleNamespaceContext(); simpleNamespaceContext.addNamespace("ns", "http://datasource.surenpi.com"); XPath xpath = new DefaultXPath("/ns:dataSources"); xpath.setNamespaceContext(simpleNamespaceContext); //? Element dataSourcesEle = (Element) xpath.selectSingleNode(doc); if (dataSourcesEle == null) { String prefix = "suren"; dataSourcesEle = doc.addElement(prefix + ":dataSources"); dataSourcesEle.addNamespace(prefix, "http://datasource.surenpi.com"); dataSourcesEle.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); dataSourcesEle.addAttribute("xsi:schemaLocation", "http://datasource.surenpi.com " + "http://surenpi.com/schema/datasource/autotest.web.framework.datasource.xsd "); } return doc; } /** * xml * @see #write(Document, OutputFormat, String) * @param doc * @param resPath */ private void write(final Document doc, final String resPath) { OutputFormat outputFormat = OutputFormat.createPrettyPrint(); outputFormat.setIndentSize(4); write(doc, outputFormat, resPath); } /** * xml * @param doc * @param format ? * @param resPath */ private void write(final Document doc, final OutputFormat format, final String resPath) { ClassLoader clsLoader = this.getClass().getClassLoader(); URL url = clsLoader.getResource(resPath); String outputFileName = null; if (url != null) { outputFileName = new File(url.getFile()).getName(); } else { outputFileName = new File(resPath).getName(); } File outputDirFile = new File(outputDir); if (!outputDirFile.isDirectory()) { outputDirFile.mkdirs(); } File outputFile = new File(outputDirFile, outputFileName); try (OutputStream dsOutput = new FileOutputStream(outputFile)) { OutputFormat outputFormat = OutputFormat.createPrettyPrint(); outputFormat.setIndentSize(4); XMLWriter xmlWriter = new XMLWriter(dsOutput, outputFormat); xmlWriter.write(doc); if (callback != null) { callback.callback(outputFile); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } class PageFieldVisitor extends VisitorSupport { private SimpleNamespaceContext simpleNamespaceContext = new SimpleNamespaceContext(); private Element pageEle; private String pagePackage; private String pageClsStr; public PageFieldVisitor(Element pageEle, String pagePackage, String pageClsStr) { this.pageEle = pageEle; this.pagePackage = pagePackage; this.pageClsStr = pageClsStr; simpleNamespaceContext.addNamespace("ns", "http://datasource.surenpi.com"); } @Override public void visit(Element node) { if (!"field".equals(node.getName())) { return; } String fieldName = node.attributeValue("name"); String data = node.attributeValue("data", ""); String type = node.attributeValue("type"); if (fieldName == null || "".equals(fieldName) || "button".equals(type)) { return; } XPath xpath; if (StringUtils.isNotBlank(pagePackage)) { pagePackage = (pagePackage.trim()); xpath = new DefaultXPath( "/ns:dataSources[@pagePackage='" + pagePackage + "']/ns:dataSource[@pageClass='" + pageClsStr + "']/ns:page[1]/ns:field[@name='" + fieldName + "']"); xpath.setNamespaceContext(simpleNamespaceContext); } else { xpath = new DefaultXPath("/ns:dataSources/ns:dataSource[@pageClass='" + pageClsStr + "']/ns:page[1]/ns:field[@name='" + fieldName + "']"); xpath.setNamespaceContext(simpleNamespaceContext); } Element fieldEle = (Element) xpath.selectSingleNode(pageEle); if (fieldEle == null) { String prefix = pageEle.getNamespacePrefix(); if (StringUtils.isNotBlank(prefix)) { prefix = prefix + ":"; } fieldEle = pageEle.addElement(prefix + "field"); fieldEle.addAttribute("name", fieldName); fieldEle.addAttribute("data", data); } } } }