Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ChangeListener to Type Library #662

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright (c) 2024 Primetals Technologies Austria GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Patrick Aigner - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.fordiac.ide.library;

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.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.fordiac.ide.model.typelibrary.TypeLibraryManager;
import org.eclipse.fordiac.ide.ui.FordiacLogHelper;

public class LibraryChangeListener implements IResourceChangeListener {
private static final int MASK = IResourceDelta.ADDED | IResourceDelta.REMOVED | IResourceDelta.CHANGED;

@Override
public void resourceChanged(final IResourceChangeEvent event) {
if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
final IResourceDelta rootDelta = event.getDelta();
try {
rootDelta.accept(visitor, IContainer.INCLUDE_HIDDEN);
} catch (final CoreException e) {
FordiacLogHelper.logError("Couldn't process resource delta", e); //$NON-NLS-1$
}
}

}

private final IResourceDeltaVisitor visitor = delta -> {
switch (delta.getResource().getType()) {
case IResource.PROJECT:
return delta.getKind() != IResourceDelta.REMOVED; // ignore deleted projects
case IResource.FILE:
// information on previous linked status is not available on delete
if (delta.getResource() instanceof final IFile file
&& (file.isLinked() || delta.getKind() == IResourceDelta.REMOVED)
&& LibraryManager.MANIFEST.equals(file.getName()) && (delta.getKind() & MASK) != 0) {
final IProject project = file.getProject();
LibraryManager.INSTANCE.startResolveJob(project, TypeLibraryManager.INSTANCE.getTypeLibrary(project));

}
return false;
case IResource.FOLDER:
if (delta.getResource() instanceof final IFolder folder) {
// only search inside linked folders inside the Type Library
return isTypeLibraryFolder(folder) || ((folder.isLinked() || delta.getKind() == IResourceDelta.REMOVED)
&& isTypeLibraryFolder(folder.getParent()));
}
break;
default:
break;
}
return true;
};

private static boolean isTypeLibraryFolder(final IContainer container) {
return container instanceof IFolder && container.getParent() instanceof IProject
&& LibraryManager.TYPE_LIB_FOLDER_NAME.equals(container.getName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.eclipse.core.resources.IPathVariableManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
Expand All @@ -54,6 +55,7 @@
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobGroup;
import org.eclipse.e4.core.contexts.EclipseContextFactory;
Expand Down Expand Up @@ -124,6 +126,8 @@ public enum LibraryManager {
private IEventBroker eventBroker;
private JobGroup jobGroup;
private boolean uninitialised = true;
private final IResourceChangeListener libraryListener = new LibraryChangeListener();
private final Set<IProject> resolvingProjects = Collections.synchronizedSet(new HashSet<>());

/**
* Initialise library maps and start the {@link WatchService}
Expand Down Expand Up @@ -157,6 +161,7 @@ private void init(final IProject project) {
// empty
}
jobGroup = new JobGroup("LibraryManager JobGroup", 0, 0); //$NON-NLS-1$
addLibraryChangeListener();
uninitialised = false;
}

Expand Down Expand Up @@ -370,6 +375,7 @@ public void importLibrary(final IProject project, final TypeLibrary typeLibrary,
final IFolder libDirectory = project.getFolder(TYPE_LIB_FOLDER_NAME)
.getFolder(libManifest.getProduct().getSymbolicName());

removeLibraryChangeListener();
SystemManager.INSTANCE.removeFordiacChangeListener();
final Map<String, TypeEntry> cachedTypes = removeOldLibVersion(libDirectory, typeLib);
final java.net.URI libUri = URIUtil.append(uri, LIB_TYPELIB_FOLDER_NAME);
Expand Down Expand Up @@ -399,20 +405,10 @@ public void importLibrary(final IProject project, final TypeLibrary typeLibrary,
}

SystemManager.INSTANCE.addFordiacChangeListener();
addLibraryChangeListener();
// dependency resolution
if (resolve && imported) {
final WorkspaceJob job = new WorkspaceJob(
"Resolve dependencies for: " + libManifest.getProduct().getSymbolicName()) { //$NON-NLS-1$
@Override
public IStatus runInWorkspace(final IProgressMonitor monitor) throws CoreException {
resolveDependencies(project, typeLib);
return Status.OK_STATUS;
}
};
job.setRule(project);
job.setJobGroup(jobGroup);
job.setPriority(Job.LONG);
job.schedule();
startResolveJob(project, typeLibrary);
}
}

Expand Down Expand Up @@ -618,7 +614,7 @@ public void checkManifestFile(final IProject project, final TypeLibrary typeLibr

ManifestHelper.sortAndSaveManifest(manifest);

startLocalResolveJob(project, typeLibrary);
startResolveJob(project, typeLibrary);
}

/**
Expand All @@ -628,7 +624,12 @@ public void checkManifestFile(final IProject project, final TypeLibrary typeLibr
* @param project selected project
* @param typeLibrary {@link TypeLibrary} to use
*/
private void startLocalResolveJob(final IProject project, final TypeLibrary typeLibrary) {
public void startResolveJob(final IProject project, final TypeLibrary typeLibrary) {
if (resolvingProjects.contains(project)) {
return;
}
resolvingProjects.add(project);

final WorkspaceJob job = new WorkspaceJob("Resolve dependencies: " + project.getName()) { //$NON-NLS-1$

@Override
Expand All @@ -641,6 +642,8 @@ public IStatus runInWorkspace(final IProgressMonitor monitor) throws CoreExcepti
job.setJobGroup(jobGroup);
job.setPriority(Job.LONG);
job.schedule();
// act after job is done and has sent its POST_CHANGE notifications
job.addJobChangeListener(IJobChangeListener.onDone(c -> resolvingProjects.remove(project)));
}

/**
Expand Down Expand Up @@ -1038,4 +1041,11 @@ public JobGroup getJobGroup() {
}
};

public void removeLibraryChangeListener() {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(libraryListener);
}

public void addLibraryChangeListener() {
ResourcesPlugin.getWorkspace().addResourceChangeListener(libraryListener);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@
import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.fordiac.ide.library.ui.wizards.LibrarySelectionPage;
import org.eclipse.fordiac.ide.model.libraryElement.Application;
import org.eclipse.fordiac.ide.model.libraryElement.AutomationSystem;
import org.eclipse.fordiac.ide.model.typelibrary.TypeLibraryManager;
import org.eclipse.fordiac.ide.model.ui.actions.OpenListenerManager;
import org.eclipse.fordiac.ide.systemmanagement.SystemManager;
import org.eclipse.fordiac.ide.systemmanagement.ui.Messages;
Expand Down Expand Up @@ -82,22 +80,13 @@ public void addPages() {
@Override
public boolean performFinish() {
try {
WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
final WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
@Override
protected void execute(final IProgressMonitor monitor) {
createProject(monitor != null ? monitor : new NullProgressMonitor());
}
};
getContainer().run(false, true, op);
// re-send TypeLibrary event after complete project setup
final IProject newProject = ResourcesPlugin.getWorkspace().getRoot().getProject(page.getProjectName());
op = new WorkspaceModifyOperation() {
@Override
protected void execute(final IProgressMonitor monitor) {
TypeLibraryManager.INSTANCE.resendCreateEvent(newProject);
}
};
getContainer().run(false, true, op);
} catch (final InvocationTargetException e) {
FordiacLogHelper.logError(e.getMessage(), e);
return false;
Expand Down
Loading