package org.easysoa.registry.wsdl;
import java.util.List;
import java.util.Map;
import org.easysoa.registry.facets.WsdlInfoFacet;
import org.easysoa.registry.types.listeners.WSDLParsingListener;
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.ow2.easywsdl.wsdl.api.Description;
/**
* Helps finding and getting info from WSDL file (Blob)
*
* TODO LATER maybe refactor it to an adapter ?
*
* @author mdutoo
*
*/
public class WsdlBlob { // TODO implements ResourceBlob ? or better as ResourceAdapter ??
private Blob blob = null;
private Description wsdl = null;
private DocumentModel sourceDocument;
private boolean hasWsdlFileChangedIfAny = true; // computed after constructor
private boolean hasWsdlFileNameChanged = true; // computed after constructor
private boolean hasWsdlContentChanged = true; // computed after constructor if filename has not changed
private boolean wsdlAlreadyComputed = false;
/**
* When it's finished, blob is null if and only if none or changed
* @param sourceDocument
* @param previousDocumentModel
* @throws ClientException
*/
public WsdlBlob(DocumentModel sourceDocument) throws ClientException {
this.sourceDocument = sourceDocument;
///this.previousDocumentModel = previousDocumentModel;
computeHasFileChanged();
}
/**
* When it's finished, blob is null if and only if none or changed
* @throws ClientException
*/
private void computeHasFileChanged() throws ClientException {
String oldWsdlFileName = (String) getSourceDocument().getPropertyValue(WsdlInfoFacet.XPATH_WSDL_FILE_NAME);
if (oldWsdlFileName != null) {
blob = WSDLParsingListener.getBlob(getSourceDocument(), oldWsdlFileName);
if (blob != null) {
hasWsdlFileNameChanged = false;
// blob is not null, therefore newDigest is not null either
hasWsdlContentChanged = isNewFileDifferent();
hasWsdlFileChangedIfAny = hasWsdlContentChanged;
}
}
}
/**
* Precondition : blob is not null (there is actually a new file)
* @throws ClientException
*/
private boolean isNewFileDifferent() throws ClientException {
// comparing digests
String oldDigest = getOldDigest();
String newDigest = getContentDigest();
// blob is not null, therefore newDigest is not null either
return !newDigest.equals(oldDigest);
}
public boolean hasFileChangedIfAny() {
return hasWsdlFileChangedIfAny;
}
public boolean hasFileNameChanged() {
return hasWsdlFileNameChanged;
}
public boolean hasContentChanged() throws ClientException {
if (hasWsdlFileNameChanged) {
getWsdl(); // make sure it's computed
}
return hasWsdlContentChanged;
}
/**
* (Computes if not yet done and) returns WSDL Blob, if any
* @return null if none
*/
public Blob getBlob() throws ClientException {
if (blob == null) {
getWsdl(); // make sure it's computed
}
return blob;
}
public Description getWsdl() throws ClientException {
if (wsdlAlreadyComputed) {
return wsdl;
}
if (blob != null) {
wsdl = WSDLParsingListener.tryParsingWsdlFromBlob(blob);
}
if (wsdl == null) {
findWsdlBlob(getSourceDocument());
}
wsdlAlreadyComputed = true;
return wsdl;
}
/**
* Looks for first WSDL
* @param sourceDocument
* @param wsdlFileName guide to find it easier
* @return
* @throws ClientException
*/
private void findWsdlBlob(DocumentModel sourceDocument) throws ClientException {
// look in attached files
List<?> filesInfos = (List<?>) sourceDocument.getPropertyValue("files:files");
if (filesInfos != null && !filesInfos.isEmpty()) {
for (Object fileInfoObject : filesInfos) {
Map<?, ?> fileInfoMap = (Map<?, ?>) fileInfoObject;
blob = (Blob) fileInfoMap.get("file");
wsdl = WSDLParsingListener.tryParsingWsdlFromBlob(blob);
}
}
if (wsdl == null) {
// look in document content
blob = (Blob) sourceDocument.getPropertyValue("file:content");
if (blob != null) {
wsdl = WSDLParsingListener.tryParsingWsdlFromBlob(blob);
}
}
if (wsdl != null) {
hasWsdlContentChanged = isNewFileDifferent();
} else {
blob = null; // no wsdl file has been found
}
}
private String getOldDigest() throws ClientException {
// alternative 1 - using the one auto computed & stored by VCS :
/*Blob oldBlob = null;
if (previousDocumentModel != null && oldWsdlFileName != null) {
String oldWsdlFileName = (String) sourceDocument.getPropertyValue(WsdlInfoFacet.XPATH_WSDL_FILE_NAME);
oldBlob = getBlob(previousDocumentModel, oldWsdlFileName);
oldDigest = oldBlob.getDigest();
} // else new document or was without wsdl so null*/
// however documentUpdated.previousDocumentModel doesn't give access to the previous blob's VCS Digest
// so alternative 2 - store it in a business metadata or our own :
String oldDigest = (String) getSourceDocument().getPropertyValue(WsdlInfoFacet.XPATH_WSDL_DIGEST);
return oldDigest;
}
public String getContentDigest() {
String newDigest = null;
// getting VCS' digest since already computed (in documentUpdated, but not beforeDocumentModification event)
if (blob != null) {
newDigest = blob.getDigest(); // NB. digest is auto computed at storage time (i.e. SQLBlob)
}
// NB. this is the same as :
//String oldDigest = ((org.nuxeo.ecm.core.storage.sql.coremodel.SQLBlob) sourceDocument.getPropertyValue("file:content")).getBinary().getDigest();
// alternative 2 - computing new digest using Nuxeo VCS algo
// NB. alternative 1 - compute it explicitly, using FileManager's algo :
/*try {
FileManager fm = Framework.getService(FileManager.class); // requires org.nuxeo.ecm.platform.filemanager.core & api
newDigest = fm.computeDigest(blob);
//blob.setDigest(newDigest); // NO changes SQLBlob's digest, but rather makes it loose the binary -_-
} catch (Exception e) {
logger.warn("Error computing WSDL digest", e);
}*/
// alternative 3 : compute it explicitly, using an algo that is specific
// to XML, WSDL (signature) or only on our extracted metadata
return newDigest;
}
/**
* @return the sourceDocument
*/
public DocumentModel getSourceDocument() {
return sourceDocument;
}
/**
* @param sourceDocument the sourceDocument to set
*/
public void setSourceDocument(DocumentModel sourceDocument) {
this.sourceDocument = sourceDocument;
}
}