package com.iambookmaster.validator;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import junit.framework.TestCase;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.iambookmaster.client.beans.AbstractParameter;
import com.iambookmaster.client.beans.ObjectBean;
import com.iambookmaster.client.beans.Paragraph;
import com.iambookmaster.client.beans.ParagraphConnection;
import com.iambookmaster.client.common.JSONParser;
import com.iambookmaster.client.exceptions.JSONException;
import com.iambookmaster.client.locale.AppConstants;
import com.iambookmaster.client.locale.AppMessages;
import com.iambookmaster.client.model.Model;
import com.iambookmaster.client.paragraph.PathFinder;
import com.iambookmaster.client.paragraph.PathFinderErrorListener;
import com.iambookmaster.server.LocalMessages;
import com.iambookmaster.server.XMLModelParser;
public class FindWayTest extends TestCase {
private static final String[] PATTERN = new String[0];
private AppConstants appConstants;
private AppMessages appMessages;
private static String locale="ru";
public void test1() throws Exception {
perform("IvanDurak");
}
public void test2() throws Exception {
perform("Dragon");
}
@Override
protected void setUp() throws Exception {
LocalMessages messages = new LocalMessages();
messages.initialize(locale);
appConstants = LocalMessages.getInstance(AppConstants.class, locale);
appMessages = LocalMessages.getInstance(AppMessages.class, locale);
}
public void perform(String name) throws Exception {
perform(name,false);
}
public void perform(String name,boolean conditionalChainAllowed) throws Exception {
Model model = createModelFromJSON(name+".xml");
ArrayList<String> res = new ArrayList<String>();
InputStream stream = getClass().getResourceAsStream(name+".txt");
String[] results;
if (stream==null) {
results = new String[0];
} else {
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String line;
while ((line = br.readLine()) != null) {
res.add(line);
}
results = res.toArray(PATTERN);
}
PathFinderErrorListener listener = createListener(results,conditionalChainAllowed);
PathFinder finder = new PathFinder(model);
finder.validate(listener);
}
private PathFinderErrorListener createListener(String[] results,boolean conditionalChainAllowed) {
return (PathFinderErrorListener)java.lang.reflect.Proxy.newProxyInstance(
PathFinderErrorListener.class.getClassLoader(),
new Class[]{PathFinderErrorListener.class},
new ListenerProxy(results,conditionalChainAllowed));
}
public class ListenerProxy implements java.lang.reflect.InvocationHandler{
private final String[] results;
private int counter;
private long timeout;
private boolean conditionalChainAllowed;
public ListenerProxy(String[] results, boolean conditionalChainAllowed) {
this.results = results;
this.conditionalChainAllowed = conditionalChainAllowed;
//3 min
timeout = System.currentTimeMillis()+1000*60*2;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("updateStatus".equals(method.getName())) {
return null;
} else if ("checkTimeout".equals(method.getName())) {
return false;
} else if ("canContinue".equals(method.getName())) {
return timeout>System.currentTimeMillis();
} else if ("conditionalChain".equals(method.getName())) {
if (conditionalChainAllowed) {
return null;
}
} else if ("canBePassed".equals(method.getName())) {
return true;
}
StringBuilder builder = new StringBuilder(method.getName());
for (Object object : args) {
builder.append(',');
if (object instanceof Paragraph) {
Paragraph paragraph = (Paragraph) object;
builder.append("p:");
builder.append(paragraph.getName());
} else if (object instanceof ParagraphConnection) {
ParagraphConnection connection = (ParagraphConnection) object;
builder.append("c:");
builder.append(connection.getFrom().getName());
builder.append("->");
builder.append(connection.getTo().getName());
} else if (object instanceof ObjectBean) {
ObjectBean bean = (ObjectBean) object;
builder.append("o:");
builder.append(bean.getName());
} else if (object instanceof AbstractParameter) {
AbstractParameter parameter = (AbstractParameter) object;
builder.append("a:");
builder.append(parameter.getName());
} else {
builder.append(String.valueOf(object));
}
}
String out = builder.toString();
assertTrue("More messages than expected:"+out,results.length>counter);
assertEquals(results[counter++],out);
return null;
}
}
private Model createModelFromJSON(String file) throws JSONException, ParserConfigurationException, SAXException, IOException {
InputStream stream = getClass().getResourceAsStream(file);
assertNotNull("Cannot load file "+file,stream);
Model model;
try {
model = new Model(appConstants,appMessages);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setNamespaceAware(false);
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource inputSource = new InputSource(stream);
Document result = db.parse(inputSource);
JSONParser parser = new XMLModelParser();
model.restore(result,parser);
} finally {
if (stream != null) {
stream.close();
}
}
return model;
}
}