📄 postsyncml.java
字号:
/** * Copyright (C) 2003-2004 Funambol * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package sync4j.test.tools;import java.net.*;import java.io.*;import java.util.List;import java.util.Iterator;import java.util.logging.Logger;import java.util.logging.Level;import org.jdom.*;import org.jdom.input.SAXBuilder;import org.jdom.output.XMLOutputter;import org.vmguys.vmtools.ota.OtaUpdate;import org.vmguys.vmtools.ota.UniqueId;import org.vmguys.vmtools.utils.DomFactory;import sync4j.framework.core.*;import sync4j.framework.protocol.*;import sync4j.framework.tools.IOTools;import sync4j.test.tools.HttpClientConnection;import sync4j.test.TestFailedException;import org.jibx.runtime.*;import org.jibx.runtime.impl.*;/** * This is a driver for running tests at the protocol level.<br> * It requires a directory structure like this: * <pre> * {test code} * <i>msg1.xml</i> * <i>msg2.xml</i> * <i>...</i> * reference * <i>msg1.xml</i> * <i>msg2.xml</i> * <i>...</i> * response * <i>msg1.xml</i> * <i>msg2.xml</i> * <i>...</i> * </pre> * <i>test code</i> is the code name of the test to be performed (i.e. WOSI0001); * msg{N}.xml are the messages that the client has to send to the server. For * each message sent, the response is stored in the <i>response</i> directory. * <p> * The directory <i>reference</i> contains the expected response messages used * by the comparison tool to identify the differences between the returned * messages and the expected values. * <p> * This class is designe to work as a standalone program. An Ant task is * developed as well; @see sync4j.test.tools.ant.PostSyncMLTask . * <p> * <b>Syntax</b> * <pre> * sync4j.test.tools.PostSyncML {initial URL} {file msg1} ... {file msgN} * * where: * * {initial URL}: the URL the first request has to be sent to (the others depend * by the RespURI element in the response. * {file msg1} .. {file msgN}: the messages to send to server. They are sent in * the order they appear on the command line. * </pre> * * @author Stefano Fornari * @version $Id: PostSyncML.java,v 1.9 2004/04/29 08:00:28 luigiafassina Exp $ */public class PostSyncML { // --------------------------------------------------------------- Constants public static String LOG_NAME = "sync4j.test.tools.PostSyncML"; public static String FILE_ERROR = "error" ; public static String FILE_RESPONSE = "response" ; public static String FILE_REFERENCE = "reference"; // ------------------------------------------------------------ Private data private CommandIdGenerator idGenerator = null; private String nextURL = null; private String[] msgs = null; private String[] msgFiles = null; private String[] ignoreXPaths = null; private File baseDir = null; private File responseDir = null, referenceDir = null, errorDir = null; private static final Logger log = Logger.getLogger(LOG_NAME); // ------------------------------------------------------------ Constructors public PostSyncML(String initialURL , File baseDir , String[] msgFiles , String[] ignoreXPaths) throws IOException { idGenerator = new CommandIdGenerator(); if ((msgFiles == null) || (msgFiles.length == 0)) { msgs = new String[0]; } msgs = new String[msgFiles.length]; this.baseDir = baseDir; this.responseDir = new File(baseDir, FILE_RESPONSE ); this.referenceDir = new File(baseDir, FILE_REFERENCE); this.errorDir = new File(baseDir, FILE_ERROR ); this.msgFiles = msgFiles; for (int i=0; i<msgFiles.length; ++i) { msgs[i] = IOTools.readFileString(new File(baseDir, msgFiles[i])); } this.ignoreXPaths = ignoreXPaths; nextURL = initialURL; } //----------------------------------------------------------- Public methods public void syncAndTest() throws IOException, TestFailedException { // // First of all clean up! // clean(); SyncML response = null; String respURI = null; String referenceXML = null; File responseFile = null; for (int i=0; i<msgs.length; ++i) { log.info("Sending " + msgFiles[i]); try { response = postRequest(msgs[i]); } catch (RepresentationException e) { IOTools.writeFile(e.getMessage(), new File(errorDir, msgFiles[i])); throw new TestFailedException ("XML syntax error: " + e.getMessage(), e); } catch (Sync4jException e) { IOTools.writeFile(e.getMessage(), new File(errorDir, msgFiles[i])); throw new TestFailedException ("XML syntax error: " + e.getMessage(), e); } // // Write the messages responded by the server, than read the reference // and make the comparison (excluding the XPaths specified by // ignoreXPaths // responseFile = new File(responseDir, msgFiles[i]); log.info("Writing the response into " + responseFile); try { String xmlMsg = marshallSyncML(response); IOTools.writeFile(xmlMsg, responseFile); } catch(Exception e) { e.printStackTrace(); throw new TestFailedException ("XML syntax error: " + e.getMessage(), e); } referenceXML = IOTools.readFileString(new File(referenceDir, msgFiles[i])); compare(msgFiles[i]); respURI = response.getSyncHdr().getRespURI(); if (respURI != null) { nextURL = respURI; } } } // --------------------------------------------------------- Private methods private SyncML postRequest(String request) throws IOException, Sync4jException, RepresentationException { HttpClientConnection syncMLConnection = new HttpClientConnection(nextURL); return syncMLConnection.sendMessage(request); } private void compare(String msgFile) throws IOException, TestFailedException { File responseFile = new File(responseDir , msgFile); File referenceFile = new File(referenceDir, msgFile); SAXBuilder sb = new SAXBuilder(); sb.setFactory(new DomFactory()); try { Document response = sb.build(responseFile ); Document reference = sb.build(referenceFile); OtaUpdate update = new OtaUpdate(false); UniqueId id = new UniqueId("SyncMLTest", msgFile); Element diffs = update.generateDiffs(response.getRootElement() , reference.getRootElement(), id ); if (log.isLoggable(Level.FINE)) { saveDiffs(diffs, new File(errorDir, msgFile + ".dbg")); } if (checkDiffs(diffs)) { saveDiffs(diffs, new File(errorDir, msgFile)); throw new TestFailedException( "Test failed on " + msgFile + ". Diff file saved in " + new File(errorDir, msgFile) ); } } catch (JDOMException e) { IOTools.writeFile(e.getMessage(), new File(errorDir, msgFile)); throw new TestFailedException("Test failed on " + msgFile + ": " + e.getMessage() + ". Error message saved in " + new File(errorDir, msgFile) ); } } /** * Checks if the given diffs Element contains significant differences, so * that differences on any node excluding the ones specified by the * <i>ignoreXPaths</i> XPaths. * * @param diffs the differences to be inspected * * @return <i>true</i> if there is at least one difference in one of the not * ignored XPaths, or <i>false</i> otherwise. */ private boolean checkDiffs(Element diffs) { List positions = diffs.getChildren("Position", diffs.getNamespace()); Element position = null; Iterator i = positions.iterator(); while(i.hasNext()) { position = (Element)i.next(); if (!ignore(position.getAttributeValue("XPath"))) { // // This means a difference! // return true; } } return false; } /** * Removes old files from the working directories */ private void clean() { FilenameFilter filter = IOTools.getFileTypeFilter("xml"); String[] files = responseDir.list(filter); for (int i=0; ((files != null) && (i<files.length)); ++i) { new File(files[i]).delete(); } files = errorDir.list(filter); for (int i=0; ((files != null) && (i<files.length)); ++i) { new File(files[i]).delete(); } } /** * Checks if the given XPath is one of the ignored XPath * * @param xPath the xPath to check * * @return <i>true</i> is the xPath in the list of the ignored XPaths, * <i>false</i> otherwise. */ private boolean ignore(String xPath) { for (int i=0; ((xPath != null) && (ignoreXPaths != null) && (i<ignoreXPaths.length)); ++i) { if (xPath.equals(ignoreXPaths[i])) { return true; } } return false; } /** * Saves the given diff element to the given file * * @param diffs the diff element * @param file the file to save into */ private void saveDiffs(Element diffs, File file) throws IOException { XMLOutputter xmlo = new XMLOutputter(" ", true); xmlo.setTextNormalize(true); FileOutputStream fos = new FileOutputStream(file); xmlo.output(diffs, fos); fos.close(); } private static void syntax() { System.out.println("Syntax: " + (PostSyncML.class) + "<initial URL> <msg1> ... <msgN>"); } private String marshallSyncML(SyncML syncML) throws Sync4jException { String msg = null; try { ByteArrayOutputStream bout = new ByteArrayOutputStream(); IBindingFactory f = BindingDirectory.getFactory(SyncML.class); IMarshallingContext c = f.createMarshallingContext(); c.setIndent(0); c.marshalDocument(syncML, "UTF-8", null, bout); msg = new String(bout.toByteArray()); } catch(Exception e) { e.printStackTrace(); throw new Sync4jException(e); } return msg; } // -------------------------------------------------------------------- Main public static void main(String args[]) throws Exception { if(args.length < 2) { syntax(); } String[] msgFiles = new String[args.length-1]; System.arraycopy(args, 1, msgFiles, 0, msgFiles.length); PostSyncML postsyncml = new PostSyncML(args[0], new File("."), msgFiles, new String[0]); postsyncml.syncAndTest(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -