| /** |
| * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, 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.internal.common.messages.Messages; |
| import org.eclipse.emf.cdo.internal.common.model.CDOClassInfoImpl; |
| import org.eclipse.emf.cdo.internal.common.model.CDOPackageInfoImpl; |
| import org.eclipse.emf.cdo.internal.common.model.CDOPackageUnitImpl; |
| import org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl; |
| |
| import org.eclipse.net4j.util.io.ExtendedDataInput; |
| import org.eclipse.net4j.util.io.ExtendedDataOutput; |
| |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.Enumerator; |
| import org.eclipse.emf.common.util.TreeIterator; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EDataType; |
| import org.eclipse.emf.ecore.EEnum; |
| import org.eclipse.emf.ecore.EEnumLiteral; |
| import org.eclipse.emf.ecore.EGenericType; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.EcorePackage; |
| import org.eclipse.emf.ecore.InternalEObject; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.ecore.util.FeatureMapUtil; |
| |
| import java.io.IOException; |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.List; |
| |
| /** |
| * @author Eike Stepper |
| * @since 2.0 |
| */ |
| public final class CDOModelUtil |
| { |
| /** |
| * @since 2.0 |
| */ |
| public static final String CORE_PACKAGE_URI = "http://www.eclipse.org/emf/2002/Ecore"; //$NON-NLS-1$ |
| |
| /** |
| * @since 2.0 |
| */ |
| public static final String ROOT_CLASS_NAME = "EObject"; //$NON-NLS-1$ |
| |
| /** |
| * @since 2.0 |
| */ |
| public static final String RESOURCE_PACKAGE_URI = "http://www.eclipse.org/emf/CDO/Eresource/2.0.0"; //$NON-NLS-1$ |
| |
| /** |
| * @since 2.0 |
| */ |
| public static final String RESOURCE_NODE_CLASS_NAME = "CDOResourceNode"; //$NON-NLS-1$ |
| |
| /** |
| * @since 2.0 |
| */ |
| public static final String RESOURCE_FOLDER_CLASS_NAME = "CDOResourceFolder"; //$NON-NLS-1$ |
| |
| /** |
| * @since 2.0 |
| */ |
| public static final String RESOURCE_CLASS_NAME = "CDOResource"; //$NON-NLS-1$ |
| |
| /** |
| * @since 4.0 |
| */ |
| public static final String TYPES_PACKAGE_URI = "http://www.eclipse.org/emf/CDO/Etypes/4.0.0"; //$NON-NLS-1$ |
| |
| /** |
| * @since 4.0 |
| */ |
| public static final String BLOB_CLASS_NAME = "Blob"; //$NON-NLS-1$ |
| |
| /** |
| * @since 4.0 |
| */ |
| public static final String CLOB_CLASS_NAME = "Clob"; //$NON-NLS-1$ |
| |
| private static CDOType[] coreTypes; |
| |
| static |
| { |
| List<CDOType> types = new ArrayList<CDOType>(); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEBigDecimal(), CDOType.BIG_DECIMAL); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEBigInteger(), CDOType.BIG_INTEGER); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEBooleanObject(), CDOType.BOOLEAN_OBJECT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEBoolean(), CDOType.BOOLEAN); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEByteArray(), CDOType.BYTE_ARRAY); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEByteObject(), CDOType.BYTE_OBJECT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEByte(), CDOType.BYTE); |
| registerCoreType(types, EcorePackage.eINSTANCE.getECharacterObject(), CDOType.CHARACTER_OBJECT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEChar(), CDOType.CHAR); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEDate(), CDOType.DATE); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEDoubleObject(), CDOType.DOUBLE_OBJECT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEDouble(), CDOType.DOUBLE); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEFloatObject(), CDOType.FLOAT_OBJECT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEFloat(), CDOType.FLOAT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEIntegerObject(), CDOType.INTEGER_OBJECT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEInt(), CDOType.INT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEJavaClass(), null); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEJavaObject(), null); |
| registerCoreType(types, EcorePackage.eINSTANCE.getELongObject(), CDOType.LONG_OBJECT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getELong(), CDOType.LONG); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEShortObject(), CDOType.SHORT_OBJECT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEShort(), CDOType.SHORT); |
| registerCoreType(types, EcorePackage.eINSTANCE.getEString(), CDOType.STRING); |
| coreTypes = types.toArray(new CDOType[types.size()]); |
| } |
| |
| private static void registerCoreType(List<CDOType> types, EClassifier classifier, CDOType type) |
| { |
| int index = classifier.getClassifierID(); |
| while (index >= types.size()) |
| { |
| types.add(null); |
| } |
| |
| types.set(index, type); |
| } |
| |
| private CDOModelUtil() |
| { |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static boolean isCorePackage(EPackage ePackage) |
| { |
| return CORE_PACKAGE_URI.equals(ePackage.getNsURI()); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static boolean isRoot(EClass eClass) |
| { |
| return isCorePackage(eClass.getEPackage()) && ROOT_CLASS_NAME.equals(eClass.getName()); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static boolean isResourcePackage(EPackage ePackage) |
| { |
| return RESOURCE_PACKAGE_URI.equals(ePackage.getNsURI()); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static boolean isSystemPackage(EPackage ePackage) |
| { |
| return isCorePackage(ePackage) || isResourcePackage(ePackage); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static boolean isResource(EClass eClass) |
| { |
| return isResourcePackage(eClass.getEPackage()) && RESOURCE_CLASS_NAME.equals(eClass.getName()); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static boolean isResourceFolder(EClass eClass) |
| { |
| return isResourcePackage(eClass.getEPackage()) && RESOURCE_FOLDER_CLASS_NAME.equals(eClass.getName()); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static boolean isResourceNode(EClass eClass) |
| { |
| return isResourcePackage(eClass.getEPackage()) |
| && (RESOURCE_NODE_CLASS_NAME.equals(eClass.getName()) || RESOURCE_CLASS_NAME.equals(eClass.getName()) || RESOURCE_FOLDER_CLASS_NAME |
| .equals(eClass.getName())); |
| } |
| |
| /** |
| * @since 4.0 |
| */ |
| public static boolean isTypesPackage(EPackage ePackage) |
| { |
| return TYPES_PACKAGE_URI.equals(ePackage.getNsURI()); |
| } |
| |
| /** |
| * @since 4.0 |
| */ |
| public static boolean isLob(EClassifier eClassifier) |
| { |
| return isTypesPackage(eClassifier.getEPackage()) |
| && (BLOB_CLASS_NAME.equals(eClassifier.getName()) || CLOB_CLASS_NAME.equals(eClassifier.getName())); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static CDOType getType(EStructuralFeature feature) |
| { |
| if (FeatureMapUtil.isFeatureMap(feature)) |
| { |
| return CDOType.FEATURE_MAP_ENTRY; |
| } |
| |
| return CDOModelUtil.getType(feature.getEType()); |
| } |
| |
| public static CDOType getType(int typeID) |
| { |
| return CDOTypeImpl.getType(typeID); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static CDOType getType(EClassifier classifier) |
| { |
| if (classifier instanceof EClass) |
| { |
| return CDOType.OBJECT; |
| } |
| |
| if (classifier instanceof EEnum) |
| { |
| return CDOType.ENUM_ORDINAL; |
| } |
| |
| EDataType eDataType = (EDataType)classifier; |
| EPackage ePackage = eDataType.getEPackage(); |
| |
| if (isCorePackage(ePackage)) |
| { |
| CDOType type = getCoreType(eDataType); |
| if (type != null) |
| { |
| return type; |
| } |
| } |
| else if (isTypesPackage(ePackage)) |
| { |
| String name = eDataType.getName(); |
| if (BLOB_CLASS_NAME.equals(name)) |
| { |
| return CDOType.BLOB; |
| } |
| |
| if (CLOB_CLASS_NAME.equals(name)) |
| { |
| return CDOType.CLOB; |
| } |
| |
| throw new IllegalArgumentException("Illegal data type: " + eDataType); |
| } |
| |
| return CDOType.CUSTOM; |
| } |
| |
| /** |
| * Core types includes also complex data like EAnnotation, and EEnum |
| * |
| * @since 2.0 |
| */ |
| public static CDOType getCoreType(EClassifier eDataType) |
| { |
| int index = eDataType.getClassifierID(); |
| if (0 <= index && index < coreTypes.length) |
| { |
| return coreTypes[index]; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static CDOType getPrimitiveType(Class<? extends Object> primitiveType) |
| { |
| if (primitiveType == String.class) |
| { |
| return CDOType.STRING; |
| } |
| |
| if (primitiveType == Boolean.class) |
| { |
| return CDOType.BOOLEAN; |
| } |
| |
| if (primitiveType == Integer.class) |
| { |
| return CDOType.INT; |
| } |
| |
| if (primitiveType == Double.class) |
| { |
| return CDOType.DOUBLE; |
| } |
| |
| if (primitiveType == Float.class) |
| { |
| return CDOType.FLOAT; |
| } |
| |
| if (primitiveType == Long.class) |
| { |
| return CDOType.LONG; |
| } |
| |
| if (primitiveType == Date.class) |
| { |
| return CDOType.DATE; |
| } |
| |
| if (primitiveType == Byte.class) |
| { |
| return CDOType.BYTE; |
| } |
| |
| if (primitiveType == Character.class) |
| { |
| return CDOType.CHAR; |
| } |
| |
| if (primitiveType == Object[].class) |
| { |
| return CDOType.OBJECT_ARRAY; |
| } |
| |
| if (EEnumLiteral.class.isAssignableFrom(primitiveType) || Enumerator.class.isAssignableFrom(primitiveType)) |
| { |
| return CDOType.ENUM_LITERAL; |
| } |
| |
| throw new IllegalArgumentException(MessageFormat.format(Messages.getString("CDOModelUtil.7"), primitiveType)); //$NON-NLS-1$ |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static CDOPackageInfo getPackageInfo(Object value, CDOPackageRegistry packageRegistry) |
| { |
| if (value instanceof EPackage) |
| { |
| return packageRegistry.getPackageInfo((EPackage)value); |
| } |
| |
| if (value instanceof CDOPackageInfo) |
| { |
| CDOPackageInfo packageInfo = (CDOPackageInfo)value; |
| if (packageInfo.getPackageUnit().getPackageRegistry() == packageRegistry) |
| { |
| return packageInfo; |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static CDOClassInfo getClassInfo(EClass eClass) |
| { |
| synchronized (eClass) |
| { |
| EList<Adapter> adapters = eClass.eAdapters(); |
| CDOClassInfo classInfo = (CDOClassInfo)EcoreUtil.getAdapter(adapters, CDOClassInfo.class); |
| if (classInfo == null) |
| { |
| classInfo = new CDOClassInfoImpl(); |
| adapters.add(classInfo); |
| } |
| |
| return classInfo; |
| } |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static EStructuralFeature[] getAllPersistentFeatures(EClass eClass) |
| { |
| CDOClassInfo classInfo = getClassInfo(eClass); |
| return classInfo.getAllPersistentFeatures(); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static CDOPackageUnit createPackageUnit() |
| { |
| return new CDOPackageUnitImpl(); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static CDOPackageInfo createPackageInfo() |
| { |
| return new CDOPackageInfoImpl(); |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public static void writePackage(ExtendedDataOutput out, EPackage ePackage, boolean zipped, |
| EPackage.Registry packageRegistry) throws IOException |
| { |
| checkCrossResourceURIs(ePackage); |
| |
| byte[] bytes = EMFUtil.getEPackageBytes(ePackage, zipped, packageRegistry); |
| out.writeString(ePackage.getNsURI()); |
| out.writeBoolean(zipped); |
| out.writeByteArray(bytes); |
| } |
| |
| /** |
| * @since 3.0 |
| */ |
| public static void checkCrossResourceURIs(EPackage ePackage) |
| { |
| TreeIterator<EObject> it = ePackage.eAllContents(); |
| while (it.hasNext()) |
| { |
| EObject e = it.next(); |
| for (EObject r : e.eCrossReferences()) |
| { |
| EObject refTarget = null; |
| |
| if (r.eIsProxy()) |
| { |
| String msg = "Package '%s' contains unresolved proxy '%s'"; |
| msg = String.format(msg, ePackage.getNsURI(), ((InternalEObject)r).eProxyURI()); |
| throw new IllegalStateException(msg); |
| } |
| |
| if (r.eResource() != null && r.eResource() != e.eResource()) |
| { |
| // It's a ref into another resource |
| EPackage pkg = null; |
| if (r instanceof EClassifier) |
| { |
| refTarget = r; |
| pkg = ((EClassifier)r).getEPackage(); |
| } |
| else if (r instanceof EStructuralFeature) |
| { |
| refTarget = r; |
| EStructuralFeature feature = (EStructuralFeature)r; |
| EClass ownerClass = (EClass)feature.eContainer(); |
| pkg = ownerClass.getEPackage(); |
| } |
| else if (r instanceof EGenericType) |
| { |
| EGenericType genType = (EGenericType)r; |
| EClassifier c = genType.getEClassifier(); |
| if (c != null) |
| { |
| refTarget = c; |
| pkg = c.getEPackage(); |
| } |
| } |
| |
| if (pkg == null) |
| { |
| continue; |
| } |
| |
| while (pkg.getESuperPackage() != null) |
| { |
| pkg = pkg.getESuperPackage(); |
| } |
| |
| String resourceURI = refTarget.eResource().getURI().toString(); |
| if (!resourceURI.toString().equals(pkg.getNsURI())) |
| { |
| String msg = "URI of the resource (%s) does not match the nsURI (%s) of the top-level package"; |
| msg = String.format(msg, resourceURI, pkg.getNsURI()); |
| throw new IllegalStateException(msg); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * @since 3.0 |
| */ |
| public static EPackage readPackage(ExtendedDataInput in, ResourceSet resourceSet, boolean lookForResource) |
| throws IOException |
| { |
| String uri = in.readString(); |
| boolean zipped = in.readBoolean(); |
| byte[] bytes = in.readByteArray(); |
| return EMFUtil.createEPackage(uri, bytes, zipped, resourceSet, lookForResource); |
| } |
| } |