package org.easysoa.registry.systems; import java.util.List; import org.apache.log4j.Logger; import org.easysoa.registry.DocumentService; import org.easysoa.registry.types.IntelligentSystem; import org.easysoa.registry.types.IntelligentSystemTreeRoot; import org.easysoa.registry.types.SoaNode; import org.easysoa.registry.types.ids.SoaNodeId; import org.easysoa.registry.utils.DocumentModelHelper; 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.PathRef; import org.nuxeo.ecm.platform.query.nxql.NXQLQueryBuilder; import org.nuxeo.runtime.api.Framework; public class IntelligentSystemTreeApiProxyImpl implements IntelligentSystemTreeApi { private static Logger logger = Logger.getLogger(IntelligentSystemTreeApiProxyImpl.class); private final CoreSession documentManager; private DocumentService documentService; public IntelligentSystemTreeApiProxyImpl(CoreSession documentManager) throws Exception { this.documentManager = documentManager; this.documentService = Framework.getService(DocumentService.class); if (this.documentService == null || this.documentManager == null) { throw new NullPointerException("Cant instantiate IST API, required session or doc service is null"); } } public boolean intelligentSystemTreeExists(String subprojectId, String name) throws ClientException { return findISTModel(subprojectId, name) != null; } public void createIntelligentSystemTree(String subprojectId, String name, String title) throws ClientException { documentService.createDocument(documentManager, IntelligentSystemTreeRoot.DOCTYPE, name, DocumentModelHelper.getWorkspacesPath(documentManager, subprojectId), title); documentManager.save(); } @Override public boolean classifySoaNode(String treeName, SoaNodeId identifier, String classification) throws ClientException { boolean treeChanged = false; DocumentModel istModel = findISTModel(identifier.getSubprojectId(), treeName); if (istModel == null) { throw new ClientException("Tree '" + treeName + "' doesn't exist, can't classify SoaNode " + identifier); } // Ensure the parent systems exist PathRef expectedParentPath = new PathRef(istModel.getPathAsString() + (("".equals(classification)) ? "" : "/" + classification)); if (!documentManager.exists(expectedParentPath)) { String[] parentSystems = classification.split("/"); DocumentModel currentFolder = istModel; for (String parentSystem : parentSystems) { PathRef childPathRef = new PathRef(currentFolder.getPathAsString() + '/' + parentSystem); if (!documentManager.exists(childPathRef)) { currentFolder = documentService.createDocument(documentManager, IntelligentSystem.DOCTYPE, parentSystem, currentFolder.getPathAsString(), parentSystem); treeChanged = true; } else { currentFolder = documentManager.getDocument(childPathRef); } } } // If the model is missing, create a proxy DocumentModel existingModel = findSoaNodeModel(istModel, treeName, identifier); if (existingModel == null) { DocumentModel sourceModel = documentService.findSoaNode(documentManager, identifier); documentManager.createProxy(sourceModel.getRef(), expectedParentPath); treeChanged = true; } // If in the IST but not at the right place, move the document else if (!existingModel.getPathAsString().equals(expectedParentPath.toString() + '/' + existingModel.getName())){ List<DocumentModel> parents = documentManager.getParentDocuments(existingModel.getRef()); documentManager.move(existingModel.getRef(), expectedParentPath, existingModel.getName()); treeChanged = true; removeEmptyParentSystems(parents); } return treeChanged; } @Override public boolean deleteSoaNode(String treeName, SoaNodeId identifier) throws ClientException { boolean treeChanged = false; // If the model was in the IST, delete it DocumentModel istModel = findISTModel(identifier.getSubprojectId(), treeName); if (istModel == null) { throw new ClientException("Tree '" + treeName + "' doesn't exist, can't remove SoaNode " + identifier); } DocumentModel soaNodeModel = findSoaNodeModel(istModel, treeName, identifier); if (soaNodeModel != null) { List<DocumentModel> parents = documentManager.getParentDocuments(soaNodeModel.getRef()); documentManager.removeDocument(soaNodeModel.getRef()); treeChanged = true; removeEmptyParentSystems(parents); } return treeChanged; } private void removeEmptyParentSystems(List<DocumentModel> hierarchy) throws ClientException { for (int i = hierarchy.size() - 2; i >= 0; i--) { DocumentModel parentModel = hierarchy.get(i); if (!documentManager.hasChildren(parentModel.getRef()) && IntelligentSystem.DOCTYPE.equals(parentModel.getType())) { documentManager.removeDocument(parentModel.getRef()); } else { break; } } } private DocumentModel findISTModel(String subprojectId, String name) throws ClientException { return documentService.findDocument(documentManager, subprojectId, IntelligentSystemTreeRoot.DOCTYPE, name); } private DocumentModel findSoaNodeModel(DocumentModel istModel, String treeName, SoaNodeId identifier) throws ClientException { String query = NXQLQueryBuilder.getQuery("SELECT * FROM ? WHERE ecm:path STARTSWITH '?' AND ? = '?'", new Object[]{ identifier.getType(), istModel.getPathAsString(), SoaNode.XPATH_SOANAME, identifier.getName() },//TODO path enough or also subprojectId ?? false, true); DocumentModelList matchingSoaNodes = documentService.query(documentManager, query, false, true); if (matchingSoaNodes.size() > 0) { if (matchingSoaNodes.size() > 1) { logger.error("The are " + matchingSoaNodes.size() + " instances of " + identifier + " in the " + treeName + " tree, but a maximum of one is normally supported. Will use the first one found."); } return matchingSoaNodes.get(0); } else { return null; } } }