/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.core.workspace; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; 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.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.URI; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.teiid.core.designer.util.FileUtils; import org.teiid.core.designer.util.StringConstants; import org.teiid.designer.core.ModelWorkspaceMock; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.extension.ExtensionPlugin; import org.teiid.designer.extension.definition.ModelExtensionAssistant; import org.teiid.designer.extension.registry.ModelExtensionRegistry; import org.teiid.designer.metamodels.function.extension.FunctionModelExtensionConstants; import org.teiid.designer.metamodels.relational.extension.CoreModelExtensionConstants; import org.teiid.designer.metamodels.relational.extension.RelationalModelExtensionConstants; import org.teiid.designer.metamodels.relational.extension.RestModelExtensionConstants; /** * */ public class MockFileBuilder implements StringConstants { private String baseName; private String extension; private File realFile; private IPath location; private IResource resource; private URI uri; private IProject project; private List<IResource> projectChildren = new ArrayList<IResource>(); // Not initialised unless we need it private ModelExtensionRegistry extensionRegistry = null; /** * Prefixes for model extension assistants */ private static final String[] EXTENSION_PREFIXES = { CoreModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix(), FunctionModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix(), RelationalModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix(), RestModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix() }; /** * @param realFile * @throws Exception */ public MockFileBuilder(final File realFile) throws Exception { this.realFile = realFile; this.location = new Path(realFile.getAbsolutePath()); String fileName = realFile.getName(); if(fileName.lastIndexOf(DOT) > 0) { this.extension = fileName.substring(fileName.lastIndexOf(DOT) + 1); this.baseName = fileName.substring(0, fileName.lastIndexOf(DOT)); } else { this.extension = EMPTY_STRING; this.baseName = fileName; } if (realFile.isDirectory()) mockDirectory(); else mockFile(); mockProject(); } /** * Enable extension registry support on resource change */ public void enableExtensionRegistry() { extensionRegistry = ExtensionPlugin.getInstance().getRegistry(); } private void mockFileProperties(IResource resource, File realFile, IPath wkspPath, int resourceType) { when(resource.getName()).thenReturn(realFile.getName()); when(resource.getLocation()).thenReturn(new Path(realFile.getAbsolutePath())); when(resource.getFullPath()).thenReturn(wkspPath); when(resource.getFileExtension()).thenReturn(wkspPath.getFileExtension()); when(resource.getType()).thenReturn(resourceType); when(resource.exists()).thenReturn(realFile.exists()); } private void mockProjectFileProperties(IProject project, final IFile file) { if (file == null) return; when(file.getParent()).thenReturn(project); when(file.getProject()).thenReturn(project); IPath filePath = file.getFullPath(); IPath projectPath = project.getFullPath(); when(file.getProjectRelativePath()).thenReturn(filePath.makeRelativeTo(projectPath)); } private void addProjectChild(IFile file) throws Exception { projectChildren.add(file); } private IFile mockProjectFile(IProject project, IPath projectPath) throws CoreException, Exception { File realFile; final IFile file = mock(IFile.class); if (project.getLocation().isPrefixOf(projectPath)) realFile = new File(projectPath.toOSString()); else realFile = new File(project.getLocation().append(projectPath).toOSString()); IPath wkspPath; if (project.getFullPath().isPrefixOf(projectPath)) wkspPath = projectPath; else wkspPath = project.getFullPath().append(projectPath); mockFileProperties(file, realFile, wkspPath, IResource.FILE); mockProjectFileProperties(project, file); // // Allow writing of contents to IFile to be sent to the real file // final File theRealFile = realFile; doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); InputStream stream = (InputStream) args[0]; try { FileUtils.write(stream, theRealFile); if (extensionRegistry != null) { for (String prefix : EXTENSION_PREFIXES) { final ModelExtensionAssistant assistant = extensionRegistry.getModelExtensionAssistant(prefix); assistant.applyMedIfNecessary(file); } } } catch (Exception ex) { ex.printStackTrace(); fail(ex.getMessage()); } finally { if (theRealFile.exists()) theRealFile.deleteOnExit(); } return null; } }).when(file).create(isA(InputStream.class), anyInt(), any(IProgressMonitor.class)); addProjectChild(file); return file; } private void mockProject() throws Exception { // // Makes real files parent a project // File parentFile = realFile.getParentFile(); final Path wkspProjectPath = new Path(File.separator + parentFile.getName()); project = mock(IProject.class); // Tie up resource to project when(resource.getParent()).thenReturn(project); when(resource.getProject()).thenReturn(project); // project's attributes mockFileProperties(project, parentFile, wkspProjectPath, IResource.PROJECT); // project returns itself when(project.getProject()).thenReturn(project); when(project.exists()).thenReturn(parentFile.exists()); // attributes for checking its a modeller project when(project.isOpen()).thenReturn(true); when(project.hasNature(ModelerCore.NATURE_ID)).thenReturn(true); // set up all child created files to return parent when(project.getFile(isA(IPath.class))).thenAnswer(new Answer<IFile>() { @Override public IFile answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); assertNotNull(args[0]); IPath path = (IPath) args[0]; return mockProjectFile(project, path); } }); // // Not forgetting this file // mockProjectFileProperties(project, getResourceFile()); when(project.members()).thenReturn(projectChildren.toArray(new IResource[0])); // The .project file File dotProjectFile = new File(parentFile, DotProjectUtils.DOT_PROJECT); dotProjectFile.createNewFile(); dotProjectFile.deleteOnExit(); IPath dotPath = new Path(dotProjectFile.getAbsolutePath()); IPath wkspDotPath = project.getFullPath().append(dotPath); IFile dotProject = mock(IFile.class); mockFileProperties(dotProject, dotProjectFile, wkspDotPath, IResource.FILE); when(dotProject.getParent()).thenReturn(project); when(dotProject.getProject()).thenReturn(project); when(project.getFile(DotProjectUtils.DOT_PROJECT)).thenReturn(dotProject); when(dotProject.isAccessible()).thenReturn(true); projectChildren.add(dotProject); } private void mockDirectory() throws Exception { resource = mock(IFolder.class); mockFileProperties(resource, realFile, location, IResource.FOLDER); } private void mockFile() throws Exception { resource = mock(IFile.class); final Path wkspPath = new Path(File.separator + new File(realFile.getParent()).getName() + File.separator + realFile.getName()); mockFileProperties(resource, realFile, wkspPath, IResource.FILE); IFile resourceFile = getResourceFile(); when(resourceFile.getContents()).thenAnswer(new Answer<InputStream>() { @Override public InputStream answer(InvocationOnMock invocation) throws Throwable { assertNotNull(realFile); return new FileInputStream(realFile); } }); } /** * @param name * @param extension * @throws Exception */ public MockFileBuilder(String name, String extension) throws Exception { this(File.createTempFile(name, DOT + extension)); // Tidy up the temporary file realFile.deleteOnExit(); } /** * Add this builder's components to a mocked model workspace * * @param modelWorkspace */ public void addToModelWorkspace(ModelWorkspaceMock modelWorkspace) { when(modelWorkspace.getEclipseMock().workspaceRoot().findMember(location)).thenReturn(resource); if (resource instanceof IFile) when(modelWorkspace.getEclipseMock().workspaceRoot().getFileForLocation(location)).thenReturn((IFile) resource); else if (resource instanceof IContainer) when(modelWorkspace.getEclipseMock().workspaceRoot().getContainerForLocation(location)).thenReturn((IContainer) resource); } /** * @return the name */ public String getName() { return this.realFile.getName(); } /** * @return base name, ie. no extension */ public String getBaseName() { return baseName; } /** * @return the extension */ public String getExtension() { return extension; } /** * @return the path */ public IPath getPath() { return this.location; } /** * @return the resourceFile */ public IFile getResourceFile() { if (this.resource instanceof IFile) return (IFile) this.resource; return null; } /** * @return the resourceFolder */ public IFolder getResourceFolder() { if (this.resource instanceof IFolder) return (IFolder) this.resource; return null; } /** * @return the realFile */ public File getRealFile() { return this.realFile; } /** * @return uri of the resource file */ public URI getURI() { if (uri == null) uri = URI.createFileURI(resource.getLocation().toString()); return uri; } /** * @return project */ public IProject getProject() { return project; } }