/** * EasySOA Registry * Copyright 2011-2013 Open Wide * * 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/>. * * Contact : easysoa-dev@googlegroups.com */ package org.easysoa.registry.types.listeners; import org.apache.log4j.Logger; import org.easysoa.registry.SoaMetamodelService; import org.easysoa.registry.dbb.ProbeConfUtil; import org.easysoa.registry.dbb.ResourceParsingService; import org.easysoa.registry.dbb.ResourceUpdateService; import org.easysoa.registry.types.Resource; import org.easysoa.registry.types.ResourceDownloadInfo; import org.nuxeo.common.collections.ScopeType; import org.nuxeo.ecm.core.api.ClientException; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.event.Event; import org.nuxeo.ecm.core.event.EventBundle; import org.nuxeo.ecm.core.event.EventContext; import org.nuxeo.ecm.core.event.EventListener; import org.nuxeo.ecm.core.event.PostCommitEventListener; import org.nuxeo.ecm.core.event.impl.DocumentEventContext; import org.nuxeo.runtime.api.Framework; /** * Triggers SOA resource download & parse as required. * * Usually called synchronously, but might also be triggered in an async * (which requires to implement PostCommitEventListener and postCommit="true", * see EventListenerDescriptor.java) manner by Nuxeo's event system, see * http://doc.nuxeo.com/display/NXDOC/Events+and+Listeners * * Should be registered on events : documentCreated, documentModified * (and not beforeDocumentModification because digest not yet computed at storage level) * * @author jguillemotte */ public class ResourceListener extends EventListenerBase implements EventListener, PostCommitEventListener { private static final String CONTEXT_REQUEST_RESOURCE_ALREADY_UPDATED = "resourceAlreadyUpdated"; private static Logger logger = Logger.getLogger(ResourceListener.class); /** * Simplistic async / postcommit impl that dispatches to handleEvent(event) * @param events * @throws ClientException */ @Override public void handleEvent(EventBundle events) throws ClientException { for (Event event : events) { try { this.handleEvent(event); } catch (Exception e) { logger.error("Error", e); } } } @Override public void handleEvent(Event event) throws ClientException { EventContext context = event.getContext(); if (!(context instanceof DocumentEventContext)) { return; } DocumentEventContext documentContext = (DocumentEventContext) context; DocumentModel sourceDocument = documentContext.getSourceDocument(); // Prevent looping on source document changes // (maybe ex. setting downloaded resource blob) if (context.hasProperty(CONTEXT_REQUEST_RESOURCE_ALREADY_UPDATED) || areListenersDisabled(context)) { return; } sourceDocument.getContextData().putScopedValue(ScopeType.REQUEST, CONTEXT_REQUEST_RESOURCE_ALREADY_UPDATED, true); // NB. available if beforeDocumentModification event DocumentModel previousDocumentModel = (DocumentModel) context.getProperty("previousDocumentModel"); ResourceUpdateService resourceUpdateService; try { resourceUpdateService = Framework.getService(ResourceUpdateService.class); // ResourceUpdateService } catch(Exception ex){ throw new ClientException("Can't get ResourceUpdateService", ex); } // if is an RDI (external, to be downloaded resource), update it if (isResourceDownloadInfo(sourceDocument)) { // TODO extract to isResourceDocument() // Check that probe is not using a custom event type String probeType = (String) sourceDocument.getPropertyValue(ResourceDownloadInfo.XPATH_PROBE_TYPE);//TODO String probeInstanceId = (String) sourceDocument.getPropertyValue(ResourceDownloadInfo.XPATH_PROBE_INSTANCEID);//TODO if (ProbeConfUtil.isResourceProbeEventCustom(probeType, probeInstanceId)) { // exit if document change but probe conf says it triggers using dedicated event return; } // Starting update : resourceUpdateService.updateResource(sourceDocument, previousDocumentModel, sourceDocument); // NB. parsing is triggered by (possibly async) resourceDownloaded event fired by resourceUpdateService } else if (isResource(sourceDocument)) { // Trigger event to directly call (WSDL) parsing listener resourceUpdateService.fireResourceDownloadedEvent(sourceDocument); } } /** * Is it a (downloadable, external) Resource that has to be downloaded before being parsed ? * @param docModel * @return * @throws ClientException */ private boolean isResourceDownloadInfo(DocumentModel docModel) throws ClientException { if (docModel.getFacets().contains(ResourceDownloadInfo.FACET_RESOURCEDOWNLOADINFO)) { // also checking that there is an url, else may be a resource with static RDI facet ex. iserv/endpoint String url = (String) docModel.getPropertyValue(ResourceDownloadInfo.XPATH_URL); return url != null && url.length() != 0; } return false; } /** * Is it an (internal) Resource that can be directly parsed ? * @param sourceDocument * @return true if Resource subtype or (HACK) iserv/endpoint (isWsdlDocumentType) with empty url */ private boolean isResource(DocumentModel docModel) throws ClientException { SoaMetamodelService soaMetaModelService; ResourceParsingService resourceParsingService; try { soaMetaModelService = Framework.getService(SoaMetamodelService.class); resourceParsingService = Framework.getService(ResourceParsingService.class); } catch(Exception ex){ throw new ClientException("Can't get SoaMetamodelService & ResourceParsingService", ex); } if (this.isResourceDownloadInfo(docModel)) { return false; } else if (soaMetaModelService.isAssignable(docModel.getType(), Resource.DOCTYPE)) { return true; } else if (resourceParsingService.isWsdlFileResource(docModel)) { //DocumentType(docModel.getType()) String resourceUrl = (String)docModel.getPropertyValue(ResourceDownloadInfo.XPATH_URL); if (resourceUrl == null || resourceUrl.length() == 0) { return true; } } return false; } }