<commit_before>/*******************************************************************************
 * Copyright (c) 2016 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:
 *    <NAME> - initial API and implementation
 *******************************************************************************/
package uk.ac.york.mondo.integration.hawk.emfsplitter;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.hawk.core.IMetaModelResourceFactory;
import org.hawk.core.IStateListener.HawkState;
import org.hawk.core.IVcsManager;
import org.hawk.core.runtime.LocalHawkFactory;
import org.hawk.emf.EMFPackage;
import org.hawk.emf.metamodel.EMFMetaModelResource;
import org.hawk.emf.metamodel.EMFMetaModelResourceFactory;
import org.hawk.emfresource.impl.LocalHawkResourceImpl;
import org.hawk.orientdb.OrientDatabase;
import org.hawk.osgiserver.HManager;
import org.hawk.osgiserver.HModel;
import org.hawk.workspace.Workspace;
import org.mondo.modular.references.ext.IEditorCrossReferences;

/**
 * Integrates Hawk into the cross reference selector dialog for EMF-Splitter. At
 * the moment, it indexes the whole workspace into a local Hawk instance, which
 * is directly accessed through the underlying graph.
 */
public class HawkCrossReferences implements IEditorCrossReferences {

	private static final String HAWK_INSTANCE = "emfsplitter";

	@Override
	public boolean init(String metamodelURI, String modularNature) {
		try {
			final HModel hm = getHawkInstance();
			if (!hm.getRegisteredMetamodels().contains(metamodelURI)) {
				final EPackage epkg = EPackage.Registry.INSTANCE.getEPackage(metamodelURI);
				if (epkg == null) {
					throw new NoSuchElementException(String.format(
							"No metamodel with URL '%s' is available in the global EMF registry.", metamodelURI));
				}

				/*
				 * TODO: this might not deal well with metamodels that also
				 * depend on other metamodels - this method may need to take a
				 * list of metamodels and not just one.
				 */
				final IMetaModelResourceFactory emfFactory = hm.getIndexer().getMetaModelParser(EMFMetaModelResourceFactory.class.getName());
				final String pkgEcore = emfFactory.dumpPackageToString(new EMFPackage(epkg, new EMFMetaModelResource(epkg.eResource(), emfFactory)));
				final File tmpEcore = File.createTempFile("tmp", ".ecore");
				try {
					try (final FileOutputStream fOS = new FileOutputStream(tmpEcore)) {
						fOS.write(pkgEcore.getBytes());
					}

					hm.getIndexer().registerMetamodels(tmpEcore);
				} finally {
					if (tmpEcore.exists()) {
						tmpEcore.delete();
					}
				}
			}
		} catch (Exception e) {
			HawkCrossReferencesPlugin.getDefault().logError(e);
			return false;
		}
		return true;
	}

	@Override
	public boolean finish(String modularNature) {
		// Nothing to do - Hawk shuts down by itself using a workbench listener
		return true;
	}

	@Override
	public boolean isGlobal() {
		// The Hawk Workspace VCS doesn't allow filtering projects yet
		return true;
	}

	@Override
	public boolean isNature(String modularNature) {
		// The Hawk Workspace VCS doesn't allow filtering projects yet
		return true;
	}

