blob: a6240cf20be835baed9082be6a9d213cc164c226 [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.LambdaType;
import org.eclipse.ocl.examples.pivot.TupleType;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.executor.PivotReflectivePackage;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
/**
* A PackageServer adapts the primary Package to coordinate the coherent behaviour of a primary and one or more
* secondary Packages as required for Complete OCL package extension.
*/
public class PackageServer extends PackageTracker
{
public static Function<PackageTracker, org.eclipse.ocl.examples.pivot.Package> tracker2package = new Function<PackageTracker, org.eclipse.ocl.examples.pivot.Package>()
{
public org.eclipse.ocl.examples.pivot.Package apply(PackageTracker packageTracker) {
return packageTracker.getTarget();
}
};
/**
* List of all package extensions including this.
*/
private final List<PackageTracker> trackers = new ArrayList<PackageTracker>();
/**
* Map of nested class-name to multi-class server.
*/
private Map<String, TypeServer> typeServers = null;
/**
* Map of nested package-name to multi-package server.
*/
private Map<String, PackageServer> nestedPackageServers = null;
/**
* The Executor package containing the dispatch table representation.
*/
private PivotReflectivePackage executorPackage = null;
protected PackageServer(PackageManager packageManager, org.eclipse.ocl.examples.pivot.Package primaryPackage) {
super(packageManager, primaryPackage);
trackers.add(this);
initContents(this);
}
public void addNestedPackage(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
if (nestedPackageServers == null) {
nestedPackageServers = new HashMap<String, PackageServer>();
}
String packageName = pivotPackage.getName();
String nsURI = pivotPackage.getNsURI();
org.eclipse.ocl.examples.pivot.Package primaryPackage = null;
if (nsURI != null) { // Explicit nsURI for explicit package (merge)
primaryPackage = packageManager.getPackageByURI(nsURI);
if (primaryPackage != null) {
PackageServer packageServer = packageManager.getPackageTracker(primaryPackage).getPackageServer();
if (primaryPackage != pivotPackage) {
packageServer.addSecondaryPackage(pivotPackage);
}
nestedPackageServers.put(packageName, packageServer);
return;
}
}
PackageServer nestedPackageServer = nestedPackageServers.get(packageName);
if (nestedPackageServer == null) {
PackageTracker nestedPackageTracker = (PackageTracker) EcoreUtil.getAdapter(pivotPackage.eAdapters(), packageManager);
if (nestedPackageTracker instanceof PackageClient) {
nestedPackageServer = nestedPackageTracker.getPackageServer();
nestedPackageServers.put(packageName, nestedPackageServer);
}
else if (nestedPackageTracker instanceof PackageServer) {
nestedPackageServers.put(packageName, nestedPackageServer);
packageManager.addedNestedPrimaryPackage(pivotPackage);
}
else {
nestedPackageServer = new PackageServer(packageManager, pivotPackage);
nestedPackageServers.put(packageName, nestedPackageServer);
packageManager.addedNestedPrimaryPackage(pivotPackage);
}
}
else {
nestedPackageServer.addSecondaryPackage(pivotPackage);
}
}
public void addSecondaryPackage(org.eclipse.ocl.examples.pivot.Package secondaryPackage) {
PackageClient packageClient = (PackageClient)EcoreUtil.getAdapter(secondaryPackage.eAdapters(), packageManager);
if (packageClient == null) {
packageClient = new PackageClient(this, secondaryPackage);
}
if (!trackers.contains(packageClient)) {
trackers.add(packageClient);
}
}
void addType(Type pivotType) {
if ((pivotType instanceof LambdaType) || (pivotType instanceof TupleType)) { // FIXME parent not necessarily in place
return;
}
if (typeServers == null) {
typeServers = new HashMap<String, TypeServer>();
}
String className = pivotType.getName();
TypeServer typeServer = typeServers.get(className);
if (typeServer == null) {
typeServer = (TypeServer) EcoreUtil.getAdapter(pivotType.eAdapters(), packageManager);
if (typeServer == null) {
typeServer = new TypeServer(packageManager, pivotType);
}
if (pivotType.getUnspecializedElement() == null) {
typeServers.put(className, typeServer);
}
}
else {
typeServer.addSecondaryType(pivotType);
}
}
void addedNestedPackage(Object nestedObject) {
if (nestedObject instanceof org.eclipse.ocl.examples.pivot.Package) {
org.eclipse.ocl.examples.pivot.Package nestedPackage = (org.eclipse.ocl.examples.pivot.Package)nestedObject;
addNestedPackage(nestedPackage);
}
}
@Override
public void dispose() {
if (!trackers.isEmpty()) {
Collection<PackageTracker> savedPackageTrackers = new ArrayList<PackageTracker>(trackers);
trackers.clear();
for (PackageTracker tracker : savedPackageTrackers) {
if (tracker instanceof PackageClient) {
tracker.dispose();
}
}
}
if (typeServers != null) {
Collection<TypeServer> savedTypeServers = new ArrayList<TypeServer>(typeServers.values());
typeServers.clear();
for (TypeServer typeServer : savedTypeServers) {
typeServer.dispose();
}
typeServers = null;
}
if (nestedPackageServers != null) {
Collection<PackageServer> savedPackageServers = new ArrayList<PackageServer>(nestedPackageServers.values());
nestedPackageServers.clear();
for (PackageServer packageServer : savedPackageServers) {
packageServer.dispose();
}
nestedPackageServers = null;
}
super.dispose();
}
public PivotReflectivePackage getExecutorPackage() {
if (executorPackage == null) {
executorPackage = new PivotReflectivePackage(getMetaModelManager(), target);
}
return executorPackage ;
}
public org.eclipse.ocl.examples.pivot.Package getNestedPackage(String nestedPackageName) {
PackageServer nestedPackageServer = nestedPackageServers.get(nestedPackageName);
return nestedPackageServer != null ? nestedPackageServer.getTarget() : null;
}
@Override
public PackageServer getPackageServer() {
return this;
}
public Iterable<org.eclipse.ocl.examples.pivot.Package> getPackages() {
return Iterables.transform(trackers, tracker2package);
}
public Type getType(String typeName) {
TypeServer typeServer = typeServers.get(typeName);
return typeServer != null ? typeServer.getTarget() : null;
}
@Override
TypeTracker getTypeTracker(Type pivotType) {
if (typeServers == null) {
typeServers = new HashMap<String, TypeServer>();
}
String className = pivotType.getName();
TypeServer typeServer = typeServers.get(className);
if (typeServer == null) {
typeServer = (TypeServer) EcoreUtil.getAdapter(pivotType.eAdapters(), packageManager);
if (typeServer == null) {
typeServer = new TypeServer(packageManager, pivotType);
}
typeServers.put(className, typeServer);
}
return typeServer.getTypeTracker(pivotType);
}
void removedClient(PackageClient packageClient) {
trackers.remove(packageClient);
}
void removedNestedPackage(Object nestedObject) {
if (nestedObject instanceof org.eclipse.ocl.examples.pivot.Package) {
org.eclipse.ocl.examples.pivot.Package nestedPackage = (org.eclipse.ocl.examples.pivot.Package)nestedObject;
PackageServer packageServer = nestedPackageServers.get(nestedPackage.getName());
packageServer.removedPackage(nestedPackage);
}
}
// public void removePackage(Package pivotPackage) {
// removedPackage(pivotPackage);
// }
void removedPackage(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
PackageTracker packageTracker = packageManager.findPackageTracker(pivotPackage);
if (packageTracker == this) {
dispose();
}
else {
trackers.remove(packageTracker);
}
}
}