blob: b6109fd6ae3862c36b974e0355071d60e90dd2ec [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2011 E.D.Willink 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:
* E.D.Willink - initial API and implementation
*
* </copyright>
*
* $Id$
*/
package org.eclipse.ocl.examples.pivot.manager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.ocl.examples.pivot.Library;
import org.eclipse.ocl.examples.pivot.Model;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.utilities.PivotUtil;
/**
* PackageManager encapsulates the knowledge about known packages and their nsURIs.
*/
public class PackageManager
{
/**
* The MetaModelManager for which this PackageManager manages the packages.
*/
protected final MetaModelManager metaModelManager;
/**
* Map from package URI to primary package.
*/
private final Map<String, org.eclipse.ocl.examples.pivot.Package> uri2package = new HashMap<String, org.eclipse.ocl.examples.pivot.Package>();
/**
* Map from package name to package URIs, used solely to support merge of an nsURI-less package such as an OCL stdlib enhancement
* into an nsURI-full package without knowledge of a particular nsURI version.
*/
private final Map<String, List<String>> name2uris = new HashMap<String, List<String>>();
/**
* Map from each merged package to the PackageTracker that supervises its merge. PackageTrackers are only
* created for merged packages, so a missing entry just denotes an unmerged package.
*/
private final Map<org.eclipse.ocl.examples.pivot.Package, PackageTracker> package2tracker = new HashMap<org.eclipse.ocl.examples.pivot.Package, PackageTracker>();
/**
* Map from each merged type to the TypeTracker that supervises its merge. TypeTrackers are only
* created for merged types, so a missing entry just denotes an unmerged type.
*/
private final Map<Type, TypeTracker> type2tracker = new HashMap<Type, TypeTracker>();
protected PackageManager(MetaModelManager metaModelManager) {
this.metaModelManager = metaModelManager;
}
public void addPackage(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
String nsURI = pivotPackage.getNsURI();
org.eclipse.ocl.examples.pivot.Package primaryPackage = null;
if (nsURI != null) { // Explicit nsURI for explicit package (merge)
primaryPackage = getPackageByURI(nsURI);
}
else {
String name = pivotPackage.getName();
if (name != null) { // Null nsURI can merge into same named package
primaryPackage = getPackageByName(name);
}
if (primaryPackage == null) { // Null URI distinct package, so invent a default nsURI
nsURI = PivotUtil.getNsURI(pivotPackage);
primaryPackage = getPackageByURI(nsURI);
}
}
if (primaryPackage != pivotPackage) { // Skip recursive call
if (primaryPackage != null) {
PackageTracker packageTracker = getPackageTracker(primaryPackage);
packageTracker.getPackageServer().addSecondaryPackage(pivotPackage);
}
else {
putPackage(nsURI, pivotPackage);
}
}
}
void addPackageTracker(org.eclipse.ocl.examples.pivot.Package pivotPackage, PackageTracker packageTracker) {
PackageTracker oldTracker = package2tracker.put(pivotPackage, packageTracker);
assert oldTracker == null;
}
void addTypeTracker(Type pivotType, TypeTracker typeTracker) {
TypeTracker oldTracker = type2tracker.put(pivotType, typeTracker);
assert oldTracker == null;
}
void addedNestedPrimaryPackage(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
String nsURI = PivotUtil.getNsURI(pivotPackage);
org.eclipse.ocl.examples.pivot.Package primaryPackage = getPackageByURI(nsURI);
if (primaryPackage == pivotPackage) {
// Recursive call
}
else if (primaryPackage != null) {
throw new IllegalArgumentException("Duplicate nsURI '" + nsURI + "'");
}
else {
putPackage(nsURI, pivotPackage);
}
}
public void dispose() {
if (!package2tracker.isEmpty()) {
Collection<PackageTracker> savedPackageTrackers = new ArrayList<PackageTracker>(package2tracker.values());
package2tracker.clear();
for (PackageTracker packageTracker : savedPackageTrackers) {
if (packageTracker instanceof PackageServer) {
packageTracker.dispose();
}
}
}
if (!type2tracker.isEmpty()) {
Collection<TypeTracker> savedTypeTrackers = new ArrayList<TypeTracker>(type2tracker.values());
type2tracker.clear();
for (TypeTracker typeTracker : savedTypeTrackers) {
typeTracker.dispose();
}
}
uri2package.clear();
name2uris.clear();
}
public PackageTracker findPackageTracker(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
return package2tracker.get(pivotPackage);
}
public TypeTracker findTypeTracker(Type pivotType) {
return type2tracker.get(pivotType);
}
public Iterable<org.eclipse.ocl.examples.pivot.Package> getAllPackages() {
return uri2package.values();
}
public MetaModelManager getMetaModelManager() {
return metaModelManager;
}
public org.eclipse.ocl.examples.pivot.Package getPackageByName(String name) {
List<String> uriList = name2uris.get(name);
if ((uriList == null) || uriList.isEmpty()) {
return null;
}
org.eclipse.ocl.examples.pivot.Package selectedPackage = getPackageByURI(uriList.get(0));
for (int i = 1; i < uriList.size(); i++) {
org.eclipse.ocl.examples.pivot.Package anotherPackage = getPackageByURI(uriList.get(i));
if (anotherPackage != selectedPackage) {
throw new IllegalArgumentException("Ambiguous package name '" + name + "'");
}
}
return selectedPackage;
}
public org.eclipse.ocl.examples.pivot.Package getPackageByURI(String nsURI) {
return uri2package.get(nsURI);
}
public PackageTracker getPackageTracker(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
PackageTracker packageTracker = findPackageTracker(pivotPackage);
if (packageTracker == null) {
packageTracker = (PackageTracker) EcoreUtil.getAdapter(pivotPackage.eAdapters(), this);
if (packageTracker == null) {
packageTracker = new PackageServer(this, pivotPackage);
}
}
return packageTracker;
}
protected void putPackage(String nsURI, org.eclipse.ocl.examples.pivot.Package pivotPackage) {
uri2package.put(nsURI, pivotPackage);
String name = pivotPackage.getName();
if ((name != null) && ((pivotPackage instanceof Library) || !(pivotPackage instanceof Model))) { // BUG 376596
List<String> uriList = name2uris.get(name);
if (uriList == null) {
uriList = new ArrayList<String>();
name2uris.put(name, uriList);
}
if (!uriList.contains(nsURI)) {
uriList.add(nsURI);
}
}
}
void removePackageTracker(PackageTracker packageTracker) {
package2tracker.remove(packageTracker.getTarget());
}
void removeTypeTracker(TypeTracker typeTracker) {
type2tracker.remove(typeTracker.getTarget());
}
}