blob: 569288326c61245592da8315e6d97b38e43d06fb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2019 Xored Software Inc 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
* https://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Xored Software Inc - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.rcptt.resources;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
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.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.rcptt.core.Q7Features;
import org.eclipse.rcptt.core.model.ModelException;
import org.eclipse.rcptt.core.persistence.IPersistenceModel;
import org.eclipse.rcptt.internal.core.RcpttPlugin;
import org.eclipse.rcptt.internal.resources.Activator;
import org.eclipse.rcptt.util.FileUtil;
import org.eclipse.rcptt.util.Predicate;
import org.eclipse.rcptt.workspace.WSContainer;
import org.eclipse.rcptt.workspace.WSFile;
import org.eclipse.rcptt.workspace.WSFileLink;
import org.eclipse.rcptt.workspace.WSFolder;
import org.eclipse.rcptt.workspace.WSFolderLink;
import org.eclipse.rcptt.workspace.WSLink;
import org.eclipse.rcptt.workspace.WSProject;
import org.eclipse.rcptt.workspace.WSResource;
import org.eclipse.rcptt.workspace.WSRoot;
import org.eclipse.rcptt.workspace.WorkspaceData;
import org.eclipse.rcptt.workspace.WorkspaceFactory;
import org.osgi.framework.Bundle;
public class WSUtils {
public static WSProject getProject(WSRoot root, String name, boolean create) {
WSProject project = getResource(root.getProjects(), name);
if (project == null && create) {
project = WorkspaceFactory.eINSTANCE.createWSProject();
project.setName(name);
root.getProjects().add(project);
}
return project;
}
public static IPath getPath(WSResource resource) {
if (resource instanceof WSRoot) {
return Path.EMPTY;
}
EObject eObject = resource.eContainer();
if (eObject instanceof WSFolder) {
IPath parentPath = getPath((WSFolder) eObject);
return parentPath.append(resource.getName());
} else {
return new Path(resource.getName());
}
}
public static WSResource getResource(WSContainer container, IPath path) {
String[] segments = path.segments();
if (segments.length == 0)
return container;
WSResource result = null;
int index = 0;
for (; index < segments.length; index++) {
String name = segments[index];
result = getResource(getContents(container), name);
if (result instanceof WSFolder) {
container = (WSFolder) result;
} else {
break;
}
}
if (index == segments.length)
return result;
return null;
}
public static List<WSResource> getContents(WSContainer container) {
if (container instanceof WSRoot) {
BasicEList<WSResource> resources = new BasicEList<WSResource>();
WSRoot root = (WSRoot) container;
resources.addAll(root.getProjects());
resources.addAll(root.getProjectLinks());
return resources;
} else {
WSFolder folder = (WSFolder) container;
BasicEList<WSResource> resources = new BasicEList<WSResource>();
resources.addAll(folder.getFolders());
resources.addAll(folder.getFolderLinks());
resources.addAll(folder.getFiles());
resources.addAll(folder.getFileLinks());
return resources;
}
}
public static WSContainer getContainer(WSContainer container, String name,
boolean create) {
if (container instanceof WSRoot) {
WSRoot root = (WSRoot) container;
return getProject(root, name, create);
} else {
WSFolder folder = (WSFolder) container;
return getFolder(folder, name, create);
}
}
public static WSFile getFile(WSFolder folder, String name, boolean create) {
WSFile file = getResource(folder.getFiles(), name);
if (file == null && create) {
file = WorkspaceFactory.eINSTANCE.createWSFile();
file.setName(name);
folder.getFiles().add(file);
}
return file;
}
public static WSFolder getFolder(WSFolder folder, String name,
boolean create) {
WSFolder result = getResource(folder.getFolders(), name);
if (result == null && create) {
result = WorkspaceFactory.eINSTANCE.createWSFolder();
result.setName(name);
folder.getFolders().add(result);
}
return result;
}
public static void remove(WSResource resource) {
EReference ref = resource.eContainmentFeature();
List<?> list = (List<?>) resource.eContainer().eGet(ref);
list.remove(resource);
}
public static <T extends WSResource> T getResource(List<T> resources,
String name) {
for (T resorce : resources) {
if (name.equals(resorce.getName())) {
return resorce;
}
}
return null;
}
public static byte[] getFileContent(String location, WSFile file)
throws IOException {
InputStream stream = getFileStream(location, file, null);
return getStreamContent(stream);
}
public static byte[] getFileContent(String location, WSFile file,
IPersistenceModel model) throws IOException {
InputStream stream = getFileStream(location, file, model);
return getStreamContent(stream);
}
public static byte[] getStreamContent(InputStream stream)
throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[4096];
int len = 0;
while ((len = stream.read(buffer)) > 0) {
output.write(buffer, 0, len);
}
} finally {
safeClose(stream);
}
return output.toByteArray();
}
public static void safeClose(Closeable closeable) {
try {
closeable.close();
} catch (Exception e) {
}
}
public static InputStream getFileStream(String location, WSFile file,
IPersistenceModel model) throws FileNotFoundException {
if (model != null) {
String name = ImportUtils.getName(file);
InputStream inputStream = model.read(name);
if (inputStream != null) {
return inputStream;
}
}
if (location == null) {
location = getContextFile(file);
if (location == null) {
location = Platform.getLocation().toString();
}
}
File parentFile = new File(location);
if (file.getContentURI() == null) {
throw new FileNotFoundException(
"Q7 could not find content for file: " + file.getName()
+ "\nPlease recapture Workspace context.");
}
File childFile = new File(parentFile, file.getContentURI());
return new BufferedInputStream(new FileInputStream(childFile));
}
private static String getContextFile(WSFile file) {
Resource res = file.eResource();
if (res != null) {
try {
// ResourceSet resources = res.getResourceSet();
// if (resources != null) {
URI uri = res.getURI();
File oFile = null;
if (uri == null) {
return null;
} else if (uri.isPlatformResource()) {
IPath path = new Path(uri.toPlatformString(true));
IFile iFile = ResourcesPlugin.getWorkspace().getRoot()
.getFile(path);
oFile = iFile.getLocation().toFile();
} else if (uri.isFile() && !uri.isRelative()) {
oFile = new File(uri.toFileString());
} else if (uri.isPlatformPlugin()) {
IPath path = new Path(uri.toPlatformString(true));
if (path.segmentCount() > 1) {
Bundle bundle = Platform.getBundle(path.segment(0));
path = path.removeFirstSegments(1);
URL url = FileLocator.find(bundle, path, null);
url = FileLocator.toFileURL(url);
oFile = new File(url.getFile());
}
}
if (oFile != null) {
return oFile.getParentFile().getAbsolutePath();
}
// }
} catch (Exception e) {
RcpttPlugin.log(e);
}
}
return null;
}
public static IFile getLinkResource(WSLink link) {
IProject project = ResourcesPlugin.getWorkspace().getRoot()
.getProject(link.getProject());
if (project == null || !project.exists())
return null;
IResource member = project.findMember(link.getPath());
if (member == null || !member.isAccessible())
return null;
if( member instanceof IFile) {
return (IFile) member;
}
return null;
}
public static IContainer getLinkContainer(WSLink link) {
IProject project = ResourcesPlugin.getWorkspace().getRoot()
.getProject(link.getProject());
if (project == null)
return null;
IResource res = project.findMember(link.getPath());
if (!(res instanceof IContainer) || !res.isAccessible())
return null;
return (IContainer) res;
}
public static byte[] loadFileLinkContent(WSFileLink fileLink)
throws IOException, ModelException {
IResource path = getLinkResource(fileLink);
if (path == null || !(path instanceof IFile))
throw new ModelException(new Status(Status.ERROR,
Activator.PLUGIN_ID, String.format(
"File of link %s/%s is not found.",
fileLink.getProject(), fileLink.getPath())));
try {
return FileUtil.getStreamContent(((IFile) path).getContents());
} catch (CoreException e) {
throw new ModelException(new Status(Status.ERROR,
Activator.PLUGIN_ID, String.format(
"Failed to load content of linked file %s/%s",
fileLink.getProject(), fileLink.getPath()),
e));
}
}
public static void loadFileLinkWithContent(WSFileLink fileLink)
throws ModelException {
try {
final byte[] content = loadFileLinkContent(fileLink);
if (Q7Features.getInstance().isTrue(
Q7Features.Q7_CONTEXTS_RESOURCES_ZIPPED_TRANSFER)) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ZipOutputStream zout = new ZipOutputStream(bout);
zout.setLevel(9);
zout.setMethod(ZipOutputStream.DEFLATED);
ZipEntry entry = new ZipEntry("content");
entry.setTime(1);
zout.putNextEntry(entry);
zout.write(content);
zout.close();
fileLink.setContent(bout.toByteArray());
} else {
fileLink.setContent(content);
}
} catch (IOException e) {
Activator.log(e);
}
}
public static void loadFolderLinkWithContent(WSFolderLink folderLink)
throws IOException, CoreException {
IContainer container = getLinkContainer(folderLink);
if (container == null)
throw new ModelException(new Status(Status.ERROR,
Activator.PLUGIN_ID, String.format(
"Can not resolve folder link %s/%s.",
folderLink.getProject(), folderLink.getPath())));
IResource[] members = container.members();
for (IResource r : members) {
if (r instanceof IFolder) {
WSFolderLink newFolderLink = WorkspaceFactory.eINSTANCE
.createWSFolderLink();
newFolderLink.setName(r.getName());
newFolderLink.setProject(r.getProject().getName());
newFolderLink.setPath(r.getProjectRelativePath()
.toPortableString());
folderLink.getFolders().add(newFolderLink);
loadFolderLinkWithContent(newFolderLink);
} else if (r instanceof IFile) {
WSFileLink newFileLink = WorkspaceFactory.eINSTANCE
.createWSFileLink();
newFileLink.setName(r.getName());
newFileLink.setProject(r.getProject().getName());
newFileLink.setPath(r.getProjectRelativePath()
.toPortableString());
folderLink.getFiles().add(newFileLink);
loadFileLinkWithContent(newFileLink);
}
}
}
public static List<WSLink> listLinks(WSResource content) {
List<WSLink> result = new ArrayList<WSLink>();
if (content instanceof WSRoot) {
result.addAll(((WSRoot) content).getProjectLinks());
EList<WSProject> projects = ((WSRoot) content).getProjects();
for (WSProject wsProject : projects) {
result.addAll(listLinks(wsProject));
}
}
if (content instanceof WSFolder) {
result.addAll(((WSFolder) content).getFolderLinks());
result.addAll(((WSFolder) content).getFileLinks());
EList<WSFolder> folders = ((WSFolder) content).getFolders();
for (WSFolder wsFolder : folders) {
result.addAll(listLinks(wsFolder));
}
}
return result;
}
/**
* Iterates over workspace applying a visitor to each element.
* @param visitor - process is interrupted if predicate is true
* @param monitor
*/
public static void visitWorkspace(WorkspaceData data, SubMonitor monitor, Predicate<WSResource> visitor) {
if (visitor.apply(data.getContent()))
return;
visitRoot(data.getContent(), visitor, monitor);
}
private static void visitRoot(WSRoot content, Predicate<WSResource> visitor, SubMonitor monitor) {
monitor.beginTask("Projects", content.getProjects().size());
try {
for (WSProject project : content.getProjects()) {
if (visitor.apply(project))
break;
if (visitProject(project, visitor, monitor.newChild(1)))
break;
}
} finally {
monitor.done();
}
}
public static boolean visitProject(WSProject project, Predicate<WSResource> visitor, SubMonitor monitor) {
return visitFolder(project, visitor, monitor);
}
public static boolean visitFolder(WSFolder folder,
Predicate<WSResource> visitor, SubMonitor monitor) {
monitor.beginTask(folder.getName(),
folder.getFiles().size()
+ folder.getFileLinks().size()
+ folder.getFolders().size()
+ folder.getFolderLinks().size()
);
if (monitor.isCanceled())
return true;
try {
for (WSFile entry: folder.getFiles()) {
if (visitor.apply(entry))
return true;
monitor.worked(1);
}
for (WSFolder entry: folder.getFolders()) {
if (visitor.apply(entry))
return true;
if (visitFolder(entry, visitor, monitor.newChild(1)))
return true;
}
for (WSLink entry: folder.getFileLinks()) {
if (visitor.apply(entry))
return true;
monitor.worked(1);
}
for (WSLink entry: folder.getFolderLinks()) {
if (visitor.apply(entry))
return true;
monitor.worked(1);
}
return false;
} finally {
monitor.done();
}
}
}