/******************************************************************************* * Copyright (c) 2007, 2009 Borland Software Corporation and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Borland Software Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.m2m.internal.qvt.oml.project.model; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.m2m.internal.qvt.oml.QvtNamesChecker; import org.eclipse.m2m.internal.qvt.oml.project.QVTOProjectPlugin; import org.eclipse.m2m.internal.qvt.oml.project.builder.QVTOBuilderConfig; public class QvtProject extends QvtBaseElement implements IQvtProject { private IProject fProject; private List<IQvtNamespace> rootNamespaces; private IQvtNamespace defaultNamespace; private IContainer srcContainer; public QvtProject(IProject project) { super(project.getFullPath(), project.getName()); fProject = project; } public IProject getProject() { return fProject; } public IQvtProject getQvtProject() { return this; } public IQvtNamespace getDefaultNamespace() throws QvtModelException { if(defaultNamespace == null) { defaultNamespace = new QvtRootNamespace(this, IQvtNamespace.DEFAULT_NAMESPACE_NAME); } return defaultNamespace; } public List<IQvtNamespace> getRootNamespaces() throws QvtModelException { if(rootNamespaces == null) { try { IContainer container = getSourceContainer(); List<IQvtNamespace> result = new ArrayList<IQvtNamespace>(); List<String> folderNames = QvtElementMemberColllector.getMemberNamespaces(container); for (String folderName : folderNames) { result.add(new QvtRootNamespace(this, folderName)); } // add virtual default name-space IQvtNamespace virtualDefault = getDefaultNamespace(); if(!virtualDefault.getCompilationUnits().isEmpty()) { result.add(getDefaultNamespace()); } rootNamespaces = result; } catch (CoreException e) { propagateAsQvtModelException(e); } } return rootNamespaces; } public IPath getQvtSourceContainerPath() throws QvtModelException { return getSourceContainer().getFullPath(); } public IContainer getSourceContainer() throws QvtModelException { if(srcContainer == null) { try { srcContainer = QVTOBuilderConfig.getConfig(fProject).getSourceContainer(); } catch (CoreException e) { propagateAsQvtModelException("Failed to read QVT builder config", e); //$NON-NLS-1$ } } return srcContainer; } public int getElementType() { return IQvtElement.QVT_PROJECT; } @Override public IResource getUnderlyingResource() throws QvtModelException { return fProject; } public IQvtNamespace findRootNamespace(String namespaceSimpleName) throws QvtModelException { for (IQvtNamespace namespace : getRootNamespaces()) { if(namespace.getName().equals(namespaceSimpleName)) { return namespace; } } return null; } public IQvtCompilationUnit findCompilationUnit(String unitQualifiedName) throws QvtModelException { String localName = QvtNamesChecker.extractLocalIdentifierPart(unitQualifiedName); String namespace = QvtNamesChecker.extractQualifyingIdentifierPart(unitQualifiedName); IQvtNamespace owner = findNamespace(namespace); if(owner != null) { return owner.findCompilationUnit(localName); } return null; } public IQvtNamespace findNamespace(String namespaceQualifiedName) throws QvtModelException { if(IQvtNamespace.DEFAULT_NAMESPACE_NAME.equals(namespaceQualifiedName)) { return getDefaultNamespace(); } IStatus nameStatus = QvtNamesChecker.validateNamespaceQualifiedIdentifier(namespaceQualifiedName); if(!nameStatus.isOK()) { throw new IllegalArgumentException(nameStatus.getMessage()); } String[] nsSegments = QvtNamesChecker.getQualifiedNameSegments(namespaceQualifiedName); IQvtNamespace rootNamespace = findRootNamespace(nsSegments[0]); if(rootNamespace == null) { return null; } // look down the hierarchy if required if(nsSegments.length > 1) { List<String> subNamespace = new ArrayList<String>(Arrays.asList(nsSegments)); subNamespace.remove(0); return findRecursively(subNamespace.toArray(new String[subNamespace.size()]), rootNamespace); } return rootNamespace; } public IQvtElement findElement(IResource resource, boolean exactMatchOnly) throws QvtModelException { if(!fProject.equals(resource.getProject())) { return null; } else if(resource.getType() == IResource.PROJECT) { return this; } IQvtElement element = findExactElement(resource); if(element == null && !exactMatchOnly) { if(resource.getParent() != null) { element = findClosestElement(resource.getParent()); } } return element; } private IPath getPathInSrcContainer(IResource resource) { try { IPath containerPath = getSourceContainer().getFullPath(); IPath resourcePath = resource.getFullPath(); if(containerPath.equals(resourcePath)) { return Path.ROOT; } if(containerPath.segmentCount() < resourcePath.segmentCount() && containerPath.isPrefixOf(resourcePath)) { return resourcePath.removeFirstSegments(containerPath.segmentCount()); } } catch (QvtModelException e) { QVTOProjectPlugin.log(e); } return null; } private IQvtElement findClosestElement(IResource resource) throws QvtModelException { IQvtElement element = findExactElement(resource); if(element == null) { if(resource.getType() == IResource.PROJECT) { return this; } IContainer parent = resource.getParent(); if(parent != null) { element = findClosestElement(parent); } } return element; } private IQvtElement findExactElement(IResource resource) throws QvtModelException { IPath srcRelativePath = getPathInSrcContainer(resource); if(srcRelativePath == null) { return null; } if(srcRelativePath.isRoot()) { return getDefaultNamespace(); } IPath namespacePath = srcRelativePath; boolean isFile = resource.getType() == IResource.FILE; if(isFile) { if(!QvtNamesChecker.isValidCompilationUnitFileName(resource.getName())) { return null; } namespacePath = (srcRelativePath.segmentCount() > 1) ? srcRelativePath.removeLastSegments(1) : null; } IQvtNamespace namespace = null; if(namespacePath == null) { namespace = getDefaultNamespace(); } else { IQvtNamespace root = findRootNamespace(namespacePath.segment(0)); if(root != null) { if(namespacePath.segmentCount() > 1) { namespace = findRecursively(namespacePath.removeFirstSegments(1).segments(), root); } else { namespace = root; } } } if(isFile && namespace != null) { // QVT module in default name-space String cuName = QvtNamesChecker.getCompilationUnitMainModuleName(resource.getName()); return namespace.findCompilationUnit(cuName); } return namespace; } private static IQvtNamespace findRecursively(String[] path, IQvtNamespace startNamespace) throws QvtModelException { IQvtNamespace parent = startNamespace; for (String nameElement : path) { IQvtNamespace next = parent.findOwnedNamespace(nameElement); if(next == null) { return null; } parent = next; } return parent; } }