/** * 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 java.io.File; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.easysoa.registry.dbb.ResourceParsingService; import org.nuxeo.ecm.core.api.Blob; 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.event.DocumentEventTypes; import org.nuxeo.ecm.core.event.Event; import org.nuxeo.ecm.core.event.EventContext; import org.nuxeo.ecm.core.event.EventListener; import org.nuxeo.ecm.core.event.impl.DocumentEventContext; import org.nuxeo.runtime.api.Framework; import org.ow2.easywsdl.wsdl.WSDLFactory; import org.ow2.easywsdl.wsdl.api.Description; import org.ow2.easywsdl.wsdl.api.WSDLException; import org.ow2.easywsdl.wsdl.api.WSDLReader; /** * Extracts metadata from WSDL if changed. * * Should be registered on events : documentCreated, documentModified * (and not beforeDocumentModification because digest not yet computed at storage level) * * @author mdutoo * */ public class WSDLParsingListener implements EventListener { public static final String SOAP_CONTENT_TYPE = "application/soap+xml"; // ; charset=utf-8 http://www.w3schools.com/soap/soap_httpbinding.asp private static Logger logger = Logger.getLogger(WSDLParsingListener.class); public WSDLParsingListener() {} @Override public void handleEvent(Event event) throws ClientException { // Ensure event nature EventContext context = event.getContext(); if (!(context instanceof DocumentEventContext)) { return; } DocumentEventContext documentContext = (DocumentEventContext) context; DocumentModel sourceDocument = documentContext.getSourceDocument(); CoreSession documentManager = documentContext.getCoreSession(); //if (DocumentEventTypes.BEFORE_DOC_UPDATE.equals(event.getName()) && !sourceDocument.isDirty()) { // return; //} //if (!sourceDocument.hasSchema(SoaNode.SCHEMA) // || sourceDocument.getPropertyValue(InformationService.XPATH_SOANAME) == null) { // return; //} ResourceParsingService resourceParsingService; try { resourceParsingService = Framework.getService(ResourceParsingService.class); } catch(Exception ex){ throw new ClientException(ex); } if (!resourceParsingService.isWsdlFileResource(sourceDocument)) { return; } // NB. available if beforeDocumentModification event (so useless for digest which comes on documentModified) //DocumentModel previousDocumentModel = (DocumentModel) context.getProperty("previousDocumentModel"); // TODO test it // TODO copy this file to ResourceListener & replace it in *listener.xml conf, // remove the following code from it, hook WsdlParsingListener rather on resourceDownloaded event in xml conf, // trigger resourceDownloaded event in ResourceUpdateService impl boolean documentModified = resourceParsingService.extractMetas(sourceDocument); // Save according to event type if (documentModified && !DocumentEventTypes.DOCUMENT_CREATED.equals(event.getName())) { documentManager.saveDocument(sourceDocument); documentManager.save(); } // else DocumentEventTypes.BEFORE_DOC_UPDATE.equals(event.getName()), therefore save will be automatically done http://doc.nuxeo.com/display/NXDOC/Events+and+Listeners } /** * @obsolete rather written inline in WsdlBlob (or listener), but shows how it is meant to work * @param sourceDocument * @return * @throws ClientException */ /*private static WsdlBlob getWsdlBlob(DocumentModel sourceDocument) throws ClientException { Blob blob = null; String oldWsdlFileName = (String) sourceDocument.getPropertyValue(WsdlInfoFacet.XPATH_WSDL_FILE_NAME); if (oldWsdlFileName != null) { blob = getBlob(sourceDocument, oldWsdlFileName); } WsdlBlob wsdlBlob = null; if (blob != null) { wsdlBlob = tryParsingWsdlFromBlob(blob); } if (wsdlBlob == null) { wsdlBlob = findWsdlBlob(sourceDocument); } return wsdlBlob; }*/ /** * TODO LATER maybe rather sourceDocument.getAdapter(BlobHolder.class) but doesn't handle file:files * * @param sourceDocument * @param fileName file name of the blob to be returned, must no be null * @return * @throws ClientException */ public static Blob getBlob(DocumentModel sourceDocument, String fileName) throws ClientException { // Look for first WSDL Blob fileBlob = null; Description wsdl = null; // look in attached files List<?> filesInfos = (List<?>) sourceDocument.getPropertyValue("files:files"); if (filesInfos != null && !filesInfos.isEmpty()) { for (Object fileInfoObject : filesInfos) { Map<?, ?> fileInfoMap = (Map<?, ?>) fileInfoObject; fileBlob = (Blob) fileInfoMap.get("file"); if (fileName.equals(fileBlob.getFilename())) { return fileBlob; } } } if (wsdl == null) { // look in document content fileBlob = (Blob) sourceDocument.getPropertyValue("file:content"); if (fileBlob != null && fileName.equals(fileBlob.getFilename())) { return fileBlob; } } return null; } public static Description tryParsingWsdlFromBlob(Blob blob) { if (blob.getFilename().toLowerCase().endsWith("wsdl")) { File file = null; try { file = File.createTempFile("wsdlCandidate", null); blob.transferTo(file); WSDLReader wsdlReader = WSDLFactory.newInstance().newWSDLReader(); try { Description wsdl = wsdlReader.read(file.toURI().toURL()); return wsdl; } catch (WSDLException e) { logger.info("Failed to extract or parse potential WSDL", e); // Not a WSDL, continue to next file } } catch (Exception e) { logger.error("Failed to extract or parse potential WSDL", e); } finally { if (file != null) { boolean delete = file.delete(); if (!delete) { logger.warn("Unable to delete temp WSDL file " + file.getAbsolutePath()); } } } } return null; } }