package org.teiid.designer.core.workspace; import java.util.HashSet; import java.util.Properties; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.ecore.EObject; import org.teiid.core.designer.ModelerCoreException; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.metamodels.core.Annotation; import org.teiid.designer.metamodels.core.ModelAnnotation; /** * @since 8.0 */ public class ModelObjectAnnotationHelper { public static final String EXTENDED_PROPERTY_NAMESPACE = "ext-custom:"; //$NON-NLS-1$ public ModelObjectAnnotationHelper() { super(); } private static String getNamespace( final String str ) { CoreArgCheck.isNotNull(str, "str"); //$NON-NLS-1$ int semiColonIndex = str.indexOf(':') + 1; if (semiColonIndex > 0) { return str.substring(0, semiColonIndex); } return null; } /** * Retrieves the tagged resource <code>Annotation</code> object referenced to a <code>EObject</code> * * @param modelObject the <code>EObject</code>. may not be null * @param forceCreate forces creation of the annotation if it does not exist. * @return the <code>Annotation</code> * @throws ModelerCoreException */ public Annotation getModelObjectAnnotation( final EObject modelObject, final boolean forceCreate ) throws ModelerCoreException { CoreArgCheck.isNotNull(modelObject, "modelObject"); //$NON-NLS-1$ Annotation annotation = ModelerCore.getModelEditor().getAnnotation(modelObject, forceCreate); return annotation; } /** * Retrieves the value of an object stored on an <code>Annotation</code> in the tags map based on the input key * * @param modelObject the <code>EObject</code>. may not be null; * @param key the key for the mapped value. may not be null; * @return the object value stored in the annotation's tags * @throws ModelerCoreException */ public Object getPropertyValue( final EObject modelObject, final String key ) throws ModelerCoreException { CoreArgCheck.isNotNull(modelObject, "modelObject"); //$NON-NLS-1$ CoreArgCheck.isNotNull(key, "key"); //$NON-NLS-1$ Annotation annotation = getModelObjectAnnotation(modelObject, false); if (annotation != null) { return annotation.getTags().get(key); } return null; } /** * Retrieves the value of an object stored on an <code>Annotation</code> in the tags map based on the input key uses upper and * lower case (excluding the namespace which is always lower case). * * @param modelObject the <code>EObject</code>. may not be null; * @param key the key for the mapped value. may not be null; * @return the object value stored in the annotation's tags * @throws ModelerCoreException */ public Object getPropertyValueAnyCase( final EObject modelObject, final String key ) throws ModelerCoreException { CoreArgCheck.isNotNull(modelObject, "modelObject"); //$NON-NLS-1$ CoreArgCheck.isNotNull(key, "key"); //$NON-NLS-1$ Annotation annotation = getModelObjectAnnotation(modelObject, false); if (annotation != null) { int beginIndex = key.indexOf(":"); //$NON-NLS-1$ String upperCase = key.substring(0, beginIndex) + key.substring(beginIndex).toUpperCase(); Object tag = annotation.getTags().get(upperCase); if (tag == null) { String lowerCase = key.substring(0, beginIndex) + key.substring(beginIndex).toLowerCase(); tag = annotation.getTags().get(lowerCase); } return tag; } return null; } /** * Returns all properties who's keys are prefixed with the given name-space prefix * * @param modelObject the <code>EObject</code>. may not be null; * @param namespacePrefix * @return the properties (never <code>null</code>) * @throws ModelWorkspaceException */ public Properties getProperties( final EObject modelObject, final String namespacePrefix ) throws ModelerCoreException { CoreArgCheck.isNotNull(modelObject, "modelObject"); //$NON-NLS-1$ CoreArgCheck.isNotNull(namespacePrefix, "namespacePrefix"); //$NON-NLS-1$ Properties props = new Properties(); Annotation annotation; if (modelObject instanceof Annotation) { annotation = (Annotation)modelObject; } else { annotation = getModelObjectAnnotation(modelObject, false); } if (annotation != null) { EMap tags = annotation.getTags(); Set<Object> keys = tags.keySet(); for (Object nextKey : keys) { String namespace = getNamespace((String)nextKey); if (namespace != null && namespace.equals(namespacePrefix)) { props.put(nextKey, tags.get(nextKey)); } } } return props; } public Properties getAllProperties( final EObject modelObject ) throws ModelerCoreException { CoreArgCheck.isNotNull(modelObject, "modelObject"); //$NON-NLS-1$ Properties props = new Properties(); Annotation annotation = getModelObjectAnnotation(modelObject, false); if (annotation != null) { EMap tags = annotation.getTags(); Set<Object> keys = tags.keySet(); for (Object nextKey : keys) { props.put(nextKey, tags.get(nextKey)); } } return props; } /** * Removes all properties stored on a model object's annotation based on a name-space prefix * * @param modelObject the <code>EObject</code>. may not be null; * @param namespacePrefix the unique prefix for the property key * @throws ModelerCoreException */ public void removeProperties( final EObject modelObject, final String namespacePrefix ) throws ModelerCoreException { CoreArgCheck.isNotNull(modelObject, "modelObject"); //$NON-NLS-1$ CoreArgCheck.isNotNull(namespacePrefix, "namespacePrefix"); //$NON-NLS-1$ Annotation annotation = getModelObjectAnnotation(modelObject, false); if (annotation != null) { EMap tags = annotation.getTags(); Set<Object> keys = new HashSet(tags.keySet()); for (Object nextKey : keys) { String namespace = getNamespace((String)nextKey); if (namespace != null && namespace.equals(namespacePrefix)) { tags.remove(nextKey); } } } } /** * Removes a single property stored on a model object's annotation based on key * * @param modelObject the <code>EObject</code>. Cannot be null; * @param key the unique value for the property key. Cannot be null. * @throws ModelerCoreException if problem obtaining the model object annotation. */ public void removeProperty( final EObject modelObject, final String key ) throws ModelerCoreException { CoreArgCheck.isNotNull(modelObject, "modelObject"); //$NON-NLS-1$ CoreArgCheck.isNotNull(key, "key"); //$NON-NLS-1$ Annotation annotation = getModelObjectAnnotation(modelObject, false); if (annotation != null) { EMap tags = annotation.getTags(); Set<String> keys = new HashSet(tags.keySet()); for (String nextKey : keys) { if (nextKey.equals(key)) { tags.remove(nextKey); break; } } } } /** * Adds a property tag to an object stored on an <code>Annotation</code> in the tags map based on the input key * * @param modelObject the <code>EObject</code>. may not be null; * @param key the key for the mapped value. may not be null; * @param value the object value to store in the annotation * @throws ModelWorkspaceException */ public void addProperty( final EObject modelObject, final String key, final Object value ) throws ModelerCoreException { CoreArgCheck.isNotNull(modelObject, "modelObject"); //$NON-NLS-1$ CoreArgCheck.isNotNull(key, "key"); //$NON-NLS-1$ CoreArgCheck.isNotNull(value, "value"); //$NON-NLS-1$ Annotation annotation = getModelObjectAnnotation(modelObject, true); annotation.getTags().put(key, value); } /** * Determines if an object has extension properties. The object may be an IFile (if it is a model) or an EObject (if the * object is a model object). In the case of IFile, the ModelAnnotation will be used to check for extension properties, since * any properties will be tied to that node. Connection and Translator properties will be excluded from the check for both * IFile and EObject, since these are not extended properties, but part of the connection profile. * * @param object the <code>Object</code>. may not be null; * @throws ModelWorkspaceException */ public boolean hasExtensionProperties( final Object object ) throws ModelerCoreException { CoreArgCheck.isNotNull(object, "object"); //$NON-NLS-1$ boolean hasExtendedProperties = false; Annotation annotation = null; if (object instanceof IFile) { // get model annotation ModelResource modelResource = ModelUtil.getModelResource((IFile)object, false); if (modelResource != null) { ModelAnnotation modelAnnotation = modelResource.getModelAnnotation(); annotation = getModelObjectAnnotation(modelAnnotation, false); if (annotation != null) { hasExtendedProperties = checkForExtendedProperties(annotation); } } } else if (object instanceof EObject) { annotation = getModelObjectAnnotation((EObject)object, false); if (annotation != null) { hasExtendedProperties = checkForExtendedProperties(annotation); } } return hasExtendedProperties; } private boolean checkForExtendedProperties( Annotation annotation ) { for (Object object : annotation.getTags().keySet()) { String key = (String)object; if (key.startsWith(EXTENDED_PROPERTY_NAMESPACE)) { return true; } } return false; } /** * Returns all extended properties, if any, for the given <code>EOBject</code>. * * @param object the <code>Object</code>. may not be null; * @throws ModelWorkspaceException */ public Properties getExtendedProperties( final EObject eObject ) throws ModelerCoreException { CoreArgCheck.isNotNull(eObject, "eObject"); //$NON-NLS-1$ Properties properties = getProperties(eObject, EXTENDED_PROPERTY_NAMESPACE); return properties; } /** * @param modelObject the <code>EObject</code>. may not be null; * @param props the properties stored on the EObjects annotation * @throws ModelerCoreException */ public void addProperties( final EObject modelObject, final Properties props ) throws ModelerCoreException { CoreArgCheck.isNotNull(modelObject, "modelObject"); //$NON-NLS-1$ CoreArgCheck.isNotNull(props, "props"); //$NON-NLS-1$ Annotation annotation = getModelObjectAnnotation(modelObject, true); Set<Object> keys = props.keySet(); for (Object nextKey : keys) { annotation.getTags().put(nextKey, props.get(nextKey)); } } }