/* * BEL Framework Webservice Plugin * * URLs: http://openbel.org/ * Copyright (C) 2012, Selventa * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.openbel.cytoscape.webservice; import java.util.Collection; import java.util.List; import javax.swing.JOptionPane; import org.openbel.framework.ws.model.BelStatement; import org.openbel.framework.ws.model.BelTerm; import org.openbel.framework.ws.model.DialectHandle; import org.openbel.framework.ws.model.EdgeDirectionType; import org.openbel.framework.ws.model.EdgeFilter; import org.openbel.framework.ws.model.FindKamNodesByNamespaceValuesRequest; import org.openbel.framework.ws.model.FindKamNodesByNamespaceValuesResponse; import org.openbel.framework.ws.model.FindKamNodesByPatternsRequest; import org.openbel.framework.ws.model.FindKamNodesByPatternsResponse; import org.openbel.framework.ws.model.FindNamespaceValuesRequest; import org.openbel.framework.ws.model.FindNamespaceValuesResponse; import org.openbel.framework.ws.model.FunctionType; import org.openbel.framework.ws.model.FunctionTypeFilterCriteria; import org.openbel.framework.ws.model.GetAdjacentKamEdgesRequest; import org.openbel.framework.ws.model.GetAdjacentKamEdgesResponse; import org.openbel.framework.ws.model.GetAllNamespacesRequest; import org.openbel.framework.ws.model.GetAllNamespacesResponse; import org.openbel.framework.ws.model.GetCatalogRequest; import org.openbel.framework.ws.model.GetCatalogResponse; import org.openbel.framework.ws.model.GetDefaultDialectRequest; import org.openbel.framework.ws.model.GetDefaultDialectResponse; import org.openbel.framework.ws.model.GetSupportingEvidenceRequest; import org.openbel.framework.ws.model.GetSupportingEvidenceResponse; import org.openbel.framework.ws.model.GetSupportingTermsRequest; import org.openbel.framework.ws.model.GetSupportingTermsResponse; import org.openbel.framework.ws.model.InterconnectRequest; import org.openbel.framework.ws.model.InterconnectResponse; import org.openbel.framework.ws.model.Kam; import org.openbel.framework.ws.model.KamEdge; import org.openbel.framework.ws.model.KamHandle; import org.openbel.framework.ws.model.KamNode; import org.openbel.framework.ws.model.LoadKamRequest; import org.openbel.framework.ws.model.LoadKamResponse; import org.openbel.framework.ws.model.Namespace; import org.openbel.framework.ws.model.NamespaceDescriptor; import org.openbel.framework.ws.model.NamespaceValue; import org.openbel.framework.ws.model.NodeFilter; import org.openbel.framework.ws.model.ObjectFactory; import org.openbel.framework.ws.model.SimplePath; import org.openbel.framework.ws.model.WebAPI; import cytoscape.Cytoscape; import cytoscape.data.webservice.WebServiceClientManager; import cytoscape.logger.CyLogger; /** * {@link DefaultKamService} implements an API wrapper around the {@link WebAPI * BEL Framework Web API}. This lightweight class reuses the same webservice * stub instance obtained from the {@link WebServiceClientManager cytoscape * webservice manager}. * * @author Anthony Bargnesi <abargnesi@selventa.com> */ class DefaultKamService implements KamService { private static final CyLogger log = CyLogger .getLogger(DefaultKamService.class); private static final ObjectFactory OBJECT_FACTORY = ObjectFactorySingleton .getInstance(); protected WebAPI webAPI; private ClientConnector clientConnector; /** * Retrieves the webservice client from the * {@link WebServiceClientManager cytoscape webservice manager} and holds * the client stub. */ DefaultKamService() { reloadClientConnector(); } /** * {@inheritDoc} */ public void reloadClientConnector() { clientConnector = (ClientConnector) WebServiceClientManager .getClient("belframework"); if (clientConnector == null) { log.warn("Unable to resolve client connector"); return; } webAPI = clientConnector.getClientStub(); } /** * {@inheritDoc} */ @Override public List<NamespaceValue> findNamespaceValues( final Collection<String> patterns, final Collection<Namespace> namespaces) { if (patterns == null || patterns.isEmpty()) { throw new IllegalArgumentException("patterns parameter is invalid"); } // namespaces can be null or empty checkValid(); final FindNamespaceValuesRequest req = OBJECT_FACTORY .createFindNamespaceValuesRequest(); req.getPatterns().addAll(patterns); if (namespaces != null) { req.getNamespaces().addAll(namespaces); } final FindNamespaceValuesResponse res = webAPI.findNamespaceValues(req); return res.getNamespaceValues(); } /** * {@inheritDoc} */ public List<KamNode> findKamNodesByNamespaceValues( final KamHandle kamHandle, final DialectHandle dialectHandle, final List<NamespaceValue> namespaceValues, final NodeFilter nodeFilter) { if (kamHandle == null) { throw new IllegalArgumentException("handle is null"); } if (namespaceValues == null || namespaceValues.isEmpty()) { throw new IllegalArgumentException( "namespaceValues parameter is invalid"); } // dialectHandle and nodeFilter can be null checkValid(); final FindKamNodesByNamespaceValuesRequest req = OBJECT_FACTORY .createFindKamNodesByNamespaceValuesRequest(); req.setHandle(kamHandle); req.getNamespaceValues().addAll(namespaceValues); if (dialectHandle != null) { req.setDialect(dialectHandle); } if (nodeFilter != null) { req.setFilter(nodeFilter); } final FindKamNodesByNamespaceValuesResponse res = webAPI .findKamNodesByNamespaceValues(req); return res.getKamNodes(); } /** * {@inheritDoc} */ @Override public List<NamespaceDescriptor> getAllNamespaces() { checkValid(); final GetAllNamespacesRequest req = OBJECT_FACTORY .createGetAllNamespacesRequest(); final GetAllNamespacesResponse res = webAPI.getAllNamespaces(req); return res.getNamespaceDescriptors(); } /** * {@inheritDoc} */ @Override public List<Kam> getCatalog() { checkValid(); final GetCatalogRequest req = OBJECT_FACTORY.createGetCatalogRequest(); final GetCatalogResponse res = webAPI.getCatalog(req); return res.getKams(); } /** * {@inheritDoc} */ @Override public LoadKamResponse loadKam(Kam kam) { if (kam == null || kam.getName() == null) { throw new IllegalArgumentException("kam parameter is invalid"); } checkValid(); final LoadKamRequest req = OBJECT_FACTORY.createLoadKamRequest(); req.setKam(kam); return webAPI.loadKam(req); } /** * {@inheritDoc} */ @Override public DialectHandle getDefaultDialect(final KamHandle kamHandle) { if (kamHandle == null) { throw new IllegalArgumentException("kam handle is null"); } checkValid(); final GetDefaultDialectRequest req = OBJECT_FACTORY .createGetDefaultDialectRequest(); req.setKam(kamHandle); final GetDefaultDialectResponse res = webAPI.getDefaultDialect(req); return res.getDialect(); } /** * {@inheritDoc} */ @Override public List<BelTerm> getSupportingTerms(final KamNode node) { if (node == null) { throw new IllegalArgumentException("node parameter is null"); } checkValid(); final GetSupportingTermsRequest req = OBJECT_FACTORY.createGetSupportingTermsRequest(); req.setKamNode(node); final GetSupportingTermsResponse res = webAPI.getSupportingTerms(req); return res.getTerms(); } /** * {@inheritDoc} */ @Override public List<BelStatement> getSupportingEvidence(final KamEdge edge) { if (edge == null) { throw new IllegalArgumentException("edge parameter is null"); } checkValid(); final GetSupportingEvidenceRequest req = OBJECT_FACTORY.createGetSupportingEvidenceRequest(); req.setKamEdge(edge); final GetSupportingEvidenceResponse res = webAPI.getSupportingEvidence(req); final List<BelStatement> stmts = res.getStatements(); for (final BelStatement stmt : stmts) { final BelTerm subject = stmt.getSubjectTerm(); subject.setLabel(subject.getLabel()); final BelTerm objectTerm = stmt.getObjectTerm(); final BelStatement objectStmt = stmt.getObjectStatement(); if (objectTerm != null) { objectTerm.setLabel(objectTerm.getLabel()); } else if (objectStmt != null) { final BelTerm nestedSub = objectStmt.getSubjectTerm(); nestedSub.setLabel(nestedSub.getLabel()); final BelTerm nestedObj = objectStmt.getObjectTerm(); nestedObj.setLabel(nestedObj.getLabel()); } } return stmts; } /** * {@inheritDoc} */ @Override public List<KamNode> findKamNodesByFunction(final KamHandle handle, final DialectHandle dialectHandle, final FunctionType function) { if (handle == null) { throw new IllegalArgumentException("handle is null"); } if (function == null) { throw new IllegalArgumentException("function is null"); } checkValid(); final FindKamNodesByPatternsRequest req = OBJECT_FACTORY.createFindKamNodesByPatternsRequest(); req.setHandle(handle); if (dialectHandle != null) { req.setDialect(dialectHandle); } req.getPatterns().add(".*"); final NodeFilter nf = new NodeFilter(); final FunctionTypeFilterCriteria ftfc = new FunctionTypeFilterCriteria(); ftfc.setIsInclude(true); ftfc.getValueSet().add(function); nf.getFunctionTypeCriteria().add(ftfc); req.setFilter(nf); final FindKamNodesByPatternsResponse res = webAPI .findKamNodesByPatterns(req); return res.getKamNodes(); } /** * {@inheritDoc} */ @Override public List<KamNode> findKamNodesByPatterns(final KamHandle handle, final DialectHandle dialectHandle, final String regex, final NodeFilter nf) { if (handle == null) { throw new IllegalArgumentException("handle is null"); } if (regex == null) { throw new IllegalArgumentException("regex is null"); } checkValid(); final FindKamNodesByPatternsRequest req = OBJECT_FACTORY.createFindKamNodesByPatternsRequest(); req.setHandle(handle); if (dialectHandle != null) { req.setDialect(dialectHandle); } req.getPatterns().add(regex); if (nf != null) { req.setFilter(nf); } final FindKamNodesByPatternsResponse res = webAPI .findKamNodesByPatterns(req); return res.getKamNodes(); } /** * {@inheritDoc} */ @Override public List<KamEdge> getAdjacentKamEdges(final DialectHandle dialectHandle, final KamNode node, final EdgeDirectionType direction, final EdgeFilter ef) { if (node == null) { throw new IllegalArgumentException("node is null"); } if (direction == null) { throw new IllegalArgumentException("direction is null"); } checkValid(); final GetAdjacentKamEdgesRequest req = OBJECT_FACTORY.createGetAdjacentKamEdgesRequest(); if (dialectHandle != null) { req.setDialect(dialectHandle); } req.setKamNode(node); req.setDirection(direction); if (ef != null) { req.setFilter(ef); } final GetAdjacentKamEdgesResponse res = webAPI.getAdjacentKamEdges(req); return res.getKamEdges(); } /** * {@inheritDoc} */ @Override public List<SimplePath> interconnect(final DialectHandle dialectHandle, final Collection<KamNode> sources, final Integer maxDepth) { if (sources == null) { throw new IllegalArgumentException("sources is null"); } if (sources.isEmpty()) { throw new IllegalArgumentException("sources is empty"); } // maxDepth is nullable, so no null check checkValid(); final InterconnectRequest req = OBJECT_FACTORY .createInterconnectRequest(); if (dialectHandle != null) { req.setDialect(dialectHandle); } req.getSources().addAll(sources); req.setMaxDepth(maxDepth); final InterconnectResponse res = webAPI.interconnect(req); return res.getPaths(); } /** * Checks for a valid connection and errors out if not. * * @throws RuntimeException Thrown to fail the existing request */ protected void checkValid() { if (webAPI == null || !clientConnector.isValid()) { // attempt to reconfigure to see if WSDL is now up clientConnector.reconfigure(); } // if reconfigure fails if (webAPI == null || !clientConnector.isValid()) { // TODO move this message dialog out of the Kam service, UI // has no place here JOptionPane.showMessageDialog(Cytoscape.getDesktop(), "Error connecting to the BELFramework Web Services.\n" + "Please check the BELFramework Web Services Configuration.", "Connection Error", JOptionPane.ERROR_MESSAGE); // TODO make this in a checked(?) exception so that layers using // the kam service can create their own UI errors throw new RuntimeException("Connection error."); } } }