	@Override
	public EList<?> getChoicesOfValues(String modularNature, Resource res, EClass anEClass) {
		LocalHawkResourceImpl hawkResource = null;
		try {
			final HModel hawkInstance = getHawkInstance();

			// Look for the Hawk resource in the resource set first
			for (Resource r : res.getResourceSet().getResources()) {
				if (r instanceof LocalHawkResourceImpl) {
					hawkResource = (LocalHawkResourceImpl)r;
					if (hawkResource.getIndexer().getName().equals(HAWK_INSTANCE)) {
						// This is the EMF-Splitter local Hawk resource
						break;
					}
				}
			}

			// If it's not in the resource set, load it and add it to the resource set
			if (hawkResource == null) {
				hawkResource = new LocalHawkResourceImpl(URI.createURI("hawk://"), hawkInstance.getIndexer(), true, Arrays.asList("*"), Arrays.asList("*"));
				hawkResource.load(null);
				res.getResourceSet().getResources().add(hawkResource);
			}

			if (modularNature != null) {
				final EList<EObject> instances = hawkResource.fetchNodes(anEClass, true);

				final List<String> acceptedPrefixes = new ArrayList<>();
				for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
					if (project.getNature(modularNature) != null) {
						project.getFullPath().toString();
					}
				}

				filterByNature:
				for (Iterator<EObject> itInstance = instances.iterator(); itInstance.hasNext(); ) {
					final EObject eob = itInstance.next();
					for (String prefix : acceptedPrefixes) {
						if (eob.eResource().getURI().path().startsWith(prefix)) {
							continue filterByNature;
						}
					}
					itInstance.remove();
				}

				return instances;
			} else if (res != null) {
				return hawkResource.fetchNodesByContainerFragment(anEClass, new Workspace().getLocation(), res.getURI().path());
			} else {
				return hawkResource.fetchNodes(anEClass, true);
			}
		} catch (Exception e) {
			HawkCrossReferencesPlugin.getDefault().logError(e);
			return new BasicEList<Object>();
		}
	}

	/**
	 * Returns the Hawk instance that indexes the whole workspace, ensuring that
	 * it exists and that it is in the {@link HawkState#RUNNING} state.
	 */
	protected HModel getHawkInstance() throws Exception {
		final HManager hawkManager = HManager.getInstance();
		synchronized (hawkManager) {
			HModel hawkInstance = hawkManager.getHawkByName(HAWK_INSTANCE);
			if (hawkInstance == null) {
				final File storageFolder = new File("hawk");

				// TODO: limit plugins to EMF, use Neo4j if available
				hawkInstance = HModel.create(new LocalHawkFactory(), HAWK_INSTANCE, storageFolder,
							storageFolder.toURI().toASCIIString(), OrientDatabase.class.getName(), null, hawkManager,
							hawkManager.getCredentialsStore(), 0, 0);

				final IVcsManager repo = new Workspace();
				hawkInstance.addVCS(repo.getLocation(), repo.getClass().getName(), "", "", false);
			}

			if (!hawkInstance.isRunning()) {
				hawkInstance.start(hawkManager);
				hawkInstance.getIndexer().waitFor(HawkState.RUNNING);
			}
			return hawkInstance;
		}
	}

}
<commit_msg>emfsplitter: checks for res == null in #getChoicesOfValues<commit_after>/*******************************************************************************
 * Copyright (c) 2016 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:
 *    <NAME> - initial API and implementation
 *******************************************************************************/
package uk.ac.york.mondo.integration.hawk.emfsplitter;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.hawk.core.IMetaModelResourceFactory;
import org.hawk.core.IStateListener.HawkState;
import org.hawk.core.IVcsManager;
import org.hawk.core.runtime.LocalHawkFactory;
import org.hawk.emf.EMFPackage;
import org.hawk.emf.metamodel.EMFMetaModelResource;
import org.hawk.emf.metamodel.EMFMetaModelResourceFactory;
import org.hawk.emfresource.impl.LocalHawkResourceImpl;
import org.hawk.orientdb.OrientDatabase;
import org.hawk.osgiserver.HManager;
import org.hawk.osgiserver.HModel;
import org.hawk.workspace.Workspace;
import org.mondo.modular.references.ext.IEditorCrossReferences;

/**
 * Integrates Hawk into the cross reference selector dialog for EMF-Splitter. At
 * the moment, it indexes the whole workspace into a local Hawk instance, which
 * is directly accessed through the underlying graph.
 */
public class HawkCrossReferences implements IEditorCrossReferences {

	private static final String HAWK_INSTANCE = "emfsplitter";

	@Override
	public boolean init(String metamodelURI, String modularNature) {
		try {
			final HModel hm = getHawkInstance();
			if (!hm.getRegisteredMetamodels().contains(metamodelURI)) {
				final EPackage epkg = EPackage.Registry.INSTANCE.getEPackage(metamodelURI);
				if (epkg == null) {
					throw new NoSuchElementException(String.format(
							"No metamodel with URL '%s' is available in the global EMF registry.", metamodelURI));
				}

				/*
				 * TODO: this might not deal well with metamodels that also
				 * depend on other metamodels - this method may need to take a
				 * list of metamodels and not just one.
				 */
				final IMetaModelResourceFactory emfFactory = hm.getIndexer().getMetaModelParser(EMFMetaModelResourceFactory.class.getName());
				final String pkgEcore = emfFactory.dumpPackageToString(new EMFPackage(epkg, new EMFMetaModelResource(epkg.eResource(), emfFactory)));
				final File tmpEcore = File.createTempFile("tmp", ".ecore");
				try {
					try (final FileOutputStream fOS = new FileOutputStream(tmpEcore)) {
						fOS.write(pkgEcore.getBytes());
					}

					hm.getIndexer().registerMetamodels(tmpEcore);
				} finally {
					if (tmpEcore.exists()) {
						tmpEcore.delete();
					}
				}
			}
		} catch (Exception e) {
			HawkCrossReferencesPlugin.getDefault().logError(e);
			return false;
		}
		return true;
	}

