package ru.runa.specific.of;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.swt.graphics.Color;
import org.jbpm.ui.orgfunctions.ExecutorsImporter;
import org.jbpm.ui.sync.SyncSettingsWizardPage;
import org.jbpm.ui.util.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import ru.runa.specific.of.SwimlaneRunaOrgStructureElement.TimingsSettingsPage;
public class RunaOrgStructureImporter extends ExecutorsImporter {
private HttpMethod method;
private static RunaOrgStructureImporter instance;
private RunaOrgStructureImporter() {
super(new TimingsConnectionResources());
}
public static synchronized RunaOrgStructureImporter getInstance() {
if (instance == null) {
instance = new RunaOrgStructureImporter();
}
return instance;
}
@Override
public TimingsConnectionResources getResources() {
return (TimingsConnectionResources) super.getResources();
}
@Override
public void connect() throws Exception {
StringBuffer url = new StringBuffer(getResources().getServletUrl());
url.append("?").append(TimingsConnectionResources.PAST_DAYS_PERIOD).append("=").append(getResources().getPastDays());
if (getResources().isTestMode()) {
url.append("&").append(TimingsConnectionResources.TEST_CONNECTION);
}
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost(getResources().getServerHost(), getResources().getServerPort(), "http");
method = new GetMethod(url.toString());
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
throw new Exception("HTTP return code: (" + statusCode + ");" + method.getStatusLine());
}
if (getResources().isTestMode() && !"TestOK".equals(method.getResponseBodyAsString())) {
throw new Exception("No valid response from servlet, check URL");
}
}
Set<Firm> firms;
@Override
protected void loadRemoteData() throws Exception {
InputStream is = method.getResponseBodyAsStream();
firms = parseTree(is);
method.releaseConnection();
}
@Override
protected void saveCachedData() throws Exception {
Document document = XmlUtil.createDocument("executors", null);
for (Firm firm : firms) {
Element firmElement = document.createElement("firm");
firmElement.setAttribute("name", firm.name);
document.getDocumentElement().appendChild(firmElement);
for (Department department : firm.departments) {
Element departmentElement = document.createElement("department");
departmentElement.setAttribute("name", department.name);
departmentElement.setAttribute("shortName", department.shortName);
firmElement.appendChild(departmentElement);
for (Actor actor : department.actors) {
Element actorElement = document.createElement("actor");
actorElement.setAttribute("id", String.valueOf(actor.id));
actorElement.setAttribute("name", actor.name);
actorElement.setAttribute("active", actor.active ? "1" : "0");
departmentElement.appendChild(actorElement);
}
}
}
XmlUtil.writeXml(document, new FileOutputStream(getCacheFile()));
}
private Set<Firm> parseTree(InputStream is) throws Exception {
Set<Firm> firms = new TreeSet<Firm>();
Document document = XmlUtil.parseDocument(is);
if (!"executors".equals(document.getDocumentElement().getNodeName())) {
throw new Exception("Invalid XML");
}
NodeList firmNodeList = document.getElementsByTagName("firm");
for (int i = 0; i < firmNodeList.getLength(); i++) {
Element firmElement = (Element) firmNodeList.item(i);
Firm firm = new Firm(firmElement.getAttribute("name"));
firms.add(firm);
NodeList departmentNodeList = firmElement.getElementsByTagName("department");
for (int j = 0; j < departmentNodeList.getLength(); j++) {
Element departmentElement = (Element) departmentNodeList.item(j);
Department department = new Department(departmentElement.getAttribute("name"), departmentElement.getAttribute("shortName"));
firm.departments.add(department);
NodeList actorNodeList = departmentElement.getElementsByTagName("actor");
for (int k = 0; k < actorNodeList.getLength(); k++) {
Element actorElement = (Element) actorNodeList.item(k);
int code = Integer.parseInt(actorElement.getAttribute("id"));
Actor actor = new Actor(code, actorElement.getAttribute("name"));
actor.active = "1".equals(actorElement.getAttribute("active"));
department.actors.add(actor);
}
}
}
return firms;
}
@Override
public Object loadCachedData() throws Exception {
File cacheFile = getCacheFile();
if (cacheFile.exists()) {
return parseTree(new FileInputStream(cacheFile));
}
return new TreeSet<Firm>();
}
@Override
public SyncSettingsWizardPage createConnectionSettingsWizardPage() {
return new TimingsSettingsPage();
}
public static class Firm implements Comparable<Firm> {
public String name;
public List<Department> departments = new ArrayList<Department>();
public Firm(String name) {
this.name = name;
}
public int compareTo(Firm o) {
return name.compareTo(o.name);
}
}
public static class Department {
public String name;
public String shortName;
public List<Actor> actors = new ArrayList<Actor>();
public Department(String name, String shortName) {
this.name = name;
this.shortName = shortName;
}
}
public static class Actor {
public int id;
public String name;
public boolean active;
public Actor(int id, String name) {
this.id = id;
this.name = name;
}
public Color getForeground() {
return active ? ColorConstants.darkGreen : ColorConstants.red;
}
}
}