package org.jbpm.ui.orgfunctions;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.security.auth.Subject;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;
import org.jbpm.ui.sync.DataImporter;
import org.jbpm.ui.sync.RunaWFESyncResources;
import org.jbpm.ui.sync.RunaWFESyncSettingsPage;
import org.jbpm.ui.sync.SyncResources;
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.af.Relation;
import ru.runa.af.presentation.AFProfileStrategy;
import ru.runa.af.service.impl.interfaces.AuthenticationService;
import ru.runa.af.service.impl.interfaces.AuthenticationServiceHome;
import ru.runa.af.service.impl.interfaces.ExecutorService;
import ru.runa.af.service.impl.interfaces.ExecutorServiceHome;
import ru.runa.af.service.impl.interfaces.Service;
import ru.runa.af.service.impl.interfaces.ServiceHome;
public class RunaWFERelationsImporter extends DataImporter {
private InitialContext remoteContext;
private Subject subject;
private List<String> relations = new ArrayList<String>();
private static RunaWFERelationsImporter instance;
private RunaWFERelationsImporter() {
super(RunaWFESyncResources.INSTANCE);
}
public static synchronized RunaWFERelationsImporter getInstance() {
if (instance == null) {
instance = new RunaWFERelationsImporter();
}
return instance;
}
@Override
public RunaWFESyncResources getResources() {
return (RunaWFESyncResources) super.getResources();
}
@Override
public void connect() throws Exception {
Hashtable<String, String> environment = new Hashtable<String, String>();
environment.put(Context.INITIAL_CONTEXT_FACTORY, getResources().getInitialCtxFactory());
environment.put(Context.URL_PKG_PREFIXES, getResources().getUrlPkgPrefixes());
environment.put(Context.PROVIDER_URL, getResources().getProviderUrl());
remoteContext = new InitialContext(environment);
AuthenticationService service = getService(AuthenticationServiceHome.JNDI_NAME, AuthenticationServiceHome.class);
if (SyncResources.LOGIN_MODE_LOGIN_PASSWORD.equals(getResources().getLoginMode())) {
subject = service.authenticate(getResources().getLogin(), getResources().getPassword());
} else {
GSSManager manager = GSSManager.getInstance();
GSSCredential clientCred = manager.createCredential(GSSCredential.INITIATE_ONLY);
GSSName peerName = manager.createName("WFServer", null);
GSSContext context = manager.createContext(peerName, (Oid) null, clientCred, GSSContext.DEFAULT_LIFETIME);
context.requestMutualAuth(false);
byte[] token = new byte[0];
token = context.initSecContext(token, 0, token.length);
subject = service.authenticate(token);
}
}
@Override
protected void clearInMemoryCache() {
relations.clear();
}
@Override
protected void saveCachedData() throws Exception {
Document document = XmlUtil.createDocument("data", null);
for (String name : relations) {
Element element = document.createElement("relation");
element.setAttribute("name", name);
document.getDocumentElement().appendChild(element);
}
XmlUtil.writeXml(document, new FileOutputStream(getCacheFile()));
}
@Override
public Object loadCachedData() throws Exception {
List<String> result = new ArrayList<String>();
File cacheFile = getCacheFile();
if (cacheFile.exists()) {
Document document = XmlUtil.parseDocument(new FileInputStream(cacheFile));
NodeList nodeList = document.getElementsByTagName("relation");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
String name = element.getAttribute("name");
result.add(name);
}
}
return result;
}
@Override
protected void loadRemoteData() throws Exception {
ExecutorService executorService = getService(ExecutorServiceHome.JNDI_NAME, ExecutorServiceHome.class);
List<Relation> loaded = executorService.getRelations(subject, AFProfileStrategy.RELATION_GROUPS_DEFAULT_BATCH_PRESENTATOIN_FACTORY.getDefaultBatchPresentation());
for (Relation relation : loaded) {
relations.add(relation.getName());
}
}
private <T extends Service> T getService(String jndiName, Class<? extends ServiceHome> homeClass) throws Exception {
Object homeRef = remoteContext.lookup(jndiName);
ServiceHome home = (ServiceHome) PortableRemoteObject.narrow(homeRef, homeClass);
Service service = (Service) home.getClass().getMethod("create", new Class[0]).invoke(home, new Object[0]);
return (T) service;
}
@Override
public SyncSettingsWizardPage createConnectionSettingsWizardPage() {
return new RunaWFESyncSettingsPage();
}
}