| /* |
| * Copyright (c) 2009-2012, 2015, 2019 Eike Stepper (Loehne, Germany) 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: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.emf.cdo.common.model; |
| |
| import org.eclipse.emf.cdo.common.model.CDOPackageUnit.Type; |
| |
| import org.eclipse.net4j.util.ObjectUtil; |
| import org.eclipse.net4j.util.om.OMPlatform; |
| |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.impl.EPackageImpl; |
| import org.eclipse.emf.ecore.plugin.EcorePlugin; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| /** |
| * A {@link #INSTANCE singleton} registry for the {@link Type package unit types} of EMF {@link EPackage packages}. |
| * |
| * @author Eike Stepper |
| * @since 2.0 |
| */ |
| public final class CDOPackageTypeRegistry |
| { |
| public static final CDOPackageTypeRegistry INSTANCE = new CDOPackageTypeRegistry(); |
| |
| private static final String ECORE_ID = "org.eclipse.emf.ecore"; //$NON-NLS-1$ |
| |
| private static final String PPID = EcorePlugin.GENERATED_PACKAGE_PPID; |
| |
| private static final String MARKER_FILE = "META-INF/CDO.MF"; //$NON-NLS-1$ |
| |
| private Map<String, CDOPackageUnit.Type> types = new HashMap<String, CDOPackageUnit.Type>(); |
| |
| private Map<String, CDOPackageUnit.Type> bundles = new HashMap<String, CDOPackageUnit.Type>(); |
| |
| private CDOPackageTypeRegistry() |
| { |
| } |
| |
| public synchronized CDOPackageUnit.Type register(EPackage ePackage) |
| { |
| CDOPackageUnit.Type type = getPackageType(ePackage); |
| types.put(ePackage.getNsURI(), type); |
| return type; |
| } |
| |
| public synchronized void registerNative(String packageURI) |
| { |
| types.put(packageURI, CDOPackageUnit.Type.NATIVE); |
| } |
| |
| public synchronized void registerLegacy(String packageURI) |
| { |
| types.put(packageURI, CDOPackageUnit.Type.LEGACY); |
| } |
| |
| public synchronized void registerDynamic(String packageURI) |
| { |
| types.put(packageURI, CDOPackageUnit.Type.DYNAMIC); |
| } |
| |
| public synchronized CDOPackageUnit.Type deregister(String packageURI) |
| { |
| return types.remove(packageURI); |
| } |
| |
| public synchronized CDOPackageUnit.Type lookup(String packageURI) |
| { |
| CDOPackageUnit.Type type = types.get(packageURI); |
| if (type == null) |
| { |
| Object value = EPackage.Registry.INSTANCE.get(packageURI); |
| if (value instanceof EPackage) |
| { |
| EPackage ePackage = (EPackage)value; |
| type = register(ePackage); |
| } |
| |
| if (type == null && OMPlatform.INSTANCE.isExtensionRegistryAvailable()) |
| { |
| type = getTypeFromBundle(packageURI); |
| types.put(packageURI, type); |
| } |
| } |
| |
| return type; |
| } |
| |
| public synchronized CDOPackageUnit.Type lookup(EPackage ePackage) |
| { |
| String packageURI = ePackage.getNsURI(); |
| CDOPackageUnit.Type type = types.get(packageURI); |
| if (type == null) |
| { |
| type = register(ePackage); |
| } |
| |
| return type; |
| } |
| |
| public synchronized void reset() |
| { |
| types.clear(); |
| bundles.clear(); |
| } |
| |
| private CDOPackageUnit.Type getTypeFromBundle(String packageURI) |
| { |
| String bundleID = getBundleID(packageURI); |
| if (bundleID == null) |
| { |
| return CDOPackageUnit.Type.UNKNOWN; |
| } |
| |
| CDOPackageUnit.Type type = bundles.get(bundleID); |
| if (type == null) |
| { |
| org.osgi.framework.Bundle bundle = org.eclipse.core.runtime.Platform.getBundle(bundleID); |
| if (bundle == null) |
| { |
| type = CDOPackageUnit.Type.UNKNOWN; |
| } |
| else if (bundle.getEntry(MARKER_FILE) != null) |
| { |
| type = CDOPackageUnit.Type.NATIVE; |
| } |
| else |
| { |
| type = CDOPackageUnit.Type.LEGACY; |
| } |
| |
| bundles.put(bundleID, type); |
| } |
| |
| return type; |
| } |
| |
| private static String getBundleID(String packageURI) |
| { |
| org.eclipse.core.runtime.IExtensionRegistry registry = org.eclipse.core.runtime.Platform.getExtensionRegistry(); |
| for (org.eclipse.core.runtime.IConfigurationElement element : registry.getConfigurationElementsFor(ECORE_ID, PPID)) |
| { |
| String uri = element.getAttribute("uri"); //$NON-NLS-1$ |
| if (ObjectUtil.equals(uri, packageURI)) |
| { |
| return element.getContributor().getName(); |
| } |
| } |
| |
| return null; |
| } |
| |
| private static CDOPackageUnit.Type getPackageType(EPackage ePackage) |
| { |
| if (ePackage.getClass() == EPackageImpl.class) |
| { |
| return CDOPackageUnit.Type.DYNAMIC; |
| } |
| |
| EPackage topLevelPackage = EMFUtil.getTopLevelPackage(ePackage); |
| EClass eClass = getAnyConcreteEClass(topLevelPackage); |
| if (eClass != null) |
| { |
| EObject testObject = EcoreUtil.create(eClass); |
| if (testObject instanceof CDOObjectMarker) |
| { |
| return CDOPackageUnit.Type.NATIVE; |
| } |
| |
| return CDOPackageUnit.Type.LEGACY; |
| } |
| |
| return null; |
| } |
| |
| private static EClass getAnyConcreteEClass(EPackage ePackage) |
| { |
| for (EClassifier classifier : ePackage.getEClassifiers()) |
| { |
| if (classifier instanceof EClass) |
| { |
| EClass eClass = (EClass)classifier; |
| if (!(eClass.isAbstract() || eClass.isInterface())) |
| { |
| return eClass; |
| } |
| } |
| } |
| |
| for (EPackage subpackage : ePackage.getESubpackages()) |
| { |
| EClass eClass = getAnyConcreteEClass(subpackage); |
| if (eClass != null) |
| { |
| return eClass; |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * A common marker interface for CDO (native) objects. |
| * |
| * @author Eike Stepper |
| * @noextend This interface is not intended to be extended by clients. |
| * @noimplement This interface is not intended to be implemented by clients. |
| */ |
| public static interface CDOObjectMarker |
| { |
| } |
| } |