	@Override
	public boolean finish(String modularNature) {
		// Nothing to do - Hawk shuts down by itself using a workbench listener
		return true;
	}

	@Override
	public boolean isGlobal() {
		// The Hawk Workspace VCS doesn't allow filtering projects yet
		return true;
	}

	@Override
	public boolean isNature(String modularNature) {
		// The Hawk Workspace VCS doesn't allow filtering projects yet
		return true;
	}

	@Override
	public EList<?> getChoicesOfValues(String modularNature, Resource res, EClass anEClass) {
		LocalHawkResourceImpl hawkResource = null;
		try {
			final HModel hawkInstance = getHawkInstance();

			// Look for the Hawk resource in the resource set first
			if (res != null) {
				for (Resource r : res.getResourceSet().getResources()) {
					if (r instanceof LocalHawkResourceImpl) {
						hawkResource = (LocalHawkResourceImpl) r;
						if (hawkResource.getIndexer().getName().equals(HAWK_INSTANCE)) {
							// This is the EMF-Splitter local Hawk resource
							break;
						}
					}
				}
			}

			// If it's not in the resource set, load it and add it to the resource set
			if (hawkResource == null) {
				hawkResource = new LocalHawkResourceImpl(URI.createURI("hawk://"), hawkInstance.getIndexer(), true, Arrays.asList("*"), Arrays.asList("*"));
				hawkResource.load(null);
				if (res != null) {
					res.getResourceSet().getResources().add(hawkResource);
				}
			}

			if (modularNature != null) {
				final EList<EObject> instances = hawkResource.fetchNodes(anEClass, true);

				final List<String> acceptedPrefixes = new ArrayList<>();
				for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
					if (project.getNature(modularNature) != null) {
						project.getFullPath().toString();
					}
				}

				filterByNature:
				for (Iterator<EObject> itInstance = instances.iterator(); itInstance.hasNext(); ) {
					final EObject eob = itInstance.next();
					for (String prefix : acceptedPrefixes) {
						if (eob.eResource().getURI().path().startsWith(prefix)) {
							continue filterByNature;
						}
					}
					itInstance.remove();
				}

				return instances;
			} else if (res != null) {
				return hawkResource.fetchNodesByContainerFragment(anEClass, new Workspace().getLocation(), res.getURI().path());
			} else {
				return hawkResource.fetchNodes(anEClass, true);
			}
		} catch (Exception e) {
			HawkCrossReferencesPlugin.getDefault().logError(e);
			return new BasicEList<Object>();
		}
	}

	/**
	 * Returns the Hawk instance that indexes the whole workspace, ensuring that
	 * it exists and that it is in the {@link HawkState#RUNNING} state.
	 */
	protected HModel getHawkInstance() throws Exception {
		final HManager hawkManager = HManager.getInstance();
		synchronized (hawkManager) {
			HModel hawkInstance = hawkManager.getHawkByName(HAWK_INSTANCE);
			if (hawkInstance == null) {
				final File storageFolder = new File("hawk");

				// TODO: limit plugins to EMF, use Neo4j if available
				hawkInstance = HModel.create(new LocalHawkFactory(), HAWK_INSTANCE, storageFolder,
							storageFolder.toURI().toASCIIString(), OrientDatabase.class.getName(), null, hawkManager,
							hawkManager.getCredentialsStore(), 0, 0);

				final IVcsManager repo = new Workspace();
				hawkInstance.addVCS(repo.getLocation(), repo.getClass().getName(), "", "", false);
			}

			if (!hawkInstance.isRunning()) {
				hawkInstance.start(hawkManager);
				hawkInstance.getIndexer().waitFor(HawkState.RUNNING);
			}
			return hawkInstance;
		}
	}

}

{'fraction_non_alphanumeric': 0.12906655326387412, 'fraction_numerical': 0.0015592883974767878, 'mean_word_length': 4.1875, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5634538', 'n_tokens_mistral': 4953, 'n_tokens_neox': 4185, 'n_words': 1045}