/** * Copyright (c) 2014 Obeo and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Obeo - initial API and implementation */ package org.eclipse.ocl.pivot.internal.registry; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; 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.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.internal.plugin.CompleteOCLRegistryReader; /** * This registry will be used to hold all complete ocl resources that have been * made available through the extension point. * * @author <a href="mailto:marwa.rostren@obeo.fr">Marwa Rostren</a> */ public class CompleteOCLRegistry { public static final @NonNull CompleteOCLRegistry INSTANCE = new CompleteOCLRegistry(null); /** * A Registration identifies a contribution to a Registry enabling the registry to be rebuilt if a registration is removed. */ public static class Registration { private @NonNull URI resourceURI; private @NonNull Set<String> nsURIs; public Registration(@NonNull URI resourceURI, @NonNull Iterable<String> nsURIs) { this.resourceURI = resourceURI; this.nsURIs = new HashSet<String>(); for (String nsURI : nsURIs) { this.nsURIs.add(nsURI); } } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof Registration)) { return false; } Registration that = (Registration)obj; return resourceURI.equals(that.resourceURI) && nsURIs.equals(that.nsURIs); } @Override public int hashCode() { int hash = resourceURI.hashCode(); for (String nsURI : nsURIs) { hash += nsURI.hashCode(); } return hash; } @Override public String toString() { StringBuilder s = new StringBuilder(); s.append(resourceURI); s.append(" : "); boolean isFirst = true; for (String nsURI : nsURIs) { if (!isFirst) { s.append(","); } s.append(nsURI); isFirst = false; } return s.toString(); } } private final @NonNull Map<String, Set<URI>> nsURI2resourceURIs = new HashMap<String, Set<URI>>(); private @Nullable Map<Registration, Integer> registrations = null; public CompleteOCLRegistry() { this(new HashMap<Registration, Integer>()); } protected CompleteOCLRegistry(@Nullable Map<Registration, Integer> registrations) { this.registrations = registrations; } public synchronized void addRegistration(@NonNull Registration registration) { Map<Registration, Integer> registrations2 = registrations; if (registrations2 == null) { registrations = registrations2 = new HashMap<Registration, Integer>(); } Integer count = registrations2.get(registration); if (count == null) { count = 1; } else { count++; } registrations2.put(registration, count); if (count == 1) { addRegistrationInternal(registration); } } private void addRegistrationInternal(@NonNull Registration registration) { for (String nsURI : registration.nsURIs) { Set<URI> resourceURIs = nsURI2resourceURIs.get(nsURI); if (resourceURIs == null) { resourceURIs = new HashSet<URI>(); nsURI2resourceURIs.put(nsURI, resourceURIs); } resourceURIs.add(registration.resourceURI); } } public synchronized void clear() { Map<Registration, Integer> registrations2 = registrations; if (registrations2 != null) { registrations2.clear(); rebuild(); } } /** * Returns all document resource URIs that provide content for any EPackege nsURI in resourceSet */ public @NonNull Set<URI> getResourceURIs(@NonNull ResourceSet resourceSet) { if (registrations == null) { registrations = new HashMap<Registration, Integer>(); new CompleteOCLRegistryReader(this).readRegistry(); } Set<String> nsURIs = new HashSet<String>(); for (Resource resource : resourceSet.getResources()) { for (TreeIterator<EObject> tit = resource.getAllContents(); tit.hasNext(); ) { EObject eObject = tit.next(); EPackage ePackage = eObject.eClass().getEPackage(); String nsURI = ePackage.getNsURI(); nsURIs.add(nsURI); } } return getResourceURIs(nsURIs); } /** * Returns all document resource URIs that provide content for any of the nsURIs */ public @NonNull Set<URI> getResourceURIs(@NonNull Iterable<String> nsURIs) { Set<URI> documentURIs = new HashSet<URI>(); for (String nsURI : nsURIs) { if (nsURI != null) { Set<URI> resourceURIs = nsURI2resourceURIs.get(nsURI); if (resourceURIs != null) { documentURIs.addAll(resourceURIs); } } } return documentURIs; } private void rebuild() { nsURI2resourceURIs.clear(); Map<Registration, Integer> registrations2 = registrations; if (registrations2 != null) { for (@SuppressWarnings("null")@NonNull Registration registration : registrations2.keySet()) { addRegistrationInternal(registration); } } } public synchronized void removeRegistration(@NonNull Registration registration) { Map<Registration, Integer> registrations2 = registrations; if (registrations2 != null) { Integer count = registrations2.get(registration); if (count != null) { if (--count <= 0) { registrations2.remove(registration); rebuild(); } else { registrations2.put(registration, count); } } } } }