From 4c770c454ff9824e44a789d00acdc09dd788c505 Mon Sep 17 00:00:00 2001 From: SebastianE Date: Mon, 24 Oct 2022 18:25:35 +0200 Subject: [PATCH 01/23] removed old hard coded handbook and tutorial buttons and git / psf integration --- org.moflon.core.ui.autosetup/.classpath | 7 - org.moflon.core.ui.autosetup/.gitignore | 3 - org.moflon.core.ui.autosetup/.project | 28 --- .../META-INF/MANIFEST.MF | 21 -- org.moflon.core.ui.autosetup/build.properties | 12 - org.moflon.core.ui.autosetup/plugin.xml | 41 ---- .../resources/icons/junitmoflon.png | Bin 1166 -> 0 bytes .../schema/RegisterPsfUrlExtension.exsd | 102 --------- .../core/ui/autosetup/CloseProjectsJob.java | 46 ---- .../autosetup/ExploreEMoflonProjectsJob.java | 183 --------------- .../LaunchConfigurationRunnerJob.java | 41 ---- .../ui/autosetup/LaunchInvocationTask.java | 63 ------ .../core/ui/autosetup/OpenProjectsJob.java | 45 ---- .../core/ui/autosetup/PsfFileUtils.java | 116 ---------- .../core/ui/autosetup/WorkspaceInstaller.java | 210 ------------------ .../RegisterPsfUrlForHandbookPart1.java | 9 - .../SokobanHandbookPsfUrlRegistration.java | 35 --- .../handler/InstallPsfFileHandler.java | 36 --- .../autosetup/handler/PopulatePsfUrlMenu.java | 49 ---- .../handler/RegisterPsfUrlExtension.java | 20 -- 20 files changed, 1067 deletions(-) delete mode 100644 org.moflon.core.ui.autosetup/.classpath delete mode 100644 org.moflon.core.ui.autosetup/.gitignore delete mode 100644 org.moflon.core.ui.autosetup/.project delete mode 100644 org.moflon.core.ui.autosetup/META-INF/MANIFEST.MF delete mode 100644 org.moflon.core.ui.autosetup/build.properties delete mode 100644 org.moflon.core.ui.autosetup/plugin.xml delete mode 100644 org.moflon.core.ui.autosetup/resources/icons/junitmoflon.png delete mode 100644 org.moflon.core.ui.autosetup/schema/RegisterPsfUrlExtension.exsd delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/CloseProjectsJob.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/ExploreEMoflonProjectsJob.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/LaunchConfigurationRunnerJob.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/LaunchInvocationTask.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/OpenProjectsJob.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/PsfFileUtils.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/WorkspaceInstaller.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handbook/RegisterPsfUrlForHandbookPart1.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handbook/SokobanHandbookPsfUrlRegistration.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/InstallPsfFileHandler.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/PopulatePsfUrlMenu.java delete mode 100644 org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/RegisterPsfUrlExtension.java diff --git a/org.moflon.core.ui.autosetup/.classpath b/org.moflon.core.ui.autosetup/.classpath deleted file mode 100644 index 4d23c295..00000000 --- a/org.moflon.core.ui.autosetup/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/org.moflon.core.ui.autosetup/.gitignore b/org.moflon.core.ui.autosetup/.gitignore deleted file mode 100644 index aec0be45..00000000 --- a/org.moflon.core.ui.autosetup/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/bin/ -/target/ -/.settings/ \ No newline at end of file diff --git a/org.moflon.core.ui.autosetup/.project b/org.moflon.core.ui.autosetup/.project deleted file mode 100644 index 3ce22c75..00000000 --- a/org.moflon.core.ui.autosetup/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.moflon.core.ui.autosetup - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/org.moflon.core.ui.autosetup/META-INF/MANIFEST.MF b/org.moflon.core.ui.autosetup/META-INF/MANIFEST.MF deleted file mode 100644 index 7d4f61bd..00000000 --- a/org.moflon.core.ui.autosetup/META-INF/MANIFEST.MF +++ /dev/null @@ -1,21 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: eMoflon::Core Workspace auto-setup components -Bundle-SymbolicName: org.moflon.core.ui.autosetup;singleton:=true -Bundle-Version: 1.0.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-17 -Require-Bundle: org.eclipse.equinox.registry;bundle-version="[3.0.0,4.0.0)", - org.eclipse.team.ui;bundle-version="[3.0.0,4.0.0)", - org.eclipse.ui.workbench;bundle-version="[3.0.0,4.0.0)", - org.eclipse.jface;bundle-version="[3.0.0,4.0.0)", - org.eclipse.debug.core;bundle-version="[3.0.0,4.0.0)", - org.emoflon.core.dependencies;bundle-version="1.0.0", - org.moflon.core.build;bundle-version="[1.0.0,2.0.0)", - org.moflon.core.utilities;bundle-version="[3.0.0,4.0.0)", - org.moflon.core.ui;bundle-version="[1.0.0,2.0.0)", - org.apache.commons.commons-io -Export-Package: org.moflon.core.ui.autosetup, - org.moflon.core.ui.autosetup.handbook, - org.moflon.core.ui.autosetup.handler -Automatic-Module-Name: org.moflon.core.ui.autosetup -Bundle-Vendor: eMoflon developers diff --git a/org.moflon.core.ui.autosetup/build.properties b/org.moflon.core.ui.autosetup/build.properties deleted file mode 100644 index c305a810..00000000 --- a/org.moflon.core.ui.autosetup/build.properties +++ /dev/null @@ -1,12 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - resources/,\ - plugin.xml,\ - src/,\ - schema/,\ - build.properties,\ - .project,\ - .gitignore,\ - .classpath diff --git a/org.moflon.core.ui.autosetup/plugin.xml b/org.moflon.core.ui.autosetup/plugin.xml deleted file mode 100644 index 91118849..00000000 --- a/org.moflon.core.ui.autosetup/plugin.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.moflon.core.ui.autosetup/resources/icons/junitmoflon.png b/org.moflon.core.ui.autosetup/resources/icons/junitmoflon.png deleted file mode 100644 index 8e81126433ffbc444f83b5489df689ef70e48f02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1166 zcmc(eu}cDB7{)(K)C56okq)XU3Mr75*5pKwBZ-VaaH#MP2$U?`+M>xCTY`o_qKF)8 zYbcsZqL84aMTbHPgu3JFd5^wB&Wu~4=lI?Ce$V^7_X*x@&L-nN?|_#v=2H^#99BQ! zap6An#+R_Tmesh-I9+?^2Rm^3RubtPChiGGbaZzOraQ09#N1DwV80{Oyw095=9Cn9 zdVVV4@H<~Wk@#oz+Bkm%nFt7g2H?P!LP(tf8W7x}9s^x9h)xQOgDW5g+t+9KLC~Q| zIPZX~s>&;s3YR3wfNJun_su%i4sFBXg+hS~RjXA_2vLtR;Ltj~0OOIGq++qibGaPX zG|hl&@<@~c8rTPJz_LIzc)eaX>P#lXTdkG>)szvvw)|EPHmkr?sZ?U+a+%d?HKyyj z0oCMD&!RN#o51`9RENW1^F(o~@GRLE?AfWsG#}PzG&s?%5C0f2`tNVSZ^55>511Kt n;6|dabOO*fYe)3H+<=yy@E>O`E>rmrJwm4_v7~$yUEKHreDUeN diff --git a/org.moflon.core.ui.autosetup/schema/RegisterPsfUrlExtension.exsd b/org.moflon.core.ui.autosetup/schema/RegisterPsfUrlExtension.exsd deleted file mode 100644 index 1d9c98e7..00000000 --- a/org.moflon.core.ui.autosetup/schema/RegisterPsfUrlExtension.exsd +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - Use this to register extensions that can contribute URL entries for built-in PSFs in the eMoflon::Core 'cloud' menu. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [Enter the first release in which this extension point appears.] - - - - - - - - - [Enter extension point usage example here.] - - - - - - - - - [Enter API information here.] - - - - - - - - - [Enter information about supplied implementation of this extension point.] - - - - - diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/CloseProjectsJob.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/CloseProjectsJob.java deleted file mode 100644 index 1833f8eb..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/CloseProjectsJob.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.moflon.core.ui.autosetup; - -import java.util.List; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.moflon.core.utilities.ProgressMonitorUtil; -import org.moflon.core.utilities.WorkspaceHelper; - -/** - * This {@link Job} closes the list of preconfigured projects (see - * {@link CloseProjectsJob#CloseProjectsJob(String, List)}) upon - * {@link #run(IProgressMonitor)} - * - * @author Roland Kluge - Initial implementation - */ -public final class CloseProjectsJob extends Job { - private final List projects; - - public CloseProjectsJob(String name, List projects) { - super(name); - this.projects = projects; - } - - @Override - protected IStatus run(final IProgressMonitor monitor) { - final SubMonitor closingMonitor = SubMonitor.convert(monitor, "Closing projects", projects.size()); - try { - for (final IProject project : projects) { - project.close(closingMonitor.split(1)); - ProgressMonitorUtil.checkCancellation(closingMonitor); - } - } catch (final CoreException e) { - return new Status(IStatus.ERROR, WorkspaceHelper.getPluginId(getClass()), e.getMessage(), e); - } finally { - SubMonitor.done(monitor); - } - - return Status.OK_STATUS; - } -} \ No newline at end of file diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/ExploreEMoflonProjectsJob.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/ExploreEMoflonProjectsJob.java deleted file mode 100644 index e27aa051..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/ExploreEMoflonProjectsJob.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.moflon.core.ui.autosetup; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.log4j.Logger; -import org.eclipse.core.resources.IBuildConfiguration; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceVisitor; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchConfigurationType; -import org.eclipse.debug.core.ILaunchManager; -import org.gervarro.eclipse.workspace.util.WorkspaceTaskJob; -import org.moflon.core.build.BuildUtilities; -import org.moflon.core.build.ProjectBuilderTask; -import org.moflon.core.utilities.LogUtils; -import org.moflon.core.utilities.ProgressMonitorUtil; -import org.moflon.core.utilities.WorkspaceHelper; - -final class ExploreEMoflonProjectsJob extends Job { - private static final Logger logger = Logger.getLogger(ExploreEMoflonProjectsJob.class); - - private static final String LAUNCH_EXT = ".launch"; - private static final CharSequence AUTO_TESTSUITE = "TestSuite"; - - private final List jobs; - - private WorkspaceInstaller workspaceInstaller; - - ExploreEMoflonProjectsJob(String name, List jobs, String label, WorkspaceInstaller workspaceInstaller) { - super(name); - this.jobs = jobs; - this.workspaceInstaller = workspaceInstaller; - } - - @Override - protected final IStatus run(final IProgressMonitor monitor) { - final IProject[] graphicalMoflonProjects = workspaceInstaller.getProjectsToBuild(); - final List mweProjects = getProjectsWithMweWorkflows(); - if (mweProjects.size() > 0) { - try { - final ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager(); - final ILaunchConfigurationType type = manager - .getLaunchConfigurationType("org.eclipse.emf.mwe2.launch.Mwe2LaunchConfigurationType"); - final ILaunchConfiguration[] configurations = manager.getLaunchConfigurations(type); - if (configurations.length > 0) { - // (1) Closing projects with textual syntax (without workspace lock) - jobs.add(new CloseProjectsJob("Closing projects", mweProjects)); - // (2) Building projects with graphical syntax (with workspace lock) - prepareIncrementalProjectBuilderJob(jobs, graphicalMoflonProjects); - // (3) Launching MWE2 workflows to generate Xtext metamodels (without workspace - // lock) - final Job mweWorkflowLauncher = new LaunchConfigurationRunnerJob("Launching MWE2 workflows", - configurations); - mweWorkflowLauncher.setRule(ResourcesPlugin.getWorkspace().getRoot()); - jobs.add(mweWorkflowLauncher); - - // (4) Opening projects with textual syntax (without workspace lock) - jobs.add(new OpenProjectsJob("Opening projects", mweProjects)); - // (5) Building projects with textual syntax (with workspace lock) - prepareIncrementalProjectBuilderJob(jobs, mweProjects); - } else { - // Building projects (with workspace lock) - prepareIncrementalProjectBuilderJob(jobs, graphicalMoflonProjects); - prepareIncrementalProjectBuilderJob(jobs, mweProjects); - } - } catch (final CoreException e) { - // Building projects with graphical syntax (with workspace lock) - prepareIncrementalProjectBuilderJob(jobs, graphicalMoflonProjects); - } - } else { - // Building projects with graphical syntax (with workspace lock) - prepareIncrementalProjectBuilderJob(jobs, graphicalMoflonProjects); - } - - enqueueJUnitTestJob(jobs); - return Status.OK_STATUS; - } - - /** - * Searches for all projects that contain JUnit test configurations and enqueues - * a job that invokes all of these configurations into the given list of jobs - * - * @param jobs - * the job list - */ - private void enqueueJUnitTestJob(final List jobs) { - final List launchConfigurations = new LinkedList(); - for (final IProject testProjectCandidate : getAllOpenProjectsInWorkspace()) { - try { - final List selectedLaunchConfigurations = Arrays.asList(testProjectCandidate.members()).stream()// - .filter(m -> m instanceof IFile) // - .map(m -> (IFile) m.getAdapter(IFile.class))// - .filter(f -> f.getName().endsWith(LAUNCH_EXT) && f.getName().contains(AUTO_TESTSUITE))// - .collect(Collectors.toList()); - launchConfigurations.addAll(selectedLaunchConfigurations); - } catch (final CoreException e) { - LogUtils.error(logger, e); - } - } - if (!launchConfigurations.isEmpty()) { - final Job testConfigurationJob = new Job("Launching test configurations") { - - @Override - protected IStatus run(final IProgressMonitor monitor) { - final MultiStatus result = new MultiStatus(WorkspaceHelper.getPluginId(getClass()), IStatus.OK, - "Test configurations executed succesfully", null); - final ILaunchManager mgr = DebugPlugin.getDefault().getLaunchManager(); - final SubMonitor subMonitor = SubMonitor.convert(monitor, launchConfigurations.size()); - for (final IFile file : launchConfigurations) { - final ILaunchConfiguration config = mgr.getLaunchConfiguration(file); - final LaunchInvocationTask launchInvocationTask = new LaunchInvocationTask(config); - result.add(launchInvocationTask.run(subMonitor.split(1))); - ProgressMonitorUtil.checkCancellation(subMonitor); - } - return result; - } - }; - testConfigurationJob.setRule(ResourcesPlugin.getWorkspace().getRoot()); - jobs.add(testConfigurationJob); - } - } - - private List getAllOpenProjectsInWorkspace() { - return WorkspaceHelper.getAllProjectsInWorkspace().stream().filter(p -> p.isAccessible()) - .collect(Collectors.toList()); - } - - private List getProjectsWithMweWorkflows() { - return getAllOpenProjectsInWorkspace().stream().filter(p -> containsMwe2Files(p)).collect(Collectors.toList()); - } - - private boolean containsMwe2Files(final IProject project) { - final List mwe2Resources = new ArrayList<>(); - try { - project.accept(new IResourceVisitor() { - - @Override - public boolean visit(IResource resource) throws CoreException { - // Quit after first identified resource - if (!mwe2Resources.isEmpty()) - return false; - - if (resource.getName().endsWith("." + WorkspaceHelper.MWE2_FILE_EXTENSION)) - mwe2Resources.add(resource); - - return true; - } - }); - return !mwe2Resources.isEmpty(); - } catch (final CoreException e) { - return false; - } - } - - private final void prepareIncrementalProjectBuilderJob(final List jobs, final Collection projects) { - projects.toArray(new IProject[projects.size()]); - } - - private final void prepareIncrementalProjectBuilderJob(final List jobs, final IProject[] projects) { - final IBuildConfiguration[] buildConfigurations = BuildUtilities - .getDefaultBuildConfigurations(Arrays.asList(projects)); - if (buildConfigurations.length > 0) { - final ProjectBuilderTask builder = new ProjectBuilderTask(buildConfigurations); - jobs.add(new WorkspaceTaskJob(builder)); - } - } -} \ No newline at end of file diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/LaunchConfigurationRunnerJob.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/LaunchConfigurationRunnerJob.java deleted file mode 100644 index 9c5c0aac..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/LaunchConfigurationRunnerJob.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.moflon.core.ui.autosetup; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.moflon.core.utilities.ProgressMonitorUtil; - -/** - * This {@link Job} invokes the preconfigured set of - * {@link ILaunchConfiguration}s upon {@link #run(IProgressMonitor)} - * - * @author Roland Kluge - Initial implementation - */ -public final class LaunchConfigurationRunnerJob extends Job { - private final ILaunchConfiguration[] configurations; - - public LaunchConfigurationRunnerJob(String name, ILaunchConfiguration[] configurations) { - super(name); - this.configurations = configurations; - } - - @Override - public IStatus run(final IProgressMonitor monitor) { - final SubMonitor mweWorkflowExecutionMonitor = SubMonitor.convert(monitor, "Executing MWE2 workflows", - configurations.length); - try { - for (int i = 0; i < configurations.length; i++) { - final ILaunchConfiguration config = configurations[i]; - final LaunchInvocationTask launchInvocationTask = new LaunchInvocationTask(config); - launchInvocationTask.run(mweWorkflowExecutionMonitor.split(1)); - ProgressMonitorUtil.checkCancellation(mweWorkflowExecutionMonitor); - } - } finally { - SubMonitor.done(monitor); - } - return Status.OK_STATUS; - } -} \ No newline at end of file diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/LaunchInvocationTask.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/LaunchInvocationTask.java deleted file mode 100644 index 72e05c99..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/LaunchInvocationTask.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.moflon.core.ui.autosetup; - -import org.apache.log4j.Logger; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.debug.core.DebugException; -import org.eclipse.debug.core.ILaunch; -import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.ILaunchManager; -import org.gervarro.eclipse.task.ITask; -import org.moflon.core.utilities.LogUtils; -import org.moflon.core.utilities.WorkspaceHelper; - -public class LaunchInvocationTask implements ITask { - private static final Logger logger = Logger.getLogger(LaunchInvocationTask.class); - private final ILaunchConfiguration launchConfiguration; - - public LaunchInvocationTask(final ILaunchConfiguration launchConfiguration) { - this.launchConfiguration = launchConfiguration; - } - - @Override - public IStatus run(final IProgressMonitor monitor) { - try { - final ILaunch launch = launchConfiguration.launch(ILaunchManager.RUN_MODE, monitor, true); - while (!launch.isTerminated()) { - try { - Thread.sleep(10000); - if (monitor.isCanceled()) { - terminateProcess(launch); - } - } catch (final InterruptedException e) { - terminateProcess(launch); - } - } - return Status.OK_STATUS; - } catch (final CoreException e) { - return new Status(IStatus.ERROR, WorkspaceHelper.getPluginId(getClass()), IStatus.ERROR, - "Unable to launch " + launchConfiguration.getName(), e); - } - } - - private final void terminateProcess(final ILaunch launch) { - if (launch.canTerminate()) { - try { - launch.terminate(); - } catch (final DebugException e) { - LogUtils.warn(logger, "Unable to terminate %s", launchConfiguration.getName()); - } - } else { - LogUtils.warn(logger, "Unable to terminate %s", launchConfiguration.getName()); - } - throw new OperationCanceledException(); - } - - @Override - public final String getTaskName() { - return "Launching configuration " + launchConfiguration.getName(); - } -} diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/OpenProjectsJob.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/OpenProjectsJob.java deleted file mode 100644 index e904d53b..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/OpenProjectsJob.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.moflon.core.ui.autosetup; - -import java.util.List; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.moflon.core.utilities.ProgressMonitorUtil; -import org.moflon.core.utilities.WorkspaceHelper; - -/** - * This {@link Job} opens the list of preconfigured projects (see - * {@link CloseProjectsJob#CloseProjectsJob(String, List)}) upon - * {@link #run(IProgressMonitor)} - * - * @author Roland Kluge - Initial implementation - */ -public final class OpenProjectsJob extends Job { - private final List projects; - - public OpenProjectsJob(final String name, final List projects) { - super(name); - this.projects = projects; - } - - @Override - protected IStatus run(IProgressMonitor monitor) { - final SubMonitor openingMonitor = SubMonitor.convert(monitor, "Opening projects", projects.size()); - try { - for (final IProject project : projects) { - project.open(openingMonitor.split(1)); - ProgressMonitorUtil.checkCancellation(openingMonitor); - } - } catch (final CoreException e) { - return new Status(IStatus.ERROR, WorkspaceHelper.getPluginId(getClass()), e.getMessage(), e); - } finally { - SubMonitor.done(monitor); - } - return Status.OK_STATUS; - } -} \ No newline at end of file diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/PsfFileUtils.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/PsfFileUtils.java deleted file mode 100644 index d0d7b873..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/PsfFileUtils.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.moflon.core.ui.autosetup; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; - -import org.apache.commons.io.FileUtils; -import org.apache.log4j.Logger; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.moflon.core.utilities.ExceptionUtil; -import org.moflon.core.utilities.UtilityClassNotInstantiableException; -import org.moflon.core.utilities.XMLUtils; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * Utility class for working with PSF files. - */ -public final class PsfFileUtils { - - private static Logger logger = Logger.getLogger(PsfFileUtils.class); - - private PsfFileUtils() { - throw new UtilityClassNotInstantiableException(); - } - - public static String joinPsfFile(Collection files) throws IOException, CoreException { - if (files == null || files.isEmpty()) - throw new IllegalArgumentException("Illegal input (empty or null): " + files); - - final Iterator iter = files.iterator(); - final File file1 = iter.next(); - if (files.size() == 1) - return FileUtils.readFileToString(file1); - - final Document document1 = XMLUtils.parseXmlDocument(file1); - final Node root1 = document1.getChildNodes().item(0); - while (iter.hasNext()) { - final File file2 = iter.next(); - final Document document2 = XMLUtils.parseXmlDocument(file2); - final Node root2 = document2.getChildNodes().item(0); - final NodeList childNodes2 = root2.getChildNodes(); - for (int i = 0; i < childNodes2.getLength(); ++i) { - final Node childNode2 = childNodes2.item(i); - final Node clonedChildNode2 = childNode2.cloneNode(true); - document1.adoptNode(clonedChildNode2); // Update/set metadata appropriately for new document - root1.appendChild(clonedChildNode2); // Insert at appropriate place in new document - } - } - - final String joinedPsfFiles = XMLUtils.formatXmlString(document1, new NullProgressMonitor()); - return joinedPsfFiles; - - } - - public static List extractPsfFileContents(final List absolutePathsToPSF) throws IOException { - final List psfContents = new ArrayList<>(); - for (final String absolutePathToPSF : absolutePathsToPSF) { - psfContents.add(FileUtils.readFileToString(new File(absolutePathToPSF))); - } - return psfContents; - } - - public static Optional extractPsfFileContent(final URL url) { - try { - URLConnection connection = url.openConnection(); - connection.setReadTimeout(60 * 1000); - String enc = connection.getContentEncoding(); - if (enc == null) - enc = ResourcesPlugin.getEncoding(); - return Optional.of(read(connection.getInputStream(), enc)); - } catch (Exception e) { - logger.error(ExceptionUtil.displayExceptionAsString(e)); - // Fail silently but return empty optional - } - - return Optional.empty(); - } - - public static String read(InputStream is, String encoding) throws IOException { - if (is == null) - throw new IOException("Stream is null"); - - BufferedReader reader = null; - try { - StringBuffer buffer = new StringBuffer(); - char[] part = new char[2048]; - int read = 0; - reader = new BufferedReader(new InputStreamReader(is, encoding)); - while ((read = reader.read(part)) != -1) - buffer.append(part, 0, read); - - return buffer.toString(); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException ex) { - // silently ignored - } - } - } - } -} diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/WorkspaceInstaller.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/WorkspaceInstaller.java deleted file mode 100644 index b008d581..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/WorkspaceInstaller.java +++ /dev/null @@ -1,210 +0,0 @@ -package org.moflon.core.ui.autosetup; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; -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.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jdt.internal.core.JavaModelManager; -import org.eclipse.team.internal.ui.wizards.ImportProjectSetOperation; -import org.eclipse.team.ui.TeamOperation; -import org.eclipse.ui.IWorkingSet; -import org.gervarro.eclipse.workspace.util.WorkspaceTask; -import org.gervarro.eclipse.workspace.util.WorkspaceTaskJob; -import org.moflon.core.build.TaskUtilities; -import org.moflon.core.utilities.ExceptionUtil; -import org.moflon.core.utilities.LogUtils; - -@SuppressWarnings("restriction") -public class WorkspaceInstaller { - protected static final Logger logger = Logger.getLogger(WorkspaceInstaller.class); - - private static final String MASTER_BRANCH = "master"; - - public void installPsfFiles(final List psfFiles) { - final String label = joinBasenames(psfFiles); - installPsfFiles(psfFiles, label); - } - - public void installPsfFiles(final List psfFiles, final String label) { - installPsfFiles(psfFiles, label, MASTER_BRANCH); - } - - public void installPsfFiles(final List psfFiles, final String label, final String customBranch) { - try { - prepareWorkspace(); - - // We extract the contents beforehand because the following action may delete - // them if we load PSF files - // directly from the workspace - final String psfContent; - if (customBranch == null || MASTER_BRANCH.equals(customBranch)) { - psfContent = PsfFileUtils.joinPsfFile(psfFiles); - } else { - psfContent = PsfFileUtils.joinPsfFile(psfFiles).replaceAll(Pattern.quote("," + MASTER_BRANCH + ","), - "," + customBranch + ","); - } - - final int numberOfProjects = StringUtils.countMatches(psfContent, " 1 ? null : psfFiles.get(0).getAbsolutePath(), // - label).run(); - } catch (final InterruptedException e) { - // Operation cancelled by the user on the GUI - throw new OperationCanceledException(); - } catch (final InvocationTargetException | IOException e) { - LogUtils.error(logger, e); - return; - } catch (final CoreException e) { - final String message = "Sorry, I was unable to check out the projects in the PSF file.\n"// - + " If you did not explicitly cancel then please check the following (most probable first):\n"// - + " (1) Ensure that the Git repositories appearing in the error message below are clean or do not exist (Window/Perspective/Open Perspective/Other.../Git)\n" // - + " (2) If possible, start with an empty, fresh workspace. Although the PSF import offers to delete the projects this may fail, especially on Windows.\n"// - + " (3) Are you sure you have access to all the projects (if they do not support anonymous access)?\n"// - + " (4) The PSF file might be outdated - please check for an update of the test plugin\n"// - + " (5) If it's quite late in the night, our server might be down performing a back-up - try again in a few hours.\n"// - + " (6) If none of these helped, write us a mail to contact@emoflon.org :)\n" // - + "\n" // - + "Exception of type " + e.getClass().getName() + ", Message: " - + ExceptionUtil.displayExceptionAsString(e); - logger.error(message); - return; - } - } - - private TeamOperation createImportProjectSetOperation(String psfContent, String urlString, String label) { - return new ImportProjectSetOperation(null, psfContent, urlString, new IWorkingSet[0]) { - - @Override - public String getJobName() { - return "Checking out projects"; - } - - @Override - public ISchedulingRule getSchedulingRule() { - return ResourcesPlugin.getWorkspace().getRoot(); - } - - @Override - public void done(final IJobChangeEvent event) { - if (event.getResult().isOK()) { - final WorkspaceTask buildConfiguratorTask = new WorkspaceTask() { - - @Override - public void run(IProgressMonitor monitor) throws CoreException { - performBuildAndTest(label); - } - - @Override - public String getTaskName() { - return "Configuring build and test process"; - } - - @Override - public ISchedulingRule getRule() { - return ResourcesPlugin.getWorkspace().getRoot(); - } - }; - new WorkspaceTaskJob(buildConfiguratorTask).schedule(); - } - } - - }; - } - - private final void performBuildAndTest(final String label) { - final List jobs = new ArrayList(); - - enqueuePreprocessingJobs(jobs); - - final Job moflonProjectExplorerJob = new ExploreEMoflonProjectsJob("Exploring eMoflon projects", jobs, label, - this); - moflonProjectExplorerJob.setRule(ResourcesPlugin.getWorkspace().getRoot()); - jobs.add(moflonProjectExplorerJob); - jobs.add(new Job("Good bye.") { - @Override - protected IStatus run(IProgressMonitor monitor) { - logger.info("Code generation jobs completed successfully."); - return Status.OK_STATUS; - } - }); - - try { - TaskUtilities.processJobQueueInBackground(jobs); - logger.info("Code generation jobs scheduled."); - } catch (final CoreException e) { - LogUtils.error(logger, e); - } - logger.info( - "End of automatic workspace configuration reached. Please wait for the code generation jobs to finish. Bye bye."); - } - - /** - * Adds jobs to the queue that shall be invoked prior to building the projects - * in the workspace - * - * @param jobs - * the job queue - */ - protected void enqueuePreprocessingJobs(final List jobs) { - // Nothing to do here - } - - /** - * The list of projects to be built - * - * @return all projects in the workspace - */ - protected IProject[] getProjectsToBuild() { - return ResourcesPlugin.getWorkspace().getRoot().getProjects(); - } - - // This is required to avoid NPEs when checking out plugin projects (a problem - // with JDT) - private static void prepareWorkspace() { - try { - JavaModelManager.getExternalManager().createExternalFoldersProject(new NullProgressMonitor()); - } catch (final CoreException e) { - LogUtils.error(logger, e); - } - - } - - private static String joinBasenames(final List files) { - return files.stream().map(f -> f.getName()).collect(Collectors.joining(", ")); - } - - public void installPsfFile(URL url, String label) { - Optional psfContent = PsfFileUtils.extractPsfFileContent(url); - psfContent.ifPresent(psf -> { - try { - createImportProjectSetOperation(psf, url.toString(), label).run(); - } catch (Exception e) { - logger.error(ExceptionUtil.displayExceptionAsString(e)); - } - }); - } -} diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handbook/RegisterPsfUrlForHandbookPart1.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handbook/RegisterPsfUrlForHandbookPart1.java deleted file mode 100644 index 2873946d..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handbook/RegisterPsfUrlForHandbookPart1.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.moflon.core.ui.autosetup.handbook; - -public class RegisterPsfUrlForHandbookPart1 extends SokobanHandbookPsfUrlRegistration { - - public RegisterPsfUrlForHandbookPart1() { - super(1, "https://raw.githubusercontent.com/eMoflon/emoflon-ibex-examples/master/sokoban/version1/projectSet.psf"); - } - -} diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handbook/SokobanHandbookPsfUrlRegistration.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handbook/SokobanHandbookPsfUrlRegistration.java deleted file mode 100644 index 6cdc6e19..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handbook/SokobanHandbookPsfUrlRegistration.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.moflon.core.ui.autosetup.handbook; - -import java.net.MalformedURLException; -import java.net.URL; - -import org.moflon.core.ui.autosetup.handler.RegisterPsfUrlExtension; - -public abstract class SokobanHandbookPsfUrlRegistration implements RegisterPsfUrlExtension { - protected static final String PREFIX = "I. Sokoban Example: "; - private String label; - private String url; - - public SokobanHandbookPsfUrlRegistration(int part, String url) { - this(PREFIX + part, url); - } - - public SokobanHandbookPsfUrlRegistration(String label, String url) { - this.url = url; - this.label = label; - } - - @Override - public String getLabel() { - return label; - } - - @Override - public URL getUrl() { - try { - return new URL(url); - } catch (MalformedURLException e) { - throw new IllegalStateException(e); - } - } -} diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/InstallPsfFileHandler.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/InstallPsfFileHandler.java deleted file mode 100644 index a797513b..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/InstallPsfFileHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.moflon.core.ui.autosetup.handler; - -import java.io.File; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.FileDialog; -import org.moflon.core.ui.AbstractCommandHandler; -import org.moflon.core.ui.autosetup.WorkspaceInstaller; - -public class InstallPsfFileHandler extends AbstractCommandHandler { - - @Override - public Object execute(final ExecutionEvent event) throws ExecutionException { - final FileDialog dialog = new FileDialog(Display.getDefault().getActiveShell(), SWT.MULTI); - dialog.setFilterExtensions(new String[] { "*.psf", "*.PSF" }); - dialog.setText("Choose your PSF file(s)"); - - String open = dialog.open(); - if (open != null) { - final String parentPath = dialog.getFilterPath(); - final List selectedFileNames = Arrays.asList(dialog.getFileNames()); - final List psfFiles = selectedFileNames.stream().map(s -> new File(new File(parentPath), s)) - .collect(Collectors.toList()); - - new WorkspaceInstaller().installPsfFiles(psfFiles); - } - return null; - } - -} diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/PopulatePsfUrlMenu.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/PopulatePsfUrlMenu.java deleted file mode 100644 index ae28a951..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/PopulatePsfUrlMenu.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.moflon.core.ui.autosetup.handler; - -import java.util.Collection; - -import org.apache.log4j.Logger; -import org.eclipse.jface.action.ContributionItem; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.ui.menus.ExtensionContributionFactory; -import org.eclipse.ui.menus.IContributionRoot; -import org.eclipse.ui.services.IServiceLocator; -import org.moflon.core.ui.autosetup.WorkspaceInstaller; -import org.moflon.core.utilities.ExtensionsUtil; - -public class PopulatePsfUrlMenu extends ExtensionContributionFactory { - private Logger logger = Logger.getLogger(PopulatePsfUrlMenu.class); - - private static final String URI_PREF_EXTENSION_ID = "org.moflon.core.ui.autosetup.RegisterPsfUrlExtension"; - - private static Collection registerPsfUrlExtensions = ExtensionsUtil - .collectExtensions(URI_PREF_EXTENSION_ID, "class", RegisterPsfUrlExtension.class); - - @Override - public void createContributionItems(IServiceLocator serviceLocator, IContributionRoot additions) { - registerPsfUrlExtensions.stream()// - .sorted((r1, r2) -> r1.getLabel().compareTo(r2.getLabel()))// - .forEach(ext -> { - additions.addContributionItem(new ContributionItem() { - @Override - public void fill(Menu menu, int index) { - logger.debug("Inserting " + ext.getLabel() + " at " + index); - MenuItem mi = new MenuItem(menu, SWT.DEFAULT, menu.getItemCount()); - mi.setText(ext.getLabel()); - mi.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - logger.info(ext.getLabel() + " selected!"); - logger.info(ext.getUrl() + " is going to be imported."); - new WorkspaceInstaller().installPsfFile(ext.getUrl(), ext.getLabel()); - } - }); - } - }, null); - }); - } -} diff --git a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/RegisterPsfUrlExtension.java b/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/RegisterPsfUrlExtension.java deleted file mode 100644 index d29382b0..00000000 --- a/org.moflon.core.ui.autosetup/src/org/moflon/core/ui/autosetup/handler/RegisterPsfUrlExtension.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.moflon.core.ui.autosetup.handler; - -import java.net.URL; - -public interface RegisterPsfUrlExtension { - /** - * Get the label to be displayed in the menu. - * - * @return A string represented the label to be displayed for the PSF in the - * menu. - */ - String getLabel(); - - /** - * Get the URL to be displayed in the menu. - * - * @return The URL to the PSF to be imported when the entry is selected. - */ - URL getUrl(); -} From 6dde13825a97a039692c6cef6de6ae2382b2a8be Mon Sep 17 00:00:00 2001 From: SebastianE Date: Tue, 25 Oct 2022 18:58:53 +0200 Subject: [PATCH 02/23] + added flag to allow creation of files that have not been there before during the save process of a smart-resource --- .../smartemf/persistence/JDOMXmiParser.java | 365 ++++++++++-------- .../persistence/SmartEMFResource.java | 14 +- .../smartemf/persistence/XmiParserUtil.java | 20 +- 3 files changed, 222 insertions(+), 177 deletions(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiParser.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiParser.java index eafbb7aa..0aa62382 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiParser.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiParser.java @@ -34,38 +34,38 @@ import org.jdom2.input.SAXBuilder; public class JDOMXmiParser { - + protected final String workspacePath; - + protected Map>> waitingCrossRefs = new HashMap<>(); protected Map>> waitingHRefs = new HashMap<>(); protected Map id2Object = new HashMap<>(); protected Map fqId2Object = new HashMap<>(); protected Map ns2Package = new HashMap<>(); protected Map ns2Factory = new HashMap<>(); - protected Map loadedResources = new HashMap<>(); + protected Map loadedResources = new HashMap<>(); protected URI initialUri = null; - + public JDOMXmiParser(final String workspacePath) { this.workspacePath = workspacePath; } - + public Map getLoadedResources() { return loadedResources; } - + public Map getFqId2ObjectMap() { return fqId2Object; } - + public void addWaitingHRefs(final Map>> hrefs) { waitingHRefs.putAll(hrefs); } - + public Map>> getWaitingHRefs() { return waitingHRefs; } - + public void load(final InputStream is, final Resource resource) throws Exception { SAXBuilder saxBuilder = new SAXBuilder(); Document parsedFile = null; @@ -74,63 +74,67 @@ public void load(final InputStream is, final Resource resource) throws Exception } catch (JDOMException | IOException e) { throw new IOException(e.getMessage(), e.getCause()); } - - if(initialUri == null) { - String resolvedPath = XmiParserUtil.resolveURIToPath(resource.getURI(), workspacePath); + + if (initialUri == null) { + String resolvedPath = XmiParserUtil.resolveURIToPath(resource.getURI(), workspacePath, false); initialUri = URI.createFileURI(resolvedPath); } - + domTreeToModel(parsedFile, resource); loadedResources.put(resource.getURI().toString(), resource); } - - public Resource load(final String uri, final ResourceSet rs) throws Exception{ + + public Resource load(final String uri, final ResourceSet rs) throws Exception { String filePath = XmiParserUtil.resolveURIRelativeToBaseURI(initialUri, URI.createURI(uri), workspacePath); - if(filePath == null) - throw new FileNotFoundException("Relative path "+uri.trim().replace("%20", " ")+" could not be resolved with the path of the initial uri "+initialUri.devicePath().trim().replace("%20", " ")+"."); - + if (filePath == null) + throw new FileNotFoundException("Relative path " + uri.trim().replace("%20", " ") + + " could not be resolved with the path of the initial uri " + + initialUri.devicePath().trim().replace("%20", " ") + "."); + Resource resource = null; - for(Resource loadedResource : rs.getResources()) { - if(XmiParserUtil.relativeURIsAreEqual(initialUri, URI.createURI(uri), loadedResource.getURI(), workspacePath)) { + for (Resource loadedResource : rs.getResources()) { + if (XmiParserUtil.relativeURIsAreEqual(initialUri, URI.createURI(uri), loadedResource.getURI(), + workspacePath)) { resource = loadedResource; break; } } - if(resource == null) { + if (resource == null) { File file = new File(filePath); FileInputStream fis = new FileInputStream(file); resource = new SmartEMFResource(URI.createFileURI(file.getCanonicalPath()), workspacePath); rs.getResources().add(resource); - + JDOMXmiParser subParser = new JDOMXmiParser(workspacePath); subParser.addWaitingHRefs(waitingHRefs); subParser.load(fis, resource); fis.close(); - - loadedResources.putAll(subParser.getLoadedResources()); + + loadedResources.putAll(subParser.getLoadedResources()); fqId2Object.putAll(subParser.getFqId2ObjectMap()); waitingHRefs.putAll(subParser.getWaitingHRefs()); } else { indexForeignResource(resource); } - + loadedResources.put(uri, resource); return resource; } - + public void domTreeToModel(final Document domTree, final Resource resource) throws Exception { Element root = domTree.getRootElement(); Namespace ns = root.getNamespace(); List roots = new LinkedList<>(); - // If there is a root node belonging to the XMI Namespace, than we have multiple container objects wrapped within an XML dummy-node to ensure XML compliance - if(XmiParserUtil.XMI_NS.equals(ns.getPrefix())) { + // If there is a root node belonging to the XMI Namespace, than we have multiple + // container objects wrapped within an XML dummy-node to ensure XML compliance + if (XmiParserUtil.XMI_NS.equals(ns.getPrefix())) { roots.addAll(root.getChildren()); } else { roots.add(root); } - + int id = 0; - for(Element subRoot : roots) { + for (Element subRoot : roots) { // Load the corresponding metamodel and factory Namespace subRootNS = subRoot.getNamespace(); EPackage metamodel = XmiParserUtil.loadMetamodel(subRootNS.getURI()); @@ -139,35 +143,39 @@ public void domTreeToModel(final Document domTree, final Resource resource) thro ns2Factory.put(subRootNS.getPrefix(), factory); // find additional namespaces Set additionalNS = subRoot.getAdditionalNamespaces().stream() - .filter(ns2 -> !ns2.getPrefix().equals(XmiParserUtil.XMI_NS) && !ns2.getPrefix().equals(XmiParserUtil.XSI_NS) && !ns2.getPrefix().equals(subRootNS.getPrefix())) - .filter(ns2 -> !ns2Package.containsKey(ns2.getPrefix())) - .collect(Collectors.toSet()); - - for(Namespace ns2 : additionalNS) { + .filter(ns2 -> !ns2.getPrefix().equals(XmiParserUtil.XMI_NS) + && !ns2.getPrefix().equals(XmiParserUtil.XSI_NS) + && !ns2.getPrefix().equals(subRootNS.getPrefix())) + .filter(ns2 -> !ns2Package.containsKey(ns2.getPrefix())).collect(Collectors.toSet()); + + for (Namespace ns2 : additionalNS) { EPackage additionalMetamodel = XmiParserUtil.loadMetamodel(ns2.getURI()); EFactory additionalFactory = additionalMetamodel.getEFactoryInstance(); ns2Package.put(ns2.getPrefix(), additionalMetamodel); ns2Factory.put(ns2.getPrefix(), additionalFactory); } - + // traverse tree and instantiate classes EObject eRoot = null; - if(roots.size() > 1) { - eRoot = parseDomTree(resource, subRoot, null, subRootNS.getPrefix(), resource.getURI().toString()+"#/"+id, "/"+id, 0); + if (roots.size() > 1) { + eRoot = parseDomTree(resource, subRoot, null, subRootNS.getPrefix(), + resource.getURI().toString() + "#/" + id, "/" + id, 0); id++; } else { - eRoot = parseDomTree(resource, subRoot, null, subRootNS.getPrefix(), resource.getURI().toString()+"#/", "/", 0); + eRoot = parseDomTree(resource, subRoot, null, subRootNS.getPrefix(), + resource.getURI().toString() + "#/", "/", 0); } resource.getContents().add(eRoot); } - + } - + @SuppressWarnings("unchecked") - protected EObject parseDomTree(final Resource resource, Element root, EReference containment, String namespace, String fqId, String id, int idx) throws Exception { + protected EObject parseDomTree(final Resource resource, Element root, EReference containment, String namespace, + String fqId, String id, int idx) throws Exception { EPackage metamodel = null; String currentNamespace = null; - if(root.getNamespace().getPrefix() == null || root.getNamespace().getPrefix().isBlank()) { + if (root.getNamespace().getPrefix() == null || root.getNamespace().getPrefix().isBlank()) { metamodel = ns2Package.get(namespace); currentNamespace = namespace; } else { @@ -175,108 +183,116 @@ protected EObject parseDomTree(final Resource resource, Element root, EReference currentNamespace = root.getNamespace().getPrefix(); } EFactory factory = ns2Factory.get(currentNamespace); - + EClass rootClass = null; String currentId = id; String currentFqId = fqId; String simpleId = null; String simpleFqId = null; - - if(containment == null) { - rootClass = (EClass)metamodel.getEClassifier(root.getName()); + + if (containment == null) { + rootClass = (EClass) metamodel.getEClassifier(root.getName()); } else { Optional typeATR = root.getAttributes().stream() - .filter(atr -> atr.getName().equals(XmiParserUtil.XSI_TYPE) && atr.getNamespacePrefix().equals(XmiParserUtil.XSI_NS)).findFirst(); - if(typeATR.isPresent()) { + .filter(atr -> atr.getName().equals(XmiParserUtil.XSI_TYPE) + && atr.getNamespacePrefix().equals(XmiParserUtil.XSI_NS)) + .findFirst(); + if (typeATR.isPresent()) { String[] exactType = typeATR.get().getValue().split(":"); - //This is obviously an element belonging to a foreign metamodel -> switch to suitable EPacakge and Factory but stay in the current namespace + // This is obviously an element belonging to a foreign metamodel -> switch to + // suitable EPacakge and Factory but stay in the current namespace String metamodelNS = exactType[0]; String className = exactType[1]; metamodel = ns2Package.get(metamodelNS); factory = ns2Factory.get(metamodelNS); - rootClass = (EClass)metamodel.getEClassifier(className); + rootClass = (EClass) metamodel.getEClassifier(className); } else { rootClass = containment.getEReferenceType(); } currentId = id + "/@" + containment.getName() + "." + idx; currentFqId = fqId + "/@" + containment.getName() + "." + idx; - // This a workaround for a useless/annoying xml simplification that occurs when a child list is exactly of size 1, then the index is omitted. - if(idx == 0) { + // This a workaround for a useless/annoying xml simplification that occurs when + // a child list is exactly of size 1, then the index is omitted. + if (idx == 0) { simpleId = id + "/@" + containment.getName(); simpleFqId = fqId + "/@" + containment.getName(); } } - + EObject eRoot = factory.create(rootClass); - + currentId = XmiParserUtil.simplifyID(currentId); currentFqId = XmiParserUtil.simplifyID(currentFqId); - + id2Object.put(currentId, eRoot); fqId2Object.put(currentFqId, eRoot); - - if(simpleId != null) { + + if (simpleId != null) { simpleId = XmiParserUtil.simplifyID(simpleId); simpleFqId = XmiParserUtil.simplifyID(simpleFqId); - + id2Object.put(simpleId, eRoot); fqId2Object.put(simpleFqId, eRoot); } - - if(waitingCrossRefs.containsKey(currentId)) { + + if (waitingCrossRefs.containsKey(currentId)) { waitingCrossRefs.get(currentId).forEach(waitingRef -> waitingRef.accept(eRoot)); waitingCrossRefs.remove(currentId); } - if(simpleId != null && waitingCrossRefs.containsKey(simpleId)) { + if (simpleId != null && waitingCrossRefs.containsKey(simpleId)) { waitingCrossRefs.get(simpleId).forEach(waitingRef -> waitingRef.accept(eRoot)); waitingCrossRefs.remove(simpleId); } - - if(waitingHRefs.containsKey(currentFqId)) { + + if (waitingHRefs.containsKey(currentFqId)) { waitingHRefs.get(currentFqId).forEach(waitingRef -> waitingRef.accept(eRoot)); waitingHRefs.remove(currentFqId); } - - if(simpleFqId != null && waitingCrossRefs.containsKey(simpleFqId)) { + + if (simpleFqId != null && waitingCrossRefs.containsKey(simpleFqId)) { waitingHRefs.get(simpleFqId).forEach(waitingRef -> waitingRef.accept(eRoot)); waitingHRefs.remove(simpleFqId); } - - Map element2Idx = new HashMap<>(); + + Map element2Idx = new HashMap<>(); Map feature2CrossRef = new HashMap<>(); - for(Element element : root.getChildren()) { - if(XmiParserUtil.XMI_NS.equals(element.getNamespace().getPrefix())) + for (Element element : root.getChildren()) { + if (XmiParserUtil.XMI_NS.equals(element.getNamespace().getPrefix())) continue; - - Optional featureOpt = rootClass.getEAllStructuralFeatures().stream().filter(sf -> sf.getName().equals(element.getName())).findFirst(); - if(!featureOpt.isPresent()) - throw new IOException("Unkown structual feature: "+element.getName()); - - EStructuralFeature feature = featureOpt.get(); - if(feature instanceof EAttribute) - throw new IOException("Illegal use of EAttribute: "+element.getName()); - - if(!element2Idx.containsKey(feature)) { + + Optional featureOpt = rootClass.getEAllStructuralFeatures().stream() + .filter(sf -> sf.getName().equals(element.getName())).findFirst(); + if (!featureOpt.isPresent()) + throw new IOException("Unkown structual feature: " + element.getName()); + + EStructuralFeature feature = featureOpt.get(); + if (feature instanceof EAttribute) + throw new IOException("Illegal use of EAttribute: " + element.getName()); + + if (!element2Idx.containsKey(feature)) { element2Idx.put(feature, 0); } - - EReference ref = (EReference)feature; - if(ref.isContainment()) { - if(ref.isMany()) { + + EReference ref = (EReference) feature; + if (ref.isContainment()) { + if (ref.isMany()) { EList objs = (EList) eRoot.eGet(ref); - EObject child = parseDomTree(resource, element, ref, currentNamespace, currentFqId, currentId, element2Idx.get(feature)); + EObject child = parseDomTree(resource, element, ref, currentNamespace, currentFqId, currentId, + element2Idx.get(feature)); objs.add(child); - element2Idx.replace(feature, element2Idx.get(feature)+1); + element2Idx.replace(feature, element2Idx.get(feature) + 1); } else { - EObject child = parseDomTree(resource, element, ref, currentNamespace, currentFqId, currentId, element2Idx.get(feature)); + EObject child = parseDomTree(resource, element, ref, currentNamespace, currentFqId, currentId, + element2Idx.get(feature)); eRoot.eSet(ref, child); - element2Idx.replace(feature, element2Idx.get(feature)+1); + element2Idx.replace(feature, element2Idx.get(feature) + 1); } } else { - if(XmiParserUtil.isHyperref(element)) { + if (XmiParserUtil.isHyperref(element)) { PendingEMFCrossReference pendingCrossref = feature2CrossRef.get(ref); - if(pendingCrossref == null) { - pendingCrossref = new PendingEMFCrossReference(eRoot, ref, (int)root.getChildren().stream().filter(elt -> elt.getName().equals(ref.getName())).count()); + if (pendingCrossref == null) { + pendingCrossref = new PendingEMFCrossReference(eRoot, ref, (int) root.getChildren().stream() + .filter(elt -> elt.getName().equals(ref.getName())).count()); feature2CrossRef.put(ref, pendingCrossref); } Attribute href = element.getAttribute(XmiParserUtil.HREF_ATR); @@ -284,195 +300,210 @@ protected EObject parseDomTree(final Resource resource, Element root, EReference String modelUri = hrefPath[0]; String hrefFQId = null; Resource otherResource = null; - - if(!loadedResources.containsKey(modelUri)) { + + if (!loadedResources.containsKey(modelUri)) { otherResource = load(modelUri, resource.getResourceSet()); - + } else { otherResource = loadedResources.get(modelUri); } - hrefFQId = otherResource.getURI().toString()+"#"+hrefPath[1]; + hrefFQId = otherResource.getURI().toString() + "#" + hrefPath[1]; hrefFQId = XmiParserUtil.simplifyID(hrefFQId); - - if(fqId2Object.containsKey(hrefFQId)) { + + if (fqId2Object.containsKey(hrefFQId)) { EObject hyperref = fqId2Object.get(hrefFQId); - - if(ref.isMany()) { + + if (ref.isMany()) { pendingCrossref.insertObject(hyperref, element2Idx.get(feature)); - element2Idx.replace(feature, element2Idx.get(feature)+1); + element2Idx.replace(feature, element2Idx.get(feature) + 1); } else { pendingCrossref.insertObject(hyperref, 0); } - - if(pendingCrossref.isCompleted()) { + + if (pendingCrossref.isCompleted()) { pendingCrossref.writeBack(); } } else { List> pendingHRefs = waitingHRefs.get(hrefFQId); - if(pendingHRefs == null) { + if (pendingHRefs == null) { pendingHRefs = new LinkedList<>(); waitingHRefs.put(hrefFQId, pendingHRefs); } - + // Make those variables final 'cause java .. final int currentIdx = element2Idx.get(feature); final PendingEMFCrossReference currentPending = pendingCrossref; pendingHRefs.add((eobj) -> { currentPending.insertObject(eobj, currentIdx); - if(currentPending.isCompleted()) { + if (currentPending.isCompleted()) { currentPending.writeBack(); } }); - element2Idx.replace(feature, element2Idx.get(feature)+1); + element2Idx.replace(feature, element2Idx.get(feature) + 1); } } else { - throw new IOException("XML DOM-Tree child: "+element.getName()+" is neither, a hyperref nor in a containment!"); + throw new IOException("XML DOM-Tree child: " + element.getName() + + " is neither, a hyperref nor in a containment!"); } - + } } - - for(Attribute attribute : root.getAttributes()) { - if(XmiParserUtil.XMI_NS.equals(attribute.getNamespace().getPrefix())) + + for (Attribute attribute : root.getAttributes()) { + if (XmiParserUtil.XMI_NS.equals(attribute.getNamespace().getPrefix())) continue; - - if(XmiParserUtil.XSI_NS.equals(attribute.getNamespace().getPrefix())) + + if (XmiParserUtil.XSI_NS.equals(attribute.getNamespace().getPrefix())) continue; - - Optional featureOpt = rootClass.getEAllStructuralFeatures().stream().filter(sf -> sf.getName().equals(attribute.getName())).findFirst(); - if(!featureOpt.isPresent()) - throw new IOException("Unkown structual feature: "+attribute.getName()); - - EStructuralFeature feature = featureOpt.get(); - if(feature instanceof EReference) { - EReference ref = (EReference)feature; - if(attribute.getValue().isBlank()) + + Optional featureOpt = rootClass.getEAllStructuralFeatures().stream() + .filter(sf -> sf.getName().equals(attribute.getName())).findFirst(); + if (!featureOpt.isPresent()) + throw new IOException("Unkown structual feature: " + attribute.getName()); + + EStructuralFeature feature = featureOpt.get(); + if (feature instanceof EReference) { + EReference ref = (EReference) feature; + if (attribute.getValue().isBlank()) continue; - + String[] entries = attribute.getValue().split(" "); - final PendingEMFCrossReference pendingCrossRefs = new PendingEMFCrossReference(eRoot, ref, entries.length); - for(int i = 0; i> otherCrossRefs = waitingCrossRefs.get(entry); - if(otherCrossRefs == null) { + if (otherCrossRefs == null) { otherCrossRefs = new LinkedList<>(); waitingCrossRefs.put(entry, otherCrossRefs); } final int currentIdx = i; otherCrossRefs.add((eobj) -> { pendingCrossRefs.insertObject(eobj, currentIdx); - if(pendingCrossRefs.isCompleted()) + if (pendingCrossRefs.isCompleted()) pendingCrossRefs.writeBack(); }); } } else { - if(id2Object.containsKey(entry)) { + if (id2Object.containsKey(entry)) { pendingCrossRefs.insertObject(id2Object.get(entry), 0); } else { // Remember this crossRef and wait for traversal List> otherCrossRefs = waitingCrossRefs.get(entry); - if(otherCrossRefs == null) { + if (otherCrossRefs == null) { otherCrossRefs = new LinkedList<>(); waitingCrossRefs.put(entry, otherCrossRefs); } otherCrossRefs.add((eobj) -> { pendingCrossRefs.insertObject(eobj, 0); - if(pendingCrossRefs.isCompleted()) + if (pendingCrossRefs.isCompleted()) pendingCrossRefs.writeBack(); }); } } } - if(pendingCrossRefs.isCompleted()) + if (pendingCrossRefs.isCompleted()) pendingCrossRefs.writeBack(); - + } else { EAttribute eAttribute = (EAttribute) feature; - - switch(attribute.getAttributeType()) { + + switch (attribute.getAttributeType()) { case CDATA: eRoot.eSet(eAttribute, XmiParserUtil.stringToValue(eAttribute, attribute.getValue())); break; case ENTITIES: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); case ENTITY: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); case ENUMERATION: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); case ID: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); case IDREF: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); case IDREFS: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); case NMTOKEN: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); case NMTOKENS: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); case NOTATION: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); case UNDECLARED: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); default: - throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); - + throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() + + " for attribute: " + attribute.getName()); + } } } return eRoot; } - + protected void indexForeignResource(final Resource resource) { - if(resource.getContents().size() < 2) { - indexForeignModel(resource.getContents().get(0), null, resource.getURI().toString()+"#/", 0, false); + if (resource.getContents().size() < 2) { + indexForeignModel(resource.getContents().get(0), null, resource.getURI().toString() + "#/", 0, false); } else { int idx = 0; - for(EObject container : resource.getContents()) { - indexForeignModel(container, null, resource.getURI().toString()+"#/"+idx++, 0, false); + for (EObject container : resource.getContents()) { + indexForeignModel(container, null, resource.getURI().toString() + "#/" + idx++, 0, false); } } - + } - + @SuppressWarnings("unchecked") - protected void indexForeignModel(final EObject root, final EReference containment, final String id, int idx, boolean useSimple) { + protected void indexForeignModel(final EObject root, final EReference containment, final String id, int idx, + boolean useSimple) { EClass rootClass = root.eClass(); String rootId = id; - if(containment != null) { - if(useSimple) { + if (containment != null) { + if (useSimple) { rootId = id + "/@" + containment.getName(); } else { rootId = id + "/@" + containment.getName() + "." + idx; } } rootId = XmiParserUtil.simplifyID(rootId); - + fqId2Object.put(rootId, root); - if(waitingHRefs.containsKey(rootId)) { + if (waitingHRefs.containsKey(rootId)) { waitingHRefs.get(rootId).forEach(waitingRef -> waitingRef.accept(root)); waitingHRefs.remove(rootId); } - + // Containments - for(EReference containmentRef : rootClass.getEAllContainments()) { + for (EReference containmentRef : rootClass.getEAllContainments()) { List containees = new LinkedList<>(); - if(containmentRef.isMany()) { + if (containmentRef.isMany()) { containees.addAll((Collection) root.eGet(containmentRef)); } else { EObject containee = (EObject) root.eGet(containmentRef); - if(containee != null) + if (containee != null) containees.add(containee); } int idIDX = 0; - for(EObject containee : containees) { - indexForeignModel(containee, containmentRef, rootId, idIDX, containees.size()==1); + for (EObject containee : containees) { + indexForeignModel(containee, containmentRef, rootId, idIDX, containees.size() == 1); idIDX++; } } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/SmartEMFResource.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/SmartEMFResource.java index 86634190..f3332d90 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/SmartEMFResource.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/SmartEMFResource.java @@ -30,8 +30,8 @@ import org.xml.sax.InputSource; /** - * A simplified resource implementation that serializes to XMI. Ignores save options. Can enable - * notification cascading for its contents. + * A simplified resource implementation that serializes to XMI. Ignores save + * options. Can enable notification cascading for its contents. */ public class SmartEMFResource extends UnlockedResourceImpl implements XMIResource { @@ -69,7 +69,7 @@ public EList eAdapters() { @Override public void save(Map options) throws IOException { - String path = XmiParserUtil.resolveURIToPath(uri, workspacePath); + String path = XmiParserUtil.resolveURIToPath(uri, workspacePath, true); if (path == null) throw new FileNotFoundException("Invalid path at: " + uri); @@ -90,7 +90,8 @@ public static void createFoldersIfNecessary(final File file) { @Override public void save(OutputStream outputStream, Map options) throws IOException { - URIConverter.Cipher cipher = (options != null) ? (URIConverter.Cipher) options.get(Resource.OPTION_CIPHER) : null; + URIConverter.Cipher cipher = (options != null) ? (URIConverter.Cipher) options.get(Resource.OPTION_CIPHER) + : null; if (cipher != null) { throw new UnsupportedOperationException("Encryption through cipher is not supported!"); } @@ -119,7 +120,7 @@ public void save(OutputStream outputStream, Map options) throws IOExceptio @Override public void load(Map options) throws IOException { - String path = XmiParserUtil.resolveURIToPath(uri, workspacePath); + String path = XmiParserUtil.resolveURIToPath(uri, workspacePath, false); if (path == null) throw new FileNotFoundException("No valid xmi file present at: " + uri); @@ -146,7 +147,8 @@ public void load(InputStream inputStream, Map options) throws IOException Notification notification = setLoaded(true); isLoading = true; - URIConverter.Cipher cipher = (options != null) ? (URIConverter.Cipher) options.get(Resource.OPTION_CIPHER) : null; + URIConverter.Cipher cipher = (options != null) ? (URIConverter.Cipher) options.get(Resource.OPTION_CIPHER) + : null; if (cipher != null) { throw new UnsupportedOperationException("Encryption through cipher is not supported!"); } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/XmiParserUtil.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/XmiParserUtil.java index 9a7e82f2..f72fb81f 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/XmiParserUtil.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/XmiParserUtil.java @@ -27,8 +27,8 @@ public final class XmiParserUtil { final public static String HREF_ATR = "href"; public static boolean URIsAreEqual(final URI uri1, final URI uri2, final String workspacePath) { - String path1 = resolveURIToPath(uri1, workspacePath); - String path2 = resolveURIToPath(uri2, workspacePath); + String path1 = resolveURIToPath(uri1, workspacePath, false); + String path2 = resolveURIToPath(uri2, workspacePath, false); return path1.equals(path2); } @@ -39,7 +39,7 @@ public static boolean relativeURIsAreEqual(final URI baseUri, final URI uri1, fi return path1.equals(path2); } - public static String resolveURIToPath(final URI uri, final String workspacePath) { + public static String resolveURIToPath(final URI uri, final String workspacePath, boolean newFile) { String path = uri.devicePath(); if (path.startsWith("/resource")) { path = path.replaceFirst("/resource", " "); @@ -59,6 +59,18 @@ public static String resolveURIToPath(final URI uri, final String workspacePath) } } + // This might be a new file that has not existed before + if (newFile) { + File parentFolder = new File(parent); + if (!parentFolder.exists()) + parentFolder.mkdirs(); + + try { + return file.getCanonicalPath(); + } catch (IOException e) { + } + } + // Otherwise -> fallback solution // Resolve workspace relative path @@ -97,7 +109,7 @@ public static String resolveURIToPath(final URI uri, final String workspacePath) } public static String resolveURIRelativeToBaseURI(final URI baseUri, final URI uri, final String workspacePath) { - String filePath = resolveURIToPath(uri, workspacePath); + String filePath = resolveURIToPath(uri, workspacePath, false); if (filePath != null) return filePath; From af7bd17e11d8666899562e52ce6c45ca4e701eb1 Mon Sep 17 00:00:00 2001 From: SebastianE Date: Wed, 26 Oct 2022 11:45:19 +0200 Subject: [PATCH 03/23] removed more old / unused projects --- .../.classpath | 7 - .../.gitignore | 3 - .../.project | 28 --- .../META-INF/MANIFEST.MF | 17 -- .../build.properties | 6 - .../icons/register.png | Bin 48181 -> 0 bytes .../plugin.xml | 30 ---- .../EmfRegistryManager.java | 166 ------------------ .../RegisterMetamodelHandler.java | 66 ------- org.moflon.git.ui/.classpath | 7 - org.moflon.git.ui/.gitignore | 1 - org.moflon.git.ui/.project | 28 --- .../.settings/org.eclipse.jdt.core.prefs | 10 -- org.moflon.git.ui/META-INF/MANIFEST.MF | 17 -- org.moflon.git.ui/build.properties | 6 - org.moflon.git.ui/plugin.xml | 17 -- .../src/org/moflon/git/GitHelper.java | 161 ----------------- .../ui/handler/GitResetProjectHandler.java | 51 ------ .../moflon/git/ui/handler/GitResetTask.java | 93 ---------- 19 files changed, 714 deletions(-) delete mode 100644 org.moflon.core.ui.packageregistration/.classpath delete mode 100644 org.moflon.core.ui.packageregistration/.gitignore delete mode 100644 org.moflon.core.ui.packageregistration/.project delete mode 100644 org.moflon.core.ui.packageregistration/META-INF/MANIFEST.MF delete mode 100644 org.moflon.core.ui.packageregistration/build.properties delete mode 100644 org.moflon.core.ui.packageregistration/icons/register.png delete mode 100644 org.moflon.core.ui.packageregistration/plugin.xml delete mode 100644 org.moflon.core.ui.packageregistration/src/org/moflon/core/ui/packageregistration/EmfRegistryManager.java delete mode 100644 org.moflon.core.ui.packageregistration/src/org/moflon/core/ui/packageregistration/RegisterMetamodelHandler.java delete mode 100644 org.moflon.git.ui/.classpath delete mode 100644 org.moflon.git.ui/.gitignore delete mode 100644 org.moflon.git.ui/.project delete mode 100644 org.moflon.git.ui/.settings/org.eclipse.jdt.core.prefs delete mode 100644 org.moflon.git.ui/META-INF/MANIFEST.MF delete mode 100644 org.moflon.git.ui/build.properties delete mode 100644 org.moflon.git.ui/plugin.xml delete mode 100644 org.moflon.git.ui/src/org/moflon/git/GitHelper.java delete mode 100644 org.moflon.git.ui/src/org/moflon/git/ui/handler/GitResetProjectHandler.java delete mode 100644 org.moflon.git.ui/src/org/moflon/git/ui/handler/GitResetTask.java diff --git a/org.moflon.core.ui.packageregistration/.classpath b/org.moflon.core.ui.packageregistration/.classpath deleted file mode 100644 index 4d23c295..00000000 --- a/org.moflon.core.ui.packageregistration/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/org.moflon.core.ui.packageregistration/.gitignore b/org.moflon.core.ui.packageregistration/.gitignore deleted file mode 100644 index 3d1f6cf4..00000000 --- a/org.moflon.core.ui.packageregistration/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/.settings/ -/bin -/target \ No newline at end of file diff --git a/org.moflon.core.ui.packageregistration/.project b/org.moflon.core.ui.packageregistration/.project deleted file mode 100644 index f2fa45b9..00000000 --- a/org.moflon.core.ui.packageregistration/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.moflon.core.ui.packageregistration - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/org.moflon.core.ui.packageregistration/META-INF/MANIFEST.MF b/org.moflon.core.ui.packageregistration/META-INF/MANIFEST.MF deleted file mode 100644 index 3f29db65..00000000 --- a/org.moflon.core.ui.packageregistration/META-INF/MANIFEST.MF +++ /dev/null @@ -1,17 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: eMoflon::Core components for registering Ecore files -Bundle-SymbolicName: org.moflon.core.ui.packageregistration;singleton:=true -Bundle-Version: 1.0.1.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-17 -Require-Bundle: org.eclipse.emf.ecore;bundle-version="2.11.0", - org.eclipse.core.resources, - org.eclipse.equinox.registry, - org.apache.log4j, - org.eclipse.jface, - org.eclipse.ui.workbench, - org.eclipse.emf.ecore.xmi, - org.moflon.core.ui -Bundle-Vendor: eMoflon developers -Automatic-Module-Name: org.moflon.core.ui.packageregistration -Export-Package: org.moflon.core.ui.packageregistration diff --git a/org.moflon.core.ui.packageregistration/build.properties b/org.moflon.core.ui.packageregistration/build.properties deleted file mode 100644 index 79785aca..00000000 --- a/org.moflon.core.ui.packageregistration/build.properties +++ /dev/null @@ -1,6 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - icons/,\ - plugin.xml diff --git a/org.moflon.core.ui.packageregistration/icons/register.png b/org.moflon.core.ui.packageregistration/icons/register.png deleted file mode 100644 index bd198799bc432b0177437d51fc9390fb8ea4af7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48181 zcmb^21#sNJnjm1uPV6|Q7-D9OnHgip%*+g9W@cuFF*7qWQ_RfF%*>v1-rKjeyH$5} zyLT!{E&Xb#TP@X$G~aZHjFd3kH_UHfU|?{fBERK6((iw#uaF;eyc>}2NAlT@UsU1i z$Kd|eAoyb)+FC@_4h#$i>F@Mudd>6oBZz7*sA4Z*Yp82)Vr7Z1U}9kiM#oCaz(h;O zTGbZp`jG?uZw`4YBYP)ZTSKs423C58_(CSOhE7(tW_HrGcv2sE&a7>fl%3Pg=B6zC z=)V842?~to7qzRXZinK0Vn11Bz{$F%S<0#~nfvl=OAEr=_lKP(8-@1r^x#@uTU*I) zC@4=*s-Kf9o!4@kYA@j=9o7nyFE42=nenVG0&2b(co~42SHmDaO8Vz;DZRv?kz=sb zN8=UCCOJjLtCdK#UA}EaOHYOur-)EyiP~w9dzZO!pv5wj+IZM?$B-5{^VIM-lmoGz zG2Uxa7K=vz2!3J+TREYBNiJ+P>7xrffbp^|je2pxkJp`#>&ZL>A|Wq8IeYIKcZLH0 zSGgbQ;|*Lq9Gjjs(aQbDnuvuNztHpg@cYN|=l_uFf3!%R$CwQU#!h8nrXc^(m>w2( zD?&9iQY?`~PbBw7ln1>}IVEnEYbELl{>~)U9U(bC$+L-RMEh+`OEvIC7MIy-qKGL| zb4Ng)t!|JII&@&4f>8{ya>fYgoReJ&4vsQ1a5pax#_z^xd#9EnSV4x)&W^bgZoTQh z8D3vLB5T(x$h^iA(l4A_l4kF*B((4?TM_4@4+wwa;hluHBv+CUgvkKWYfFBV{7U%s%%fMH9)P>n0=BKOS_my=OP5hCGrLHdhc@GlR#pa7P+hB}_z471v& zDmSj~FiX6t`o`?R{n2!%7AOGge4E`@!^~gct#2-XI&r87SCxQqWS2EOvbIy!`nmNqCnCrEc*S52t{<_t2K0e>551cu3G(` za3=}Jv*{k0&;jt8NMAwFcRqYdKXQs?)9#aq{pJfq)?J|f9rFOipQ^7oR8HWy1A31# z@BHo>lmXI|0Z}G-h$-teQ5diUegp>e{#1d{%y@8~hUFZX-BCK=oRO-`Lb>|OvR`_I zv3u!77CQOXdHCK5*%{#yvVK4myJ3szBPn<@SYyQ3c^T?pYO&L0+R{1kZLaqmNVvgS zKP|hRMck7?*%J}OclKU5Ew}R1IjoyG)H0o&P>ZiwsDD|Tx1=WyLHIs2NxNnT*T@7c zFr%ZA^iacS-G*PwU^ra$CSX;M{WV1)mnbAzLkXp->HQA>b_*LN_Q_xg7T<$#NNJG3 zls?=yCo)v8TBRZQJ2D$VDxnmy0wov)rFu^8{8^U3V7d$xH!TX|ntDYVwQ_NV(0Io- zdOMh=b^h-{>X0M@dz2+ZXVY(Z`e%>fkT`$dbEN`r@u1t*qb2dY`@n2tna-lue-DFd zQP%9*?1^LuNfA9ci)iG4z4$lmM*FiA<(wx@Volk)FR&sC%yTi=-=DNUrC3oCV5pHW z0nkmP>d3^v$(te|L|KNeZGJxr#W4Hs{uzxugd!X{jXfNwV(3Gd@e8B4j2%~DOT)LR z2)_tdCv|23KV=_*bpG0eS&Pvtp@i9=G)EsjmuI{f0BNhEaIw?F)c^;H(_4k@_*}-s z{H>d@2gM!>oMRT>E0(65kwqL~%s5zP=0UcA2#cms&R9kciF!sRdylRTI}q60!a&6L zN)Mf15zb-Mr2T0is7LLpegpMUL?bX~K!zBZ+DGrC;inp`AgP`hx<%%eG0LWKV-r@_ zjwe_Y(a@KPt=Iz<7o8ezXu9shGSYbc!z29IWh+Hj8}ec*0C#DBEC(aS@zC^B6bkI! z*4IH@xf!~(S{1I=+2oDyp!_w(khJM^ts}uEsB?<;f>sK=e1KSd%kE;TH?-Dj`30ra zADk_wKu>qb-nghAWOhev7GKlWeFSYCf+DvFac{s&_wgf2{Zai2`m;>vjn!aNlthg) zCKn2rc;9Unc z9(@GZ!97LB=$+mVb>9YZrmTNg Jjadbc=f)Q24w`K{=1u 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 - - - - - - - - - - - - - - - - - - - - - diff --git a/org.moflon.core.ui.packageregistration/src/org/moflon/core/ui/packageregistration/EmfRegistryManager.java b/org.moflon.core.ui.packageregistration/src/org/moflon/core/ui/packageregistration/EmfRegistryManager.java deleted file mode 100644 index d281179e..00000000 --- a/org.moflon.core.ui.packageregistration/src/org/moflon/core/ui/packageregistration/EmfRegistryManager.java +++ /dev/null @@ -1,166 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 The University of York. - * 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: - * Dimitrios Kolovos - initial API and implementation - ******************************************************************************/ -package org.moflon.core.ui.packageregistration; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EDataType; -import org.eclipse.emf.ecore.EEnum; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EPackage; -import org.eclipse.emf.ecore.EcorePackage; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; -import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; - -/** - * This class allows to register and manage EMF metamodels - * - * @author Roland Kluge - Initial implementation - * - */ -public class EmfRegistryManager { - private static EmfRegistryManager instance = null; - - private HashMap> managedMetamodels = new HashMap<>(); - - public static EmfRegistryManager getInstance() { - if (instance == null) { - instance = new EmfRegistryManager(); - } - return instance; - } - - public void registerMetamodel(String fileName) throws Exception { - List ePackages = register(URI.createPlatformResourceURI(fileName, true), EPackage.Registry.INSTANCE); - managedMetamodels.put(fileName, ePackages); - } - - // The following methods are taken from org.eclipse.epsilon.emc.emf.EmfUtil - - public static List register(URI uri, EPackage.Registry registry) throws Exception { - return register(uri, registry, true); - } - - /** - * Register all the packages in the metamodel specified by the uri in the - * registry. - * - * @param uri - * The URI of the metamodel - * @param registry - * The registry in which the metamodel's packages are registered - * @param useUriForResource - * If True, the URI of the resource created for the metamodel would - * be overwritten with the URI of the last EPackage in the metamodel. - * @return A list of the EPackages registered. - * @throws Exception - * If there is an error accessing the resources. - */ - public static List register(URI uri, EPackage.Registry registry, boolean useUriForResource) - throws Exception { - - List ePackages = new ArrayList(); - - initialiseResourceFactoryRegistry(); - - ResourceSet resourceSet = new ResourceSetImpl(); - resourceSet.getPackageRegistry().put(EcorePackage.eINSTANCE.getNsURI(), EcorePackage.eINSTANCE); - - Resource metamodel = resourceSet.createResource(uri); - metamodel.load(Collections.EMPTY_MAP); - - setDataTypesInstanceClasses(metamodel); - - Iterator it = metamodel.getAllContents(); - while (it.hasNext()) { - Object next = it.next(); - if (next instanceof EPackage) { - EPackage p = (EPackage) next; - - adjustNsAndPrefix(metamodel, p, useUriForResource); - registry.put(p.getNsURI(), p); - ePackages.add(p); - } - } - - return ePackages; - - } - - private static void initialiseResourceFactoryRegistry() { - final Map etfm = Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap(); - - if (!etfm.containsKey("*")) { - etfm.put("*", new XMIResourceFactoryImpl()); - } - - } - - private static void adjustNsAndPrefix(Resource metamodel, EPackage p, boolean useUriForResource) { - if (p.getNsURI() == null || p.getNsURI().trim().length() == 0) { - if (p.getESuperPackage() == null) { - p.setNsURI(p.getName()); - } else { - p.setNsURI(p.getESuperPackage().getNsURI() + "/" + p.getName()); - } - } - - if (p.getNsPrefix() == null || p.getNsPrefix().trim().length() == 0) { - if (p.getESuperPackage() != null) { - if (p.getESuperPackage().getNsPrefix() != null) { - p.setNsPrefix(p.getESuperPackage().getNsPrefix() + "." + p.getName()); - } else { - p.setNsPrefix(p.getName()); - } - } - } - - if (p.getNsPrefix() == null) - p.setNsPrefix(p.getName()); - if (useUriForResource) - metamodel.setURI(URI.createURI(p.getNsURI())); - } - - protected static void setDataTypesInstanceClasses(Resource metamodel) { - Iterator it = metamodel.getAllContents(); - while (it.hasNext()) { - EObject eObject = (EObject) it.next(); - if (eObject instanceof EEnum) { - // ((EEnum) eObject).setInstanceClassName("java.lang.Integer"); - } else if (eObject instanceof EDataType) { - EDataType eDataType = (EDataType) eObject; - String instanceClass = ""; - if (eDataType.getName().equals("String")) { - instanceClass = "java.lang.String"; - } else if (eDataType.getName().equals("Boolean")) { - instanceClass = "java.lang.Boolean"; - } else if (eDataType.getName().equals("Integer")) { - instanceClass = "java.lang.Integer"; - } else if (eDataType.getName().equals("Float")) { - instanceClass = "java.lang.Float"; - } else if (eDataType.getName().equals("Double")) { - instanceClass = "java.lang.Double"; - } - if (instanceClass.trim().length() > 0) { - eDataType.setInstanceClassName(instanceClass); - } - } - } - } -} diff --git a/org.moflon.core.ui.packageregistration/src/org/moflon/core/ui/packageregistration/RegisterMetamodelHandler.java b/org.moflon.core.ui.packageregistration/src/org/moflon/core/ui/packageregistration/RegisterMetamodelHandler.java deleted file mode 100644 index 7fa7eb1c..00000000 --- a/org.moflon.core.ui.packageregistration/src/org/moflon/core/ui/packageregistration/RegisterMetamodelHandler.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 The University of York. - * 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: - * Dimitrios Kolovos - initial API and implementation - ******************************************************************************/ -package org.moflon.core.ui.packageregistration; - -import java.util.Iterator; - -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IFile; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.handlers.HandlerUtil; -import org.moflon.core.ui.AbstractCommandHandler; - -/** - * This class provides the front-end capabilities for registering an EMF model. - * - * @author Dimitrios Kolovos - initial API and implementation - * @author Roland Kluge - Adjustment to eMoflon::Core - */ -public class RegisterMetamodelHandler extends AbstractCommandHandler { - - /** - * Invokes {@link #registerMetamodelInFile(IFile)} for each {@link IFile} in the selection - * @param event the event to handle - * @param {@link AbstractCommandHandler#DEFAULT_HANDLER_RESULT} - */ - @Override - public Object execute(final ExecutionEvent event) throws ExecutionException { - final ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); - - if (selection instanceof IStructuredSelection) { - final IStructuredSelection structuredSelection = (IStructuredSelection) selection; - final Iterator it = structuredSelection.iterator(); - while (it.hasNext()) { - final IFile file = (IFile) it.next(); - registerMetamodelInFile(file); - } - } - - return AbstractCommandHandler.DEFAULT_HANDLER_RESULT; - } - - /** - * Uses {@link EmfRegistryManager} to register the given {@link IFile} - * @param file the file to register - */ - private void registerMetamodelInFile(final IFile file) { - final String fileName = file.getFullPath().toOSString(); - try { - EmfRegistryManager.getInstance().registerMetamodel(fileName); - logger.info("Metamodel " + fileName + " registered successfully"); - } catch (final Exception ex) { - logger.error("Metamodel " + fileName + " could not be registered", ex); - } - } - -} diff --git a/org.moflon.git.ui/.classpath b/org.moflon.git.ui/.classpath deleted file mode 100644 index 4d23c295..00000000 --- a/org.moflon.git.ui/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/org.moflon.git.ui/.gitignore b/org.moflon.git.ui/.gitignore deleted file mode 100644 index ae3c1726..00000000 --- a/org.moflon.git.ui/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bin/ diff --git a/org.moflon.git.ui/.project b/org.moflon.git.ui/.project deleted file mode 100644 index 310025bc..00000000 --- a/org.moflon.git.ui/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.moflon.git.ui - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/org.moflon.git.ui/.settings/org.eclipse.jdt.core.prefs b/org.moflon.git.ui/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index e6819ed3..00000000 --- a/org.moflon.git.ui/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,10 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=16 -org.eclipse.jdt.core.compiler.compliance=16 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning -org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=16 diff --git a/org.moflon.git.ui/META-INF/MANIFEST.MF b/org.moflon.git.ui/META-INF/MANIFEST.MF deleted file mode 100644 index 827d6e8b..00000000 --- a/org.moflon.git.ui/META-INF/MANIFEST.MF +++ /dev/null @@ -1,17 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: eMoflon::Core Git tooling -Bundle-SymbolicName: org.moflon.git.ui;singleton:=true -Bundle-Version: 1.0.0.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-17 -Require-Bundle: org.eclipse.equinox.registry;bundle-version="3.6.100", - org.eclipse.ui.workbench;bundle-version="3.0.0", - org.eclipse.jface;bundle-version="3.0.0", - org.eclipse.jgit;bundle-version="4.0.0", - org.emoflon.core.dependencies;bundle-version="1.0.0", - org.moflon.core.ui;bundle-version="1.0.0", - org.moflon.core.utilities;bundle-version="3.0.0" -Bundle-Vendor: eMoflon developers -Automatic-Module-Name: org.moflon.git.ui -Export-Package: org.moflon.git, - org.moflon.git.ui.handler diff --git a/org.moflon.git.ui/build.properties b/org.moflon.git.ui/build.properties deleted file mode 100644 index 99a3f50c..00000000 --- a/org.moflon.git.ui/build.properties +++ /dev/null @@ -1,6 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - plugin.xml,\ - src/ diff --git a/org.moflon.git.ui/plugin.xml b/org.moflon.git.ui/plugin.xml deleted file mode 100644 index ba656d78..00000000 --- a/org.moflon.git.ui/plugin.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/org.moflon.git.ui/src/org/moflon/git/GitHelper.java b/org.moflon.git.ui/src/org/moflon/git/GitHelper.java deleted file mode 100644 index ce510430..00000000 --- a/org.moflon.git.ui/src/org/moflon/git/GitHelper.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.moflon.git; - -import java.io.File; -import java.io.IOException; - -import org.apache.log4j.Logger; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.jgit.api.CleanCommand; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.ResetCommand; -import org.eclipse.jgit.api.ResetCommand.ResetType; -import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.storage.file.FileRepositoryBuilder; -import org.moflon.core.utilities.LogUtils; -import org.moflon.core.utilities.ProgressMonitorUtil; -import org.moflon.core.utilities.UtilityClassNotInstantiableException; -import org.moflon.core.utilities.WorkspaceHelper;; - -/** - * Utility methods for working with Git - * - * @author Lars Fritsche - Initial implementation - * @author Roland Kluge - * - */ -public final class GitHelper { - private static final Logger logger = Logger.getLogger(GitHelper.class); - - private static final String GIT_FOLDER = "/.git"; - - /** - * Disabled constructor - */ - private GitHelper() { - throw new UtilityClassNotInstantiableException(); - } - - /** - * @param project - * the project to check - * @return true if the project is contained in a Git repository - */ - public static boolean isInGitRepository(final IProject project) { - return findGitRepositoryRoot(project) != null; - } - - /** - * Resets and cleans the given Git repository - * - * The repository should exist - * - * The effect of this method is equal to - * git reset --hard && git clean -fxd - * - * @param rep - * the repository to reset and clean - * @param monitor - * the monitor to be used - * @return the success or failure status - */ - public static IStatus resetAndCleanGitRepository(final Repository rep, final IProgressMonitor monitor) { - final SubMonitor subMon = SubMonitor.convert(monitor, "Resetting Git repository " + rep, 2); - final Git git = new Git(rep); - try { - final ResetCommand resetCmd = git.reset(); - resetCmd.setMode(ResetType.HARD); - - final CleanCommand cleanCmd = git.clean(); - cleanCmd.setCleanDirectories(true); - cleanCmd.setIgnore(false); - - try { - logger.debug("Resetting " + rep); - resetCmd.call(); - } catch (final Exception e) { - return new Status(IStatus.ERROR, WorkspaceHelper.getPluginId(GitHelper.class), - String.format("Failed to reset %s", rep), e); - } - subMon.worked(1); - ProgressMonitorUtil.checkCancellation(subMon); - - try { - logger.debug("Cleaning " + rep); - cleanCmd.call(); - } catch (final Exception e) { - return new Status(IStatus.ERROR, WorkspaceHelper.getPluginId(GitHelper.class), - String.format("Failed to clean %s", rep), e); - } - subMon.worked(1); - ProgressMonitorUtil.checkCancellation(subMon); - - LogUtils.info(logger, "Resetting and cleaning of %s successful", rep); - } finally { - git.close(); - } - - return Status.OK_STATUS; - } - - /** - * Retrieves the Git repository containing the given project. - * - * @param project - * the project - * @param multiStatus - * used to report problems - * @return the repository or null if the project is not inside a - * Git repository - */ - public static Repository findGitRepository(final IProject project, final MultiStatus multiStatus) { - final IPath pathToRepository = findGitRepositoryRoot(project); - - if (pathToRepository == null) { - multiStatus.add(new Status(IStatus.ERROR, WorkspaceHelper.getPluginId(GitHelper.class), - String.format("Not a git repository: %s", project.getLocation().makeAbsolute()))); - return null; - } - - final File gitFolder = new File(pathToRepository + GIT_FOLDER); - - try { - final Repository rep = FileRepositoryBuilder.create(gitFolder); - return rep; - } catch (final IOException e) { - multiStatus.add(new Status(IStatus.ERROR, WorkspaceHelper.getPluginId(GitHelper.class), - String.format("Exception while opening git repository in %s", gitFolder), e)); - return null; - } - } - - /** - * Finds the folder containing the Git metadata folder .git in the parents of - * the given project - * - * @param project - * the project - * @return the folder or null if no such folder exists - */ - private static IPath findGitRepositoryRoot(final IProject project) { - IPath pathToRepository = project.getLocation().makeAbsolute(); - { - File gitFolder = null; - do { - gitFolder = new File(pathToRepository + GIT_FOLDER); - - if (gitFolder.exists()) { - return pathToRepository; - } - - pathToRepository = pathToRepository.removeLastSegments(1); - } while (!pathToRepository.isRoot()); - } - return null; - } -} diff --git a/org.moflon.git.ui/src/org/moflon/git/ui/handler/GitResetProjectHandler.java b/org.moflon.git.ui/src/org/moflon/git/ui/handler/GitResetProjectHandler.java deleted file mode 100644 index 9187d1aa..00000000 --- a/org.moflon.git.ui/src/org/moflon/git/ui/handler/GitResetProjectHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.moflon.git.ui.handler; - -import java.util.Collection; - -import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.handlers.HandlerUtil; -import org.gervarro.eclipse.workspace.util.IWorkspaceTask; -import org.gervarro.eclipse.workspace.util.WorkspaceTaskJob; -import org.moflon.core.ui.AbstractCommandHandler; - -public class GitResetProjectHandler extends AbstractCommandHandler { - @Override - public Object execute(final ExecutionEvent event) throws ExecutionException { - final ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); - if (!(selection instanceof IStructuredSelection)) - return AbstractCommandHandler.DEFAULT_HANDLER_RESULT; - - final IStructuredSelection structuredSelection = (IStructuredSelection) selection; - - final Collection projects = AbstractCommandHandler.getProjectsFromSelection(structuredSelection); - - if (projects.size() == 0) { - MessageDialog.openInformation(null, "Selection must contain a project", - "You need at least one selection within your workspace to find the repository."); - return AbstractCommandHandler.DEFAULT_HANDLER_RESULT; - } - - if (!showWarningDialog()) - return null; - - final IWorkspaceTask task = new GitResetTask(projects); - final WorkspaceTaskJob job = new WorkspaceTaskJob(task); - job.setUser(true); - job.setRule(ResourcesPlugin.getWorkspace().getRoot()); - job.schedule(); - - return AbstractCommandHandler.DEFAULT_HANDLER_RESULT; - } - - private static boolean showWarningDialog() { - final boolean userHasConfirmed = MessageDialog.openConfirm(null, "Confirm reset", - "This will undo all changes and reset the project to HEAD. Proceed?"); - return userHasConfirmed; - } -} diff --git a/org.moflon.git.ui/src/org/moflon/git/ui/handler/GitResetTask.java b/org.moflon.git.ui/src/org/moflon/git/ui/handler/GitResetTask.java deleted file mode 100644 index 729e6c1f..00000000 --- a/org.moflon.git.ui/src/org/moflon/git/ui/handler/GitResetTask.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.moflon.git.ui.handler; - -import java.util.Collection; -import java.util.Set; -import java.util.stream.Collectors; - -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.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.jgit.lib.Repository; -import org.gervarro.eclipse.workspace.util.IWorkspaceTask; -import org.moflon.core.utilities.ProgressMonitorUtil; -import org.moflon.core.utilities.WorkspaceHelper; -import org.moflon.git.GitHelper; - -class GitResetTask implements IWorkspaceTask { - private final Collection projects; - - GitResetTask(Collection projects) { - this.projects = projects; - } - - @Override - public String getTaskName() { - return "Reset and clean Git repositories"; - } - - public ISchedulingRule getRule() { - return ResourcesPlugin.getWorkspace().getRoot(); - } - - @Override - public void run(final IProgressMonitor monitor) throws CoreException { - final SubMonitor subMon = SubMonitor.convert(monitor, "Resetting and cleaning Git repositories", - 2 * this.projects.size()); - final MultiStatus status = new MultiStatus(WorkspaceHelper.getPluginId(getClass()), 0, - "Problems during resetting and cleaning", null); - - final Set repositories = collectRepositories(status); - if (status.matches(IStatus.ERROR)) { - throw new CoreException(status); - } - - resetAndCleanRepositories(repositories, status, subMon.split(this.projects.size())); - if (status.matches(IStatus.ERROR)) { - throw new CoreException(status); - } - - for (final IProject project : this.projects) { - project.refreshLocal(IResource.DEPTH_INFINITE, subMon.split(1)); - } - } - - /** - * Resets and cleans all of the listed repositories - * - * @param repositories - * the repositories - * @param status - * used for collecting problems - * @param monitor - * the progress monitor - */ - private void resetAndCleanRepositories(final Set repositories, final MultiStatus status, - final IProgressMonitor monitor) { - final SubMonitor subMon = SubMonitor.convert(monitor, "Resetting and cleaning Git repositories", - repositories.size()); - for (final Repository repository : repositories) { - final IStatus resetStatus = GitHelper.resetAndCleanGitRepository(repository, subMon); - subMon.worked(1); - status.add(resetStatus); - ProgressMonitorUtil.checkCancellation(subMon); - } - } - - /** - * Retrieves the set of repositories that contain the configured projects - * - * @param status - * used for collection problems - * @return the list of repositories - */ - private Set collectRepositories(final MultiStatus status) { - return this.projects.stream().filter(GitHelper::isInGitRepository) - .map(project -> GitHelper.findGitRepository(project, status)).collect(Collectors.toSet()); - } -} \ No newline at end of file From 309b209004941fb09c3a57be1416412662b8c5fc Mon Sep 17 00:00:00 2001 From: SebastianE Date: Wed, 26 Oct 2022 14:46:48 +0200 Subject: [PATCH 04/23] added a color picker function to account for dark themes --- .../src/org/moflon/core/ui/MoflonConsole.java | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/org.moflon.core.ui/src/org/moflon/core/ui/MoflonConsole.java b/org.moflon.core.ui/src/org/moflon/core/ui/MoflonConsole.java index 6217c7f6..7347b3d9 100644 --- a/org.moflon.core.ui/src/org/moflon/core/ui/MoflonConsole.java +++ b/org.moflon.core.ui/src/org/moflon/core/ui/MoflonConsole.java @@ -5,12 +5,14 @@ import java.io.IOException; import java.net.URL; import java.util.Properties; +import java.util.function.Supplier; import org.apache.log4j.Level; import org.apache.log4j.PatternLayout; import org.apache.log4j.WriterAppender; import org.apache.log4j.spi.LoggingEvent; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; @@ -24,11 +26,17 @@ public class MoflonConsole extends WriterAppender { private static final String PATTERN_KEY = "log4j.appender." + MOFLON_CONSOLE + ".layout.ConversionPattern"; private static final String DEFAULT_PATTERN = "%5p [%c{2}::%L]: %m"; + private static final Color WHITE = new Color(Display.getDefault(), 255, 255, 255); + private static final Color BLACK = new Color(Display.getDefault(), 0, 0, 0); + private static final Color RED = new Color(Display.getDefault(), 255, 0, 0); + private static final Color BRIGHT_RED = new Color(Display.getDefault(), 252, 63, 63); private static final Color BLUE = new Color(Display.getDefault(), 0, 0, 128); + private static final Color LIGHT_BLUE = new Color(Display.getDefault(), 85, 85, 230); private static final Color YELLOW = new Color(Display.getDefault(), 239, 155, 15); + private static final Color BRIGHT_YELLOW = new Color(Display.getDefault(), 245, 191, 100); public MoflonConsole(final URL configFile) { Properties properties = new Properties(); @@ -60,45 +68,41 @@ private static MessageConsole findConsole(final String name) { /** * Prints a message on the MoflonConsole. * - * @param message - * The message to print. + * @param message The message to print. */ private static void printMessage(final String message) { - printMessage(message, null); + printMessage(message, () -> (calcBGLuminance() > 0.5) ? BLACK : WHITE); } /** * Prints a message in red on the MoflonConsole. * - * @param message - * The message to print. + * @param message The message to print. */ private static void printErrorMessage(final String message) { - printMessage(message, RED); + printMessage(message, () -> (calcBGLuminance() < 0.5) ? BRIGHT_RED : RED); } /** * Prints a message in blue on the MoflonConsole. * - * @param message - * The message to print. + * @param message The message to print. */ private static void printInfoMessage(final String message) { - printMessage(message, BLUE); + printMessage(message, () -> (calcBGLuminance() < 0.5) ? LIGHT_BLUE : BLUE); } /** * Prints a message on the MoflonConsole. * - * @param message - * The message to print. + * @param message The message to print. */ - private static synchronized void printMessage(final String message, final Color color) { + private static synchronized void printMessage(final String message, final Supplier color) { Display device = Display.getDefault(); device.asyncExec(new Runnable() { @Override public void run() { - _printMessage(message, color); + _printMessage(message, color.get()); } }); } @@ -147,6 +151,18 @@ else if (event.getLevel().equals(Level.INFO)) } private void printWarningMessage(final String message) { - printMessage(message, YELLOW); + printMessage(message, () -> (calcBGLuminance() < 0.5) ? BRIGHT_YELLOW : YELLOW); + } + + public static double calcBGLuminance() { + if (ConsolePlugin.getStandardDisplay().getActiveShell() == null) + return 0.0; + + Color col = ConsolePlugin.getStandardDisplay().getActiveShell().getBackground(); + if (col == null) + return 0.0; + + RGB rgb = col.getRGB(); + return (0.299 * rgb.red + 0.587 * rgb.green + 0.114 * rgb.blue) / 255; } } From 379b6582ada88e972ae5ff7582cab8f384ec3d75 Mon Sep 17 00:00:00 2001 From: SebastianE Date: Tue, 8 Nov 2022 15:57:28 +0100 Subject: [PATCH 05/23] code formatting --- .../emoflon/smartemf/SmartEMFGenerator.java | 66 +- .../smartemf/persistence/AdapterList.java | 12 +- .../smartemf/persistence/JDOMXmiUnparser.java | 523 +++-- .../persistence/PendingEMFCrossReference.java | 10 +- .../persistence/PendingXMLCrossReference.java | 27 +- .../SmartEMFResourceFactoryImpl.java | 1 + .../runtime/MinimalSObjectContainer.java | 35 +- .../emoflon/smartemf/runtime/SmartObject.java | 92 +- .../smartemf/runtime/SmartPackage.java | 13 +- .../smartemf/runtime/SmartPackageImpl.java | 219 +- .../collections/DefaultSmartEList.java | 28 +- .../runtime/collections/LinkedSmartESet.java | 16 +- .../ResourceContentSmartEList.java | 23 +- .../runtime/collections/SmartCollection.java | 13 +- .../runtime/collections/SmartEList.java | 3 +- .../runtime/collections/SmartESet.java | 10 +- .../notification/NotificationList.java | 10 +- .../runtime/notification/NotifyStatus.java | 4 +- .../notification/SmartContentAdapter.java | 20 +- .../SmartEMFCrossReferenceAdapter.java | 2058 ++++++++--------- .../notification/SmartEMFNotification.java | 38 +- .../smartemf/runtime/util/SmartEMFUtil.java | 9 +- .../smartemf/templates/CodeTemplate.java | 2 +- .../templates/util/CodeFormattingUtil.java | 4 +- .../smartemf/templates/util/JarExtractor.java | 156 +- .../smartemf/templates/util/Keywords.java | 18 +- 26 files changed, 1618 insertions(+), 1792 deletions(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/SmartEMFGenerator.java b/emfcodegenerator/src/org/emoflon/smartemf/SmartEMFGenerator.java index b2ef40ab..c32b3af6 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/SmartEMFGenerator.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/SmartEMFGenerator.java @@ -24,38 +24,38 @@ /** * Class which generates the code */ -public class SmartEMFGenerator{ +public class SmartEMFGenerator { + + /** ########################Attributes######################## */ - /**########################Attributes########################*/ - private String path; private Collection templates; private GenModel genModel; - /**########################Constructor########################*/ + /** ########################Constructor######################## */ /** * constructs a new EMFGenerator object + * * @param ePackage to build from * @param genmodel to build with - * @param path to the original Ecore of the corresponding project - */ + * @param path to the original Ecore of the corresponding project + */ public SmartEMFGenerator(IProject project, EPackage ePackage, GenModel genmodel) { String projectPath = project.getLocation().makeAbsolute().toString(); - + // if modeldirectory contains project name -> don't duplicate it - if(genmodel.getModelDirectory().contains(project.getName())) { + if (genmodel.getModelDirectory().contains(project.getName())) { File f = new File(projectPath); path = f.getParentFile().getAbsolutePath() + "/" + genmodel.getModelDirectory() + "/"; - } - else { - path = projectPath + "/" + genmodel.getModelDirectory()+ "/"; + } else { + path = projectPath + "/" + genmodel.getModelDirectory() + "/"; } templates = new LinkedList<>(); this.genModel = genmodel; - - for(GenPackage genPkg : getGenPackages(genmodel)){ + + for (GenPackage genPkg : getGenPackages(genmodel)) { initTemplates(genPkg); } } @@ -67,65 +67,65 @@ private void initTemplates(GenPackage genPkg) { initFactoryImplementation(genPkg); initSmartEMFInterfaces(genPkg); initSmartEMFImplementations(genPkg); - - for(GenPackage subPkg : genPkg.getSubGenPackages()) { + + for (GenPackage subPkg : genPkg.getSubGenPackages()) { initTemplates(subPkg); } } - + private Collection getGenPackages(GenModel genmodel) { Collection visited = new HashSet<>(); Collection unvisited = new HashSet<>(); unvisited.addAll(genmodel.getGenPackages()); - while(!unvisited.isEmpty()) { + while (!unvisited.isEmpty()) { GenPackage next = unvisited.iterator().next(); visited.add(next); unvisited.remove(next); - + unvisited.addAll(next.getSubGenPackages()); } return visited; } - + private void initPackageInterface(GenPackage genPkg) { PackageInterfaceTemplate creator = new PackageInterfaceTemplate(genPkg, path); templates.add(creator); - - for(org.eclipse.emf.ecore.EEnum eenum : TemplateUtil.getEEnums(genPkg)){ + + for (org.eclipse.emf.ecore.EEnum eenum : TemplateUtil.getEEnums(genPkg)) { EEnumTemplate eenum_creator = new EEnumTemplate(genPkg, eenum, path); templates.add(eenum_creator); } } - + private void initPackageImplementation(GenPackage genPkg) { PackageImplTemplate creator = new PackageImplTemplate(genPkg, path); templates.add(creator); } - + private void initFactoryInterface(GenPackage genPkg) { FactoryInterfaceTemplate creator = new FactoryInterfaceTemplate(genPkg, path); templates.add(creator); } - + private void initFactoryImplementation(GenPackage genPkg) { FactoryImplTemplate creator = new FactoryImplTemplate(genPkg, path); templates.add(creator); } - + private void initSmartEMFInterfaces(GenPackage genPkg) { - for(EClassifier classifier : genPkg.getEcorePackage().getEClassifiers()){ - if(classifier instanceof EClass eClass) { + for (EClassifier classifier : genPkg.getEcorePackage().getEClassifiers()) { + if (classifier instanceof EClass eClass) { SmartEMFInterfaceTemplate interfaceTemplate = new SmartEMFInterfaceTemplate(genPkg, eClass, path); - templates.add(interfaceTemplate); + templates.add(interfaceTemplate); } } - + } - + private void initSmartEMFImplementations(GenPackage genPkg) { - for(EClassifier classifier : genPkg.getEcorePackage().getEClassifiers()){ - if(classifier instanceof EClass eClass) { - if(eClass.isInterface()) { + for (EClassifier classifier : genPkg.getEcorePackage().getEClassifiers()) { + if (classifier instanceof EClass eClass) { + if (eClass.isInterface()) { continue; } SmartEMFObjectTemplate implTemplate = new SmartEMFObjectTemplate(genPkg, eClass, path); diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/AdapterList.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/AdapterList.java index 25fbd661..02304d9e 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/AdapterList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/AdapterList.java @@ -13,11 +13,11 @@ public class AdapterList implements EList { private Collection adapters = new LinkedHashSet<>(); private SmartEMFResource resource; - + public AdapterList(SmartEMFResource resource) { this.resource = resource; } - + @Override public int size() { return adapters.size(); @@ -50,7 +50,7 @@ public T[] toArray(T[] a) { @Override public boolean add(Adapter e) { - if(!adapters.contains(e)) { + if (!adapters.contains(e)) { boolean result = adapters.add(e); resource.adapterAdded(e); return result; @@ -75,7 +75,7 @@ public boolean containsAll(Collection c) { @Override public boolean addAll(Collection c) { boolean changed = false; - for(Adapter a : c) { + for (Adapter a : c) { changed = changed || add(a); } return changed; @@ -89,10 +89,10 @@ public boolean addAll(int index, Collection c) { @Override public boolean removeAll(Collection c) { boolean changed = false; - for(Object a : c) { + for (Object a : c) { boolean success = remove(a); changed = changed || success; - if(success) + if (success) resource.sendRemoveAdapterMessages((Adapter) a); } return changed; diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiUnparser.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiUnparser.java index 1f268271..bb609140 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiUnparser.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiUnparser.java @@ -26,305 +26,316 @@ public class JDOMXmiUnparser { - Map metamodel2NS = new HashMap<> (); - Map object2ID = new HashMap<>(); - Map>> waitingCrossRefs = new HashMap<>(); - - public void modelToJDOMTree(final Resource resource, final Document domTree) throws IOException { - // Create tree by traversing model - if(resource.getContents().size()> 1 || resource.getContents().size()< 1) { - Element root = new Element(XmiParserUtil.XMI_ROOT_NODE, XmiParserUtil.XMI_NS, XmiParserUtil.XMI_URI); - domTree.setRootElement(root); - - int idx = 0; - for(EObject container : resource.getContents()) { - root.getChildren().add(createDOMTree(container, container, null, "/"+idx, 0, false)); - idx++; - } - } else { - EObject container = resource.getContents().get(0); - domTree.setRootElement(createDOMTree(container, container, null, "/", 0, false)); + Map metamodel2NS = new HashMap<>(); + Map object2ID = new HashMap<>(); + Map>> waitingCrossRefs = new HashMap<>(); + + public void modelToJDOMTree(final Resource resource, final Document domTree) throws IOException { + // Create tree by traversing model + if (resource.getContents().size() > 1 || resource.getContents().size() < 1) { + Element root = new Element(XmiParserUtil.XMI_ROOT_NODE, XmiParserUtil.XMI_NS, XmiParserUtil.XMI_URI); + domTree.setRootElement(root); + + int idx = 0; + for (EObject container : resource.getContents()) { + root.getChildren().add(createDOMTree(container, container, null, "/" + idx, 0, false)); + idx++; } - - // Resolve unresolved Cross-Refs -> These are HRefs to foreign models - for(EObject href : waitingCrossRefs.keySet()) { - if(href.eResource() == resource) { - throw new IOException("Cross-reference to "+href+" could not be resolved during saving."); - } - - // Explore and index foreign model - if(!object2ID.containsKey(href)) { - indexForeignResource(href.eResource()); + } else { + EObject container = resource.getContents().get(0); + domTree.setRootElement(createDOMTree(container, container, null, "/", 0, false)); + } + + // Resolve unresolved Cross-Refs -> These are HRefs to foreign models + for (EObject href : waitingCrossRefs.keySet()) { + if (href.eResource() == resource) { + throw new IOException("Cross-reference to " + href + " could not be resolved during saving."); + } + + // Explore and index foreign model + if (!object2ID.containsKey(href)) { + indexForeignResource(href.eResource()); + } + + String foreignID = object2ID.get(href); + waitingCrossRefs.get(href).forEach(waiting -> waiting.accept(foreignID)); + } + + // Add default xmi namespaces and version attribute + if (resource.getContents().size() <= 1) { + Namespace xmiNS = Namespace.getNamespace(XmiParserUtil.XMI_NS, XmiParserUtil.XMI_URI); + domTree.getRootElement().addNamespaceDeclaration(xmiNS); + } + + Namespace xsiNS = Namespace.getNamespace(XmiParserUtil.XSI_NS, XmiParserUtil.XSI_URI); + domTree.getRootElement().addNamespaceDeclaration(xsiNS); + + for (EPackage pkg : metamodel2NS.keySet()) { + domTree.getRootElement().addNamespaceDeclaration(metamodel2NS.get(pkg)); + } + + domTree.getRootElement().getAttributes().add(new Attribute(XmiParserUtil.XMI_VERSION_ATR, + XmiParserUtil.XMI_VERSION, Namespace.getNamespace(XmiParserUtil.XMI_NS, XmiParserUtil.XMI_URI))); + } + + @SuppressWarnings("unchecked") + protected Element createDOMTree(EObject root, EObject currentEObject, EReference containment, String id, int idx, + boolean useSimple) throws IOException { + EClass currentClass = currentEObject.eClass(); + EPackage metamodel = currentClass.getEPackage(); + + Namespace ns = null; + if (!metamodel2NS.containsKey(metamodel)) { + ns = Namespace.getNamespace(metamodel.getName(), metamodel.getNsURI()); + metamodel2NS.put(metamodel, ns); + } else { + ns = metamodel2NS.get(metamodel); + } + + String currentId = id; + Element current = null; + if (containment != null) { + current = new Element(containment.getName()); + EPackage rootMetamodel = root.eClass().getEPackage(); + if (metamodel != rootMetamodel) { + current.getAttributes() + .add(new Attribute(XmiParserUtil.XSI_TYPE, + metamodel2NS.get(metamodel).getPrefix() + ":" + currentClass.getName(), + Namespace.getNamespace(XmiParserUtil.XSI_NS, XmiParserUtil.XSI_URI))); + } else { + // If the current object is a sub-type of the edge type then this must be + // defined in the xmi model + if (!containment.getEType().equals(currentEObject.eClass())) { + current.getAttributes() + .add(new Attribute(XmiParserUtil.XSI_TYPE, ns.getPrefix() + ":" + currentClass.getName(), + Namespace.getNamespace(XmiParserUtil.XSI_NS, XmiParserUtil.XSI_URI))); } - - String foreignID = object2ID.get(href); - waitingCrossRefs.get(href).forEach(waiting -> waiting.accept(foreignID)); } - - // Add default xmi namespaces and version attribute - if(resource.getContents().size() <= 1) { - Namespace xmiNS = Namespace.getNamespace(XmiParserUtil.XMI_NS, XmiParserUtil.XMI_URI); - domTree.getRootElement().addNamespaceDeclaration(xmiNS); + + // This a workaround for a useless/annoying xml simplification that occurs when + // a child list is exactly of size 1, then the index is omitted. + if (useSimple) { + currentId = id + "/@" + containment.getName(); + } else { + currentId = id + "/@" + containment.getName() + "." + idx; } - - Namespace xsiNS = Namespace.getNamespace(XmiParserUtil.XSI_NS, XmiParserUtil.XSI_URI); - domTree.getRootElement().addNamespaceDeclaration(xsiNS); - - for(EPackage pkg : metamodel2NS.keySet()) { - domTree.getRootElement().addNamespaceDeclaration(metamodel2NS.get(pkg)); + + } else { + current = new Element(currentClass.getName(), ns); + } + + object2ID.put(currentEObject, currentId); + if (waitingCrossRefs.containsKey(currentEObject)) { + for (Consumer consumer : waitingCrossRefs.get(currentEObject)) { + consumer.accept(currentId); } - - domTree.getRootElement().getAttributes().add(new Attribute(XmiParserUtil.XMI_VERSION_ATR, XmiParserUtil.XMI_VERSION, Namespace.getNamespace(XmiParserUtil.XMI_NS, XmiParserUtil.XMI_URI))); + waitingCrossRefs.remove(currentEObject); } - - @SuppressWarnings("unchecked") - protected Element createDOMTree(EObject root, EObject currentEObject, EReference containment, String id, int idx, boolean useSimple) throws IOException { - EClass currentClass = currentEObject.eClass(); - EPackage metamodel = currentClass.getEPackage(); - - Namespace ns = null; - if(!metamodel2NS.containsKey(metamodel)) { - ns = Namespace.getNamespace(metamodel.getName(), metamodel.getNsURI()); - metamodel2NS.put(metamodel, ns); + + // Containments + for (EReference containmentRef : currentClass.getEAllContainments()) { + List containees = new LinkedList<>(); + if (containmentRef.isMany()) { + containees.addAll((Collection) currentEObject.eGet(containmentRef)); } else { - ns = metamodel2NS.get(metamodel); + EObject containee = (EObject) currentEObject.eGet(containmentRef); + if (containee != null) + containees.add(containee); } - - String currentId = id; - Element current = null; - if(containment != null) { - current = new Element(containment.getName()); - EPackage rootMetamodel = root.eClass().getEPackage(); - if(metamodel != rootMetamodel) { - current.getAttributes().add(new Attribute(XmiParserUtil.XSI_TYPE, metamodel2NS.get(metamodel).getPrefix()+":"+currentClass.getName(), - Namespace.getNamespace(XmiParserUtil.XSI_NS, XmiParserUtil.XSI_URI))); - } else { - // If the current object is a sub-type of the edge type then this must be defined in the xmi model - if(!containment.getEType().equals(currentEObject.eClass())) { - current.getAttributes().add(new Attribute(XmiParserUtil.XSI_TYPE, ns.getPrefix()+":"+currentClass.getName(), - Namespace.getNamespace(XmiParserUtil.XSI_NS, XmiParserUtil.XSI_URI))); + int idIDX = 0; + for (EObject containee : containees) { + current.getChildren().add( + createDOMTree(root, containee, containmentRef, currentId, idIDX, !containmentRef.isMany())); + idIDX++; + } + } + + // Crossrefs + for (EReference crossRef : currentClass.getEAllReferences().stream().filter(ref -> !ref.isContainment()) + .filter(ref -> { + if (!(metamodel instanceof SmartPackage)) { + return true; + } else { + SmartPackage smartMetamodel = (SmartPackage) metamodel; + return !smartMetamodel.isDynamicEStructuralFeature(currentClass, ref); } - } - - // This a workaround for a useless/annoying xml simplification that occurs when a child list is exactly of size 1, then the index is omitted. - if(useSimple) { - currentId = id + "/@" + containment.getName(); - } else { - currentId = id + "/@" + containment.getName() + "." + idx; - } - + }).collect(Collectors.toList())) { + + LinkedList refs = new LinkedList<>(); + if (crossRef.isMany()) { + refs.addAll((Collection) currentEObject.eGet(crossRef)); } else { - current = new Element(currentClass.getName(), ns); - } - - object2ID.put(currentEObject, currentId); - if(waitingCrossRefs.containsKey(currentEObject)) { - for(Consumer consumer : waitingCrossRefs.get(currentEObject)) { - consumer.accept(currentId); - } - waitingCrossRefs.remove(currentEObject); + EObject currentRef = (EObject) currentEObject.eGet(crossRef); + if (currentRef != null) + refs.add(currentRef); } - - // Containments - for(EReference containmentRef : currentClass.getEAllContainments()) { - List containees = new LinkedList<>(); - if(containmentRef.isMany()) { - containees.addAll((Collection) currentEObject.eGet(containmentRef)); - } else { - EObject containee = (EObject) currentEObject.eGet(containmentRef); - if(containee != null) - containees.add(containee); - } - int idIDX = 0; - for(EObject containee : containees) { - current.getChildren().add(createDOMTree(root, containee, containmentRef, currentId, idIDX, !containmentRef.isMany())); - idIDX++; - } - } - - // Crossrefs - for(EReference crossRef : currentClass.getEAllReferences().stream() - .filter(ref -> !ref.isContainment()) - .filter(ref -> { - if(!(metamodel instanceof SmartPackage)) { - return true; - } else { - SmartPackage smartMetamodel = (SmartPackage) metamodel; - return !smartMetamodel.isDynamicEStructuralFeature(currentClass, ref); - } - }).collect(Collectors.toList())) { - - LinkedList refs = new LinkedList<>(); - if(crossRef.isMany()) { - refs.addAll((Collection) currentEObject.eGet(crossRef)); + if (refs.isEmpty()) + continue; + + Attribute refAtr = new Attribute(crossRef.getName(), ""); + PendingXMLCrossReference pendingCrossRefs = new PendingXMLCrossReference(current, refAtr, refs.size()); + if (refs.size() < 2) { + EObject refObj = refs.get(0); + // Ignore dangling references + if (refObj.eResource() == null) + continue; + + if (object2ID.containsKey(refObj)) { + pendingCrossRefs.insertID(object2ID.get(refObj), 0); } else { - EObject currentRef = (EObject) currentEObject.eGet(crossRef); - if(currentRef != null) - refs.add(currentRef); + // Remember this crossRef and wait for traversal + Set> otherPendingRefs = waitingCrossRefs.get(refObj); + if (otherPendingRefs == null) { + otherPendingRefs = new LinkedHashSet<>(); + waitingCrossRefs.put(refObj, otherPendingRefs); + } + + if (refObj.eResource() == currentEObject.eResource()) { + otherPendingRefs.add((crossRefID) -> { + pendingCrossRefs.insertID(crossRefID, 0); + if (pendingCrossRefs.isCompleted()) { + pendingCrossRefs.writeBack(); + } + }); + } else { + // this is reference to a foreign element -> href! + otherPendingRefs.add((crossRefID) -> { + pendingCrossRefs.insertID(crossRefID, 0); + EPackage otherMetamodel = refObj.eClass().getEPackage(); + if (!metamodel2NS.containsKey(otherMetamodel)) { + Namespace otherNS = Namespace.getNamespace(otherMetamodel.getName(), + otherMetamodel.getNsURI()); + metamodel2NS.put(otherMetamodel, otherNS); + } + if (otherMetamodel != metamodel) { + pendingCrossRefs.elementIsHref(true, 0, crossRef.getName(), + metamodel2NS.get(otherMetamodel).getPrefix() + ":" + refObj.eClass().getName()); + } else { + pendingCrossRefs.elementIsHref(true, 0, crossRef.getName(), null); + } + + if (pendingCrossRefs.isCompleted()) { + pendingCrossRefs.writeBack(); + } + }); + } + } - if(refs.isEmpty()) - continue; - - - Attribute refAtr = new Attribute(crossRef.getName(), ""); - PendingXMLCrossReference pendingCrossRefs = new PendingXMLCrossReference(current, refAtr, refs.size()); - if(refs.size()<2) { - EObject refObj = refs.get(0); - //Ignore dangling references - if(refObj.eResource() == null) + + } else if (refs.size() > 1) { + int crossRefIdx = 0; + for (EObject ref : refs) { + // Ignore dangling references + if (ref.eResource() == null) continue; - - if(object2ID.containsKey(refObj)) { - pendingCrossRefs.insertID(object2ID.get(refObj), 0); + + if (object2ID.containsKey(ref)) { + pendingCrossRefs.insertID(object2ID.get(ref), crossRefIdx); } else { // Remember this crossRef and wait for traversal - Set> otherPendingRefs = waitingCrossRefs.get(refObj); - if(otherPendingRefs == null) { + Set> otherPendingRefs = waitingCrossRefs.get(ref); + if (otherPendingRefs == null) { otherPendingRefs = new LinkedHashSet<>(); - waitingCrossRefs.put(refObj, otherPendingRefs); + waitingCrossRefs.put(ref, otherPendingRefs); } - - if(refObj.eResource() == currentEObject.eResource()) { + final int currentIdx = crossRefIdx; + + if (ref.eResource() == currentEObject.eResource()) { otherPendingRefs.add((crossRefID) -> { - pendingCrossRefs.insertID(crossRefID, 0); - if(pendingCrossRefs.isCompleted()) { + pendingCrossRefs.insertID(crossRefID, currentIdx); + if (pendingCrossRefs.isCompleted()) { pendingCrossRefs.writeBack(); } }); } else { // this is reference to a foreign element -> href! otherPendingRefs.add((crossRefID) -> { - pendingCrossRefs.insertID(crossRefID, 0); - EPackage otherMetamodel = refObj.eClass().getEPackage(); - if(!metamodel2NS.containsKey(otherMetamodel)) { - Namespace otherNS = Namespace.getNamespace(otherMetamodel.getName(), otherMetamodel.getNsURI()); + pendingCrossRefs.insertID(crossRefID, currentIdx); + EPackage otherMetamodel = ref.eClass().getEPackage(); + if (!metamodel2NS.containsKey(otherMetamodel)) { + Namespace otherNS = Namespace.getNamespace(otherMetamodel.getName(), + otherMetamodel.getNsURI()); metamodel2NS.put(otherMetamodel, otherNS); } - if(otherMetamodel != metamodel) { - pendingCrossRefs.elementIsHref(true, 0, crossRef.getName(), metamodel2NS.get(otherMetamodel).getPrefix()+":"+refObj.eClass().getName()); + if (otherMetamodel != metamodel) { + pendingCrossRefs.elementIsHref(true, currentIdx, crossRef.getName(), + metamodel2NS.get(otherMetamodel).getPrefix() + ":" + + ref.eClass().getName()); } else { - pendingCrossRefs.elementIsHref(true, 0, crossRef.getName(), null); + pendingCrossRefs.elementIsHref(true, currentIdx, crossRef.getName(), null); } - - if(pendingCrossRefs.isCompleted()) { + + if (pendingCrossRefs.isCompleted()) { pendingCrossRefs.writeBack(); } }); } - - } - - - } else if(refs.size()>1) { - int crossRefIdx = 0; - for(EObject ref : refs) { - //Ignore dangling references - if(ref.eResource() == null) - continue; - - if(object2ID.containsKey(ref)) { - pendingCrossRefs.insertID(object2ID.get(ref), crossRefIdx); - } else { - // Remember this crossRef and wait for traversal - Set> otherPendingRefs = waitingCrossRefs.get(ref); - if(otherPendingRefs == null) { - otherPendingRefs = new LinkedHashSet<>(); - waitingCrossRefs.put(ref, otherPendingRefs); - } - final int currentIdx = crossRefIdx; - - if(ref.eResource() == currentEObject.eResource()) { - otherPendingRefs.add((crossRefID) -> { - pendingCrossRefs.insertID(crossRefID, currentIdx); - if(pendingCrossRefs.isCompleted()) { - pendingCrossRefs.writeBack(); - } - }); - } else { - // this is reference to a foreign element -> href! - otherPendingRefs.add((crossRefID) -> { - pendingCrossRefs.insertID(crossRefID, currentIdx); - EPackage otherMetamodel = ref.eClass().getEPackage(); - if(!metamodel2NS.containsKey(otherMetamodel)) { - Namespace otherNS = Namespace.getNamespace(otherMetamodel.getName(), otherMetamodel.getNsURI()); - metamodel2NS.put(otherMetamodel, otherNS); - } - if(otherMetamodel != metamodel) { - pendingCrossRefs.elementIsHref(true, currentIdx, crossRef.getName(), metamodel2NS.get(otherMetamodel).getPrefix()+":"+ref.eClass().getName()); - } else { - pendingCrossRefs.elementIsHref(true, currentIdx, crossRef.getName(), null); - } - - if(pendingCrossRefs.isCompleted()) { - pendingCrossRefs.writeBack(); - } - }); - } - - } - crossRefIdx++; + } - + crossRefIdx++; } - - if(pendingCrossRefs.isCompleted()) - pendingCrossRefs.writeBack(); - + } - - // Attributes - for(EAttribute attribute : currentClass.getEAllAttributes()) { - String value = XmiParserUtil.valueToString(attribute, currentEObject.eGet(attribute)); - if(value == null) - continue; - - Attribute refAtr = new Attribute(attribute.getName(), value); - current.getAttributes().add(refAtr); + + if (pendingCrossRefs.isCompleted()) + pendingCrossRefs.writeBack(); + + } + + // Attributes + for (EAttribute attribute : currentClass.getEAllAttributes()) { + String value = XmiParserUtil.valueToString(attribute, currentEObject.eGet(attribute)); + if (value == null) + continue; + + Attribute refAtr = new Attribute(attribute.getName(), value); + current.getAttributes().add(refAtr); + } + return current; + } + + protected void indexForeignResource(final Resource resource) { + if (resource.getContents().size() < 2) { + indexForeignModel(resource.getContents().get(0), null, resource.getURI().toString() + "#/", 0, false); + } else { + int idx = 0; + for (EObject container : resource.getContents()) { + indexForeignModel(container, null, resource.getURI().toString() + "#/" + idx++, 0, false); } - return current; } - - protected void indexForeignResource(final Resource resource) { - if(resource.getContents().size() < 2) { - indexForeignModel(resource.getContents().get(0), null, resource.getURI().toString()+"#/", 0, false); + + } + + @SuppressWarnings("unchecked") + protected void indexForeignModel(final EObject root, final EReference containment, final String id, int idx, + boolean useSimple) { + EClass rootClass = root.eClass(); + String rootId = id; + if (containment != null) { + if (useSimple) { + rootId = id + "/@" + containment.getName(); } else { - int idx = 0; - for(EObject container : resource.getContents()) { - indexForeignModel(container, null, resource.getURI().toString()+"#/"+idx++, 0, false); - } + rootId = id + "/@" + containment.getName() + "." + idx; } - } - - @SuppressWarnings("unchecked") - protected void indexForeignModel(final EObject root, final EReference containment, final String id, int idx, boolean useSimple) { - EClass rootClass = root.eClass(); - String rootId = id; - if(containment != null) { - if(useSimple) { - rootId = id + "/@" + containment.getName(); - } else { - rootId = id + "/@" + containment.getName() + "." + idx; - } + object2ID.put(root, rootId); + + // Containments + for (EReference containmentRef : rootClass.getEAllContainments()) { + List containees = new LinkedList<>(); + if (containmentRef.isMany()) { + containees.addAll((Collection) root.eGet(containmentRef)); + } else { + EObject containee = (EObject) root.eGet(containmentRef); + if (containee != null) + containees.add(containee); } - object2ID.put(root, rootId); - - // Containments - for(EReference containmentRef : rootClass.getEAllContainments()) { - List containees = new LinkedList<>(); - if(containmentRef.isMany()) { - containees.addAll((Collection) root.eGet(containmentRef)); - } else { - EObject containee = (EObject) root.eGet(containmentRef); - if(containee != null) - containees.add(containee); - } - int idIDX = 0; - for(EObject containee : containees) { - indexForeignModel(containee, containmentRef, rootId, idIDX, !containmentRef.isMany()); - idIDX++; - } + int idIDX = 0; + for (EObject containee : containees) { + indexForeignModel(containee, containmentRef, rootId, idIDX, !containmentRef.isMany()); + idIDX++; } } + } } \ No newline at end of file diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/PendingEMFCrossReference.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/PendingEMFCrossReference.java index bd2f9cad..ab39c79d 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/PendingEMFCrossReference.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/PendingEMFCrossReference.java @@ -11,25 +11,25 @@ public class PendingEMFCrossReference { final private EReference reference; final private EObject[] crossRefs; private int insertedObjects = 0; - + public PendingEMFCrossReference(final EObject node, final EReference reference, int numOfRefs) { this.node = node; this.reference = reference; crossRefs = new EObject[numOfRefs]; } - + public void insertObject(final EObject ref, int idx) { crossRefs[idx] = ref; insertedObjects++; } - + public boolean isCompleted() { return insertedObjects == crossRefs.length; } - + @SuppressWarnings("unchecked") public void writeBack() { - if(reference.isMany()) { + if (reference.isMany()) { List refs = (List) node.eGet(reference); refs.addAll(Arrays.asList(crossRefs)); } else { diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/PendingXMLCrossReference.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/PendingXMLCrossReference.java index 398f4a3b..ead40353 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/PendingXMLCrossReference.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/PendingXMLCrossReference.java @@ -15,40 +15,41 @@ class PendingXMLCrossReference { final Map idx2name = new HashMap<>(); final Map idx2Type = new HashMap<>(); private int insertedIds = 0; - + public PendingXMLCrossReference(final Element element, final Attribute attribute, int numOfIds) { this.element = element; this.attribute = attribute; ids = new String[numOfIds]; isHref = new boolean[numOfIds]; } - + public void insertID(final String id, int idx) { ids[idx] = id; insertedIds++; } - + public void elementIsHref(boolean isHref, int idx, final String name, final String type) { this.isHref[idx] = isHref; idx2name.put(idx, name); - if(type != null) + if (type != null) idx2Type.put(idx, type); } - + public boolean isCompleted() { return insertedIds == ids.length; } - - public void writeBack() { + + public void writeBack() { StringBuilder sb = new StringBuilder(); - for(int i = 0; i eAdapters() { @Override /** - * returns whether message should be delivered, which is redirected to the containing resource + * returns whether message should be delivered, which is redirected to the + * containing resource */ public boolean eDeliver() { return eResource().eDeliver(); @@ -160,7 +161,8 @@ protected Object eDynamicGet(EStructuralFeature feature) { return null; } } else { - throw new RuntimeException("Feature <" + feature + "> is not present in objects of EClass <" + staticClass + ">"); + throw new RuntimeException( + "Feature <" + feature + "> is not present in objects of EClass <" + staticClass + ">"); } } } @@ -169,7 +171,8 @@ protected void eDynamicSet(EStructuralFeature feature, Object value) { Object oldValue = null; if (feature2Value.containsKey(feature)) { if (feature.isMany()) { - throw new RuntimeException("Feature <" + feature + "> represents a collection. Set can not be used on collection type attributes."); + throw new RuntimeException("Feature <" + feature + + "> represents a collection. Set can not be used on collection type attributes."); } else { oldValue = feature2Value.replace(feature, value); } @@ -177,13 +180,14 @@ protected void eDynamicSet(EStructuralFeature feature, Object value) { } else { if (staticPackage.isDynamicEStructuralFeature(staticClass, feature)) { if (feature.isMany()) { - throw new RuntimeException( - "Feature <" + feature + "> represents a collection. Set can not be used on collection type attributes."); + throw new RuntimeException("Feature <" + feature + + "> represents a collection. Set can not be used on collection type attributes."); } else { feature2Value.put(feature, value); } } else { - throw new RuntimeException("Feature <" + feature + "> is not present in objects of EClass <" + staticClass + ">"); + throw new RuntimeException( + "Feature <" + feature + "> is not present in objects of EClass <" + staticClass + ">"); } } @@ -236,7 +240,8 @@ protected void eDynamicUnset(EStructuralFeature feature) { feature2Value.put(feature, null); } } else { - throw new RuntimeException("Feature <" + feature + "> is not present in objects of EClass <" + staticClass + ">"); + throw new RuntimeException( + "Feature <" + feature + "> is not present in objects of EClass <" + staticClass + ">"); } } @@ -245,7 +250,8 @@ protected void eDynamicUnset(EStructuralFeature feature) { @SuppressWarnings("unchecked") protected void eDynamicInverseAdd(Object otherEnd, EStructuralFeature feature) { if (feature.isMany()) { - SmartCollection> list = (SmartCollection>) eGet(feature); + SmartCollection> list = (SmartCollection>) eGet( + feature); if (list.addInternal(otherEnd, false) == NotifyStatus.SUCCESS_NO_NOTIFICATION) { // sendNotification(SmartEMFNotification.createAddNotification(this, feature, otherEnd, -1)); } @@ -257,7 +263,8 @@ protected void eDynamicInverseAdd(Object otherEnd, EStructuralFeature feature) { @SuppressWarnings("unchecked") protected void eDynamicInverseRemove(Object otherEnd, EStructuralFeature feature) { if (feature.isMany()) { - SmartCollection> list = (SmartCollection>) eGet(feature); + SmartCollection> list = (SmartCollection>) eGet( + feature); list.removeInternal(otherEnd, false, true); } else { eUnset(feature); @@ -268,9 +275,9 @@ protected void eDynamicInverseRemove(Object otherEnd, EStructuralFeature feature public boolean eIsSet(EStructuralFeature feature) { Object obj = eGet(feature); if (feature.isMany()) { - if(obj instanceof Collection col) + if (obj instanceof Collection col) return !col.isEmpty(); - if(obj instanceof Map map) + if (obj instanceof Map map) return !map.isEmpty(); else throw new RuntimeException("Feature " + feature.getName() + " is neither a map nor a collection."); @@ -301,7 +308,8 @@ public EStructuralFeature eContainingFeature() { * @return status of execution and if a REMOVE notification was sent or not */ public NotifyStatus resetContainment() { - // if there is no eContainer, then this element is only contained within the resource and should be + // if there is no eContainer, then this element is only contained within the + // resource and should be // removed if (eContainer == null && resource != null) { resource.getContents().remove(this); @@ -317,14 +325,13 @@ public NotifyStatus resetContainment() { eContainer = null; eContainingFeature = null; - if(oldFeature.isMany()) { - if(((Collection) oldContainer.eGet(oldFeature)).remove(this)) { + if (oldFeature.isMany()) { + if (((Collection) oldContainer.eGet(oldFeature)).remove(this)) { return NotifyStatus.SUCCESS_NOTIFICATION_SEND; } else { return NotifyStatus.FAILURE_NO_NOTIFICATION; } - } - else { + } else { oldContainer.eUnset(oldFeature); } @@ -343,29 +350,31 @@ public NotifyStatus setContainment(EObject eContainer, EStructuralFeature featur NotifyStatus status = NotifyStatus.FAILURE_NO_NOTIFICATION; // clean up old containment - // we don't use resetContainment here to optimize the number of generated notifications + // we don't use resetContainment here to optimize the number of generated + // notifications if (this.eContainer != null) { if (eContainingFeature.isMany()) { // remove quietly if element is only moved within the same resource - if(eContainer != null && resource != null && resource.equals(eContainer.eResource())) - ((SmartCollection) this.eContainer.eGet(eContainingFeature)).removeWithoutContainerResetting(this); + if (eContainer != null && resource != null && resource.equals(eContainer.eResource())) + ((SmartCollection) this.eContainer.eGet(eContainingFeature)) + .removeWithoutContainerResetting(this); else - ((SmartCollection) this.eContainer.eGet(eContainingFeature)).remove(this); + ((SmartCollection) this.eContainer.eGet(eContainingFeature)).remove(this); } else { // remove quietly if element is only moved within the same resource - if(eContainer != null && resource != null && resource.equals(eContainer.eResource())) { + if (eContainer != null && resource != null && resource.equals(eContainer.eResource())) { Resource.Internal tmp = resource; resource = null; ((SmartObject) this.eContainer).eUnset(eContainingFeature); resource = tmp; - } - else { + } else { ((SmartObject) this.eContainer).eUnset(eContainingFeature); } } status = NotifyStatus.SUCCESS_NOTIFICATION_SEND; } else { - // if there is no eContainer, then this element is only contained within the resource and should be + // if there is no eContainer, then this element is only contained within the + // resource and should be // removed before setting the new eContainer if (resource != null) { resource.getContents().remove(this); @@ -399,13 +408,13 @@ protected void sendRemoveAdapterNotification(EObject obj) { } } } - + public void sendRemoveAdapterNotificationsRecursively(Adapter adapter) { adapter.notifyChanged(SmartEMFNotification.createRemovingAdapterNotification(this, null, adapter, -1)); - + setResourceOfContainments((o) -> o.sendRemoveAdapterNotificationsRecursively(adapter)); } - + public void setResourceWithoutChecks(Internal resource) { this.resource = resource; } @@ -419,7 +428,8 @@ public NotifyStatus setResource(Resource resource, boolean sendNotification) { return NotifyStatus.SUCCESS_NO_NOTIFICATION; // send remove messages to old adapters - // TODO lfritsche: should we optimize this and only do this if the adapters of both resources + // TODO lfritsche: should we optimize this and only do this if the adapters of + // both resources // differ? sendRemoveAdapterNotification(this); @@ -430,22 +440,26 @@ public NotifyStatus setResource(Resource resource, boolean sendNotification) { NotifyStatus status = NotifyStatus.SUCCESS_NO_NOTIFICATION; if (resource != null) { if (sendNotification) { - // if container is null, then this element is a root element within a resource and notifications are + // if container is null, then this element is a root element within a resource + // and notifications are // handled there if (eContainer() == null) { sendNotification(SmartEMFNotification.createAddNotification(resource, null, this, -1)); status = NotifyStatus.SUCCESS_NOTIFICATION_SEND; } else if (eContainingFeature().isMany()) { - sendNotification(SmartEMFNotification.createAddNotification(eContainer(), eContainingFeature(), this, -1)); + sendNotification( + SmartEMFNotification.createAddNotification(eContainer(), eContainingFeature(), this, -1)); status = NotifyStatus.SUCCESS_NOTIFICATION_SEND; } else { - sendNotification(SmartEMFNotification.createSetNotification(eContainer(), eContainingFeature(), null, this, -1)); + sendNotification(SmartEMFNotification.createSetNotification(eContainer(), eContainingFeature(), + null, this, -1)); status = NotifyStatus.SUCCESS_NOTIFICATION_SEND; } } - // if cascading is activated, we recursively generate add messages; else just this once + // if cascading is activated, we recursively generate add messages; else just + // this once SmartEMFResource smartResource = smartResource(); if (smartResource != null && smartResource.getCascade()) setResourceCall = (o) -> o.setResource(resource, true); @@ -467,10 +481,11 @@ public void setResourceSilently(Resource resource) { return; // send remove messages to old adapters - // TODO lfritsche: should we optimize this and only do this if the adapters of both resources + // TODO lfritsche: should we optimize this and only do this if the adapters of + // both resources // differ? sendRemoveAdapterNotification(this); - + this.resource = (Internal) resource; setResourceOfContainmentsSilently(resource); @@ -564,7 +579,8 @@ public NotificationChain eSetResource(Internal resource, NotificationChain notif } @Override - public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain notifications) { + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Class baseClass, + NotificationChain notifications) { return new NotificationChainImpl(); } @@ -573,13 +589,15 @@ public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Cl public abstract void eInverseRemove(Object otherEnd, EStructuralFeature feature); @Override - public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain notifications) { + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, + NotificationChain notifications) { throw new UnsupportedOperationException("Unsupported by SmartEMF"); } @Override - public NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID, NotificationChain notifications) { + public NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID, + NotificationChain notifications) { throw new UnsupportedOperationException("Unsupported by SmartEMF"); } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartPackage.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartPackage.java index d7195ae2..1b060c74 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartPackage.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartPackage.java @@ -8,15 +8,16 @@ import org.eclipse.emf.ecore.EStructuralFeature; public interface SmartPackage extends EPackage { - + public EStructuralFeature insertNewFeature(final EClass eClass, final EStructuralFeature eFeature); - + public boolean isDynamicEStructuralFeature(final EClass eClass, final EStructuralFeature eFeature); - + public boolean hasDynamicEStructuralFeatures(final EClass eClass); - + public Collection getDynamicEStructuralFeatures(final EClass eClass); - - public void registerDynamicFeatureUpdateCallback(final EClass eClass, final BiConsumer callback); + + public void registerDynamicFeatureUpdateCallback(final EClass eClass, + final BiConsumer callback); } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartPackageImpl.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartPackageImpl.java index 8d51e55a..7d43e6a0 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartPackageImpl.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartPackageImpl.java @@ -18,113 +18,117 @@ import org.eclipse.emf.ecore.impl.EReferenceImpl; public abstract class SmartPackageImpl extends EPackageImpl implements SmartPackage { - + private Map> dynamicFeatures = new HashMap<>(); private Map> subClassesInPackage = new HashMap<>(); private Map>> foreignSubClassCallbacks = new HashMap<>(); - public SmartPackageImpl(final String nsUri, final EFactory factory) { super(nsUri, factory); } - + @Override public EStructuralFeature insertNewFeature(final EClass eClass, final EStructuralFeature eFeature) { - if(!eContents().parallelStream().filter(obj -> (obj instanceof EClass)).filter(ecls -> eClass.equals(ecls)).findAny().isPresent()) { - throw new RuntimeException("EClass <"+eClass+"> is not present in the package <"+this+">"); + if (!eContents().parallelStream().filter(obj -> (obj instanceof EClass)).filter(ecls -> eClass.equals(ecls)) + .findAny().isPresent()) { + throw new RuntimeException("EClass <" + eClass + "> is not present in the package <" + this + ">"); } - - if(eFeature instanceof EReference) { - EReferenceImpl createdERef = (EReferenceImpl)ecoreFactory.createEReference(); + + if (eFeature instanceof EReference) { + EReferenceImpl createdERef = (EReferenceImpl) ecoreFactory.createEReference(); createdERef.setFeatureID(eClass.getEStructuralFeatures().size()); eClass.getEStructuralFeatures().add(createdERef); - - initEReference(createdERef, eFeature.getEType(), ((EReference) eFeature).getEOpposite(), eFeature.getName(), eFeature.getDefaultValueLiteral(), - eFeature.getLowerBound(), eFeature.getUpperBound(), eClass.getInstanceClass(), eFeature.isTransient(), eFeature.isVolatile(), eFeature.isChangeable(), - ((EReference) eFeature).isContainment(), ((EReference) eFeature).isResolveProxies(), eFeature.isUnsettable(), eFeature.isUnique(), eFeature.isDerived(), - eFeature.isOrdered()); - + + initEReference(createdERef, eFeature.getEType(), ((EReference) eFeature).getEOpposite(), eFeature.getName(), + eFeature.getDefaultValueLiteral(), eFeature.getLowerBound(), eFeature.getUpperBound(), + eClass.getInstanceClass(), eFeature.isTransient(), eFeature.isVolatile(), eFeature.isChangeable(), + ((EReference) eFeature).isContainment(), ((EReference) eFeature).isResolveProxies(), + eFeature.isUnsettable(), eFeature.isUnique(), eFeature.isDerived(), eFeature.isOrdered()); + insertClass2Feature(eClass, createdERef); getSubClassesInPackage(eClass).forEach(subClass -> { insertClass2Feature(subClass, createdERef); }); - - if(foreignSubClassCallbacks.containsKey(eClass)) { + + if (foreignSubClassCallbacks.containsKey(eClass)) { foreignSubClassCallbacks.get(eClass).forEach(callback -> callback.accept(eClass, createdERef)); } - + return createdERef; - } else if(eFeature instanceof EAttribute) { - EAttributeImpl createdEAtr = (EAttributeImpl)ecoreFactory.createEAttribute(); + } else if (eFeature instanceof EAttribute) { + EAttributeImpl createdEAtr = (EAttributeImpl) ecoreFactory.createEAttribute(); createdEAtr.setFeatureID(eClass.getEStructuralFeatures().size()); eClass.getEStructuralFeatures().add(createdEAtr); - - initEAttribute(createdEAtr, ((EAttribute)eFeature).getEType(), eFeature.getName(), eFeature.getDefaultValueLiteral(), eFeature.getLowerBound(), eFeature.getUpperBound(), - eClass.getInstanceClass(), createdEAtr.isTransient(), createdEAtr.isVolatile(), createdEAtr.isChangeable(), createdEAtr.isUnsettable(), createdEAtr.isID(), createdEAtr.isUnique(), + + initEAttribute(createdEAtr, ((EAttribute) eFeature).getEType(), eFeature.getName(), + eFeature.getDefaultValueLiteral(), eFeature.getLowerBound(), eFeature.getUpperBound(), + eClass.getInstanceClass(), createdEAtr.isTransient(), createdEAtr.isVolatile(), + createdEAtr.isChangeable(), createdEAtr.isUnsettable(), createdEAtr.isID(), createdEAtr.isUnique(), createdEAtr.isDerived(), createdEAtr.isOrdered()); - + insertClass2Feature(eClass, createdEAtr); getSubClassesInPackage(eClass).forEach(subClass -> { insertClass2Feature(subClass, createdEAtr); }); - - if(foreignSubClassCallbacks.containsKey(eClass)) { + + if (foreignSubClassCallbacks.containsKey(eClass)) { foreignSubClassCallbacks.get(eClass).forEach(callback -> callback.accept(eClass, createdEAtr)); } - + return createdEAtr; } else { - throw new RuntimeException("Unsupported EStructuralFeature type: "+eFeature); + throw new RuntimeException("Unsupported EStructuralFeature type: " + eFeature); } } - + @Override public boolean isDynamicEStructuralFeature(final EClass eClass, final EStructuralFeature eFeature) { - if(!dynamicFeatures.containsKey(eClass)) + if (!dynamicFeatures.containsKey(eClass)) return false; - + return dynamicFeatures.get(eClass).contains(eFeature); - + } - + @Override public boolean hasDynamicEStructuralFeatures(final EClass eClass) { - if(!dynamicFeatures.containsKey(eClass)) + if (!dynamicFeatures.containsKey(eClass)) return false; - + return true; } - + @Override public Collection getDynamicEStructuralFeatures(final EClass eClass) { - if(!dynamicFeatures.containsKey(eClass)) + if (!dynamicFeatures.containsKey(eClass)) return new HashSet<>(); - + return dynamicFeatures.get(eClass); } - + @Override - public void registerDynamicFeatureUpdateCallback(final EClass eClass, final BiConsumer callback) { + public void registerDynamicFeatureUpdateCallback(final EClass eClass, + final BiConsumer callback) { Set> currentCallbacks = foreignSubClassCallbacks.get(eClass); - if(currentCallbacks == null) { + if (currentCallbacks == null) { currentCallbacks = new HashSet<>(); foreignSubClassCallbacks.put(eClass, currentCallbacks); } currentCallbacks.add(callback); } - + protected void injectExternalReferences() { // Insert own features Collection externalRefs = getExternalUnidirectionalReferences(); - for(EReference ref : externalRefs) { - if(! (ref.getEType().getEPackage() instanceof SmartPackage)) + for (EReference ref : externalRefs) { + if (!(ref.getEType().getEPackage() instanceof SmartPackage)) continue; - - SmartPackage foreignPackage = (SmartPackage)ref.getEType().getEPackage(); - - EReferenceImpl inverse = (EReferenceImpl)ecoreFactory.createEReference(); - inverse.setName(ref.getName()+"_inverseTo_"+getName()); + + SmartPackage foreignPackage = (SmartPackage) ref.getEType().getEPackage(); + + EReferenceImpl inverse = (EReferenceImpl) ecoreFactory.createEReference(); + inverse.setName(ref.getName() + "_inverseTo_" + getName()); inverse.setEType(ref.getEContainingClass()); inverse.setEOpposite(ref); inverse.setLowerBound(0); @@ -138,19 +142,19 @@ protected void injectExternalReferences() { inverse.setUnique(ref.isUnique()); inverse.setDerived(ref.isDerived()); inverse.setOrdered(ref.isOrdered()); - + EReference trueInverse = (EReference) foreignPackage.insertNewFeature((EClass) ref.getEType(), inverse); ref.setEOpposite(trueInverse); } } - + protected void injectDynamicOpposites() { // Insert own features Collection internalRefs = getInternalUnidirectionalReferences(); - for(EReference ref : internalRefs) { - - EReferenceImpl inverse = (EReferenceImpl)ecoreFactory.createEReference(); - inverse.setName(ref.getName()+"_inverseTo_"+getName()); + for (EReference ref : internalRefs) { + + EReferenceImpl inverse = (EReferenceImpl) ecoreFactory.createEReference(); + inverse.setName(ref.getName() + "_inverseTo_" + getName()); inverse.setEType(ref.getEContainingClass()); inverse.setEOpposite(ref); inverse.setLowerBound(0); @@ -164,103 +168,92 @@ protected void injectDynamicOpposites() { inverse.setUnique(ref.isUnique()); inverse.setDerived(ref.isDerived()); inverse.setOrdered(ref.isOrdered()); - + EReference trueInverse = (EReference) insertNewFeature((EClass) ref.getEType(), inverse); ref.setEOpposite(trueInverse); } } - + protected void fetchDynamicEStructuralFeaturesOfSuperTypes() { // Update dynamic feature collection with dynamic features from super classes - Set ownClasses = eContents().parallelStream() - .filter(obj->(obj instanceof EClass)) - .map(ecls -> (EClass)ecls) - .collect(Collectors.toSet()); - - for(EClass ownClass : ownClasses) { - for(EClass foreignSuperClass : ownClass.getEAllSuperTypes().stream() - .filter(ecls -> (ecls instanceof EClass)) - .map(ecls -> (EClass)ecls) - .filter(ecls -> ecls.eContainer()!=this && (ecls.eContainer() instanceof SmartPackage)) + Set ownClasses = eContents().parallelStream().filter(obj -> (obj instanceof EClass)) + .map(ecls -> (EClass) ecls).collect(Collectors.toSet()); + + for (EClass ownClass : ownClasses) { + for (EClass foreignSuperClass : ownClass.getEAllSuperTypes().stream() + .filter(ecls -> (ecls instanceof EClass)).map(ecls -> (EClass) ecls) + .filter(ecls -> ecls.eContainer() != this && (ecls.eContainer() instanceof SmartPackage)) .collect(Collectors.toSet())) { - SmartPackage otherPkg = (SmartPackage)foreignSuperClass.eContainer(); - // Register a callback -> super classes might be subject to change during runtime + SmartPackage otherPkg = (SmartPackage) foreignSuperClass.eContainer(); + // Register a callback -> super classes might be subject to change during + // runtime otherPkg.registerDynamicFeatureUpdateCallback(foreignSuperClass, this::insertFeatureOfSuperType); - - if(!otherPkg.hasDynamicEStructuralFeatures(foreignSuperClass)) + + if (!otherPkg.hasDynamicEStructuralFeatures(foreignSuperClass)) continue; - - otherPkg.getDynamicEStructuralFeatures(foreignSuperClass).forEach(feature -> insertClass2Feature(ownClass, feature)); + + otherPkg.getDynamicEStructuralFeatures(foreignSuperClass) + .forEach(feature -> insertClass2Feature(ownClass, feature)); } } } - + protected Collection getExternalUnidirectionalReferences() { - Set ownClasses = eContents().parallelStream().filter(obj->(obj instanceof EClass)).map(ecls -> (EClass)ecls).collect(Collectors.toSet()); + Set ownClasses = eContents().parallelStream().filter(obj -> (obj instanceof EClass)) + .map(ecls -> (EClass) ecls).collect(Collectors.toSet()); // Find all references that point to EClasses not defined in this package. - return eContents().parallelStream() - .filter(obj->(obj instanceof EClass)) - .map(ecls -> (EClass)ecls) - .flatMap(ecls -> ecls.getEAllStructuralFeatures().parallelStream()) - .filter(ref -> (ref instanceof EReference)) - .map(ref -> (EReference) ref) - .filter(ref -> ref.getEOpposite() == null) - .filter(ref -> !ownClasses.contains(ref.getEType())) - .filter(ref -> !ref.isContainment()) - .collect(Collectors.toSet()); + return eContents().parallelStream().filter(obj -> (obj instanceof EClass)).map(ecls -> (EClass) ecls) + .flatMap(ecls -> ecls.getEAllStructuralFeatures().parallelStream()) + .filter(ref -> (ref instanceof EReference)).map(ref -> (EReference) ref) + .filter(ref -> ref.getEOpposite() == null).filter(ref -> !ownClasses.contains(ref.getEType())) + .filter(ref -> !ref.isContainment()).collect(Collectors.toSet()); } - + protected Collection getInternalUnidirectionalReferences() { - Set ownClasses = eContents().parallelStream().filter(obj->(obj instanceof EClass)).map(ecls -> (EClass)ecls).collect(Collectors.toSet()); + Set ownClasses = eContents().parallelStream().filter(obj -> (obj instanceof EClass)) + .map(ecls -> (EClass) ecls).collect(Collectors.toSet()); // Find all references that point to EClasses defined in this package. - return eContents().parallelStream() - .filter(obj->(obj instanceof EClass)) - .map(ecls -> (EClass)ecls) - .flatMap(ecls -> ecls.getEAllStructuralFeatures().parallelStream()) - .filter(ref -> (ref instanceof EReference)) - .map(ref -> (EReference) ref) - .filter(ref -> ref.getEOpposite() == null) - .filter(ref -> ownClasses.contains(ref.getEType())) - .filter(ref -> !ref.isContainment()) - .collect(Collectors.toSet()); + return eContents().parallelStream().filter(obj -> (obj instanceof EClass)).map(ecls -> (EClass) ecls) + .flatMap(ecls -> ecls.getEAllStructuralFeatures().parallelStream()) + .filter(ref -> (ref instanceof EReference)).map(ref -> (EReference) ref) + .filter(ref -> ref.getEOpposite() == null).filter(ref -> ownClasses.contains(ref.getEType())) + .filter(ref -> !ref.isContainment()).collect(Collectors.toSet()); } - + private void insertClass2Feature(final EClass eClass, final EStructuralFeature eFeature) { Set currentFeatures = dynamicFeatures.get(eClass); - if(currentFeatures == null) { + if (currentFeatures == null) { currentFeatures = new HashSet<>(); dynamicFeatures.put(eClass, currentFeatures); } currentFeatures.add(eFeature); } - + private void insertFeatureOfSuperType(final EClass superClass, final EStructuralFeature eFeature) { - Set subClasses = eContents().parallelStream() - .filter(obj->(obj instanceof EClass)) - .map(ecls -> (EClass)ecls) - .filter(ecls -> ecls.getEAllSuperTypes().contains(superClass)) + Set subClasses = eContents().parallelStream().filter(obj -> (obj instanceof EClass)) + .map(ecls -> (EClass) ecls).filter(ecls -> ecls.getEAllSuperTypes().contains(superClass)) .collect(Collectors.toSet()); - - for(EClass subClass : subClasses) { + + for (EClass subClass : subClasses) { insertClass2Feature(subClass, eFeature); } - + } - + protected Set getSubClassesInPackage(final EClass eClass) { - if(subClassesInPackage.containsKey(eClass)) + if (subClassesInPackage.containsKey(eClass)) return subClassesInPackage.get(eClass); - + Set subClasses = new HashSet<>(); subClassesInPackage.put(eClass, subClasses); - - for(EClass someClass : eContents().stream().filter(obj->(obj instanceof EClass)).map(ecls -> (EClass)ecls).filter(ecls -> ecls != eClass).collect(Collectors.toSet())) { - if(someClass.getEAllSuperTypes().contains(eClass)) { + + for (EClass someClass : eContents().stream().filter(obj -> (obj instanceof EClass)).map(ecls -> (EClass) ecls) + .filter(ecls -> ecls != eClass).collect(Collectors.toSet())) { + if (someClass.getEAllSuperTypes().contains(eClass)) { subClasses.add(someClass); } } return subClasses; } - } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/DefaultSmartEList.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/DefaultSmartEList.java index 4d538926..fb186f81 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/DefaultSmartEList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/DefaultSmartEList.java @@ -20,15 +20,15 @@ public final class DefaultSmartEList extends LinkedList implements EList, InternalEList { private EStructuralFeature feature = null; - + public DefaultSmartEList() { - + } - + public DefaultSmartEList(EStructuralFeature feature) { this.feature = feature; } - + /** * */ @@ -38,42 +38,42 @@ public DefaultSmartEList(EStructuralFeature feature) { public boolean add(T e) { return super.add(e); } - + @Override public void add(int index, T element) { super.add(index, element); } - + @Override public boolean addAll(Collection c) { return super.addAll(c); } - + @Override public boolean addAll(int index, Collection c) { return super.addAll(index, c); } - + @Override public void clear() { super.clear(); } - + @Override public T remove(int index) { return super.remove(index); } - + @Override public boolean remove(Object o) { return super.remove(o); } - + @Override public boolean removeAll(Collection c) { return super.removeAll(c); } - + @Override public T basicGet(int index) { return get(index); @@ -83,7 +83,7 @@ public T basicGet(int index) { public List basicList() { return this; } - + @Override public Iterator iterator() { return basicIterator(); @@ -93,7 +93,7 @@ public Iterator iterator() { public Iterator basicIterator() { Iterator listIterator = super.iterator(); Iterator featureIterator = new EContentsEList.FeatureIterator() { - + @Override public boolean hasNext() { return listIterator.hasNext(); diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/LinkedSmartESet.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/LinkedSmartESet.java index 8a02f2af..c1d34e05 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/LinkedSmartESet.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/LinkedSmartESet.java @@ -22,7 +22,7 @@ public LinkedSmartESet(EObject eContainer, EReference feature) { protected void initializeCollection(EObject eContainer, EReference feature) { elements = new LinkedHashSet(); } - + @Override public T basicGet(int index) { return get(index); @@ -105,17 +105,19 @@ public ReplacingIterator replacingIterator() { @Override public void replace(T element) { if (iteratorIndex <= 0) - throw new NoSuchElementException("There is no last element to replace! Please call method next(), first!"); + throw new NoSuchElementException( + "There is no last element to replace! Please call method next(), first!"); elements.remove(copiedElements[iteratorIndex - 1]); - // since this SmartCollection behaves like a set, we do not have to insert the new element at the + // since this SmartCollection behaves like a set, we do not have to insert the + // new element at the // same position as the removed one elements.add(element); } }; } - + // Unsupported EList operations - + @Override public void move(int newPosition, T object) { throw new UnsupportedOperationException("Not supported for Sets"); @@ -161,7 +163,7 @@ public ListIterator listIterator(int index) { public List subList(int fromIndex, int toIndex) { throw new UnsupportedOperationException("Not supported for Sets"); } - + @Override public NotificationChain basicRemove(Object object, NotificationChain notifications) { throw new UnsupportedOperationException("Not supported for SmartESets"); @@ -171,7 +173,7 @@ public NotificationChain basicRemove(Object object, NotificationChain notificati public NotificationChain basicAdd(T object, NotificationChain notifications) { throw new UnsupportedOperationException("Not supported for SmartESets"); } - + @Override public T setUnique(int index, T object) { throw new UnsupportedOperationException("Not supported for SmartESets"); diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java index 321cd5d6..c2b3a374 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java @@ -19,7 +19,8 @@ import org.emoflon.smartemf.runtime.SmartObject; import org.emoflon.smartemf.runtime.notification.SmartEMFNotification; -public final class ResourceContentSmartEList extends LinkedHashSet implements EList, InternalEList { +public final class ResourceContentSmartEList extends LinkedHashSet + implements EList, InternalEList { /** * @@ -98,15 +99,14 @@ private void resetContainment(T e, boolean removeRecursively) { if (oldContainer != null) { if (e.eContainingFeature().isMany()) { Object getResult = oldContainer.eGet(e.eContainingFeature()); - if(removeRecursively) + if (removeRecursively) ((SmartCollection) getResult).remove(e); else ((SmartCollection) getResult).removeWithoutContainerResetting(e); } else { - if(removeRecursively) { + if (removeRecursively) { oldContainer.eUnset(e.eContainingFeature()); - } - else { + } else { Resource tmp = e.eResource(); ((SmartObject) e).setResourceWithoutChecks(null); oldContainer.eUnset(e.eContainingFeature()); @@ -115,7 +115,8 @@ private void resetContainment(T e, boolean removeRecursively) { } } } else { - // if there is no eContainer, then this element is only contained within the resource and should be removed before setting the new eContainer + // if there is no eContainer, then this element is only contained within the + // resource and should be removed before setting the new eContainer if (e.eResource() != null) { e.eResource().getContents().remove(e); } @@ -174,7 +175,7 @@ public boolean removeAll(Collection c) { Collection objs = new LinkedList<>(c); for (Object t : objs) - success = this.remove(t) || success; + success = this.remove(t) || success; return success; } @@ -317,8 +318,8 @@ protected void sendNotifications(NotificationChain notificationChain) { @Override public T get(int index) { int counter = 0; - for(T t : this) { - if(counter == index) + for (T t : this) { + if (counter == index) return t; counter++; } @@ -333,8 +334,8 @@ public T set(int index, T element) { @Override public int indexOf(Object o) { int counter = 0; - for(T t : this) { - if(t.equals(o)) { + for (T t : this) { + if (t.equals(o)) { return counter; } counter++; diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartCollection.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartCollection.java index 8e3b3d64..b305148c 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartCollection.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartCollection.java @@ -28,7 +28,7 @@ public SmartCollection(EObject eContainer, EReference feature, boolean sendNotif this(eContainer, feature); this.sendNotifications = sendNotifications; } - + public SmartCollection(EObject eContainer, EReference feature) { this.eContainer = eContainer; this.feature = feature; @@ -122,7 +122,8 @@ public boolean addAll(Collection c) { status = addStatus; } - // if feature is containment then set resource should have sent this notification already + // if feature is containment then set resource should have sent this + // notification already if (!feature.isContainment()) sendNotification(SmartEMFNotification.createAddManyNotification(eContainer, feature, newList, 0)); @@ -139,7 +140,6 @@ public NotifyStatus removeWithoutContainerResetting(Object o) { return NotifyStatus.SUCCESS_NOTIFICATION_SEND; } - /** * Returns status of execution and if a REMOVE notification was sent or not */ @@ -237,12 +237,13 @@ public boolean retainAll(Collection c) { } protected void sendNotification(Notification n) { - // if the feature is a containment, then notifications are handled when setting the resource + // if the feature is a containment, then notifications are handled when setting + // the resource // if(feature.isContainment()) // return; - if(!sendNotifications) + if (!sendNotifications) return; - + Resource r = eContainer.eResource(); if (r != null) { for (Adapter a : r.eAdapters()) { diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartEList.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartEList.java index 3524ba0b..77ff8ee6 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartEList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartEList.java @@ -198,7 +198,8 @@ public ReplacingIterator replacingIterator() { @Override public void replace(T element) { if (iteratorIndex <= 0) - throw new NoSuchElementException("There is no last element to replace! Please call method next(), first!"); + throw new NoSuchElementException( + "There is no last element to replace! Please call method next(), first!"); elements.set(iteratorIndex - 1, element); } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartESet.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartESet.java index 8919231e..28026c01 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartESet.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartESet.java @@ -16,9 +16,9 @@ public class SmartESet extends SmartCollection> { public SmartESet(EObject eContainer, EReference feature, boolean sendNotifications) { - super(eContainer, feature, sendNotifications); + super(eContainer, feature, sendNotifications); } - + public SmartESet(EObject eContainer, EReference feature) { super(eContainer, feature); } @@ -170,9 +170,11 @@ public ReplacingIterator replacingIterator() { @Override public void replace(T element) { if (iteratorIndex <= 0) - throw new NoSuchElementException("There is no last element to replace! Please call method next(), first!"); + throw new NoSuchElementException( + "There is no last element to replace! Please call method next(), first!"); elements.remove(copiedElements[iteratorIndex - 1]); - // since this SmartCollection behaves like a set, we do not have to insert the new element at the + // since this SmartCollection behaves like a set, we do not have to insert the + // new element at the // same position as the removed one elements.add(element); } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/NotificationList.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/NotificationList.java index a226b995..ed7bbc61 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/NotificationList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/NotificationList.java @@ -7,7 +7,9 @@ import org.eclipse.emf.common.notify.Notifier; /** - * This class implements the {@link NotificationChain} interface. It is used to collect notifications without immediately merging them. + * This class implements the {@link NotificationChain} interface. It is used to + * collect notifications without immediately merging them. + * * @author paulschiffner */ public class NotificationList extends LinkedList implements NotificationChain { @@ -20,18 +22,18 @@ public NotificationList(Iterable notifications) { add(n); } } - + public NotificationList(Notification... notifications) { super(); for (Notification n : notifications) { add(n); } } - + @Override public void dispatch() { for (Notification n : this) { - Notifier notifier = (Notifier)(n.getNotifier()); + Notifier notifier = (Notifier) (n.getNotifier()); notifier.eNotify(n); } } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/NotifyStatus.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/NotifyStatus.java index bc4bc282..9a3f2b76 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/NotifyStatus.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/NotifyStatus.java @@ -3,8 +3,8 @@ public enum NotifyStatus { SUCCESS_NO_NOTIFICATION, - + SUCCESS_NOTIFICATION_SEND, - + FAILURE_NO_NOTIFICATION } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartContentAdapter.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartContentAdapter.java index 41b7490e..ee2b873e 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartContentAdapter.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartContentAdapter.java @@ -8,17 +8,15 @@ import org.eclipse.emf.ecore.util.EContentAdapter; public class SmartContentAdapter extends EContentAdapter { - + @Override - protected void unsetTarget(Resource target) - { - basicUnsetTarget(target); - List contents = target.getContents(); - for (EObject e : contents) - { - Notifier notifier = e; - removeAdapter(notifier, true, false); - } - } + protected void unsetTarget(Resource target) { + basicUnsetTarget(target); + List contents = target.getContents(); + for (EObject e : contents) { + Notifier notifier = e; + removeAdapter(notifier, true, false); + } + } } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFCrossReferenceAdapter.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFCrossReferenceAdapter.java index 429f71e6..f8623fc9 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFCrossReferenceAdapter.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFCrossReferenceAdapter.java @@ -30,1152 +30,922 @@ import org.eclipse.emf.ecore.util.InternalEList; import org.eclipse.emf.ecore.util.EContentsEList.FeatureIterator; - /** - * This reference adapter is mostly a copy of the original ECrossReferenceAdapter but without expensive get calls to the underlying resource + * This reference adapter is mostly a copy of the original + * ECrossReferenceAdapter but without expensive get calls to the underlying + * resource + * * @author Lars * */ -public class SmartEMFCrossReferenceAdapter implements Adapter.Internal -{ - /** - * Returns the first {@link ECrossReferenceAdapter} in the notifier's {@link Notifier#eAdapters() adapter list}, - * or null, if there isn't one. - * @param notifier the object to search. - * @return the first ECrossReferenceAdapter in the notifier's adapter list. - */ - public static ECrossReferenceAdapter getCrossReferenceAdapter(Notifier notifier) - { - List adapters = notifier.eAdapters(); - for (int i = 0, size = adapters.size(); i < size; ++i) - { - Object adapter = adapters.get(i); - if (adapter instanceof ECrossReferenceAdapter) - { - return (ECrossReferenceAdapter)adapter; - } - } - return null; - } - - protected Set unloadedResources = new HashSet(); - protected Map unloadedEObjects = new HashMap(); - - protected class InverseCrossReferencer extends EcoreUtil.CrossReferencer - { - private static final long serialVersionUID = 1L; - - protected Map> proxyMap; - - /** - * @since 2.10 - */ - protected EContentsEList.FeatureFilter crossReferenceFilter; - - protected InverseCrossReferencer() - { - super((Collection)null); - - crossReferenceFilter = createCrossReferenceFilter(); - } - - /** - * @since 2.10 - */ - protected EContentsEList.FeatureFilter createCrossReferenceFilter() - { - return new EContentsEList.FeatureFilter() - { - public boolean isIncluded(EStructuralFeature eStructuralFeature) - { - return FeatureMapUtil.isFeatureMap(eStructuralFeature) || SmartEMFCrossReferenceAdapter.this.isIncluded((EReference)eStructuralFeature); - } - }; - } - - @Override - protected EContentsEList.FeatureIterator getCrossReferences(EObject eObject) - { - InternalEList eCrossReferences = (InternalEList)eObject.eCrossReferences(); - - final EContentsEList.FeatureIterator underlyingIterator = (FeatureIterator)(resolve() ? eCrossReferences.iterator() : eCrossReferences.basicIterator()); - - if (underlyingIterator instanceof EContentsEList.Filterable) - { - // Simply filter the model-provided iterator to skip the references that we don't need to index - ((EContentsEList.Filterable)underlyingIterator).filter(crossReferenceFilter); - return underlyingIterator; - } - - // Otherwise, we'll post-filter the iterator, ourselves, but this does mean that we may compute derived features unnecessarily - return new EContentsEList.FeatureIterator() - { - private boolean prepared; - - private EObject preparedNext; - - private EStructuralFeature preparedFeature; - - private EStructuralFeature feature; - - public boolean hasNext() - { - if (!prepared) - { - while (underlyingIterator.hasNext()) - { - preparedNext = underlyingIterator.next(); - preparedFeature = underlyingIterator.feature(); - if (crossReferenceFilter.isIncluded(preparedFeature)) - { - prepared = true; - break; - } - } - } - - return prepared; - } - - public EObject next() - { - if (!prepared && !hasNext()) - { - throw new NoSuchElementException(); - } - - feature = preparedFeature; - prepared = false; - return preparedNext; - } - - public void remove() - { - // Must not attempt to remove cross-references in indexing them - throw new UnsupportedOperationException(); - } - - public EStructuralFeature feature() - { - return feature; - } - }; - } - - @Override - protected boolean crossReference(EObject eObject, EReference eReference, EObject crossReferencedEObject) - { - return isIncluded(eReference); - } - - @Override - protected Collection newCollection() - { - return - new BasicEList() - { - private static final long serialVersionUID = 1L; - - private static final int THRESHOLD = 100; - - private Map map; - - @Override - protected Object[] newData(int capacity) - { - return new EStructuralFeature.Setting [capacity]; - } - - @Override - protected void didAdd(int index, EStructuralFeature.Setting setting) - { - if (map != null) - { - EObject eObject = setting.getEObject(); - EStructuralFeature eStructuralFeature = setting.getEStructuralFeature(); - Object object = map.get(eObject); - if (object == null) - { - map.put(eObject, eStructuralFeature); - } - else if (object instanceof Object[]) - { - Object[] oldFeatures = (Object[])object; - Object[] newFeatures = new Object[oldFeatures.length + 1]; - System.arraycopy(oldFeatures, 0, newFeatures, 0, oldFeatures.length); - newFeatures[oldFeatures.length] = eStructuralFeature; - map.put(eObject, newFeatures); - } - else - { - Object[] newFeatures = new Object[2]; - newFeatures[0] = object; - newFeatures[1] = eStructuralFeature; - map.put(eObject, newFeatures); - } - } - } - - @Override - protected void didRemove(int index, EStructuralFeature.Setting setting) - { - if (map != null) - { - if (size < THRESHOLD / 2) - { - map = null; - } - else - { - EObject eObject = setting.getEObject(); - Object object = map.get(eObject); - if (object instanceof Object[]) - { - Object[] oldFeatures = (Object[])object; - EStructuralFeature eStructuralFeature = setting.getEStructuralFeature(); - if (oldFeatures.length == 2) - { - map.put(eObject, oldFeatures[0] == eStructuralFeature ? oldFeatures[1] : oldFeatures[0]); - } - else - { - Object[] newFeatures = new Object [oldFeatures.length - 1]; - for (int i = 0; i < oldFeatures.length; ++i) - { - Object oldFeature = oldFeatures[i]; - if (oldFeature == eStructuralFeature) - { - System.arraycopy(oldFeatures, i + 1, newFeatures, i, oldFeatures.length - i - 1); - break; - } - else - { - newFeatures[i] = oldFeatures[i]; - } - } - map.put(eObject, newFeatures); - } - } - else - { - map.remove(eObject); - } - } - } - } - - @Override - public boolean add(EStructuralFeature.Setting setting) - { - if (size > 0 && (!settingTargets || SmartEMFCrossReferenceAdapter.this.resolve())) - { - EObject eObject = setting.getEObject(); - if (size > THRESHOLD) - { - if (map == null) - { - map = new HashMap(); - EStructuralFeature.Setting[] settingData = (EStructuralFeature.Setting[])data; - for (int i = 0; i < size; ++i) - { - didAdd(i, settingData[i]); - } - } - - Object object = map.get(eObject); - if (object != null) - { - EStructuralFeature eStructuralFeature = setting.getEStructuralFeature(); - if (object == eStructuralFeature) - { - return false; - } - else if (object instanceof Object[]) - { - Object[] features = (Object[])object; - for (int i = 0; i < features.length; ++i) - { - if (features[i] == eStructuralFeature) - { - return false; - } - } - } - } - } - else - { - EStructuralFeature eStructuralFeature = setting.getEStructuralFeature(); - EStructuralFeature.Setting[] settingData = (EStructuralFeature.Setting[])data; - for (int i = 0; i < size; ++i) - { - EStructuralFeature.Setting containedSetting = settingData[i]; - if (containedSetting.getEObject() == eObject && containedSetting.getEStructuralFeature() == eStructuralFeature) - { - return false; - } - } - } - } - addUnique(setting); - return true; - } - }; - } - - public void add(EObject eObject) - { - handleCrossReference(eObject); - if (!resolve()) - { - addProxy(eObject, eObject); - } - } - - @Override - protected void add(InternalEObject eObject, EReference eReference, EObject crossReferencedEObject) - { - super.add(eObject, eReference, crossReferencedEObject); - if (!resolve()) - { - addProxy(crossReferencedEObject, eObject); - } - } - - public void add(EObject eObject, EReference eReference, EObject crossReferencedEObject) - { - add((InternalEObject)eObject, eReference, crossReferencedEObject); - } - - protected void addProxy(EObject proxy, EObject context) - { - if (proxy.eIsProxy()) - { - if (proxyMap == null) - { - proxyMap = new HashMap>(); - } - URI uri = normalizeURI(((InternalEObject)proxy).eProxyURI(), context); - List proxies = proxyMap.get(uri); - if (proxies == null) - { - proxyMap.put(uri, proxies = new BasicEList.FastCompare()); - } - proxies.add(proxy); - } - } - - public Object remove(EObject eObject) - { - if (!resolve()) - { - removeProxy(eObject, eObject); - } - return super.remove(eObject); - } - - public void remove(EObject eObject, EReference eReference, EObject crossReferencedEObject) - { - if (!resolve()) - { - removeProxy(crossReferencedEObject, eObject); - } - BasicEList collection = (BasicEList)get(crossReferencedEObject); - if (collection != null) - { - EStructuralFeature.Setting [] settingData = (EStructuralFeature.Setting[])collection.data(); - for (int i = 0, size = collection.size(); i < size; ++i) - { - EStructuralFeature.Setting setting = settingData[i]; - if (setting.getEObject() == eObject && setting.getEStructuralFeature() == eReference) - { - if (collection.size() == 1) - { - super.remove(crossReferencedEObject); - } - else - { - collection.remove(i); - } - break; - } - } - } - } - - protected void removeProxy(EObject proxy, EObject context) - { - if (proxyMap != null && proxy.eIsProxy()) - { - URI uri = normalizeURI(((InternalEObject)proxy).eProxyURI(), context); - List proxies = proxyMap.get(uri); - if (proxies != null) - { - proxies.remove(proxy); - if (proxies.isEmpty()) - { - proxyMap.remove(uri); - } - } - } - } - - protected List removeProxies(URI uri) - { - return proxyMap != null ? proxyMap.remove(uri) : null; - } - - protected URI normalizeURI(URI uri, EObject objectContext) - { - // This should be the same as the logic in ResourceImpl.getEObject(String). - // - String fragment = uri.fragment(); - if (fragment != null) - { - int length = fragment.length(); - if (length > 0 && fragment.charAt(0) != '/' && fragment.charAt(length - 1) == '?') - { - int index = fragment.lastIndexOf('?', length - 2); - if (index > 0) - { - uri = uri.trimFragment().appendFragment(fragment.substring(0, index)); - } - } - } - Resource resourceContext = objectContext.eResource(); - if (resourceContext != null) - { - ResourceSet resourceSetContext = resourceContext.getResourceSet(); - if (resourceSetContext != null) - { - return resourceSetContext.getURIConverter().normalize(uri); - } - } - return uri; - } - - @Override - protected boolean resolve() - { - return SmartEMFCrossReferenceAdapter.this.resolve(); - } - } - - protected InverseCrossReferencer inverseCrossReferencer; - - protected boolean settingTargets; - - /** - * Indicates whether the adapter is currently being attached {@link #useRecursion() iteratively}. - * - * @see #useRecursion() - * @see #setTarget(EObject) - * @see #unsetTarget(EObject) - * @since 2.14 - */ - protected boolean iterating; - - public SmartEMFCrossReferenceAdapter() - { - inverseCrossReferencer = createInverseCrossReferencer(); - } - - /** - * Returns whether the process of attaching this adapter should be done recursively or iteratively; - * the default is to return {@code true} for recursion. - * - * @since 2.14 - * @return whether the process of attaching this adapter should be done recursively or iteratively. - */ - protected boolean useRecursion() - { - return true; - } - - public Collection getNonNavigableInverseReferences(EObject eObject) - { - return getNonNavigableInverseReferences(eObject, !resolve()); - } - - public Collection getNonNavigableInverseReferences(EObject eObject, boolean resolve) - { - if (resolve) - { - resolveAll(eObject); - } - - Collection result = inverseCrossReferencer.get(eObject); - if (result == null) - { - result = Collections.emptyList(); - } - return result; - } - - public Collection getInverseReferences(EObject eObject) - { - return getInverseReferences(eObject, !resolve()); - } - - public Collection getInverseReferences(EObject eObject, boolean resolve) - { - Collection result = new ArrayList(); - - if (resolve) - { - resolveAll(eObject); - } - - EObject eContainer = resolve ? eObject.eContainer() : ((InternalEObject)eObject).eInternalContainer(); - if (eContainer != null) - { - result.add(((InternalEObject)eContainer).eSetting(eObject.eContainmentFeature())); - } - - Collection nonNavigableInverseReferences = inverseCrossReferencer.get(eObject); - if (nonNavigableInverseReferences != null) - { - result.addAll(nonNavigableInverseReferences); - } - - for (EReference eReference : eObject.eClass().getEAllReferences()) - { - EReference eOpposite = eReference.getEOpposite(); - if (eOpposite != null && !eReference.isContainer() && eObject.eIsSet(eReference)) - { - if (eReference.isMany()) - { - Object collection = eObject.eGet(eReference); - for (@SuppressWarnings("unchecked") Iterator j = - resolve ? - ((Collection)collection).iterator() : - ((InternalEList)collection).basicIterator(); - j.hasNext(); ) - { - InternalEObject referencingEObject = (InternalEObject)j.next(); - result.add(referencingEObject.eSetting(eOpposite)); - } - } - else - { - result.add(((InternalEObject)eObject.eGet(eReference, resolve)).eSetting(eOpposite)); - } - } - } - - return result; - } - - /** - * @since 2.17 - */ - public Collection getInverseReferences(EObject eObject, EReference eReference, boolean resolve) - { - Collection result = new ArrayList(); - - if (resolve) - { - resolveAll(eObject); - } - - if (eReference.isContainment()) - { - EReference containmentFeature = eObject.eContainmentFeature(); - if (eReference == containmentFeature) - { - EObject eContainer = resolve ? eObject.eContainer() : ((InternalEObject)eObject).eInternalContainer(); - if (eContainer != null) - { - result.add(((InternalEObject)eContainer).eSetting(containmentFeature)); - } - } - } - else - { - EReference eOpposite = eReference.getEOpposite(); - if (eOpposite == null) - { - Collection nonNavigableInverseReferences = inverseCrossReferencer.get(eObject); - if (nonNavigableInverseReferences != null) - { - for (EStructuralFeature.Setting setting : nonNavigableInverseReferences) - { - if (eReference == setting.getEStructuralFeature()) - { - result.add(setting); - } - } - } - } - else - { - int featureID = eObject.eClass().getFeatureID(eOpposite); - if (featureID != -1) - { - InternalEObject internalEObject = (InternalEObject)eObject; - if (internalEObject.eIsSet(featureID)) - { - Object value = internalEObject.eGet(featureID, resolve, true); - if (eOpposite.isMany()) - { - for (@SuppressWarnings("unchecked") - Iterator j = resolve ? ((Collection)value).iterator() : ((InternalEList)value).basicIterator(); j.hasNext();) - { - InternalEObject referencingEObject = (InternalEObject)j.next(); - result.add(referencingEObject.eSetting(eReference)); - } - } - else - { - result.add(((InternalEObject)value).eSetting(eReference)); - } - } - } - } - } - - return result; - } - - protected void resolveAll(EObject eObject) - { - if (!eObject.eIsProxy()) - { - Resource resource = eObject.eResource(); - if (resource != null) - { - URI uri = resource.getURI(); - if (uri != null) - { - ResourceSet resourceSet = resource.getResourceSet(); - if (resourceSet != null) - { - uri = resourceSet.getURIConverter().normalize(uri); - } - uri = uri.appendFragment(resource.getURIFragment(eObject)); - } - else - { - uri = URI.createHierarchicalURI(null, null, resource.getURIFragment(eObject)); - } - List proxies = inverseCrossReferencer.removeProxies(uri); - if (proxies != null) - { - for (int i = 0, size = proxies.size(); i < size; ++i) - { - EObject proxy = proxies.get(i); - for (EStructuralFeature.Setting setting : getInverseReferences(proxy, false)) - { - resolveProxy(resource, eObject, proxy, setting); - } - } - } - } - } - } - - protected void resolveProxy(Resource resource, EObject eObject, EObject proxy, EStructuralFeature.Setting setting) - { - Object value = setting.get(true); - if (setting.getEStructuralFeature().isMany()) - { - InternalEList list = (InternalEList)value; - List basicList = list.basicList(); - int index = basicList.indexOf(proxy); - if (index != -1) - { - list.get(index); - } - } - } - - protected boolean isIncluded(EReference eReference) - { - return eReference.getEOpposite() == null && !eReference.isDerived(); - } - - protected InverseCrossReferencer createInverseCrossReferencer() - { - return new InverseCrossReferencer(); - } - - /** - * Handles a notification by calling {@link #selfAdapt selfAdapter}. - */ - public void notifyChanged(Notification notification) - { - selfAdapt(notification); - } - - /** - * Handles a notification by calling {@link #handleContainment handleContainment} - * for any containment-based notification. - */ - protected void selfAdapt(Notification notification) - { - Object notifier = notification.getNotifier(); - if (notifier instanceof EObject) - { - Object feature = notification.getFeature(); - if (feature instanceof EReference) - { - EReference reference = (EReference)feature; - if (reference.isContainment()) - { - handleContainment(notification); - } - else if (isIncluded(reference)) - { - handleCrossReference(reference, notification); - } - } - } - else if (notifier instanceof Resource) - { - switch (notification.getFeatureID(Resource.class)) - { - case Resource.RESOURCE__CONTENTS: - { - if (!unloadedResources.contains(notifier)) - { - switch (notification.getEventType()) - { - case Notification.REMOVE: - { - Resource resource = (Resource)notifier; - if (!resource.isLoaded()) - { - EObject eObject = (EObject)notification.getOldValue(); - unloadedEObjects.put(eObject, resource); - for (Iterator i = EcoreUtil.getAllProperContents(eObject, false); i.hasNext(); ) - { - unloadedEObjects.put(i.next(), resource); - } - } - break; - } - case Notification.REMOVE_MANY: - { - Resource resource = (Resource)notifier; - if (!resource.isLoaded()) - { - @SuppressWarnings("unchecked") - List eObjects = (List)notification.getOldValue(); - for (Iterator i = EcoreUtil.getAllProperContents(eObjects, false); i.hasNext(); ) - { - unloadedEObjects.put(i.next(), resource); - } - } - break; - } - default: - { - handleContainment(notification); - break; - } - } - } - break; - } - case Resource.RESOURCE__IS_LOADED: - { - if (notification.getNewBooleanValue()) - { - unloadedResources.remove(notifier); - for (Notifier child : ((Resource)notifier).getContents()) - { - addAdapter(child); - } - } - else - { - unloadedResources.add((Resource)notifier); - for (Iterator> i = unloadedEObjects.entrySet().iterator(); i.hasNext(); ) - { - Map.Entry entry = i.next(); - if (entry.getValue() == notifier) - { - i.remove(); - if (!resolve()) - { - EObject eObject = entry.getKey(); - Collection settings = inverseCrossReferencer.get(eObject); - if (settings != null) - { - for (EStructuralFeature.Setting setting : settings) - { - inverseCrossReferencer.addProxy(eObject, setting.getEObject()); - } - } - } - } - } - } - break; - } - } - } - else if (notifier instanceof ResourceSet) - { - if (notification.getFeatureID(ResourceSet.class) == ResourceSet.RESOURCE_SET__RESOURCES) - { - handleContainment(notification); - } - } - } - - /** - * Handles a containment change by adding and removing the adapter as appropriate. - */ - protected void handleContainment(Notification notification) - { - switch (notification.getEventType()) - { - case Notification.RESOLVE: - { - Notifier oldValue = (Notifier)notification.getOldValue(); - removeAdapter(oldValue); - Notifier newValue = (Notifier)notification.getNewValue(); - addAdapter(newValue); - break; - } - case Notification.UNSET: - { - Object newValue = notification.getNewValue(); - if (newValue != null && newValue != Boolean.TRUE && newValue != Boolean.FALSE) - { - addAdapter((Notifier)newValue); - } - break; - } - case Notification.SET: - { - Notifier newValue = (Notifier)notification.getNewValue(); - if (newValue != null) - { - addAdapter(newValue); - } - break; - } - case Notification.ADD: - { - Notifier newValue = (Notifier)notification.getNewValue(); - if (newValue != null) - { - addAdapter(newValue); - } - break; - } - case Notification.ADD_MANY: - { - for (Object newValue : (Collection)notification.getNewValue()) - { - addAdapter((Notifier)newValue); - } - break; - } - } - } - - /** - * Handles a cross reference change by adding and removing the adapter as appropriate. - */ - protected void handleCrossReference(EReference reference, Notification notification) - { - switch (notification.getEventType()) - { - case Notification.RESOLVE: - case Notification.SET: - case Notification.UNSET: - { - EObject notifier = (EObject)notification.getNotifier(); - EReference feature = (EReference)notification.getFeature(); - if (!feature.isMany() || notification.getPosition() != Notification.NO_INDEX) - { - EObject oldValue = (EObject)notification.getOldValue(); - if (oldValue != null) - { - inverseCrossReferencer.remove(notifier, feature, oldValue); - } - EObject newValue = (EObject)notification.getNewValue(); - if (newValue != null) - { - inverseCrossReferencer.add(notifier, feature, newValue); - } - } - break; - } - case Notification.ADD: - { - EObject newValue = (EObject)notification.getNewValue(); - if (newValue != null) - { - inverseCrossReferencer.add((EObject)notification.getNotifier(), (EReference)notification.getFeature(), newValue); - } - break; - } - case Notification.ADD_MANY: - { - EObject notifier = (EObject)notification.getNotifier(); - EReference feature = (EReference)notification.getFeature(); - for (Object newValue : (Collection)notification.getNewValue()) - { - inverseCrossReferencer.add(notifier, feature, (EObject)newValue); - } - break; - } - case Notification.REMOVE: - { - EObject oldValue = (EObject)notification.getOldValue(); - if (oldValue != null) - { - inverseCrossReferencer.remove((EObject)notification.getNotifier(), (EReference)notification.getFeature(), oldValue); - } - break; - } - case Notification.REMOVE_MANY: - { - EObject notifier = (EObject)notification.getNotifier(); - EReference feature = (EReference)notification.getFeature(); - for (Object oldValue : (Collection)notification.getOldValue()) - { - inverseCrossReferencer.remove(notifier, feature, (EObject)oldValue); - } - break; - } - } - } - - /** - * Handles installation of the adapter - * by adding the adapter to each of the directly contained objects. - */ - public void setTarget(Notifier target) - { - if (target instanceof EObject) - { - setTarget((EObject)target); - } - else if (target instanceof Resource) - { - setTarget((Resource)target); - } - else if (target instanceof ResourceSet) - { - setTarget((ResourceSet)target); - } - } - - /** - * Handles installation of the adapter on an EObject - * by adding the adapter to each of the directly contained objects. - */ - protected void setTarget(EObject target) - { - inverseCrossReferencer.add(target); - - if (useRecursion()) - { - for (@SuppressWarnings("unchecked") Iterator i = - resolve() ? - target.eContents().iterator() : - (Iterator)((InternalEList)target.eContents()).basicIterator(); - i.hasNext(); ) - { - Notifier notifier = i.next(); - addAdapter(notifier); - } - } - else if (!iterating) - { - iterating = true; - for (TreeIterator i = EcoreUtil.getAllContents(target, resolve()); i.hasNext(); ) - { - EObject eObject = i.next(); - if (eObject.eAdapters().contains(this)) - { - i.prune(); - } - else - { - addAdapter(eObject); - } - } - iterating = false; - } - } - - /** - * Handles installation of the adapter on a Resource - * by adding the adapter to each of the directly contained objects. - */ - protected void setTarget(Resource target) - { - if (!target.isLoaded()) - { - unloadedResources.add(target); - } - List contents = target.getContents(); - for (EObject e : contents) - { - Notifier notifier = e; - addAdapter(notifier); - } - } - - /** - * Handles installation of the adapter on a ResourceSet - * by adding the adapter to each of the directly contained objects. - */ - protected void setTarget(ResourceSet target) - { - List resources = target.getResources(); - for (Resource e : resources) - { - Notifier notifier = e; - addAdapter(notifier); - } - } - - /** - * Handles undoing the installation of the adapter - * by removing the adapter to each of the directly contained objects. - */ - public void unsetTarget(Notifier target) - { - if (target instanceof EObject) - { - unsetTarget((EObject)target); - } - else if (target instanceof Resource) - { - unsetTarget((Resource)target); - } - else if (target instanceof ResourceSet) - { - unsetTarget((ResourceSet)target); - } - } - - /** - * Handles undoing the installation of the adapter from an EObject - * by removing the adapter to each of the directly contained objects. - */ - protected void unsetTarget(EObject target) - { - for (EContentsEList.FeatureIterator i = inverseCrossReferencer.getCrossReferences(target); i.hasNext(); ) - { - EObject crossReferencedEObject = i.next(); - inverseCrossReferencer.remove(target, (EReference)i.feature(), crossReferencedEObject); - } - - if (useRecursion()) - { - for (@SuppressWarnings("unchecked") Iterator i = - resolve() ? - (Iterator)(Iterator)target.eContents().iterator() : - (Iterator)((InternalEList)target.eContents()).basicIterator(); - i.hasNext(); ) - { - // Don't remove the adapter if the object is in a different resource - // and that resource (and hence all its contents) are being cross referenced. - // - InternalEObject internalEObject = i.next(); - Resource eDirectResource = internalEObject.eDirectResource(); - if (eDirectResource == null || !eDirectResource.eAdapters().contains(this)) - { - removeAdapter(internalEObject); - } - } - } - else if (!iterating) - { - iterating = true; - for (TreeIterator i = EcoreUtil.getAllContents(target, resolve()); i.hasNext(); ) - { - // Don't remove the adapter if the object is in a different resource - // and that resource (and hence all its contents) are being cross referenced. - // - InternalEObject internalEObject = i.next(); - Resource eDirectResource = internalEObject.eDirectResource(); - if (eDirectResource == null || !eDirectResource.eAdapters().contains(this)) - { - removeAdapter(internalEObject); - } - } - iterating = false; - } - } - - /** - * Handles undoing the installation of the adapter from a Resource - * by removing the adapter to each of the directly contained objects. - */ - protected void unsetTarget(Resource target) - { - List contents = target.getContents(); - for (EObject e : contents) - { - Notifier notifier = e; - removeAdapter(notifier); - } - unloadedResources.remove(target); - } - - /** - * Handles undoing the installation of the adapter from a ResourceSet - * by removing the adapter to each of the directly contained objects. - */ - protected void unsetTarget(ResourceSet target) - { - List resources = target.getResources(); - for (Resource e : resources) - { - Notifier notifier = e; - removeAdapter(notifier); - } - } - - protected void addAdapter(Notifier notifier) - { - List eAdapters = notifier.eAdapters(); - if (!eAdapters.contains(this)) - { - boolean oldSettingTargets = settingTargets; - try - { - settingTargets = true; - eAdapters.add(this); - } - finally - { - settingTargets = oldSettingTargets; - } - } - } - - protected void removeAdapter(Notifier notifier) - { - notifier.eAdapters().remove(this); - } - - public void dump() - { - EcoreUtil.CrossReferencer.print(System.out, inverseCrossReferencer); - } - - public Notifier getTarget() - { - return null; - } - - public boolean isAdapterForType(Object type) - { - return false; - } - - protected boolean resolve() - { - return true; - } +public class SmartEMFCrossReferenceAdapter implements Adapter.Internal { + /** + * Returns the first {@link ECrossReferenceAdapter} in the notifier's + * {@link Notifier#eAdapters() adapter list}, or null, if there + * isn't one. + * + * @param notifier the object to search. + * @return the first ECrossReferenceAdapter in the notifier's adapter list. + */ + public static ECrossReferenceAdapter getCrossReferenceAdapter(Notifier notifier) { + List adapters = notifier.eAdapters(); + for (int i = 0, size = adapters.size(); i < size; ++i) { + Object adapter = adapters.get(i); + if (adapter instanceof ECrossReferenceAdapter) { + return (ECrossReferenceAdapter) adapter; + } + } + return null; + } + + protected Set unloadedResources = new HashSet(); + protected Map unloadedEObjects = new HashMap(); + + protected class InverseCrossReferencer extends EcoreUtil.CrossReferencer { + private static final long serialVersionUID = 1L; + + protected Map> proxyMap; + + /** + * @since 2.10 + */ + protected EContentsEList.FeatureFilter crossReferenceFilter; + + protected InverseCrossReferencer() { + super((Collection) null); + + crossReferenceFilter = createCrossReferenceFilter(); + } + + /** + * @since 2.10 + */ + protected EContentsEList.FeatureFilter createCrossReferenceFilter() { + return new EContentsEList.FeatureFilter() { + public boolean isIncluded(EStructuralFeature eStructuralFeature) { + return FeatureMapUtil.isFeatureMap(eStructuralFeature) + || SmartEMFCrossReferenceAdapter.this.isIncluded((EReference) eStructuralFeature); + } + }; + } + + @Override + protected EContentsEList.FeatureIterator getCrossReferences(EObject eObject) { + InternalEList eCrossReferences = (InternalEList) eObject.eCrossReferences(); + + final EContentsEList.FeatureIterator underlyingIterator = (FeatureIterator) (resolve() + ? eCrossReferences.iterator() + : eCrossReferences.basicIterator()); + + if (underlyingIterator instanceof EContentsEList.Filterable) { + // Simply filter the model-provided iterator to skip the references that we + // don't need to index + ((EContentsEList.Filterable) underlyingIterator).filter(crossReferenceFilter); + return underlyingIterator; + } + + // Otherwise, we'll post-filter the iterator, ourselves, but this does mean that + // we may compute derived features unnecessarily + return new EContentsEList.FeatureIterator() { + private boolean prepared; + + private EObject preparedNext; + + private EStructuralFeature preparedFeature; + + private EStructuralFeature feature; + + public boolean hasNext() { + if (!prepared) { + while (underlyingIterator.hasNext()) { + preparedNext = underlyingIterator.next(); + preparedFeature = underlyingIterator.feature(); + if (crossReferenceFilter.isIncluded(preparedFeature)) { + prepared = true; + break; + } + } + } + + return prepared; + } + + public EObject next() { + if (!prepared && !hasNext()) { + throw new NoSuchElementException(); + } + + feature = preparedFeature; + prepared = false; + return preparedNext; + } + + public void remove() { + // Must not attempt to remove cross-references in indexing them + throw new UnsupportedOperationException(); + } + + public EStructuralFeature feature() { + return feature; + } + }; + } + + @Override + protected boolean crossReference(EObject eObject, EReference eReference, EObject crossReferencedEObject) { + return isIncluded(eReference); + } + + @Override + protected Collection newCollection() { + return new BasicEList() { + private static final long serialVersionUID = 1L; + + private static final int THRESHOLD = 100; + + private Map map; + + @Override + protected Object[] newData(int capacity) { + return new EStructuralFeature.Setting[capacity]; + } + + @Override + protected void didAdd(int index, EStructuralFeature.Setting setting) { + if (map != null) { + EObject eObject = setting.getEObject(); + EStructuralFeature eStructuralFeature = setting.getEStructuralFeature(); + Object object = map.get(eObject); + if (object == null) { + map.put(eObject, eStructuralFeature); + } else if (object instanceof Object[]) { + Object[] oldFeatures = (Object[]) object; + Object[] newFeatures = new Object[oldFeatures.length + 1]; + System.arraycopy(oldFeatures, 0, newFeatures, 0, oldFeatures.length); + newFeatures[oldFeatures.length] = eStructuralFeature; + map.put(eObject, newFeatures); + } else { + Object[] newFeatures = new Object[2]; + newFeatures[0] = object; + newFeatures[1] = eStructuralFeature; + map.put(eObject, newFeatures); + } + } + } + + @Override + protected void didRemove(int index, EStructuralFeature.Setting setting) { + if (map != null) { + if (size < THRESHOLD / 2) { + map = null; + } else { + EObject eObject = setting.getEObject(); + Object object = map.get(eObject); + if (object instanceof Object[]) { + Object[] oldFeatures = (Object[]) object; + EStructuralFeature eStructuralFeature = setting.getEStructuralFeature(); + if (oldFeatures.length == 2) { + map.put(eObject, + oldFeatures[0] == eStructuralFeature ? oldFeatures[1] : oldFeatures[0]); + } else { + Object[] newFeatures = new Object[oldFeatures.length - 1]; + for (int i = 0; i < oldFeatures.length; ++i) { + Object oldFeature = oldFeatures[i]; + if (oldFeature == eStructuralFeature) { + System.arraycopy(oldFeatures, i + 1, newFeatures, i, + oldFeatures.length - i - 1); + break; + } else { + newFeatures[i] = oldFeatures[i]; + } + } + map.put(eObject, newFeatures); + } + } else { + map.remove(eObject); + } + } + } + } + + @Override + public boolean add(EStructuralFeature.Setting setting) { + if (size > 0 && (!settingTargets || SmartEMFCrossReferenceAdapter.this.resolve())) { + EObject eObject = setting.getEObject(); + if (size > THRESHOLD) { + if (map == null) { + map = new HashMap(); + EStructuralFeature.Setting[] settingData = (EStructuralFeature.Setting[]) data; + for (int i = 0; i < size; ++i) { + didAdd(i, settingData[i]); + } + } + + Object object = map.get(eObject); + if (object != null) { + EStructuralFeature eStructuralFeature = setting.getEStructuralFeature(); + if (object == eStructuralFeature) { + return false; + } else if (object instanceof Object[]) { + Object[] features = (Object[]) object; + for (int i = 0; i < features.length; ++i) { + if (features[i] == eStructuralFeature) { + return false; + } + } + } + } + } else { + EStructuralFeature eStructuralFeature = setting.getEStructuralFeature(); + EStructuralFeature.Setting[] settingData = (EStructuralFeature.Setting[]) data; + for (int i = 0; i < size; ++i) { + EStructuralFeature.Setting containedSetting = settingData[i]; + if (containedSetting.getEObject() == eObject + && containedSetting.getEStructuralFeature() == eStructuralFeature) { + return false; + } + } + } + } + addUnique(setting); + return true; + } + }; + } + + public void add(EObject eObject) { + handleCrossReference(eObject); + if (!resolve()) { + addProxy(eObject, eObject); + } + } + + @Override + protected void add(InternalEObject eObject, EReference eReference, EObject crossReferencedEObject) { + super.add(eObject, eReference, crossReferencedEObject); + if (!resolve()) { + addProxy(crossReferencedEObject, eObject); + } + } + + public void add(EObject eObject, EReference eReference, EObject crossReferencedEObject) { + add((InternalEObject) eObject, eReference, crossReferencedEObject); + } + + protected void addProxy(EObject proxy, EObject context) { + if (proxy.eIsProxy()) { + if (proxyMap == null) { + proxyMap = new HashMap>(); + } + URI uri = normalizeURI(((InternalEObject) proxy).eProxyURI(), context); + List proxies = proxyMap.get(uri); + if (proxies == null) { + proxyMap.put(uri, proxies = new BasicEList.FastCompare()); + } + proxies.add(proxy); + } + } + + public Object remove(EObject eObject) { + if (!resolve()) { + removeProxy(eObject, eObject); + } + return super.remove(eObject); + } + + public void remove(EObject eObject, EReference eReference, EObject crossReferencedEObject) { + if (!resolve()) { + removeProxy(crossReferencedEObject, eObject); + } + BasicEList collection = (BasicEList) get( + crossReferencedEObject); + if (collection != null) { + EStructuralFeature.Setting[] settingData = (EStructuralFeature.Setting[]) collection.data(); + for (int i = 0, size = collection.size(); i < size; ++i) { + EStructuralFeature.Setting setting = settingData[i]; + if (setting.getEObject() == eObject && setting.getEStructuralFeature() == eReference) { + if (collection.size() == 1) { + super.remove(crossReferencedEObject); + } else { + collection.remove(i); + } + break; + } + } + } + } + + protected void removeProxy(EObject proxy, EObject context) { + if (proxyMap != null && proxy.eIsProxy()) { + URI uri = normalizeURI(((InternalEObject) proxy).eProxyURI(), context); + List proxies = proxyMap.get(uri); + if (proxies != null) { + proxies.remove(proxy); + if (proxies.isEmpty()) { + proxyMap.remove(uri); + } + } + } + } + + protected List removeProxies(URI uri) { + return proxyMap != null ? proxyMap.remove(uri) : null; + } + + protected URI normalizeURI(URI uri, EObject objectContext) { + // This should be the same as the logic in ResourceImpl.getEObject(String). + // + String fragment = uri.fragment(); + if (fragment != null) { + int length = fragment.length(); + if (length > 0 && fragment.charAt(0) != '/' && fragment.charAt(length - 1) == '?') { + int index = fragment.lastIndexOf('?', length - 2); + if (index > 0) { + uri = uri.trimFragment().appendFragment(fragment.substring(0, index)); + } + } + } + Resource resourceContext = objectContext.eResource(); + if (resourceContext != null) { + ResourceSet resourceSetContext = resourceContext.getResourceSet(); + if (resourceSetContext != null) { + return resourceSetContext.getURIConverter().normalize(uri); + } + } + return uri; + } + + @Override + protected boolean resolve() { + return SmartEMFCrossReferenceAdapter.this.resolve(); + } + } + + protected InverseCrossReferencer inverseCrossReferencer; + + protected boolean settingTargets; + + /** + * Indicates whether the adapter is currently being attached + * {@link #useRecursion() iteratively}. + * + * @see #useRecursion() + * @see #setTarget(EObject) + * @see #unsetTarget(EObject) + * @since 2.14 + */ + protected boolean iterating; + + public SmartEMFCrossReferenceAdapter() { + inverseCrossReferencer = createInverseCrossReferencer(); + } + + /** + * Returns whether the process of attaching this adapter should be done + * recursively or iteratively; the default is to return {@code true} for + * recursion. + * + * @since 2.14 + * @return whether the process of attaching this adapter should be done + * recursively or iteratively. + */ + protected boolean useRecursion() { + return true; + } + + public Collection getNonNavigableInverseReferences(EObject eObject) { + return getNonNavigableInverseReferences(eObject, !resolve()); + } + + public Collection getNonNavigableInverseReferences(EObject eObject, boolean resolve) { + if (resolve) { + resolveAll(eObject); + } + + Collection result = inverseCrossReferencer.get(eObject); + if (result == null) { + result = Collections.emptyList(); + } + return result; + } + + public Collection getInverseReferences(EObject eObject) { + return getInverseReferences(eObject, !resolve()); + } + + public Collection getInverseReferences(EObject eObject, boolean resolve) { + Collection result = new ArrayList(); + + if (resolve) { + resolveAll(eObject); + } + + EObject eContainer = resolve ? eObject.eContainer() : ((InternalEObject) eObject).eInternalContainer(); + if (eContainer != null) { + result.add(((InternalEObject) eContainer).eSetting(eObject.eContainmentFeature())); + } + + Collection nonNavigableInverseReferences = inverseCrossReferencer.get(eObject); + if (nonNavigableInverseReferences != null) { + result.addAll(nonNavigableInverseReferences); + } + + for (EReference eReference : eObject.eClass().getEAllReferences()) { + EReference eOpposite = eReference.getEOpposite(); + if (eOpposite != null && !eReference.isContainer() && eObject.eIsSet(eReference)) { + if (eReference.isMany()) { + Object collection = eObject.eGet(eReference); + for (@SuppressWarnings("unchecked") + Iterator j = resolve ? ((Collection) collection).iterator() + : ((InternalEList) collection).basicIterator(); j.hasNext();) { + InternalEObject referencingEObject = (InternalEObject) j.next(); + result.add(referencingEObject.eSetting(eOpposite)); + } + } else { + result.add(((InternalEObject) eObject.eGet(eReference, resolve)).eSetting(eOpposite)); + } + } + } + + return result; + } + + /** + * @since 2.17 + */ + public Collection getInverseReferences(EObject eObject, EReference eReference, + boolean resolve) { + Collection result = new ArrayList(); + + if (resolve) { + resolveAll(eObject); + } + + if (eReference.isContainment()) { + EReference containmentFeature = eObject.eContainmentFeature(); + if (eReference == containmentFeature) { + EObject eContainer = resolve ? eObject.eContainer() : ((InternalEObject) eObject).eInternalContainer(); + if (eContainer != null) { + result.add(((InternalEObject) eContainer).eSetting(containmentFeature)); + } + } + } else { + EReference eOpposite = eReference.getEOpposite(); + if (eOpposite == null) { + Collection nonNavigableInverseReferences = inverseCrossReferencer + .get(eObject); + if (nonNavigableInverseReferences != null) { + for (EStructuralFeature.Setting setting : nonNavigableInverseReferences) { + if (eReference == setting.getEStructuralFeature()) { + result.add(setting); + } + } + } + } else { + int featureID = eObject.eClass().getFeatureID(eOpposite); + if (featureID != -1) { + InternalEObject internalEObject = (InternalEObject) eObject; + if (internalEObject.eIsSet(featureID)) { + Object value = internalEObject.eGet(featureID, resolve, true); + if (eOpposite.isMany()) { + for (@SuppressWarnings("unchecked") + Iterator j = resolve ? ((Collection) value).iterator() + : ((InternalEList) value).basicIterator(); j.hasNext();) { + InternalEObject referencingEObject = (InternalEObject) j.next(); + result.add(referencingEObject.eSetting(eReference)); + } + } else { + result.add(((InternalEObject) value).eSetting(eReference)); + } + } + } + } + } + + return result; + } + + protected void resolveAll(EObject eObject) { + if (!eObject.eIsProxy()) { + Resource resource = eObject.eResource(); + if (resource != null) { + URI uri = resource.getURI(); + if (uri != null) { + ResourceSet resourceSet = resource.getResourceSet(); + if (resourceSet != null) { + uri = resourceSet.getURIConverter().normalize(uri); + } + uri = uri.appendFragment(resource.getURIFragment(eObject)); + } else { + uri = URI.createHierarchicalURI(null, null, resource.getURIFragment(eObject)); + } + List proxies = inverseCrossReferencer.removeProxies(uri); + if (proxies != null) { + for (int i = 0, size = proxies.size(); i < size; ++i) { + EObject proxy = proxies.get(i); + for (EStructuralFeature.Setting setting : getInverseReferences(proxy, false)) { + resolveProxy(resource, eObject, proxy, setting); + } + } + } + } + } + } + + protected void resolveProxy(Resource resource, EObject eObject, EObject proxy, EStructuralFeature.Setting setting) { + Object value = setting.get(true); + if (setting.getEStructuralFeature().isMany()) { + InternalEList list = (InternalEList) value; + List basicList = list.basicList(); + int index = basicList.indexOf(proxy); + if (index != -1) { + list.get(index); + } + } + } + + protected boolean isIncluded(EReference eReference) { + return eReference.getEOpposite() == null && !eReference.isDerived(); + } + + protected InverseCrossReferencer createInverseCrossReferencer() { + return new InverseCrossReferencer(); + } + + /** + * Handles a notification by calling {@link #selfAdapt selfAdapter}. + */ + public void notifyChanged(Notification notification) { + selfAdapt(notification); + } + + /** + * Handles a notification by calling {@link #handleContainment + * handleContainment} for any containment-based notification. + */ + protected void selfAdapt(Notification notification) { + Object notifier = notification.getNotifier(); + if (notifier instanceof EObject) { + Object feature = notification.getFeature(); + if (feature instanceof EReference) { + EReference reference = (EReference) feature; + if (reference.isContainment()) { + handleContainment(notification); + } else if (isIncluded(reference)) { + handleCrossReference(reference, notification); + } + } + } else if (notifier instanceof Resource) { + switch (notification.getFeatureID(Resource.class)) { + case Resource.RESOURCE__CONTENTS: { + if (!unloadedResources.contains(notifier)) { + switch (notification.getEventType()) { + case Notification.REMOVE: { + Resource resource = (Resource) notifier; + if (!resource.isLoaded()) { + EObject eObject = (EObject) notification.getOldValue(); + unloadedEObjects.put(eObject, resource); + for (Iterator i = EcoreUtil.getAllProperContents(eObject, false); i.hasNext();) { + unloadedEObjects.put(i.next(), resource); + } + } + break; + } + case Notification.REMOVE_MANY: { + Resource resource = (Resource) notifier; + if (!resource.isLoaded()) { + @SuppressWarnings("unchecked") + List eObjects = (List) notification.getOldValue(); + for (Iterator i = EcoreUtil.getAllProperContents(eObjects, false); i.hasNext();) { + unloadedEObjects.put(i.next(), resource); + } + } + break; + } + default: { + handleContainment(notification); + break; + } + } + } + break; + } + case Resource.RESOURCE__IS_LOADED: { + if (notification.getNewBooleanValue()) { + unloadedResources.remove(notifier); + for (Notifier child : ((Resource) notifier).getContents()) { + addAdapter(child); + } + } else { + unloadedResources.add((Resource) notifier); + for (Iterator> i = unloadedEObjects.entrySet().iterator(); i + .hasNext();) { + Map.Entry entry = i.next(); + if (entry.getValue() == notifier) { + i.remove(); + if (!resolve()) { + EObject eObject = entry.getKey(); + Collection settings = inverseCrossReferencer.get(eObject); + if (settings != null) { + for (EStructuralFeature.Setting setting : settings) { + inverseCrossReferencer.addProxy(eObject, setting.getEObject()); + } + } + } + } + } + } + break; + } + } + } else if (notifier instanceof ResourceSet) { + if (notification.getFeatureID(ResourceSet.class) == ResourceSet.RESOURCE_SET__RESOURCES) { + handleContainment(notification); + } + } + } + + /** + * Handles a containment change by adding and removing the adapter as + * appropriate. + */ + protected void handleContainment(Notification notification) { + switch (notification.getEventType()) { + case Notification.RESOLVE: { + Notifier oldValue = (Notifier) notification.getOldValue(); + removeAdapter(oldValue); + Notifier newValue = (Notifier) notification.getNewValue(); + addAdapter(newValue); + break; + } + case Notification.UNSET: { + Object newValue = notification.getNewValue(); + if (newValue != null && newValue != Boolean.TRUE && newValue != Boolean.FALSE) { + addAdapter((Notifier) newValue); + } + break; + } + case Notification.SET: { + Notifier newValue = (Notifier) notification.getNewValue(); + if (newValue != null) { + addAdapter(newValue); + } + break; + } + case Notification.ADD: { + Notifier newValue = (Notifier) notification.getNewValue(); + if (newValue != null) { + addAdapter(newValue); + } + break; + } + case Notification.ADD_MANY: { + for (Object newValue : (Collection) notification.getNewValue()) { + addAdapter((Notifier) newValue); + } + break; + } + } + } + + /** + * Handles a cross reference change by adding and removing the adapter as + * appropriate. + */ + protected void handleCrossReference(EReference reference, Notification notification) { + switch (notification.getEventType()) { + case Notification.RESOLVE: + case Notification.SET: + case Notification.UNSET: { + EObject notifier = (EObject) notification.getNotifier(); + EReference feature = (EReference) notification.getFeature(); + if (!feature.isMany() || notification.getPosition() != Notification.NO_INDEX) { + EObject oldValue = (EObject) notification.getOldValue(); + if (oldValue != null) { + inverseCrossReferencer.remove(notifier, feature, oldValue); + } + EObject newValue = (EObject) notification.getNewValue(); + if (newValue != null) { + inverseCrossReferencer.add(notifier, feature, newValue); + } + } + break; + } + case Notification.ADD: { + EObject newValue = (EObject) notification.getNewValue(); + if (newValue != null) { + inverseCrossReferencer.add((EObject) notification.getNotifier(), (EReference) notification.getFeature(), + newValue); + } + break; + } + case Notification.ADD_MANY: { + EObject notifier = (EObject) notification.getNotifier(); + EReference feature = (EReference) notification.getFeature(); + for (Object newValue : (Collection) notification.getNewValue()) { + inverseCrossReferencer.add(notifier, feature, (EObject) newValue); + } + break; + } + case Notification.REMOVE: { + EObject oldValue = (EObject) notification.getOldValue(); + if (oldValue != null) { + inverseCrossReferencer.remove((EObject) notification.getNotifier(), + (EReference) notification.getFeature(), oldValue); + } + break; + } + case Notification.REMOVE_MANY: { + EObject notifier = (EObject) notification.getNotifier(); + EReference feature = (EReference) notification.getFeature(); + for (Object oldValue : (Collection) notification.getOldValue()) { + inverseCrossReferencer.remove(notifier, feature, (EObject) oldValue); + } + break; + } + } + } + + /** + * Handles installation of the adapter by adding the adapter to each of the + * directly contained objects. + */ + public void setTarget(Notifier target) { + if (target instanceof EObject) { + setTarget((EObject) target); + } else if (target instanceof Resource) { + setTarget((Resource) target); + } else if (target instanceof ResourceSet) { + setTarget((ResourceSet) target); + } + } + + /** + * Handles installation of the adapter on an EObject by adding the adapter to + * each of the directly contained objects. + */ + protected void setTarget(EObject target) { + inverseCrossReferencer.add(target); + + if (useRecursion()) { + for (@SuppressWarnings("unchecked") + Iterator i = resolve() ? target.eContents().iterator() + : (Iterator) ((InternalEList) target.eContents()).basicIterator(); i.hasNext();) { + Notifier notifier = i.next(); + addAdapter(notifier); + } + } else if (!iterating) { + iterating = true; + for (TreeIterator i = EcoreUtil.getAllContents(target, resolve()); i.hasNext();) { + EObject eObject = i.next(); + if (eObject.eAdapters().contains(this)) { + i.prune(); + } else { + addAdapter(eObject); + } + } + iterating = false; + } + } + + /** + * Handles installation of the adapter on a Resource by adding the adapter to + * each of the directly contained objects. + */ + protected void setTarget(Resource target) { + if (!target.isLoaded()) { + unloadedResources.add(target); + } + List contents = target.getContents(); + for (EObject e : contents) { + Notifier notifier = e; + addAdapter(notifier); + } + } + + /** + * Handles installation of the adapter on a ResourceSet by adding the adapter to + * each of the directly contained objects. + */ + protected void setTarget(ResourceSet target) { + List resources = target.getResources(); + for (Resource e : resources) { + Notifier notifier = e; + addAdapter(notifier); + } + } + + /** + * Handles undoing the installation of the adapter by removing the adapter to + * each of the directly contained objects. + */ + public void unsetTarget(Notifier target) { + if (target instanceof EObject) { + unsetTarget((EObject) target); + } else if (target instanceof Resource) { + unsetTarget((Resource) target); + } else if (target instanceof ResourceSet) { + unsetTarget((ResourceSet) target); + } + } + + /** + * Handles undoing the installation of the adapter from an EObject by removing + * the adapter to each of the directly contained objects. + */ + protected void unsetTarget(EObject target) { + for (EContentsEList.FeatureIterator i = inverseCrossReferencer.getCrossReferences(target); i + .hasNext();) { + EObject crossReferencedEObject = i.next(); + inverseCrossReferencer.remove(target, (EReference) i.feature(), crossReferencedEObject); + } + + if (useRecursion()) { + for (@SuppressWarnings("unchecked") + Iterator i = resolve() + ? (Iterator) (Iterator) target.eContents().iterator() + : (Iterator) ((InternalEList) target.eContents()).basicIterator(); i + .hasNext();) { + // Don't remove the adapter if the object is in a different resource + // and that resource (and hence all its contents) are being cross referenced. + // + InternalEObject internalEObject = i.next(); + Resource eDirectResource = internalEObject.eDirectResource(); + if (eDirectResource == null || !eDirectResource.eAdapters().contains(this)) { + removeAdapter(internalEObject); + } + } + } else if (!iterating) { + iterating = true; + for (TreeIterator i = EcoreUtil.getAllContents(target, resolve()); i.hasNext();) { + // Don't remove the adapter if the object is in a different resource + // and that resource (and hence all its contents) are being cross referenced. + // + InternalEObject internalEObject = i.next(); + Resource eDirectResource = internalEObject.eDirectResource(); + if (eDirectResource == null || !eDirectResource.eAdapters().contains(this)) { + removeAdapter(internalEObject); + } + } + iterating = false; + } + } + + /** + * Handles undoing the installation of the adapter from a Resource by removing + * the adapter to each of the directly contained objects. + */ + protected void unsetTarget(Resource target) { + List contents = target.getContents(); + for (EObject e : contents) { + Notifier notifier = e; + removeAdapter(notifier); + } + unloadedResources.remove(target); + } + + /** + * Handles undoing the installation of the adapter from a ResourceSet by + * removing the adapter to each of the directly contained objects. + */ + protected void unsetTarget(ResourceSet target) { + List resources = target.getResources(); + for (Resource e : resources) { + Notifier notifier = e; + removeAdapter(notifier); + } + } + + protected void addAdapter(Notifier notifier) { + List eAdapters = notifier.eAdapters(); + if (!eAdapters.contains(this)) { + boolean oldSettingTargets = settingTargets; + try { + settingTargets = true; + eAdapters.add(this); + } finally { + settingTargets = oldSettingTargets; + } + } + } + + protected void removeAdapter(Notifier notifier) { + notifier.eAdapters().remove(this); + } + + public void dump() { + EcoreUtil.CrossReferencer.print(System.out, inverseCrossReferencer); + } + + public Notifier getTarget() { + return null; + } + + public boolean isAdapterForType(Object type) { + return false; + } + + protected boolean resolve() { + return true; + } } \ No newline at end of file diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java index 9461870a..fc2bddd7 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java @@ -12,7 +12,8 @@ public final class SmartEMFNotification implements Notification { private Object newValue; private int position; - private SmartEMFNotification(int eventType, Object notifier, EStructuralFeature feature, Object oldValue, Object newValue, int position) { + private SmartEMFNotification(int eventType, Object notifier, EStructuralFeature feature, Object oldValue, + Object newValue, int position) { this.eventType = eventType; this.notifier = notifier; this.feature = feature; @@ -21,35 +22,43 @@ private SmartEMFNotification(int eventType, Object notifier, EStructuralFeature this.position = position; } - public static Notification createAddNotification(Object notifier, EStructuralFeature feature, Object newValue, int index) { + public static Notification createAddNotification(Object notifier, EStructuralFeature feature, Object newValue, + int index) { return new SmartEMFNotification(ADD, notifier, feature, null, newValue, index); } - public static Notification createAddManyNotification(Object notifier, EStructuralFeature feature, Object newValue, int index) { + public static Notification createAddManyNotification(Object notifier, EStructuralFeature feature, Object newValue, + int index) { return new SmartEMFNotification(ADD_MANY, notifier, feature, null, newValue, index); } - public static Notification createSetNotification(Object notifier, EStructuralFeature feature, Object oldValue, Object newValue, int index) { + public static Notification createSetNotification(Object notifier, EStructuralFeature feature, Object oldValue, + Object newValue, int index) { return new SmartEMFNotification(SET, notifier, feature, oldValue, newValue, index); } - public static Notification createUnSetNotification(Object notifier, EStructuralFeature feature, Object oldValue, int index) { + public static Notification createUnSetNotification(Object notifier, EStructuralFeature feature, Object oldValue, + int index) { return new SmartEMFNotification(UNSET, notifier, feature, oldValue, null, index); } - public static Notification createRemoveNotification(Object notifier, EStructuralFeature feature, Object oldValue, int index) { + public static Notification createRemoveNotification(Object notifier, EStructuralFeature feature, Object oldValue, + int index) { return new SmartEMFNotification(REMOVE, notifier, feature, oldValue, null, index); } - public static Notification createRemoveManyNotification(Object notifier, EStructuralFeature feature, Object oldValue, int index) { + public static Notification createRemoveManyNotification(Object notifier, EStructuralFeature feature, + Object oldValue, int index) { return new SmartEMFNotification(REMOVE_MANY, notifier, feature, oldValue, null, index); } - public static Notification createRemovingAdapterNotification(Object notifier, EStructuralFeature feature, Object oldValue, int index) { + public static Notification createRemovingAdapterNotification(Object notifier, EStructuralFeature feature, + Object oldValue, int index) { return new SmartEMFNotification(REMOVING_ADAPTER, notifier, feature, oldValue, null, index); } - public static Notification createMoveNotification(Object notifier, EStructuralFeature feature, Object value, int oldIndex, int newIndex) { + public static Notification createMoveNotification(Object notifier, EStructuralFeature feature, Object value, + int oldIndex, int newIndex) { return new SmartEMFNotification(MOVE, notifier, feature, oldIndex, value, newIndex); } @@ -139,7 +148,8 @@ public int getPosition() { @Override /** - * Returns whether the notification can be and has been merged with this one.
+ * Returns whether the notification can be and has been merged with this one. + *
* Notifications can be merged when all these conditions are met: *
    *
  • They have the same notifier
  • @@ -152,10 +162,12 @@ public int getPosition() { *
* * - * null is treated as a "nothing new happened" notification and will always be merged; the - * result of this merging is the unmodified old notification. + * null is treated as a "nothing new happened" notification and will + * always be merged; the result of this merging is the unmodified old + * notification. * - * @param notification a notification that happened after this one (if order is relevant) + * @param notification a notification that happened after this one (if order is + * relevant) * @return whether the notification can be and has been merged with this one. */ public boolean merge(Notification notification) { diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/util/SmartEMFUtil.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/util/SmartEMFUtil.java index 29828224..08a8cdd1 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/util/SmartEMFUtil.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/util/SmartEMFUtil.java @@ -26,7 +26,8 @@ public class SmartEMFUtil { public static void deleteNode(EObject node, boolean recursive) { - // reset containment is only called for this element (and not recursively) like in EMF + // reset containment is only called for this element (and not recursively) like + // in EMF deleteNode_internal(node, recursive); ((SmartObject) node).resetContainment(); } @@ -93,7 +94,8 @@ private static void resolveAll(EObject eObject) { @SuppressWarnings("unchecked") private static void resolveCrossReferences(EObject eObject) { - // for all but SmartEMF objects we assume the references are resolved by iterating over them + // for all but SmartEMF objects we assume the references are resolved by + // iterating over them if (eObject instanceof SmartObject) { for (EReference reference : eObject.eClass().getEAllReferences()) { if (reference.isContainment()) @@ -124,7 +126,8 @@ private static void resolveCrossReferences(EObject eObject) { } private static void resolveProxyContainer(EObject eObject) { - // for all but SmartEMF objects we assume the container is resolved by calling EObject#eContainer + // for all but SmartEMF objects we assume the container is resolved by calling + // EObject#eContainer EObject eContainer = eObject.eContainer(); if (eContainer != null && eContainer instanceof SmartObject && eContainer.eIsProxy()) { EObject resolved = EcoreUtil.resolve(eContainer, eObject); diff --git a/emfcodegenerator/src/org/emoflon/smartemf/templates/CodeTemplate.java b/emfcodegenerator/src/org/emoflon/smartemf/templates/CodeTemplate.java index 59872f44..d89d38c4 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/templates/CodeTemplate.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/templates/CodeTemplate.java @@ -3,5 +3,5 @@ public interface CodeTemplate { public void createCode(); - + } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/templates/util/CodeFormattingUtil.java b/emfcodegenerator/src/org/emoflon/smartemf/templates/util/CodeFormattingUtil.java index c5cdd675..6581d1f9 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/templates/util/CodeFormattingUtil.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/templates/util/CodeFormattingUtil.java @@ -13,9 +13,9 @@ public class CodeFormattingUtil { public static String format(String code) { CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(null); TextEdit textEdit = codeFormatter.format(CodeFormatter.K_UNKNOWN, code, 0, code.length(), 0, null); - if(textEdit == null) + if (textEdit == null) return code; - + IDocument doc = new Document(code); try { textEdit.apply(doc); diff --git a/emfcodegenerator/src/org/emoflon/smartemf/templates/util/JarExtractor.java b/emfcodegenerator/src/org/emoflon/smartemf/templates/util/JarExtractor.java index 468c40d6..09c00937 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/templates/util/JarExtractor.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/templates/util/JarExtractor.java @@ -25,108 +25,108 @@ import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; public class JarExtractor { - + private Map name2genModelFiles = new HashMap<>(); - private Map name2ecoreModelFiles = new HashMap<>(); - - private String tempPath; - private String path; - - public JarExtractor(String tempPath, String path) { - this.tempPath = tempPath; - this.path = path; - - GenModelPackage.eINSTANCE.getName(); - EcorePackage.eINSTANCE.getName(); - } + private Map name2ecoreModelFiles = new HashMap<>(); + + private String tempPath; + private String path; + + public JarExtractor(String tempPath, String path) { + this.tempPath = tempPath; + this.path = path; + + GenModelPackage.eINSTANCE.getName(); + EcorePackage.eINSTANCE.getName(); + } public Collection extractGenModels() throws IOException { File tmpFolder = new File(tempPath); tmpFolder.mkdirs(); Collection genModels = new LinkedList<>(); - + // read jar file and extract files readJarFile(path); - + // add all genmodels - for(String fileName : name2genModelFiles.keySet()) { - GenModel gen = getGenModel(name2genModelFiles.get(fileName)); + for (String fileName : name2genModelFiles.keySet()) { + GenModel gen = getGenModel(name2genModelFiles.get(fileName)); genModels.add(gen); } - + // clean up all created files name2genModelFiles.values().forEach(File::delete); name2ecoreModelFiles.values().forEach(File::delete); - + tmpFolder.delete(); - + return genModels; } - + public String readJarFile(String jarFilePath) { - try { - ZipFile zipFile = new ZipFile(jarFilePath); - Enumeration e = zipFile.entries(); - - while (e.hasMoreElements()) { - ZipEntry entry = (ZipEntry) e.nextElement(); - // if the entry is not directory and matches relative file then extract it - if (!entry.isDirectory()) { - BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry)); - - // Read the file - String entryName = entry.getName(); - if(entryName.endsWith(".genmodel") || entryName.endsWith(".ecore")) { - File jarFile = new File(entryName); - - String fullFileName = jarFile.getName(); - String[] fileNameSplit = fullFileName.split("[.]"); - String fileName = fileNameSplit[0]; - String extensionName = fileNameSplit[1]; - - File newFile = new File(tempPath+File.separator+fullFileName); - newFile.createNewFile(); - copyInputStreamToFile(bis, newFile); - - if(extensionName.equals("genmodel")) { - name2genModelFiles.put(fileName, newFile); - } - if(extensionName.equals("ecore")) { - name2ecoreModelFiles.put(fileName, newFile); - } - } - bis.close(); - } else { - continue; - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return null; + try { + ZipFile zipFile = new ZipFile(jarFilePath); + Enumeration e = zipFile.entries(); + + while (e.hasMoreElements()) { + ZipEntry entry = (ZipEntry) e.nextElement(); + // if the entry is not directory and matches relative file then extract it + if (!entry.isDirectory()) { + BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry)); + + // Read the file + String entryName = entry.getName(); + if (entryName.endsWith(".genmodel") || entryName.endsWith(".ecore")) { + File jarFile = new File(entryName); + + String fullFileName = jarFile.getName(); + String[] fileNameSplit = fullFileName.split("[.]"); + String fileName = fileNameSplit[0]; + String extensionName = fileNameSplit[1]; + + File newFile = new File(tempPath + File.separator + fullFileName); + newFile.createNewFile(); + copyInputStreamToFile(bis, newFile); + + if (extensionName.equals("genmodel")) { + name2genModelFiles.put(fileName, newFile); + } + if (extensionName.equals("ecore")) { + name2ecoreModelFiles.put(fileName, newFile); + } + } + bis.close(); + } else { + continue; + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; } - + public static GenModel getGenModel(File genModelFile) throws IOException { ResourceSet rs = new ResourceSetImpl(); rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("genmodel", new XMIResourceFactoryImpl()); rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("ecore", new XMIResourceFactoryImpl()); - Resource createResource = rs.createResource(URI.createFileURI(genModelFile.getAbsolutePath())); - createResource.load(null); - if(createResource.getContents().get(0) instanceof GenModel gen) { - // tricking emf into loading the ecore - GenPackage genPackage = gen.getGenPackages().get(0); - genPackage.getEcorePackage(); - return gen; - } - throw new RuntimeException("Genmodel not found in " + genModelFile.getAbsolutePath()); + Resource createResource = rs.createResource(URI.createFileURI(genModelFile.getAbsolutePath())); + createResource.load(null); + if (createResource.getContents().get(0) instanceof GenModel gen) { + // tricking emf into loading the ecore + GenPackage genPackage = gen.getGenPackages().get(0); + genPackage.getEcorePackage(); + return gen; + } + throw new RuntimeException("Genmodel not found in " + genModelFile.getAbsolutePath()); } - - public static void copyInputStreamToFile(InputStream input, File file) { - try (OutputStream output = new FileOutputStream(file)) { - input.transferTo(output); - } catch (IOException ioException) { - ioException.printStackTrace(); - } + + public static void copyInputStreamToFile(InputStream input, File file) { + try (OutputStream output = new FileOutputStream(file)) { + input.transferTo(output); + } catch (IOException ioException) { + ioException.printStackTrace(); + } } } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/templates/util/Keywords.java b/emfcodegenerator/src/org/emoflon/smartemf/templates/util/Keywords.java index 8292298b..6ad495ba 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/templates/util/Keywords.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/templates/util/Keywords.java @@ -7,13 +7,15 @@ public class Keywords { /** * The list of invalid parameter names. */ - final public static String[] keywords = new String[] {"class", "rule", "clone", "equals", "finalize", - "getClass", "hashCode", "notify", "notifyAll", "toString", "wait", - "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "EAttribute", "EBoolean", "EDataType", - "EClass", "EClassifier", "EDouble", "EFloat", "EInt", "else", "enum", "EPackage", "EReference", "EString", "extends", "final", "finally", "float", "for", "goto", "if", - "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "short", "static", - "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while"}; - + final public static String[] keywords = new String[] { "class", "rule", "clone", "equals", "finalize", "getClass", + "hashCode", "notify", "notifyAll", "toString", "wait", "abstract", "assert", "boolean", "break", "byte", + "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "EAttribute", "EBoolean", + "EDataType", "EClass", "EClassifier", "EDouble", "EFloat", "EInt", "else", "enum", "EPackage", "EReference", + "EString", "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", + "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", + "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", + "transient", "try", "void", "volatile", "while" }; + final public static HashSet blacklist = new HashSet<>(Arrays.asList(keywords)); - + } From 04227a01646b601413b418ebe2630a89e0745296 Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Tue, 11 Apr 2023 16:35:10 +0200 Subject: [PATCH 06/23] MoflonEmfBuilder no longer throws exceptions when there is no model folder --- .../src/org/moflon/emf/build/MoflonEmfBuilder.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/org.moflon.emf.build/src/org/moflon/emf/build/MoflonEmfBuilder.java b/org.moflon.emf.build/src/org/moflon/emf/build/MoflonEmfBuilder.java index 877b0af3..3b91851c 100644 --- a/org.moflon.emf.build/src/org/moflon/emf/build/MoflonEmfBuilder.java +++ b/org.moflon.emf.build/src/org/moflon/emf/build/MoflonEmfBuilder.java @@ -1,5 +1,6 @@ package org.moflon.emf.build; +import java.io.File; import java.util.Arrays; import java.util.Collection; import java.util.Map; @@ -44,6 +45,9 @@ public class MoflonEmfBuilder extends IncrementalProjectBuilder { protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { IProject project = getProject(); IFolder folder = project.getFolder("model"); + if(!folder.exists()) { + return new IProject[] {project}; + } Collection resources = Arrays.asList(folder.members()); Collection genModelResources = resources.stream().filter(r -> r.getName().endsWith(".genmodel")).collect(Collectors.toList()); Collection ecoreResources = resources.stream().filter(r -> r.getName().endsWith(".ecore")).collect(Collectors.toList()); From 0aaeedf36749395a95f0139e512877ebf76e19d2 Mon Sep 17 00:00:00 2001 From: SebastianE Date: Tue, 25 Oct 2022 18:58:53 +0200 Subject: [PATCH 07/23] Revert "+ added flag to allow creation of files that have not been there before during the save process of a smart-resource" This reverts commit 6dde13825a97a039692c6cef6de6ae2382b2a8be. --- .../smartemf/persistence/JDOMXmiParser.java | 365 ++++++++---------- .../persistence/SmartEMFResource.java | 14 +- .../smartemf/persistence/XmiParserUtil.java | 20 +- 3 files changed, 177 insertions(+), 222 deletions(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiParser.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiParser.java index 0aa62382..eafbb7aa 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiParser.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/JDOMXmiParser.java @@ -34,38 +34,38 @@ import org.jdom2.input.SAXBuilder; public class JDOMXmiParser { - + protected final String workspacePath; - + protected Map>> waitingCrossRefs = new HashMap<>(); protected Map>> waitingHRefs = new HashMap<>(); protected Map id2Object = new HashMap<>(); protected Map fqId2Object = new HashMap<>(); protected Map ns2Package = new HashMap<>(); protected Map ns2Factory = new HashMap<>(); - protected Map loadedResources = new HashMap<>(); + protected Map loadedResources = new HashMap<>(); protected URI initialUri = null; - + public JDOMXmiParser(final String workspacePath) { this.workspacePath = workspacePath; } - + public Map getLoadedResources() { return loadedResources; } - + public Map getFqId2ObjectMap() { return fqId2Object; } - + public void addWaitingHRefs(final Map>> hrefs) { waitingHRefs.putAll(hrefs); } - + public Map>> getWaitingHRefs() { return waitingHRefs; } - + public void load(final InputStream is, final Resource resource) throws Exception { SAXBuilder saxBuilder = new SAXBuilder(); Document parsedFile = null; @@ -74,67 +74,63 @@ public void load(final InputStream is, final Resource resource) throws Exception } catch (JDOMException | IOException e) { throw new IOException(e.getMessage(), e.getCause()); } - - if (initialUri == null) { - String resolvedPath = XmiParserUtil.resolveURIToPath(resource.getURI(), workspacePath, false); + + if(initialUri == null) { + String resolvedPath = XmiParserUtil.resolveURIToPath(resource.getURI(), workspacePath); initialUri = URI.createFileURI(resolvedPath); } - + domTreeToModel(parsedFile, resource); loadedResources.put(resource.getURI().toString(), resource); } - - public Resource load(final String uri, final ResourceSet rs) throws Exception { + + public Resource load(final String uri, final ResourceSet rs) throws Exception{ String filePath = XmiParserUtil.resolveURIRelativeToBaseURI(initialUri, URI.createURI(uri), workspacePath); - if (filePath == null) - throw new FileNotFoundException("Relative path " + uri.trim().replace("%20", " ") - + " could not be resolved with the path of the initial uri " - + initialUri.devicePath().trim().replace("%20", " ") + "."); - + if(filePath == null) + throw new FileNotFoundException("Relative path "+uri.trim().replace("%20", " ")+" could not be resolved with the path of the initial uri "+initialUri.devicePath().trim().replace("%20", " ")+"."); + Resource resource = null; - for (Resource loadedResource : rs.getResources()) { - if (XmiParserUtil.relativeURIsAreEqual(initialUri, URI.createURI(uri), loadedResource.getURI(), - workspacePath)) { + for(Resource loadedResource : rs.getResources()) { + if(XmiParserUtil.relativeURIsAreEqual(initialUri, URI.createURI(uri), loadedResource.getURI(), workspacePath)) { resource = loadedResource; break; } } - if (resource == null) { + if(resource == null) { File file = new File(filePath); FileInputStream fis = new FileInputStream(file); resource = new SmartEMFResource(URI.createFileURI(file.getCanonicalPath()), workspacePath); rs.getResources().add(resource); - + JDOMXmiParser subParser = new JDOMXmiParser(workspacePath); subParser.addWaitingHRefs(waitingHRefs); subParser.load(fis, resource); fis.close(); - - loadedResources.putAll(subParser.getLoadedResources()); + + loadedResources.putAll(subParser.getLoadedResources()); fqId2Object.putAll(subParser.getFqId2ObjectMap()); waitingHRefs.putAll(subParser.getWaitingHRefs()); } else { indexForeignResource(resource); } - + loadedResources.put(uri, resource); return resource; } - + public void domTreeToModel(final Document domTree, final Resource resource) throws Exception { Element root = domTree.getRootElement(); Namespace ns = root.getNamespace(); List roots = new LinkedList<>(); - // If there is a root node belonging to the XMI Namespace, than we have multiple - // container objects wrapped within an XML dummy-node to ensure XML compliance - if (XmiParserUtil.XMI_NS.equals(ns.getPrefix())) { + // If there is a root node belonging to the XMI Namespace, than we have multiple container objects wrapped within an XML dummy-node to ensure XML compliance + if(XmiParserUtil.XMI_NS.equals(ns.getPrefix())) { roots.addAll(root.getChildren()); } else { roots.add(root); } - + int id = 0; - for (Element subRoot : roots) { + for(Element subRoot : roots) { // Load the corresponding metamodel and factory Namespace subRootNS = subRoot.getNamespace(); EPackage metamodel = XmiParserUtil.loadMetamodel(subRootNS.getURI()); @@ -143,39 +139,35 @@ public void domTreeToModel(final Document domTree, final Resource resource) thro ns2Factory.put(subRootNS.getPrefix(), factory); // find additional namespaces Set additionalNS = subRoot.getAdditionalNamespaces().stream() - .filter(ns2 -> !ns2.getPrefix().equals(XmiParserUtil.XMI_NS) - && !ns2.getPrefix().equals(XmiParserUtil.XSI_NS) - && !ns2.getPrefix().equals(subRootNS.getPrefix())) - .filter(ns2 -> !ns2Package.containsKey(ns2.getPrefix())).collect(Collectors.toSet()); - - for (Namespace ns2 : additionalNS) { + .filter(ns2 -> !ns2.getPrefix().equals(XmiParserUtil.XMI_NS) && !ns2.getPrefix().equals(XmiParserUtil.XSI_NS) && !ns2.getPrefix().equals(subRootNS.getPrefix())) + .filter(ns2 -> !ns2Package.containsKey(ns2.getPrefix())) + .collect(Collectors.toSet()); + + for(Namespace ns2 : additionalNS) { EPackage additionalMetamodel = XmiParserUtil.loadMetamodel(ns2.getURI()); EFactory additionalFactory = additionalMetamodel.getEFactoryInstance(); ns2Package.put(ns2.getPrefix(), additionalMetamodel); ns2Factory.put(ns2.getPrefix(), additionalFactory); } - + // traverse tree and instantiate classes EObject eRoot = null; - if (roots.size() > 1) { - eRoot = parseDomTree(resource, subRoot, null, subRootNS.getPrefix(), - resource.getURI().toString() + "#/" + id, "/" + id, 0); + if(roots.size() > 1) { + eRoot = parseDomTree(resource, subRoot, null, subRootNS.getPrefix(), resource.getURI().toString()+"#/"+id, "/"+id, 0); id++; } else { - eRoot = parseDomTree(resource, subRoot, null, subRootNS.getPrefix(), - resource.getURI().toString() + "#/", "/", 0); + eRoot = parseDomTree(resource, subRoot, null, subRootNS.getPrefix(), resource.getURI().toString()+"#/", "/", 0); } resource.getContents().add(eRoot); } - + } - + @SuppressWarnings("unchecked") - protected EObject parseDomTree(final Resource resource, Element root, EReference containment, String namespace, - String fqId, String id, int idx) throws Exception { + protected EObject parseDomTree(final Resource resource, Element root, EReference containment, String namespace, String fqId, String id, int idx) throws Exception { EPackage metamodel = null; String currentNamespace = null; - if (root.getNamespace().getPrefix() == null || root.getNamespace().getPrefix().isBlank()) { + if(root.getNamespace().getPrefix() == null || root.getNamespace().getPrefix().isBlank()) { metamodel = ns2Package.get(namespace); currentNamespace = namespace; } else { @@ -183,116 +175,108 @@ protected EObject parseDomTree(final Resource resource, Element root, EReference currentNamespace = root.getNamespace().getPrefix(); } EFactory factory = ns2Factory.get(currentNamespace); - + EClass rootClass = null; String currentId = id; String currentFqId = fqId; String simpleId = null; String simpleFqId = null; - - if (containment == null) { - rootClass = (EClass) metamodel.getEClassifier(root.getName()); + + if(containment == null) { + rootClass = (EClass)metamodel.getEClassifier(root.getName()); } else { Optional typeATR = root.getAttributes().stream() - .filter(atr -> atr.getName().equals(XmiParserUtil.XSI_TYPE) - && atr.getNamespacePrefix().equals(XmiParserUtil.XSI_NS)) - .findFirst(); - if (typeATR.isPresent()) { + .filter(atr -> atr.getName().equals(XmiParserUtil.XSI_TYPE) && atr.getNamespacePrefix().equals(XmiParserUtil.XSI_NS)).findFirst(); + if(typeATR.isPresent()) { String[] exactType = typeATR.get().getValue().split(":"); - // This is obviously an element belonging to a foreign metamodel -> switch to - // suitable EPacakge and Factory but stay in the current namespace + //This is obviously an element belonging to a foreign metamodel -> switch to suitable EPacakge and Factory but stay in the current namespace String metamodelNS = exactType[0]; String className = exactType[1]; metamodel = ns2Package.get(metamodelNS); factory = ns2Factory.get(metamodelNS); - rootClass = (EClass) metamodel.getEClassifier(className); + rootClass = (EClass)metamodel.getEClassifier(className); } else { rootClass = containment.getEReferenceType(); } currentId = id + "/@" + containment.getName() + "." + idx; currentFqId = fqId + "/@" + containment.getName() + "." + idx; - // This a workaround for a useless/annoying xml simplification that occurs when - // a child list is exactly of size 1, then the index is omitted. - if (idx == 0) { + // This a workaround for a useless/annoying xml simplification that occurs when a child list is exactly of size 1, then the index is omitted. + if(idx == 0) { simpleId = id + "/@" + containment.getName(); simpleFqId = fqId + "/@" + containment.getName(); } } - + EObject eRoot = factory.create(rootClass); - + currentId = XmiParserUtil.simplifyID(currentId); currentFqId = XmiParserUtil.simplifyID(currentFqId); - + id2Object.put(currentId, eRoot); fqId2Object.put(currentFqId, eRoot); - - if (simpleId != null) { + + if(simpleId != null) { simpleId = XmiParserUtil.simplifyID(simpleId); simpleFqId = XmiParserUtil.simplifyID(simpleFqId); - + id2Object.put(simpleId, eRoot); fqId2Object.put(simpleFqId, eRoot); } - - if (waitingCrossRefs.containsKey(currentId)) { + + if(waitingCrossRefs.containsKey(currentId)) { waitingCrossRefs.get(currentId).forEach(waitingRef -> waitingRef.accept(eRoot)); waitingCrossRefs.remove(currentId); } - if (simpleId != null && waitingCrossRefs.containsKey(simpleId)) { + if(simpleId != null && waitingCrossRefs.containsKey(simpleId)) { waitingCrossRefs.get(simpleId).forEach(waitingRef -> waitingRef.accept(eRoot)); waitingCrossRefs.remove(simpleId); } - - if (waitingHRefs.containsKey(currentFqId)) { + + if(waitingHRefs.containsKey(currentFqId)) { waitingHRefs.get(currentFqId).forEach(waitingRef -> waitingRef.accept(eRoot)); waitingHRefs.remove(currentFqId); } - - if (simpleFqId != null && waitingCrossRefs.containsKey(simpleFqId)) { + + if(simpleFqId != null && waitingCrossRefs.containsKey(simpleFqId)) { waitingHRefs.get(simpleFqId).forEach(waitingRef -> waitingRef.accept(eRoot)); waitingHRefs.remove(simpleFqId); } - - Map element2Idx = new HashMap<>(); + + Map element2Idx = new HashMap<>(); Map feature2CrossRef = new HashMap<>(); - for (Element element : root.getChildren()) { - if (XmiParserUtil.XMI_NS.equals(element.getNamespace().getPrefix())) + for(Element element : root.getChildren()) { + if(XmiParserUtil.XMI_NS.equals(element.getNamespace().getPrefix())) continue; - - Optional featureOpt = rootClass.getEAllStructuralFeatures().stream() - .filter(sf -> sf.getName().equals(element.getName())).findFirst(); - if (!featureOpt.isPresent()) - throw new IOException("Unkown structual feature: " + element.getName()); - - EStructuralFeature feature = featureOpt.get(); - if (feature instanceof EAttribute) - throw new IOException("Illegal use of EAttribute: " + element.getName()); - - if (!element2Idx.containsKey(feature)) { + + Optional featureOpt = rootClass.getEAllStructuralFeatures().stream().filter(sf -> sf.getName().equals(element.getName())).findFirst(); + if(!featureOpt.isPresent()) + throw new IOException("Unkown structual feature: "+element.getName()); + + EStructuralFeature feature = featureOpt.get(); + if(feature instanceof EAttribute) + throw new IOException("Illegal use of EAttribute: "+element.getName()); + + if(!element2Idx.containsKey(feature)) { element2Idx.put(feature, 0); } - - EReference ref = (EReference) feature; - if (ref.isContainment()) { - if (ref.isMany()) { + + EReference ref = (EReference)feature; + if(ref.isContainment()) { + if(ref.isMany()) { EList objs = (EList) eRoot.eGet(ref); - EObject child = parseDomTree(resource, element, ref, currentNamespace, currentFqId, currentId, - element2Idx.get(feature)); + EObject child = parseDomTree(resource, element, ref, currentNamespace, currentFqId, currentId, element2Idx.get(feature)); objs.add(child); - element2Idx.replace(feature, element2Idx.get(feature) + 1); + element2Idx.replace(feature, element2Idx.get(feature)+1); } else { - EObject child = parseDomTree(resource, element, ref, currentNamespace, currentFqId, currentId, - element2Idx.get(feature)); + EObject child = parseDomTree(resource, element, ref, currentNamespace, currentFqId, currentId, element2Idx.get(feature)); eRoot.eSet(ref, child); - element2Idx.replace(feature, element2Idx.get(feature) + 1); + element2Idx.replace(feature, element2Idx.get(feature)+1); } } else { - if (XmiParserUtil.isHyperref(element)) { + if(XmiParserUtil.isHyperref(element)) { PendingEMFCrossReference pendingCrossref = feature2CrossRef.get(ref); - if (pendingCrossref == null) { - pendingCrossref = new PendingEMFCrossReference(eRoot, ref, (int) root.getChildren().stream() - .filter(elt -> elt.getName().equals(ref.getName())).count()); + if(pendingCrossref == null) { + pendingCrossref = new PendingEMFCrossReference(eRoot, ref, (int)root.getChildren().stream().filter(elt -> elt.getName().equals(ref.getName())).count()); feature2CrossRef.put(ref, pendingCrossref); } Attribute href = element.getAttribute(XmiParserUtil.HREF_ATR); @@ -300,210 +284,195 @@ protected EObject parseDomTree(final Resource resource, Element root, EReference String modelUri = hrefPath[0]; String hrefFQId = null; Resource otherResource = null; - - if (!loadedResources.containsKey(modelUri)) { + + if(!loadedResources.containsKey(modelUri)) { otherResource = load(modelUri, resource.getResourceSet()); - + } else { otherResource = loadedResources.get(modelUri); } - hrefFQId = otherResource.getURI().toString() + "#" + hrefPath[1]; + hrefFQId = otherResource.getURI().toString()+"#"+hrefPath[1]; hrefFQId = XmiParserUtil.simplifyID(hrefFQId); - - if (fqId2Object.containsKey(hrefFQId)) { + + if(fqId2Object.containsKey(hrefFQId)) { EObject hyperref = fqId2Object.get(hrefFQId); - - if (ref.isMany()) { + + if(ref.isMany()) { pendingCrossref.insertObject(hyperref, element2Idx.get(feature)); - element2Idx.replace(feature, element2Idx.get(feature) + 1); + element2Idx.replace(feature, element2Idx.get(feature)+1); } else { pendingCrossref.insertObject(hyperref, 0); } - - if (pendingCrossref.isCompleted()) { + + if(pendingCrossref.isCompleted()) { pendingCrossref.writeBack(); } } else { List> pendingHRefs = waitingHRefs.get(hrefFQId); - if (pendingHRefs == null) { + if(pendingHRefs == null) { pendingHRefs = new LinkedList<>(); waitingHRefs.put(hrefFQId, pendingHRefs); } - + // Make those variables final 'cause java .. final int currentIdx = element2Idx.get(feature); final PendingEMFCrossReference currentPending = pendingCrossref; pendingHRefs.add((eobj) -> { currentPending.insertObject(eobj, currentIdx); - if (currentPending.isCompleted()) { + if(currentPending.isCompleted()) { currentPending.writeBack(); } }); - element2Idx.replace(feature, element2Idx.get(feature) + 1); + element2Idx.replace(feature, element2Idx.get(feature)+1); } } else { - throw new IOException("XML DOM-Tree child: " + element.getName() - + " is neither, a hyperref nor in a containment!"); + throw new IOException("XML DOM-Tree child: "+element.getName()+" is neither, a hyperref nor in a containment!"); } - + } } - - for (Attribute attribute : root.getAttributes()) { - if (XmiParserUtil.XMI_NS.equals(attribute.getNamespace().getPrefix())) + + for(Attribute attribute : root.getAttributes()) { + if(XmiParserUtil.XMI_NS.equals(attribute.getNamespace().getPrefix())) continue; - - if (XmiParserUtil.XSI_NS.equals(attribute.getNamespace().getPrefix())) + + if(XmiParserUtil.XSI_NS.equals(attribute.getNamespace().getPrefix())) continue; - - Optional featureOpt = rootClass.getEAllStructuralFeatures().stream() - .filter(sf -> sf.getName().equals(attribute.getName())).findFirst(); - if (!featureOpt.isPresent()) - throw new IOException("Unkown structual feature: " + attribute.getName()); - - EStructuralFeature feature = featureOpt.get(); - if (feature instanceof EReference) { - EReference ref = (EReference) feature; - if (attribute.getValue().isBlank()) + + Optional featureOpt = rootClass.getEAllStructuralFeatures().stream().filter(sf -> sf.getName().equals(attribute.getName())).findFirst(); + if(!featureOpt.isPresent()) + throw new IOException("Unkown structual feature: "+attribute.getName()); + + EStructuralFeature feature = featureOpt.get(); + if(feature instanceof EReference) { + EReference ref = (EReference)feature; + if(attribute.getValue().isBlank()) continue; - + String[] entries = attribute.getValue().split(" "); - final PendingEMFCrossReference pendingCrossRefs = new PendingEMFCrossReference(eRoot, ref, - entries.length); - for (int i = 0; i < entries.length; i++) { - String entry = (entries[i].contains("#")) ? entries[i].split("#")[1] : entries[i]; + final PendingEMFCrossReference pendingCrossRefs = new PendingEMFCrossReference(eRoot, ref, entries.length); + for(int i = 0; i> otherCrossRefs = waitingCrossRefs.get(entry); - if (otherCrossRefs == null) { + if(otherCrossRefs == null) { otherCrossRefs = new LinkedList<>(); waitingCrossRefs.put(entry, otherCrossRefs); } final int currentIdx = i; otherCrossRefs.add((eobj) -> { pendingCrossRefs.insertObject(eobj, currentIdx); - if (pendingCrossRefs.isCompleted()) + if(pendingCrossRefs.isCompleted()) pendingCrossRefs.writeBack(); }); } } else { - if (id2Object.containsKey(entry)) { + if(id2Object.containsKey(entry)) { pendingCrossRefs.insertObject(id2Object.get(entry), 0); } else { // Remember this crossRef and wait for traversal List> otherCrossRefs = waitingCrossRefs.get(entry); - if (otherCrossRefs == null) { + if(otherCrossRefs == null) { otherCrossRefs = new LinkedList<>(); waitingCrossRefs.put(entry, otherCrossRefs); } otherCrossRefs.add((eobj) -> { pendingCrossRefs.insertObject(eobj, 0); - if (pendingCrossRefs.isCompleted()) + if(pendingCrossRefs.isCompleted()) pendingCrossRefs.writeBack(); }); } } } - if (pendingCrossRefs.isCompleted()) + if(pendingCrossRefs.isCompleted()) pendingCrossRefs.writeBack(); - + } else { EAttribute eAttribute = (EAttribute) feature; - - switch (attribute.getAttributeType()) { + + switch(attribute.getAttributeType()) { case CDATA: eRoot.eSet(eAttribute, XmiParserUtil.stringToValue(eAttribute, attribute.getValue())); break; case ENTITIES: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); case ENTITY: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); case ENUMERATION: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); case ID: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); case IDREF: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); case IDREFS: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); case NMTOKEN: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); case NMTOKENS: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); case NOTATION: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); case UNDECLARED: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); default: - throw new IOException("Unsupported XML attribute type: " + attribute.getAttributeType() - + " for attribute: " + attribute.getName()); - + throw new IOException("Unsupported XML attribute type: "+attribute.getAttributeType()+" for attribute: "+attribute.getName()); + } } } return eRoot; } - + protected void indexForeignResource(final Resource resource) { - if (resource.getContents().size() < 2) { - indexForeignModel(resource.getContents().get(0), null, resource.getURI().toString() + "#/", 0, false); + if(resource.getContents().size() < 2) { + indexForeignModel(resource.getContents().get(0), null, resource.getURI().toString()+"#/", 0, false); } else { int idx = 0; - for (EObject container : resource.getContents()) { - indexForeignModel(container, null, resource.getURI().toString() + "#/" + idx++, 0, false); + for(EObject container : resource.getContents()) { + indexForeignModel(container, null, resource.getURI().toString()+"#/"+idx++, 0, false); } } - + } - + @SuppressWarnings("unchecked") - protected void indexForeignModel(final EObject root, final EReference containment, final String id, int idx, - boolean useSimple) { + protected void indexForeignModel(final EObject root, final EReference containment, final String id, int idx, boolean useSimple) { EClass rootClass = root.eClass(); String rootId = id; - if (containment != null) { - if (useSimple) { + if(containment != null) { + if(useSimple) { rootId = id + "/@" + containment.getName(); } else { rootId = id + "/@" + containment.getName() + "." + idx; } } rootId = XmiParserUtil.simplifyID(rootId); - + fqId2Object.put(rootId, root); - if (waitingHRefs.containsKey(rootId)) { + if(waitingHRefs.containsKey(rootId)) { waitingHRefs.get(rootId).forEach(waitingRef -> waitingRef.accept(root)); waitingHRefs.remove(rootId); } - + // Containments - for (EReference containmentRef : rootClass.getEAllContainments()) { + for(EReference containmentRef : rootClass.getEAllContainments()) { List containees = new LinkedList<>(); - if (containmentRef.isMany()) { + if(containmentRef.isMany()) { containees.addAll((Collection) root.eGet(containmentRef)); } else { EObject containee = (EObject) root.eGet(containmentRef); - if (containee != null) + if(containee != null) containees.add(containee); } int idIDX = 0; - for (EObject containee : containees) { - indexForeignModel(containee, containmentRef, rootId, idIDX, containees.size() == 1); + for(EObject containee : containees) { + indexForeignModel(containee, containmentRef, rootId, idIDX, containees.size()==1); idIDX++; } } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/SmartEMFResource.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/SmartEMFResource.java index f3332d90..86634190 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/SmartEMFResource.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/SmartEMFResource.java @@ -30,8 +30,8 @@ import org.xml.sax.InputSource; /** - * A simplified resource implementation that serializes to XMI. Ignores save - * options. Can enable notification cascading for its contents. + * A simplified resource implementation that serializes to XMI. Ignores save options. Can enable + * notification cascading for its contents. */ public class SmartEMFResource extends UnlockedResourceImpl implements XMIResource { @@ -69,7 +69,7 @@ public EList eAdapters() { @Override public void save(Map options) throws IOException { - String path = XmiParserUtil.resolveURIToPath(uri, workspacePath, true); + String path = XmiParserUtil.resolveURIToPath(uri, workspacePath); if (path == null) throw new FileNotFoundException("Invalid path at: " + uri); @@ -90,8 +90,7 @@ public static void createFoldersIfNecessary(final File file) { @Override public void save(OutputStream outputStream, Map options) throws IOException { - URIConverter.Cipher cipher = (options != null) ? (URIConverter.Cipher) options.get(Resource.OPTION_CIPHER) - : null; + URIConverter.Cipher cipher = (options != null) ? (URIConverter.Cipher) options.get(Resource.OPTION_CIPHER) : null; if (cipher != null) { throw new UnsupportedOperationException("Encryption through cipher is not supported!"); } @@ -120,7 +119,7 @@ public void save(OutputStream outputStream, Map options) throws IOExceptio @Override public void load(Map options) throws IOException { - String path = XmiParserUtil.resolveURIToPath(uri, workspacePath, false); + String path = XmiParserUtil.resolveURIToPath(uri, workspacePath); if (path == null) throw new FileNotFoundException("No valid xmi file present at: " + uri); @@ -147,8 +146,7 @@ public void load(InputStream inputStream, Map options) throws IOException Notification notification = setLoaded(true); isLoading = true; - URIConverter.Cipher cipher = (options != null) ? (URIConverter.Cipher) options.get(Resource.OPTION_CIPHER) - : null; + URIConverter.Cipher cipher = (options != null) ? (URIConverter.Cipher) options.get(Resource.OPTION_CIPHER) : null; if (cipher != null) { throw new UnsupportedOperationException("Encryption through cipher is not supported!"); } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/XmiParserUtil.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/XmiParserUtil.java index f72fb81f..9a7e82f2 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/XmiParserUtil.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/XmiParserUtil.java @@ -27,8 +27,8 @@ public final class XmiParserUtil { final public static String HREF_ATR = "href"; public static boolean URIsAreEqual(final URI uri1, final URI uri2, final String workspacePath) { - String path1 = resolveURIToPath(uri1, workspacePath, false); - String path2 = resolveURIToPath(uri2, workspacePath, false); + String path1 = resolveURIToPath(uri1, workspacePath); + String path2 = resolveURIToPath(uri2, workspacePath); return path1.equals(path2); } @@ -39,7 +39,7 @@ public static boolean relativeURIsAreEqual(final URI baseUri, final URI uri1, fi return path1.equals(path2); } - public static String resolveURIToPath(final URI uri, final String workspacePath, boolean newFile) { + public static String resolveURIToPath(final URI uri, final String workspacePath) { String path = uri.devicePath(); if (path.startsWith("/resource")) { path = path.replaceFirst("/resource", " "); @@ -59,18 +59,6 @@ public static String resolveURIToPath(final URI uri, final String workspacePath, } } - // This might be a new file that has not existed before - if (newFile) { - File parentFolder = new File(parent); - if (!parentFolder.exists()) - parentFolder.mkdirs(); - - try { - return file.getCanonicalPath(); - } catch (IOException e) { - } - } - // Otherwise -> fallback solution // Resolve workspace relative path @@ -109,7 +97,7 @@ public static String resolveURIToPath(final URI uri, final String workspacePath, } public static String resolveURIRelativeToBaseURI(final URI baseUri, final URI uri, final String workspacePath) { - String filePath = resolveURIToPath(uri, workspacePath, false); + String filePath = resolveURIToPath(uri, workspacePath); if (filePath != null) return filePath; From 454d90fac618576b00bde3671377da97851ea93d Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Tue, 11 Jul 2023 00:02:01 +0200 Subject: [PATCH 08/23] fixed npe for notifications that involve string attributes --- .../smartemf/runtime/notification/SmartEMFNotification.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java index fc2bddd7..4a3cd71b 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java @@ -257,11 +257,15 @@ public short getNewShortValue() { @Override public String getOldStringValue() { + if(oldValue == null) + return null; return oldValue.toString(); } @Override public String getNewStringValue() { + if(newValue == null) + return null; return newValue.toString(); } From 4a6ae0da76f3b9ae341717355d0918e67018d75f Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Sat, 29 Jul 2023 17:24:23 +0200 Subject: [PATCH 09/23] fixed a bug where adding an element to a resource did not reset eContainer but opposite container edges --- .../src/org/emoflon/smartemf/runtime/SmartObject.java | 5 +++++ .../emoflon/smartemf/templates/SmartEMFObjectTemplate.xtend | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java index 825dfdeb..c19f6197 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java @@ -387,6 +387,11 @@ public NotifyStatus setContainment(EObject eContainer, EStructuralFeature featur status = setResource(eContainer.eResource(), true); return status; } + + protected void resetContainmentSilently() { + this.eContainer = null; + this.eContainingFeature = null; + } @Override public boolean isContainmentObject() { diff --git a/emfcodegenerator/src/org/emoflon/smartemf/templates/SmartEMFObjectTemplate.xtend b/emfcodegenerator/src/org/emoflon/smartemf/templates/SmartEMFObjectTemplate.xtend index 18303a5e..59aa78bf 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/templates/SmartEMFObjectTemplate.xtend +++ b/emfcodegenerator/src/org/emoflon/smartemf/templates/SmartEMFObjectTemplate.xtend @@ -361,7 +361,13 @@ class SmartEMFObjectTemplate implements CodeTemplate{ } «ENDIF» + «IF feature.container» + if(this.«TemplateUtil.getValidName(feature.name)» != null && value == null) { + resetContainmentSilently(); + } + «ENDIF» this.«TemplateUtil.getValidName(feature.name)» = value; + «IF feature.isMany && !"EFeatureMapEntry".equals(feature.EType.name) && !feature.EType.name.contains("MapEntry")» From 334d7f2220081f2ab0dafd7f1443cc247ef058b7 Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Sat, 29 Jul 2023 23:19:03 +0200 Subject: [PATCH 10/23] fixed a problem where setting a containment edge did not set the resource (recursively) --- .../smartemf/templates/SmartEMFObjectTemplate.xtend | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/templates/SmartEMFObjectTemplate.xtend b/emfcodegenerator/src/org/emoflon/smartemf/templates/SmartEMFObjectTemplate.xtend index 59aa78bf..c4fd3454 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/templates/SmartEMFObjectTemplate.xtend +++ b/emfcodegenerator/src/org/emoflon/smartemf/templates/SmartEMFObjectTemplate.xtend @@ -382,13 +382,14 @@ class SmartEMFObjectTemplate implements CodeTemplate{ «ENDIF» «IF feature.containment» - if(value != null) - status = ((MinimalSObjectContainer) this.«TemplateUtil.getValidName(feature.name)»).setContainment(this, «TemplateUtil.getPackageClassName(feature)».Literals.«TemplateUtil.getLiteral(feature)»); - if(oldValue != null && value != null) { setResourceWithoutChecks(resource); } + if(value != null) + status = ((MinimalSObjectContainer) this.«TemplateUtil.getValidName(feature.name)»).setContainment(this, «TemplateUtil.getPackageClassName(feature)».Literals.«TemplateUtil.getLiteral(feature)»); + + if(status == NotifyStatus.SUCCESS_NO_NOTIFICATION || oldValue != null && value != null) «ENDIF» sendNotification(SmartEMFNotification.createSetNotification(this, «TemplateUtil.getPackageClassName(feature)».Literals.«TemplateUtil.getLiteral(feature)», oldValue, value, -1)); From 559bd41ae32e7dd6306fe19fa85858a693ddc9e4 Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Wed, 2 Aug 2023 17:42:16 +0200 Subject: [PATCH 11/23] fixed missing notifications such as add messages for the ResourceContentSmartEList --- .../src/org/emoflon/smartemf/runtime/SmartObject.java | 10 ++++++++-- .../runtime/collections/ResourceContentSmartEList.java | 1 + .../smartemf/runtime/collections/SmartCollection.java | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java index c19f6197..2eae0a50 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java @@ -409,14 +409,20 @@ protected void sendNotification(Notification n) { protected void sendRemoveAdapterNotification(EObject obj) { if (resource != null) { for (Adapter a : resource.eAdapters()) { + if(obj.eContainingFeature() != null) { + a.notifyChanged(SmartEMFNotification.createRemoveNotification(obj.eContainer(), obj.eContainingFeature(), obj, -1)); + } a.notifyChanged(SmartEMFNotification.createRemovingAdapterNotification(this, null, a, -1)); } } } - + public void sendRemoveAdapterNotificationsRecursively(Adapter adapter) { + if(eContainingFeature() != null) { + adapter.notifyChanged(SmartEMFNotification.createRemoveNotification(eContainer, eContainingFeature(), this, -1)); + } adapter.notifyChanged(SmartEMFNotification.createRemovingAdapterNotification(this, null, adapter, -1)); - + setResourceOfContainments((o) -> o.sendRemoveAdapterNotificationsRecursively(adapter)); } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java index c2b3a374..08a95f2e 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java @@ -41,6 +41,7 @@ public boolean add(T element) { if (element instanceof SmartObject) { resetContainment(element, !resource.equals(element.eResource())); ((SmartObject) element).setResource(resource, true); + sendAddNotification(element); return super.add(element); } else { element.eAdapters().addAll(resource.eAdapters()); diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartCollection.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartCollection.java index b305148c..ae0fdd42 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartCollection.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/SmartCollection.java @@ -88,7 +88,8 @@ public NotifyStatus addInternal(T e, boolean addToEOpposite) { NotifyStatus resultStatus; if (feature.isContainment()) { - resultStatus = ((SmartObject) e).setContainment(eContainer, feature); + var smartObject = ((SmartObject) e); + resultStatus = smartObject.setContainment(eContainer, feature); } else resultStatus = NotifyStatus.SUCCESS_NO_NOTIFICATION; From 791e41be161a5e06f1baf28da92b8d786d93b1d1 Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Thu, 10 Aug 2023 18:49:09 +0200 Subject: [PATCH 12/23] fixed a problem where too many add and remove messages were sent (when adding/removing directly from resources) --- .../runtime/collections/ResourceContentSmartEList.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java index 08a95f2e..99a663cf 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java @@ -41,7 +41,7 @@ public boolean add(T element) { if (element instanceof SmartObject) { resetContainment(element, !resource.equals(element.eResource())); ((SmartObject) element).setResource(resource, true); - sendAddNotification(element); +// sendAddNotification(element); return super.add(element); } else { element.eAdapters().addAll(resource.eAdapters()); @@ -156,8 +156,8 @@ public T remove(int index) { @Override public boolean remove(Object o) { boolean success = super.remove(o); - if (success) - sendRemoveNotification((EObject) o); +// if (success) +// sendRemoveNotification((EObject) o); if (o instanceof SmartObject) { ((SmartObject) o).setResource(null, true); From d8d8608d616597a9756b649c290e5d2d31a6b58f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20M=C3=B6ller?= <45700082+adrianmoeller@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:31:06 +0200 Subject: [PATCH 13/23] Extend copyAll returned result --- .../src/org/moflon/core/utilities/eMoflonEMFUtil.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/org.moflon.core.utilities/src/org/moflon/core/utilities/eMoflonEMFUtil.java b/org.moflon.core.utilities/src/org/moflon/core/utilities/eMoflonEMFUtil.java index 8f4b81e9..13564dae 100644 --- a/org.moflon.core.utilities/src/org/moflon/core/utilities/eMoflonEMFUtil.java +++ b/org.moflon.core.utilities/src/org/moflon/core/utilities/eMoflonEMFUtil.java @@ -1128,7 +1128,7 @@ private static Status createSameNameValidationProblem(GenPackage genPackage) { } /** - * Returns true iff the given {@link GenPackage} contains an {@link EClassifier} + * Returns true if the given {@link GenPackage} contains an {@link EClassifier} * with the same name as the package. * * @param genPackage @@ -1149,9 +1149,9 @@ public static CopyResult copyAll(Collection eObjects) { Map inversed = new HashMap<>(); for (var entry : copier.entrySet()) inversed.put(entry.getValue(), entry.getKey()); - return new CopyResult(result, inversed); + return new CopyResult(result, inversed, new HashMap<>(copier)); } - public record CopyResult(Collection copies, Map copies2originals) { + public record CopyResult(Collection copies, Map copies2originals, Map originals2copies) { } } From 48398872e57eb60af329cbe309b9ca925347e94d Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Tue, 15 Aug 2023 22:17:33 +0200 Subject: [PATCH 14/23] fixed an issue where removing the adapter from the resource led to a stackOverFlow --- .../src/org/emoflon/smartemf/persistence/AdapterList.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/persistence/AdapterList.java b/emfcodegenerator/src/org/emoflon/smartemf/persistence/AdapterList.java index 02304d9e..33390deb 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/persistence/AdapterList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/persistence/AdapterList.java @@ -61,9 +61,10 @@ public boolean add(Adapter e) { @Override public boolean remove(Object o) { boolean remove = adapters.remove(o); - if (remove) + if (remove) { resource.adapterRemoved((Adapter) o); - resource.sendRemoveAdapterMessages((Adapter) o); + resource.sendRemoveAdapterMessages((Adapter) o); + } return remove; } From 6899bd37815875b3078d360c2641df1780b7219a Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Fri, 18 Aug 2023 01:59:55 +0200 Subject: [PATCH 15/23] fixed an issue with missing add messages when putting an element directly into a resource --- .../smartemf/runtime/collections/ResourceContentSmartEList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java index 99a663cf..46eb4306 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java @@ -41,7 +41,7 @@ public boolean add(T element) { if (element instanceof SmartObject) { resetContainment(element, !resource.equals(element.eResource())); ((SmartObject) element).setResource(resource, true); -// sendAddNotification(element); + sendAddNotification(element); return super.add(element); } else { element.eAdapters().addAll(resource.eAdapters()); From 1318dac5c765594fb3cdde58085b8395385fed08 Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Fri, 18 Aug 2023 02:00:27 +0200 Subject: [PATCH 16/23] improved the EMoflonModelVisualiser by using name attributes when available --- .../visualisation/models/EMoflonModelVisualiser.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/org.moflon.core.ui/src/org/moflon/core/ui/visualisation/models/EMoflonModelVisualiser.java b/org.moflon.core.ui/src/org/moflon/core/ui/visualisation/models/EMoflonModelVisualiser.java index 050e6b5a..105bfe6f 100644 --- a/org.moflon.core.ui/src/org/moflon/core/ui/visualisation/models/EMoflonModelVisualiser.java +++ b/org.moflon.core.ui/src/org/moflon/core/ui/visualisation/models/EMoflonModelVisualiser.java @@ -4,7 +4,9 @@ import java.util.Collection; import java.util.Map; +import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.moflon.core.ui.VisualiserUtilities; @@ -68,6 +70,15 @@ private void determineObjectNames(Collection elements, Map Date: Sat, 19 Aug 2023 00:18:02 +0200 Subject: [PATCH 17/23] improved readability of SmartEMFNotification.toString() --- .../notification/SmartEMFNotification.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java index 4a3cd71b..0afa0dee 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/notification/SmartEMFNotification.java @@ -2,6 +2,7 @@ import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EStructuralFeature; +import org.emoflon.smartemf.runtime.SmartObject; public final class SmartEMFNotification implements Notification { @@ -304,15 +305,28 @@ public String toString() { b.append("eventType: "); b.append(getEventTypeAsString()); b.append(", notifier: "); - b.append(notifier); + b.append(objectToString(notifier)); b.append(", feature: "); - b.append(feature); + b.append(feature != null ? feature.getName() : feature); b.append(", oldValue: "); - b.append(oldValue); + b.append(objectToString(oldValue)); b.append(", newValue: "); - b.append(newValue); + b.append(objectToString(newValue)); b.append(")"); return b.toString(); } + + private Object objectToString(Object obj) { + if(obj == null) + return obj; + + if(obj instanceof SmartObject smartObject) { + for(var attribute : smartObject.eClass().getEAllAttributes()) { + if(attribute.getName().equals("name")) + return smartObject.eClass().getName() + "(" + (String) smartObject.eGet(attribute) + ")"; + } + } + return obj.toString(); + } } From eb8192995072bc37e86c7ef3ec1a75929469212f Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Sat, 19 Aug 2023 00:18:24 +0200 Subject: [PATCH 18/23] removed unncessary remove Notifications and readded missing ones --- .../src/org/emoflon/smartemf/runtime/SmartObject.java | 2 +- .../runtime/collections/ResourceContentSmartEList.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java index 2eae0a50..c226cb51 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java @@ -410,7 +410,7 @@ protected void sendRemoveAdapterNotification(EObject obj) { if (resource != null) { for (Adapter a : resource.eAdapters()) { if(obj.eContainingFeature() != null) { - a.notifyChanged(SmartEMFNotification.createRemoveNotification(obj.eContainer(), obj.eContainingFeature(), obj, -1)); +// a.notifyChanged(SmartEMFNotification.createRemoveNotification(obj.eContainer(), obj.eContainingFeature(), obj, -1)); } a.notifyChanged(SmartEMFNotification.createRemovingAdapterNotification(this, null, a, -1)); } diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java index 46eb4306..08a95f2e 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/collections/ResourceContentSmartEList.java @@ -156,8 +156,8 @@ public T remove(int index) { @Override public boolean remove(Object o) { boolean success = super.remove(o); -// if (success) -// sendRemoveNotification((EObject) o); + if (success) + sendRemoveNotification((EObject) o); if (o instanceof SmartObject) { ((SmartObject) o).setResource(null, true); From d85f57982f0c05a4267bf2e50ee01007a635812d Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Sat, 19 Aug 2023 01:10:53 +0200 Subject: [PATCH 19/23] added another message back in or else readded edges cannot be distinguished from removed ones --- .../src/org/emoflon/smartemf/runtime/SmartObject.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java index c226cb51..2eae0a50 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java @@ -410,7 +410,7 @@ protected void sendRemoveAdapterNotification(EObject obj) { if (resource != null) { for (Adapter a : resource.eAdapters()) { if(obj.eContainingFeature() != null) { -// a.notifyChanged(SmartEMFNotification.createRemoveNotification(obj.eContainer(), obj.eContainingFeature(), obj, -1)); + a.notifyChanged(SmartEMFNotification.createRemoveNotification(obj.eContainer(), obj.eContainingFeature(), obj, -1)); } a.notifyChanged(SmartEMFNotification.createRemovingAdapterNotification(this, null, a, -1)); } From fe9e7e0701558bb115dbfbcc34c23a55a414379a Mon Sep 17 00:00:00 2001 From: Lars Fritsche Date: Thu, 12 Oct 2023 09:45:40 +0200 Subject: [PATCH 20/23] small fix for success notifications in smartemf --- .../src/org/emoflon/smartemf/runtime/SmartObject.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java index 2eae0a50..87b56e94 100644 --- a/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java +++ b/emfcodegenerator/src/org/emoflon/smartemf/runtime/SmartObject.java @@ -315,7 +315,7 @@ public NotifyStatus resetContainment() { resource.getContents().remove(this); } - setResource(null, true); + var setResourceState = setResource(null, true); if (eContainingFeature == null) return NotifyStatus.SUCCESS_NO_NOTIFICATION; @@ -326,6 +326,10 @@ public NotifyStatus resetContainment() { eContainingFeature = null; if (oldFeature.isMany()) { + if(setResourceState == NotifyStatus.SUCCESS_NOTIFICATION_SEND) { + ((SmartCollection) oldContainer.eGet(oldFeature)).removeInternal(this, true, false); + return NotifyStatus.SUCCESS_NOTIFICATION_SEND; + } if (((Collection) oldContainer.eGet(oldFeature)).remove(this)) { return NotifyStatus.SUCCESS_NOTIFICATION_SEND; } else { From 67514c295a6f124a7db3e73ecad093be7e9dcbae Mon Sep 17 00:00:00 2001 From: Maximilian Kratz Date: Thu, 12 Oct 2023 11:39:45 +0200 Subject: [PATCH 21/23] Removes non-existing plugins from feature.xml to fix updatesite --- org.moflon.core.feature/feature.xml | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/org.moflon.core.feature/feature.xml b/org.moflon.core.feature/feature.xml index d3b083ce..12d06299 100644 --- a/org.moflon.core.feature/feature.xml +++ b/org.moflon.core.feature/feature.xml @@ -107,20 +107,6 @@ See here for more details on EPL: https://www.eclipse.org/org/documents/epl-v10. version="0.0.0" unpack="false"/> - - - - - - Date: Fri, 19 Jan 2024 15:33:39 +0100 Subject: [PATCH 22/23] fixed an issue where platform:/resource uris were converted to platform:/resource/resource --- .../org/emoflon/smartemf/templates/util/TemplateUtil.xtend | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/org.emoflon.smartemf/src/org/emoflon/smartemf/templates/util/TemplateUtil.xtend b/org.emoflon.smartemf/src/org/emoflon/smartemf/templates/util/TemplateUtil.xtend index daa7d8c9..0af2ff77 100644 --- a/org.emoflon.smartemf/src/org/emoflon/smartemf/templates/util/TemplateUtil.xtend +++ b/org.emoflon.smartemf/src/org/emoflon/smartemf/templates/util/TemplateUtil.xtend @@ -132,7 +132,9 @@ class TemplateUtil { for(genpkg : genModel.genPackages) { val pkgURI = genpkg.NSURI val genModelURI = pkgURI.replace(".ecore", ".genmodel") - val resourceURI = genModelURI.replace("platform:/", "platform:/resource/") + var resourceURI = genModelURI + if(!resourceURI.contains("platform:/resource/")) + resourceURI = resourceURI.replace("platform:/", "platform:/resource/") uriStringToGenModelMap.put(resourceURI, genModel) } } From 0422864874ae92ffcc24fdb9c090609c014e2427 Mon Sep 17 00:00:00 2001 From: Maximilian Kratz Date: Thu, 20 Mar 2025 12:28:34 +0100 Subject: [PATCH 23/23] Properly update all projects to Java 21 --- .../.settings/org.eclipse.jdt.core.prefs | 6 +++--- org.emoflon.smartemf.dependencies/.classpath | 2 +- .../.settings/org.eclipse.jdt.core.prefs | 6 +++--- org.emoflon.smartemf.dependencies/META-INF/MANIFEST.MF | 2 +- org.moflon.core.ui/.settings/org.eclipse.jdt.core.prefs | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/org.emoflon.core.dependencies/.settings/org.eclipse.jdt.core.prefs b/org.emoflon.core.dependencies/.settings/org.eclipse.jdt.core.prefs index d4540a53..3a79233b 100644 --- a/org.emoflon.core.dependencies/.settings/org.eclipse.jdt.core.prefs +++ b/org.emoflon.core.dependencies/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 +org.eclipse.jdt.core.compiler.source=21 diff --git a/org.emoflon.smartemf.dependencies/.classpath b/org.emoflon.smartemf.dependencies/.classpath index 1d64234c..6d4a7d88 100644 --- a/org.emoflon.smartemf.dependencies/.classpath +++ b/org.emoflon.smartemf.dependencies/.classpath @@ -1,6 +1,6 @@ - + diff --git a/org.emoflon.smartemf.dependencies/.settings/org.eclipse.jdt.core.prefs b/org.emoflon.smartemf.dependencies/.settings/org.eclipse.jdt.core.prefs index c05cfdd9..23fa13b1 100644 --- a/org.emoflon.smartemf.dependencies/.settings/org.eclipse.jdt.core.prefs +++ b/org.emoflon.smartemf.dependencies/.settings/org.eclipse.jdt.core.prefs @@ -1,9 +1,9 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=15 -org.eclipse.jdt.core.compiler.compliance=15 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=15 +org.eclipse.jdt.core.compiler.source=21 diff --git a/org.emoflon.smartemf.dependencies/META-INF/MANIFEST.MF b/org.emoflon.smartemf.dependencies/META-INF/MANIFEST.MF index 9cc0eb7f..d288ae76 100644 --- a/org.emoflon.smartemf.dependencies/META-INF/MANIFEST.MF +++ b/org.emoflon.smartemf.dependencies/META-INF/MANIFEST.MF @@ -51,5 +51,5 @@ Export-Package: org.jdom2, org.jdom2.xpath.jaxen, org.jdom2.xpath.util Require-Bundle: org.junit -Bundle-RequiredExecutionEnvironment: JavaSE-15 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Automatic-Module-Name: org.emoflon.smartemf.dependencies diff --git a/org.moflon.core.ui/.settings/org.eclipse.jdt.core.prefs b/org.moflon.core.ui/.settings/org.eclipse.jdt.core.prefs index d4540a53..3a79233b 100644 --- a/org.moflon.core.ui/.settings/org.eclipse.jdt.core.prefs +++ b/org.moflon.core.ui/.settings/org.eclipse.jdt.core.prefs @@ -1,10 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 -org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=17 +org.eclipse.jdt.core.compiler.source=21