package org.easysoa.registry;
import java.io.Serializable;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.apache.log4j.Logger;
import org.easysoa.registry.facets.ServiceImplementationDataFacet;
import org.easysoa.registry.matching.MatchingHelper;
import org.easysoa.registry.matching.MatchingQuery;
import org.easysoa.registry.types.Component;
import org.easysoa.registry.types.Deliverable;
import org.easysoa.registry.types.Endpoint;
import org.easysoa.registry.types.InformationService;
import org.easysoa.registry.types.Platform;
import org.easysoa.registry.types.ServiceImplementation;
import org.easysoa.registry.types.SubprojectNode;
import org.easysoa.registry.types.ids.SoaNodeId;
import org.easysoa.registry.utils.EmptyDocumentModelList;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
import org.nuxeo.ecm.core.api.IdRef;
import org.nuxeo.ecm.core.model.NoSuchDocumentException;
import org.nuxeo.ecm.core.query.sql.NXQL;
import org.nuxeo.runtime.api.Framework;
/**
* TODO matching should be attempted / done if at least one exact (portType, endpointUrl)
* or provided guide (component, platform (id) of "actual" (??)) info
* (and not only portType)
*
* @author mdutoo
*
*/
public class EndpointMatchingServiceImpl implements EndpointMatchingService {
private static Logger logger = Logger.getLogger(EndpointMatchingServiceImpl.class);
public boolean isEndpointAlreadyMatched(DocumentModel endpointDocument,
CoreSession documentManager) throws ClientException {
return endpointDocument.isProxy() // the proxy, possibly still being created,
// used to link endpoint under impl (else loops)
|| !documentManager.query("SELECT * FROM " + Endpoint.DOCTYPE
+ " WHERE " + NXQL.ECM_ISPROXY + " = 0 AND "
+ NXQL.ECM_UUID + "='" + endpointDocument.getId() + "' AND "
// NB. %ServiceImplementation to also handle JavaServiceImplementations
+ Endpoint.XPATH_PARENTSIDS + "/* LIKE '%ServiceImplementation:%'").isEmpty();
}
public DocumentModelList findServiceImplementations(CoreSession documentManager,
DocumentModel endpoint, String filterComponentId,
boolean skipPlatformMatching, boolean requireAtLeastOneExactCriteria) throws ClientException { // TODO impl vs runtime platform matching ?
// how should work matching in discovery & dashboard for :
// endpoint : if has no impl,
// find impl : on IS req itf (portType), and whose IS is in provided component if any,
// and whose impl platform (criteria) match the endpoint's discovered impl platform (criteria) if any ;
// if single matched link to it
// (if more than one result, use matching dashboard)
// if none, create impl and do as for in ServiceMatchingImpl : 1. and fill component, else 2. and link to platform, else 3.
// Init
DocumentService documentService = getDocumentService();
boolean anyExactCriteria = false;
MatchingQuery query = new MatchingQuery(DocumentService.NXQL_SELECT_FROM + ServiceImplementation.DOCTYPE);
// Filter by subproject
query.addCriteria(SubprojectServiceImpl.buildCriteriaSeenFromSubproject(endpoint));
// Match platform properties :
// 1. IF A LINKED PLATFORM HAS BEEN PROVIDED FOR THE ENDPOINT BY THE PROBE EX. WEB DISCO
if (!skipPlatformMatching) {
String platformUuid = (String) endpoint.getPropertyValue(Endpoint.XPATH_LINKED_PLATFORM);
if (/*endpoint.hasSchema(Endpoint.SCHEMA_ENDPOINT) // always
&& */platformUuid != null && platformUuid.length() != 0) {
try {
DocumentModel platformDocument = documentManager.getDocument(new IdRef(platformUuid));
for (String property : MatchingHelper.implPlatformPropsToMatch ) {
query.addConstraintMatchCriteriaIfSet(property,
platformDocument.getPropertyValue(property));
}
// TODO up to runtime platform constraints
// TODO rather match platform ID (if any) than criteria
//query.addConstraintMatchCriteriaWithAltIfSet("iserv:linkedPlatform", "impl:platform",
// endpoint.getPropertyValue(Endpoint.XPATH_LINKED_PLATFORM));
} catch (ClientException cex) {
if (cex.getCause() instanceof NoSuchDocumentException) {
throw new ClientException("Can't find platform with id " + platformUuid
+ " looking for implementations of endpoint " + endpoint, cex);
}
throw cex;
}
}
// TODO ELSE MATCH DISCOVERED PLATFORM CRITERIA OF THE ENDPOINT
// AGAINST THE IMPL'S SERVICE'S PLATFORM IF ANY ELSE AGAINST THE IMPL'S DISCOVERED PLATFORM CRITERIA
// TODO make it possible in disco (?) & model (yes)
else if (endpoint.hasFacet(ServiceImplementationDataFacet.FACET_SERVICEIMPLEMENTATIONDATA)) {
// TODO rather match platform only if known as "actual" (or linked platform provided ??), rather than ...IfSet
query.addConstraintMatchCriteriaWithAltIfSet(Platform.XPATH_IDE,
ServiceImplementation.XPATH_IMPL_IDE,
endpoint.getPropertyValue(ServiceImplementation.XPATH_IMPL_IDE)); // TODO Q rather Endpoint.xx ?!?
query.addConstraintMatchCriteriaWithAltIfSet(Platform.XPATH_LANGUAGE,
ServiceImplementation.XPATH_IMPL_LANGUAGE,
endpoint.getPropertyValue(ServiceImplementation.XPATH_IMPL_LANGUAGE)); // TODO Q rather Endpoint.xx ?!?
query.addConstraintMatchCriteriaWithAltIfSet(Platform.XPATH_BUILD,
ServiceImplementation.XPATH_IMPL_BUILD,
endpoint.getPropertyValue(ServiceImplementation.XPATH_IMPL_BUILD)); // TODO Q rather Endpoint.xx ?!?
query.addConstraintMatchCriteriaWithAltIfSet(Platform.XPATH_DELIVERABLE_NATURE,
Deliverable.XPATH_NATURE,
endpoint.getPropertyValue(Deliverable.XPATH_NATURE)); // TODO Q rather Endpoint.xx ?!?
query.addConstraintMatchCriteriaWithAltIfSet(Platform.XPATH_DELIVERABLE_REPOSITORY_URL,
Deliverable.XPATH_REPOSITORY_URL,
endpoint.getPropertyValue(Deliverable.XPATH_REPOSITORY_URL)); // TODO Q rather Endpoint.xx ?!?
//if (endpoint.hasSchema(Endpoint.SCHEMA_ENDPOINT)) { // always
// endpoint platform criteria : match those provided on the endpoint against required platform
String endpointServiceProtocol = (String) endpoint.getPropertyValue(Endpoint.XPATH_ENDP_SERVICE_PROTOCOL);
String endpointTansportProtocol = (String) endpoint.getPropertyValue(Endpoint.XPATH_ENDP_TRANSPORT_PROTOCOL);
String endpointServiceRuntime = (String) endpoint.getPropertyValue(Endpoint.XPATH_ENDP_SERVICE_RUNTIME);
String endpointAppServerRuntime = (String) endpoint.getPropertyValue(Endpoint.XPATH_ENDP_APP_SERVER_RUNTIME);
query.addConstraintMatchCriteriaIfSet(Platform.XPATH_SERVICE_PROTOCOL, endpointServiceProtocol); // SOAP, XML or JSON (or AtomPub...) for REST...
query.addConstraintMatchCriteriaIfSet(Platform.XPATH_TRANSPORT_PROTOCOL, endpointTansportProtocol); // HTTP (HTTPS ?)...
query.addConstraintMatchCriteriaIfSet(Platform.XPATH_SERVICE_RUNTIME, endpointServiceRuntime); // CXF (, Axis2...)
query.addConstraintMatchCriteriaIfSet(Platform.XPATH_APP_SERVER_RUNTIME, endpointAppServerRuntime); // ApacheTomcat, Jetty...
//}
}
} // else find impl for "matchingFirst" impl (see DiscoveryService)
// TODO IF FOUND PLATFORM LINK TO IT ?????
// Match endpoint properties
if (MatchingHelper.isWsdlInfo(endpoint)) { // TODO rather specific to Endpoint !!!!!!!!!!!!!!!
//query.addCriteria("ecm:mixinType = '" + Endpoint.FACET_WSDLINFO + "'"); // not required unless added dynamically but hard to do in DiscoveryServiceImpl
query.addCriteria(ServiceImplementation.XPATH_TECHNOLOGY , Platform.SERVICE_LANGUAGE_JAXWS);
String endpointPortTypeName = (String) endpoint.getPropertyValue(Endpoint.XPATH_WSDL_PORTTYPE_NAME);
query.addCriteria(ServiceImplementation.XPATH_WSDL_PORTTYPE_NAME, endpointPortTypeName); anyExactCriteria = true;
// NB. exact match (else useless because too wide), is set since is WS(DL)
} else if (MatchingHelper.isRestInfo(endpoint)) { // TODO rather specific to Endpoint !!!!!!!!!!!!!!!
//query.addCriteria("ecm:mixinType = '" + Endpoint.FACET_RESTINFO + "'"); // not required unless added dynamically but hard to do in DiscoveryServiceImpl
query.addCriteria(ServiceImplementation.XPATH_TECHNOLOGY , Platform.SERVICE_LANGUAGE_JAXRS);
String endpointRestPath = (String) endpoint.getPropertyValue(Endpoint.XPATH_REST_PATH); anyExactCriteria = true;
//String endpointRestContentType = (String) endpoint.getPropertyValue(Endpoint.XPATH_REST_MEDIA_TYPE); // OPT
//OPT String endpointRestAccepts = (String) impl.getPropertyValue(Endpoint.XPATH_REST_ACCEPTS); // OPT
query.addCriteria(ServiceImplementation.XPATH_REST_PATH, endpointRestPath); anyExactCriteria = true;
// NB. exact match (else useless because too wide), is set (at least to "") since is REST
//query.addConstraintMatchCriteria(ServiceImplementation.XPATH_REST_ACCEPTS, endpointRestAccepts); // OPT
//query.addConstraintMatchCriteria(ServiceImplementation.XPATH_REST_MEDIA_TYPE, endpointRestContentType); // OPT
}
// TODO UPDATE
/*String endpointServiceProtocol= "SOAP"; // REST/XML
String endpointTransportProtocol = "HTTP"; // if WS extracted from WSDL binding/transport=="http://schemas.xmlsoap.org/soap/http"
// NB. endpointServiceProtocol=WS|REST is implied by platform:serviceDefinition=WSDL|JAXRS, though SOAP spec includes also ex. HTTP binding
infoServiceQueryString +=
" AND platform:transportProtocol='" + endpointTransportProtocol + "'"; // if any
boolean isHttp = "HTTP".equals(endpointTransportProtocol);
if (isHttp) { // consistency logic
String endpointServiceTransportHttpContentType = "application/json+nxautomation";
String endpointServiceTransportHttpContentKind = "XML"; // deduced from ContentType if possible, else from message monitoring
infoServiceQueryString +=
" AND platform:transportProtocol='" + endpointServiceTransportHttpContentType + "'" +
" AND platform:transportProtocol='" + endpointServiceTransportHttpContentKind + "'"; // if any
}*/
// Filter by component
filterComponentId = MatchingHelper.appendComponentFilterToQuery(documentManager, query, filterComponentId, endpoint);
anyExactCriteria = anyExactCriteria || filterComponentId != null;
// TODO filter mock ? a priori not...
//query.addConstraintMatchCriteria(ServiceImplementation.XPATH_ISMOCK, "0");
if (requireAtLeastOneExactCriteria && !anyExactCriteria) {
return EmptyDocumentModelList.INSTANCE;
}
// Run query
String implQuery = query.build();
DocumentModelList foundImpls = documentService.query(documentManager,
implQuery, true, false);
return foundImpls;
}
@Override
public DocumentModelList findInformationServices(CoreSession documentManager,
DocumentModel endpoint, String filterComponentId,
boolean requireAtLeastOneExactCriteria) throws ClientException { // TODO impl vs runtime platform matching ?
// Init
DocumentService documentService = getDocumentService();
boolean anyExactCriteria = false;
MatchingQuery query = new MatchingQuery("SELECT * FROM " + InformationService.DOCTYPE);
// Filter by subproject
query.addCriteria(SubprojectServiceImpl.buildCriteriaSeenFromSubproject(endpoint));
// 1. IF A LINKED PLATFORM HAS BEEN PROVIDED FOR THE ENDPOINT BY THE PROBE EX. WEB DISCO
if (endpoint.hasFacet(Endpoint.SCHEMA_ENDPOINT)
&& endpoint.getPropertyValue(Endpoint.XPATH_LINKED_PLATFORM) != null) {
DocumentModel platformDocument = documentManager.getDocument(
new IdRef((String) endpoint.getPropertyValue(Endpoint.XPATH_LINKED_PLATFORM)));
for (String property : MatchingHelper.allPlatformPropsToMatch ) {
query.addConstraintMatchCriteriaIfSet(property,
platformDocument.getPropertyValue(property));
}
// TODO rather match platform ID (if any) than criteria
//query.addConstraintMatchCriteriaIfSet("iserv:linkedPlatform",
// endpoint.getPropertyValue(Endpoint.XPATH_LINKED_PLATFORM));
}
// 2. NB. NO PLATFORM MATCHING WHEN FINDING COMPATIBLE IS
// else couldn't match SOAPUI mock endpoint with JAXWS expected IS + Component
// (but do match it with impl)
// TODO rather match platform only if known as "actual" (or linked platform provided ??), rather than ...IfSet
if (MatchingHelper.isWsdlInfo(endpoint)) { // is endpoint WSDL (JAXWS) ?
//query.addCriteria("ecm:mixinType = '" + Endpoint.FACET_WSDLINFO + "'"); // not required unless added dynamically but hard to do in DiscoveryServiceImpl
//query.addConstraintMatchCriteriaIfSet(Platform.XPATH_SERVICE_LANGUAGE , endpoint.getPropertyValue(Endpoint.XPATH_TECHNOLOGY));
// NO not necessarily JAWS ! .NET, HTTP mock or no requirement at all would be OK
String endpointPortTypeName = (String) endpoint.getPropertyValue(Endpoint.XPATH_WSDL_PORTTYPE_NAME);
query.addCriteria(InformationService.XPATH_WSDL_PORTTYPE_NAME, endpointPortTypeName); anyExactCriteria = true;
// NB. exact match (else useless because too wide), is set since is WS(DL)
} else if (MatchingHelper.isRestInfo(endpoint)) { // is endpoint REST (JAXRS) ?
//query.addCriteria("ecm:mixinType = '" + Endpoint.FACET_RESTINFO + "'"); // not required unless added dynamically but hard to do in DiscoveryServiceImpl
//query.addConstraintMatchCriteriaIfSet(Platform.XPATH_SERVICE_LANGUAGE, endpoint.getPropertyValue(Endpoint.XPATH_TECHNOLOGY));
// NO not necessarily JAXRS ! .NET, HTTP mock or no requirement at all would be OK
String endpointRestPath = (String) endpoint.getPropertyValue(Endpoint.XPATH_REST_PATH);
//OPT String endpointRestAccepts = (String) endpoint.getPropertyValue(Endpoint.XPATH_REST_ACCEPTS); // OPT
//OPT String endpointRestContentType = (String) endpoint.getPropertyValue(Endpoint.XPATH_REST_CONTENT_TYPE); // OPT
query.addCriteria(InformationService.XPATH_REST_PATH, endpointRestPath); anyExactCriteria = true;
// NB. exact match (else useless because too wide), is set (at least to "") since is REST
//query.addConstraintMatchCriteria(InformationService.XPATH_REST_ACCEPTS, implRestAccepts); // OPT
//query.addConstraintMatchCriteria(InformationService.XPATH_REST_CONTENT_TYPE, implRestContentType); // OPT
}
// Filter by component
filterComponentId = MatchingHelper.appendComponentFilterToQuery(documentManager, query, filterComponentId, endpoint);
anyExactCriteria = anyExactCriteria || filterComponentId != null;
// Run query
String isQuery = query.build();
DocumentModelList foundIs = documentService.query(documentManager, isQuery, true, false);
return foundIs;
}
@Override
public DocumentModelList findEndpointsCompatibleWithImplementation(CoreSession documentManager,
DocumentModel serviceImpl) throws ClientException {
DocumentService documentService = getDocumentService();
MatchingQuery query = new MatchingQuery("SELECT * FROM " + Endpoint.DOCTYPE);
// Filter by subproject
query.addCriteria(SubprojectServiceImpl.buildCriteriaSeesSubproject(serviceImpl)); // NB. multivalued prop
if (MatchingHelper.isWsdlInfo(serviceImpl)) { // consistency logic
//query.addCriteria("ecm:mixinType = '" + InformationService.FACET_WSDLINFO + "'"); // NO should be added dynamically but hard to do in DiscoveryServiceImpl
query.addConstraintMatchCriteria(Endpoint.XPATH_TECHNOLOGY , Platform.SERVICE_LANGUAGE_JAXWS); // require to be its "actual" impl ; OPT for other impl platform metas
String implPortTypeName = (String) serviceImpl.getPropertyValue(ServiceImplementation.XPATH_WSDL_PORTTYPE_NAME); // if JAXWS
query.addConstraintMatchCriteria(Endpoint.XPATH_WSDL_PORTTYPE_NAME, implPortTypeName);
// NB. exact match (else useless because too wide), is set since is WS(DL)
} else if (MatchingHelper.isRestInfo(serviceImpl)) {
//query.addCriteria("ecm:mixinType = '" + ServiceImplementation.FACET_RESTINFO + "'"); // NO should be added dynamically but hard to do in DiscoveryServiceImpl
query.addConstraintMatchCriteria(Endpoint.XPATH_TECHNOLOGY , Platform.SERVICE_LANGUAGE_JAXRS); // require to be its "actual" impl ; OPT for other impl platform metas
String implRestPath = (String) serviceImpl.getPropertyValue(ServiceImplementation.XPATH_REST_PATH);
//OPT String implRestAccepts = (String) serviceImpl.getPropertyValue(ServiceImplementation.XPATH_REST_ACCEPTS); // OPT
//OPT String implRestContentType = (String) serviceImpl.getPropertyValue(ServiceImplementation.XPATH_REST_CONTENT_TYPE); // OPT
query.addConstraintMatchCriteria(Endpoint.XPATH_REST_PATH, implRestPath);
// NB. exact match (else useless because too wide), is set (at least to "") since is REST
//query.addConstraintMatchCriteria(Endpoint.XPATH_REST_ACCEPTS, implRestAccepts); // OPT
//query.addConstraintMatchCriteria(Endpoint.XPATH_REST_CONTENT_TYPE, implRestContentType); // OPT
}
// NB. IS-focused & partial matching, other platform metas are checked in the following call to findServiceImplementations()
// TODO handle the case of impl-endpoint links that are now wrong i.e. SOA validation
String serviceImplQuery = query.build();
return documentService.query(documentManager, serviceImplQuery, true, false);
}
@Override
public void linkServiceImplementation(CoreSession documentManager,
SoaNodeId endpointId, SoaNodeId implId, boolean save)
throws Exception {
if (implId != null) {
// Create link
DiscoveryService discoveryService = Framework.getService(DiscoveryService.class);
discoveryService.runDiscovery(documentManager, endpointId, null, Arrays.asList(implId)); // null props, else saved which triggers loop
// TODO or explicitly ??
// i.e. impl.SOA_NAME (= implId.getName()) == ep.getParentOfType(ServiceImplementation.DOCTYPE).getName()
// TODO if unmatched impl, enrich impl with impl-level platform metas to help it match to IS ??
}
else {
// Remove link
DocumentService docService = Framework.getService(DocumentService.class);
DocumentModelList endpointProxies = docService.findProxies(documentManager, endpointId);
SoaMetamodelService soaMetamodelService = Framework.getService(SoaMetamodelService.class);
for (DocumentModel endpointProxy : endpointProxies) {
DocumentModel proxyParent = documentManager.getParentDocument(endpointProxy.getRef());
if (soaMetamodelService.isAssignable(proxyParent.getType(), ServiceImplementation.DOCTYPE)) {
documentManager.removeDocument(endpointProxy.getRef());
}
}
}
if (save) {
documentManager.save();
}
}
@Override
public void linkInformationServiceThroughPlaceholder(
CoreSession documentManager, DocumentModel endpoint,
DocumentModel informationService, boolean save) throws Exception {
DocumentService docService = getDocumentService();
if (informationService == null) {
// Remove link TODO useful ???
DocumentModel serviceimpl = docService.getServiceImplementationFromEndpoint(endpoint);
SoaNodeId endpointId = docService.createSoaNodeId(endpoint);
DocumentModelList endpointProxies = docService.findProxies(documentManager, endpointId);
SoaMetamodelService soaMetamodelService = Framework.getService(SoaMetamodelService.class);
for (DocumentModel endpointProxy : endpointProxies) {
DocumentModel proxyParent = documentManager.getParentDocument(endpointProxy.getRef());
if (soaMetamodelService.isAssignable(proxyParent.getType(), ServiceImplementation.DOCTYPE)) {
documentManager.removeDocument(endpointProxy.getRef());
}
}
if ((Boolean) serviceimpl.getPropertyValue(ServiceImplementation.XPATH_ISPLACEHOLDER) != true) {
List<DocumentModel> remainingEndpoints = docService.getEndpointsOfImplementation(serviceimpl, null); // in all subprojects (??)
if (remainingEndpoints.isEmpty()) {
// remove placeholder impl
docService.delete(documentManager, endpointId);
}
}
} else { // else create link
// Create placeholder impl (in endpoint subproject) :
HashMap<String, Serializable> nuxeoProperties = new HashMap<String, Serializable>(2);
nuxeoProperties.put(ServiceImplementation.XPATH_ISPLACEHOLDER, true);
String interfaceName;
if (MatchingHelper.isWsdlInfo(endpoint)) {
String portTypeName = (String) endpoint.getPropertyValue(Endpoint.XPATH_WSDL_PORTTYPE_NAME);
nuxeoProperties.put(ServiceImplementation.XPATH_WSDL_PORTTYPE_NAME, portTypeName);
interfaceName = portTypeName;
} else if (MatchingHelper.isWsdlInfo(endpoint)) {
String restPath = (String) endpoint.getPropertyValue(Endpoint.XPATH_REST_PATH);
nuxeoProperties.put(ServiceImplementation.XPATH_REST_PATH, restPath);
interfaceName = restPath;
} else {
// some meaningful default
interfaceName = new URL((String) endpoint.getPropertyValue(Endpoint.XPATH_URL)).getPath();
}
if (endpoint.hasFacet(ServiceImplementationDataFacet.FACET_SERVICEIMPLEMENTATIONDATA)) {
// set platform criteria matched by endpoint on impl TODO OR NOT ??
// (else a new placeholder is created each time, because can't be matched)
putPropertyIfNotEmpty(endpoint, ServiceImplementation.XPATH_IMPL_IDE, nuxeoProperties);
putPropertyIfNotEmpty(endpoint, ServiceImplementation.XPATH_IMPL_LANGUAGE, nuxeoProperties);
putPropertyIfNotEmpty(endpoint, ServiceImplementation.XPATH_IMPL_BUILD, nuxeoProperties);
putPropertyIfNotEmpty(endpoint, Deliverable.XPATH_NATURE, nuxeoProperties);
putPropertyIfNotEmpty(endpoint, Deliverable.XPATH_REPOSITORY_URL, nuxeoProperties);
}
if (endpoint.hasFacet(Component.FACET_ARCHITECTURECOMPONENT)) {
putPropertyIfNotEmpty(endpoint, Endpoint.XPATH_COMPONENT_ID, nuxeoProperties);
}
// if SOA node id already exists, create a new one for placeholder
// (else would be merged in RepositoryManagementListener)
String subprojectId = (String) endpoint.getPropertyValue(SubprojectNode.XPATH_SUBPROJECT);
SoaNodeId implId = new SoaNodeId(subprojectId, ServiceImplementation.DOCTYPE, interfaceName);
int i = 1;
while (docService.findSoaNode(documentManager, implId) != null) {
implId = new SoaNodeId(subprojectId, ServiceImplementation.DOCTYPE, interfaceName + "_" + i++);
}
// TODO also copy other impl-level platform metas. To be used when merging placeholder ? NOO rather delete placeholder and rematch endpoint
// NB. don't do a documentManager.create() here, else triggers documentCreated event
// (and from there event loop) , even though properties have not been set yet
DocumentModel implModel = DiscoveryServiceImpl.createOrUpdate(documentManager,
Framework.getService(DocumentService.class), // TODO more service-like
null, null, implId, nuxeoProperties, false);
// Attach placeholder impl to information service
try {
ServiceMatchingService serviceMatchingService = Framework.getService(ServiceMatchingService.class);
serviceMatchingService.linkInformationService(documentManager, implModel, informationService.getId(), true);
} catch (Exception e) {
documentManager.removeDocument(implModel.getRef());
throw new ClientException("Service matching service unavailable, aborting");
}
// Attach endpoint to placeholder impl
linkServiceImplementation(documentManager,
docService.createSoaNodeId(endpoint),
docService.createSoaNodeId(implModel),
false);
}
if (save) {
documentManager.save();
}
}
private void putPropertyIfNotEmpty(DocumentModel documentModel, String propXpath,
HashMap<String, Serializable> nuxeoProperties) throws ClientException {
Serializable value = documentModel.getPropertyValue(propXpath);
if (value != null && !(value instanceof String && ((String) value).length() == 0)) {
nuxeoProperties.put(propXpath, value);
}
}
private DocumentService getDocumentService() throws ClientException {
try {
return Framework.getService(DocumentService.class);
} catch (Exception e) {
throw new ClientException("Document service unavailable, aborting");
}
}
}