blob: 1d540f4f4302ae99be44b38fde0522cf9242380c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2015 Sonatype, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.m2e.wtp.overlay.internal.modulecore;
import java.io.File;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
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.core.runtime.jobs.ISchedulingRule;
import org.eclipse.m2e.wtp.overlay.internal.Messages;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent;
import org.eclipse.wst.common.componentcore.internal.flat.IChildModuleReference;
import org.eclipse.wst.common.componentcore.internal.flat.IFlatFile;
import org.eclipse.wst.common.componentcore.internal.flat.IFlatFolder;
import org.eclipse.wst.common.componentcore.internal.flat.IFlatResource;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualFile;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualContainer;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Virtual folder mapping a FlatVirtualComponent
*
* @provisional This class has been added as part of a work in progress.
* It is not guaranteed to work or remain the same in future releases.
* For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
*
* @author Fred Bricon
*
*/
@SuppressWarnings("restriction")
public class CompositeVirtualFolder implements IFilteredVirtualFolder {
private static final Logger LOG = LoggerFactory.getLogger(CompositeVirtualFolder.class);
private FlatVirtualComponent flatVirtualComponent;
private IPath runtimePath;
private IProject project;
private Set<IVirtualReference> references = new LinkedHashSet<>();
private IVirtualResource[] members;
private IResourceFilter filter;
public CompositeVirtualFolder(FlatVirtualComponent aFlatVirtualComponent, IPath aRuntimePath, IResourceFilter filter) {
this.flatVirtualComponent = aFlatVirtualComponent;
if (flatVirtualComponent != null && flatVirtualComponent.getComponent() != null) {
project = flatVirtualComponent.getComponent().getProject();
}
this.runtimePath = aRuntimePath;
this.filter = filter;
try {
treeWalk();
} catch (CoreException e) {
LOG.error(Messages.CompositeVirtualFolder_Error_Scanning, e);
}
}
@Override
public IProject getProject() {
return project;
}
@Override
public IPath getRuntimePath() {
return runtimePath;
}
@Override
public IVirtualResource[] members() throws CoreException {
if (members == null) {
members = new IVirtualResource[0];
}
return members;
}
public void treeWalk() throws CoreException {
IFlatResource[] flatResources = flatVirtualComponent.fetchResources();
List<IVirtualResource> membersList = new ArrayList<>(flatResources.length);
for (IFlatResource flatResource : flatResources) {
IVirtualResource resource = convert(flatResource);
if (resource != null) {
membersList.add(resource);
}
}
for (IChildModuleReference childModule : flatVirtualComponent.getChildModules()) {
IVirtualReference reference = childModule.getReference();
if (reference != null) {
String filePath = getFilePath(reference);
if (filter == null || filter.accepts(filePath, true)) {
references.add(reference);
}
}
}
members = new IVirtualResource[membersList.size()];
membersList.toArray(members);
}
private IVirtualResource convert(IFlatResource flatResource) {
IVirtualResource virtualResource = null;
if (flatResource instanceof IFlatFolder) {
virtualResource = convertFolder((IFlatFolder) flatResource);
} else if (flatResource instanceof IFlatFile){
virtualResource = convertFile((IFlatFile) flatResource);
}
return virtualResource;
}
private IVirtualFolder convertFolder(IFlatFolder flatFolder) {
IFlatResource[] flatMembers = flatFolder.members();
List<IVirtualResource> membersList = new ArrayList<>(flatMembers.length);
for (IFlatResource flatResource : flatMembers) {
IVirtualResource resource = convert(flatResource);
if (resource != null) {
membersList.add(resource);
}
}
final IVirtualResource[] folderMembers = new IVirtualResource[membersList.size()];
membersList.toArray(folderMembers);
VirtualFolder vf = new VirtualFolder(project, flatFolder.getModuleRelativePath().append(flatFolder.getName())) {
@Override
public IVirtualResource[] members() throws CoreException {
return folderMembers;
}
};
return vf;
}
private IVirtualFile convertFile(IFlatFile flatFile) {
final IFile f = (IFile)flatFile.getAdapter(IFile.class);
String filePath = null;
if (f == null) {
//Not a workspace file, we assume it's an external reference
File underlyingFile = (File)flatFile.getAdapter(File.class);
if (underlyingFile != null && underlyingFile.exists()) {
filePath = flatFile.getModuleRelativePath().toPortableString() + Path.SEPARATOR + underlyingFile.getName();
if (filter == null || filter.accepts(filePath, true)) {
IVirtualReference reference = createReference(underlyingFile, flatFile.getModuleRelativePath());
references.add(reference);
}
}
} else {
final String fileName = f.getName();
IPath ffRuntimePath = flatFile.getModuleRelativePath();
filePath = ffRuntimePath.toPortableString() + Path.SEPARATOR + fileName;
if (filter == null || filter.accepts(filePath, true)) {
return new VirtualFile(project, ffRuntimePath, f) {
@Override
public String getName() {
return fileName;
}
@Override
public IPath getWorkspaceRelativePath() {
return f.getFullPath();
}
@Override
public IFile getUnderlyingFile() {
IFile f = super.getUnderlyingFile();
return f;
}
};
}
}
return null;
}
private IVirtualReference createReference(File underlyingFile, IPath path) {
VirtualArchiveComponent archive = new VirtualArchiveComponent(project, VirtualArchiveComponent.LIBARCHIVETYPE + Path.SEPARATOR + underlyingFile.getAbsolutePath(), path);
IVirtualReference ref = ComponentCore.createReference(flatVirtualComponent.getComponent(), archive);
ref.setArchiveName(archive.getArchivePath().lastSegment());
ref.setRuntimePath(path);
return ref;
}
@Override
public void create(int arg0, IProgressMonitor arg1) throws CoreException {
// ignore
}
@Override
public boolean exists(IPath arg0) {
return false;
}
@Override
public IVirtualResource findMember(String sPath) {
return findMember(new Path(sPath), 0);
}
@Override
public IVirtualResource findMember(String sPath, int searchFlags) {
return findMember(new Path(sPath), searchFlags);
}
@Override
public IVirtualResource findMember(IPath path) {
return findMember(path, 0);
}
@Override
public IVirtualResource findMember(IPath path, int theSearchFlags) {
if (path == null) {
return null;
}
Queue<String> segments = new ArrayDeque<String>(path.segmentCount());
for (String s : path.segments()) {
segments.add(s);
}
try {
return findMember(segments, members);
} catch (CoreException ce) {
LOG.error(Messages.CompositeVirtualFolder_Error_Finding_Member, ce);
}
return null;
}
private static IVirtualResource findMember(Queue<String> segments, IVirtualResource[] members) throws CoreException {
if (segments.isEmpty()) {
return null;
}
String segment = segments.poll();
boolean finalResource = segments.isEmpty();
for (IVirtualResource m : members) {
if (m.getName().equals(segment)) {
if (finalResource) {
return m;
}
if (m instanceof IVirtualFolder) {
return findMember(segments, ((IVirtualFolder)m).members());
}
}
}
return null;
}
@Override
public IVirtualFile getFile(IPath arg0) {
// ignore
return null;
}
@Override
public IVirtualFile getFile(String arg0) {
// ignore
return null;
}
@Override
public IVirtualFolder getFolder(IPath arg0) {
// ignore
return null;
}
@Override
public IVirtualFolder getFolder(String arg0) {
// ignore
return null;
}
@Override
public IVirtualResource[] getResources(String arg0) {
// ignore
return null;
}
@Override
public IVirtualResource[] members(int arg0) throws CoreException {
// ignore
return null;
}
@Override
public void createLink(IPath arg0, int arg1, IProgressMonitor arg2)
throws CoreException {
// ignore
}
@Override
public void delete(int arg0, IProgressMonitor arg1) throws CoreException {
// ignore
}
@Override
public boolean exists() {
// ignore
return false;
}
@Override
public IVirtualComponent getComponent() {
// ignore
return null;
}
@Override
public String getFileExtension() {
// ignore
return null;
}
@Override
public String getName() {
// ignore
return null;
}
@Override
public IVirtualContainer getParent() {
// ignore
return null;
}
@Override
public IPath getProjectRelativePath() {
// ignore
return null;
}
@Override
public String getResourceType() {
// ignore
return null;
}
@Override
public int getType() {
// ignore
return 0;
}
@Override
public IResource getUnderlyingResource() {
// ignore
return null;
}
@Override
public IResource[] getUnderlyingResources() {
// ignore
return null;
}
@Override
public IPath getWorkspaceRelativePath() {
// ignore
return null;
}
@Override
public boolean isAccessible() {
// ignore
return false;
}
@Override
public void removeLink(IPath arg0, int arg1, IProgressMonitor arg2)
throws CoreException {
// ignore
}
@Override
public void setResourceType(String arg0) {
// ignore
}
@Override
public boolean contains(ISchedulingRule rule) {
// ignore
return false;
}
@Override
public boolean isConflicting(ISchedulingRule rule) {
// ignore
return false;
}
@Override
public Object getAdapter(Class adapter) {
// ignore
return null;
}
@Override
public IContainer getUnderlyingFolder() {
// ignore
return null;
}
@Override
public IContainer[] getUnderlyingFolders() {
// ignore
return null;
}
public IVirtualReference[] getReferences() {
return references.toArray(new IVirtualReference[references.size()]);
}
@Override
public IResourceFilter getFilter() {
return filter;
}
@Override
public void setFilter(IResourceFilter filter) {
this.filter = filter;
}
private String getFilePath(IVirtualReference reference) {
StringBuilder path = new StringBuilder();
String prefix = reference.getRuntimePath().makeRelative().toString();
path.append(prefix);
if (prefix.length() > 0 && prefix.charAt(prefix.length() - 1)!= '/') {
path.append("/"); //$NON-NLS-1$
}
String archiveName = reference.getArchiveName();
if (archiveName == null || archiveName.isEmpty()) {
archiveName = reference.getReferencedComponent().getDeployedName() + ".jar"; //$NON-NLS-1$
}
path.append(archiveName);
return path.toString();
}
}