/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.ui.viewsupport;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.ChangeNotifier;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.views.properties.IPropertySourceProvider;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.core.designer.util.I18nUtil;
import org.teiid.core.designer.util.ResourceNameUtil;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.core.container.Container;
import org.teiid.designer.core.index.IndexUtil;
import org.teiid.designer.core.metamodel.MetamodelDescriptor;
import org.teiid.designer.core.search.runtime.ResourceImportRecord;
import org.teiid.designer.core.workspace.ModelResource;
import org.teiid.designer.core.workspace.ModelUtil;
import org.teiid.designer.core.workspace.ModelWorkspaceException;
import org.teiid.designer.core.workspace.ModelWorkspaceItem;
import org.teiid.designer.core.workspace.ModelWorkspaceManager;
import org.teiid.designer.core.workspace.WorkspaceResourceFinderUtil;
import org.teiid.designer.core.workspace.WorkspaceResourceFinderUtil.FileResourceCollectorVisitor;
import org.teiid.designer.extension.ExtensionPlugin;
import org.teiid.designer.extension.definition.ModelExtensionAssistant;
import org.teiid.designer.extension.definition.ModelObjectExtensionAssistant;
import org.teiid.designer.extension.registry.ModelExtensionRegistry;
import org.teiid.designer.jdbc.JdbcPackage;
import org.teiid.designer.jdbc.JdbcSource;
import org.teiid.designer.metamodels.core.ModelAnnotation;
import org.teiid.designer.metamodels.core.ModelImport;
import org.teiid.designer.metamodels.core.ModelType;
import org.teiid.designer.metamodels.relational.RelationalPackage;
import org.teiid.designer.metamodels.relational.aspects.validation.RelationalStringNameValidator;
import org.teiid.designer.metamodels.relational.extension.CoreModelExtensionAssistant;
import org.teiid.designer.metamodels.relational.extension.CoreModelExtensionConstants;
import org.teiid.designer.ui.PluginConstants;
import org.teiid.designer.ui.UiConstants;
import org.teiid.designer.ui.common.eventsupport.SelectionUtilities;
import org.teiid.designer.ui.common.util.WidgetUtil;
import org.teiid.designer.ui.editors.ModelEditorManager;
import org.teiid.designer.ui.editors.OpenEditorMap;
import org.teiid.designer.ui.properties.ModelObjectAdapterFactoryContentProvider;
import org.teiid.designer.ui.properties.ModelObjectPropertySourceProvider;
import org.teiid.designer.ui.util.DiagramProxy;
/**
* ModelUtilities is a collection of static methods that isolate our connection to ModelerCore and generic model/metamodel
* functionality.
*
* @since 8.0
*/
public abstract class ModelUtilities implements UiConstants {
private static Container workspaceContainer;
private static AdapterFactoryContentProvider emfContentProvider;
private static ModelObjectAdapterFactoryContentProvider modelContentProvider;
private static AdapterFactoryLabelProvider emfLabelProvider;
private static AdapterFactoryItemDelegator emfItemDelegator;
// private static ContainerNotificationManager notificationMgr;
private static ModelObjectPropertySourceProvider propertySourceProvider;
private static ILabelProvider labelProvider;
private static ModelFileCache modelFileCache = new ModelFileCache();
public static final String MODEL_FILE_EXTENSION = ResourceNameUtil.XMI_FILE_EXTENSION;
public static final String VDB_FILE_EXTENSION = ResourceNameUtil.VDB_FILE_EXTENSION;
public static final String XSD_FILE_EXTENSION = ResourceNameUtil.XSD_FILE_EXTENSION;
public static final String MED_FILE_EXTENSION = ResourceNameUtil.MED_FILE_EXTENSION;
public static final String DOT_MODEL_FILE_EXTENSION = ResourceNameUtil.DOT_XMI_FILE_EXTENSION;
public static final String DOT_VDB_FILE_EXTENSION = ResourceNameUtil.DOT_VDB_FILE_EXTENSION;
public static final String DOT_XSD_FILE_EXTENSION = ResourceNameUtil.DOT_XSD_FILE_EXTENSION;
private static final String I18N_PREFIX = I18nUtil.getPropertyPrefix(ModelUtilities.class);
private static final String FILE_DOES_NOT_EXIST_TITLE = getString("fileDoesNotExist.title"); //$NON-NLS-1$
private static final String FILE_DOES_NOT_EXIST_MSG_KEY = "fileDoesNotExist.message"; //$NON-NLS-1$
private static final String CLOSED_PROJECT_TITLE = getString("projectClosed.title"); //$NON-NLS-1$
private static final String CLOSED_PROJECT_MSG_KEY = "projectClosed.message"; //$NON-NLS-1$
private static final String MODEL_CHANGES_PENDING_TITLE = getString("modelChangesPending.title"); //$NON-NLS-1$
private static final String MODEL_CHANGES_PENDING_MSG_KEY = "modelChangesPending.message"; //$NON-NLS-1$
private static final String MODEL_ERRORS_TITLE = getString("modelHasErrors.title"); //$NON-NLS-1$
private static final String MODEL_ERRORS_MSG_KEY = "modelHasErrors.message"; //$NON-NLS-1$
private static final String MODEL_NOT_VALIDATED_TITLE = getString("modelNotValidated.title"); //$NON-NLS-1$
private static final String MODEL_NOT_VALIDATED_MSG_KEY = "modelNotValidated.message"; //$NON-NLS-1$
private static final String MODEL_RESOURCE_NOT_FOUND_MSG_KEY = "modelResourceNotFound.message"; //$NON-NLS-1$
private static final String MODEL_IMPORTED_NOT_FOUND_TITLE = getString("modelHasMissingImports.title"); //$NON-NLS-1$
private static final String MODEL_IMPORTED_NOT_FOUND_MSG_KEY = "modelHasMissingImports.message"; //$NON-NLS-1$
private static final String MODEL_IMPORTED_PROBLEM_MSG_KEY = "importedError"; //$NON-NLS-1$
/**
* @since 4.2
*/
private static String getString( final String id ) {
return Util.getString(I18N_PREFIX + id);
}
/**
* @since 4.2
*/
private static String getString( final String id,
String arg ) {
return Util.getString(I18N_PREFIX + id, arg);
}
/**
* Get the Modeler's Content Provider for navigating the workspace and diving into models
*
* @return
*/
public static ITreeContentProvider getModelContentProvider() {
if (modelContentProvider == null) {
AdapterFactory factory = ModelerCore.getMetamodelRegistry().getAdapterFactory();
modelContentProvider = new ModelObjectAdapterFactoryContentProvider(factory);
}
return modelContentProvider;
}
/**
* Get EMF's Content Provider for navigating EObjects inside models
*
* @return
*/
public static AdapterFactoryContentProvider getEmfAdapterFactoryContentProvider() {
if (emfContentProvider == null) {
AdapterFactory factory = ModelerCore.getMetamodelRegistry().getAdapterFactory();
emfContentProvider = new AdapterFactoryContentProvider(factory);
}
return emfContentProvider;
}
/**
* Get the EMF ItemDelegator for working with EObject properties
*
* @since 4.0
*/
public static AdapterFactoryItemDelegator getEMFItemDelegator() {
if (emfItemDelegator == null) {
AdapterFactory factory = ModelerCore.getMetamodelRegistry().getAdapterFactory();
emfItemDelegator = new AdapterFactoryItemDelegator(factory);
}
return emfItemDelegator;
}
public static AdapterFactoryLabelProvider getAdapterFactoryLabelProvider() {
if (emfLabelProvider == null) {
AdapterFactory factory = ModelerCore.getMetamodelRegistry().getAdapterFactory();
emfLabelProvider = new AdapterFactoryLabelProvider(factory);
}
return emfLabelProvider;
}
/**
* Get the EMF LabelProvider for decorating EObjects
*
* @since 4.0
*/
public static ILabelProvider getEMFLabelProvider() {
if (labelProvider == null) {
labelProvider = new ModelObjectLabelProvider();
}
return labelProvider;
}
/**
* Get the ModelObjectLabelProvider LabelProvider for decorating EObjects
*
* @since 4.0
*/
public static ModelObjectLabelProvider getModelObjectLabelProvider() {
if (labelProvider == null) {
labelProvider = new ModelObjectLabelProvider();
}
return (ModelObjectLabelProvider)labelProvider;
}
/**
* @since 4.0
*/
public static IPropertySourceProvider getEmfPropertySourceProvider() {
if (modelContentProvider == null) {
AdapterFactory factory = ModelerCore.getMetamodelRegistry().getAdapterFactory();
modelContentProvider = new ModelObjectAdapterFactoryContentProvider(factory);
}
return modelContentProvider;
}
/**
* Temporary implementation to determine if the specified resource is a model file.
*
* @param resource
* @return
*/
public static boolean isModelFile( IResource resource ) {
// return ModelUtil.isModelFile(resource);
return modelFileCache.isModelFile(resource);
}
/**
* Indicates if the specified resource is related to modeling (models, VDB, WSDL, etc.).
*
* @param theResource the resource being checked
* @return <code>true</code> if modeling related resource; <code>false</code> otherwise.
* @throws AssertionError if resource is <code>null</code>
* @since 5.0.1
*/
public static boolean isModelingRelatedFile( IResource theResource ) {
CoreArgCheck.isNotNull(theResource);
return (theResource instanceof IFile)
&& (ModelUtilities.isModelFile(theResource) || ModelUtilities.isVdbFile(theResource) || ModelUtilities.isWsdlFile(theResource));
}
/**
* Determines if the specified resource is a vdb file in a valid Modeler Project
*
* @param resource
* @return
*/
public static boolean isVdbFile( IResource resource ) {
boolean result = false;
// check if the extension = ".vdb"
if (resource instanceof IFile) {
String ext = ((IFile)resource).getFileExtension();
if (ext != null && ext.equals(VDB_FILE_EXTENSION)) result = true;
}
return result;
}
/**
* Determines if the specified resource is a WSDL file.
*
* @param theResource the resource being checked
* @return <code>true</code> if a WSDL; <code>false</code> otherwise.
*/
public static boolean isWsdlFile( IResource theResource ) {
boolean result = false;
if (theResource instanceof IFile) {
String ext = ((IFile)theResource).getFileExtension();
if ((ext != null) && ext.equalsIgnoreCase(ResourceNameUtil.WSDL_FILE_EXTENSION)) {
result = true;
}
}
return result;
}
/**
* Indicates if the specified file system file is a WSDL.
* @param theFile the file being checked
* @return <code>true</code>if a WSDL file; <code>false</code> otherwise.
* @since 4.2
*/
public static boolean isWsdlFile(final File theFile) {
String name = theFile.getName();
return name.toLowerCase().endsWith(ResourceNameUtil.DOT_WSDL_FILE_EXTENSION);
}
/**
* Determines if the specified resource is an mxd file in a valid Modeler Project
*
* @param resource the supplied IResource
* @return 'true' if the supplied resource is and mxd file, 'false' if not
*/
public static boolean isMedFile( IResource resource ) {
boolean result = false;
// check if the extension = ".mxd"
if (resource instanceof IFile) {
String ext = ((IFile)resource).getFileExtension();
if (ext != null && ext.equals(MED_FILE_EXTENSION)) result = true;
}
return result;
}
/**
* Helper method that determines that the given resource is a IFile and exists in a modeling project.
*/
public static boolean isModelProjectResource( final IResource resource ) {
if (resource != null) {
IProject proj = resource.getProject();
if (proj != null && ModelerCore.hasModelNature(proj)) {
return true;
}
}
return false;
}
/**
* @param selection the objects being checked
* @return <code>true</code> if all selected objects are model projects or model project members
*/
public static boolean isAllModelProjectMembers(ISelection selection) {
// nothing selected
if (SelectionUtilities.isEmptySelection(selection) || !(selection instanceof IStructuredSelection)) return false;
// check each selected object
IStructuredSelection structuredSelection = (IStructuredSelection)selection;
// only need to check resources and EObjects
for (Object obj : structuredSelection.toArray()) {
if (obj instanceof IResource) {
// return false if resource is not contained in a model project
if (!isModelProjectResource((IResource)obj)) return false;
}
if (obj instanceof EObject) {
// return false if an EObject but not in a model project
if (getModelResourceForModelObject((EObject)obj) == null) return false;
}
}
// all model projects and model project members are selected
return true;
}
/**
* Get the representative {@link IFile} from the given container path and model name.
*
* @param containerPath
* @param modelName
*
* @return {@link IFile} of the model
*
* @throws ModelWorkspaceException
*/
public static IFile getModelFile(String containerPath, String modelName) throws ModelWorkspaceException {
if (containerPath == null || modelName == null) {
return null;
}
IPath modelPath = new Path(containerPath).append(modelName);
if (!modelPath.toString().toLowerCase().endsWith(DOT_MODEL_FILE_EXTENSION)) {
modelPath = modelPath.addFileExtension(MODEL_FILE_EXTENSION);
}
ModelWorkspaceItem item = ModelWorkspaceManager.getModelWorkspaceManager().findModelWorkspaceItem(modelPath, IResource.FILE);
if (item != null) {
return (IFile) item.getCorrespondingResource();
}
return null;
}
/**
* Get a ModelResource for a model file.
*
* @param resourace
* @param forceOpen true if the ModelResource should open in responce to this call, false if it is okay to lazily open the
* resource.
* @return the <code>ModelResource</code>; null only if the resource is not known
* @throws ModelWorkspaceException
*/
public static ModelResource getModelResource( Resource resource,
boolean forceOpen ) {
if (resource == null) {
return null;
}
return ModelerCore.getModelEditor().findModelResource(resource);
}
/**
* Get a ModelResource for a model file.
*
* @param modelFile
* @param forceOpen true if the ModelResource should open in responce to this call, false if it is okay to lazily open the
* resource.
* @return the <code>ModelResource</code>; null only if the resource is not known
*/
public static ModelResource getModelResourceForIFile( IFile modelFile,
boolean forceOpen ) {
if (modelFile == null) {
return null;
}
ModelResource mr = null;
try {
mr = ModelUtil.getModelResource(modelFile, forceOpen);
} catch (ModelWorkspaceException err1) {
String message = UiConstants.Util.getString("ModelUtilities.errorFindingModelResource", modelFile);//$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err1, message);
}
return mr;
}
/**
* Get a <code>ModelResource</code> for a specified <code>EObject</code>
*
* @param an <code>EObject</code> contained within a <code>ModelResource</code>
* @return the <code>ModelResource</code>; null only if the resource is not known
*/
public static ModelResource getModelResourceForModelObject( EObject modelObject ) {
if (modelObject == null) {
return null;
}
if (modelObject instanceof DiagramProxy) {
ModelResource modelResource = ((DiagramProxy)modelObject).getModelResource();
if (modelResource != null) {
return modelResource;
}
return ModelerCore.getModelEditor().findModelResource(((DiagramProxy)modelObject).getTarget());
}
return ModelerCore.getModelEditor().findModelResource(modelObject);
}
/**
* Get a <code>ModelResource</code> for a specified input object. Object may be a <code>ModelResource</code>, an
* <code>EObject</code>, an <code>IFile</code> or a <code>Resource</code>
*
* @param an <code>EObject</code> contained within a <code>ModelResource</code>
* @return the <code>ModelResource</code>; null only if the resource is not known
* @since 5.0.2
*/
public static ModelResource getModelResource( Object object ) {
if (object == null) {
return null;
}
if (object instanceof ModelResource) {
return (ModelResource)object;
}
if (object instanceof IFile) {
return getModelResourceForIFile((IFile)object, true);
}
if (object instanceof EObject) {
return getModelResourceForModelObject((EObject)object);
}
if (object instanceof Resource) {
ModelResource mr = null;
mr = getModelResource((Resource)object, true);
return mr;
}
return null;
}
public static IProject getProject(Object object) {
ModelResource mr = getModelResource(object);
try {
return mr.getCorrespondingResource().getProject();
} catch (ModelWorkspaceException ex) {
String message = "[ModelUtilities.getProject()] ERROR: exception finding project"; //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, ex, message);
}
return null;
}
/**
*
* @param modelObject the eObject
* @return the model name containing the model object
*/
public static String getModelName(EObject modelObject) {
try {
return ModelUtilities.getModelResource(modelObject).getCorrespondingResource().getName();
} catch (Exception ex) {
String message = "[ModelUtilities.getModelName()] ERROR: exception finding model name"; //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, ex, message);
}
return null;
}
/**
* Obtain the WorkspaceContainer for this application.
*
* @return
*/
public static Container getWorkspaceContainer() throws CoreException {
if (workspaceContainer == null) {
workspaceContainer = ModelerCore.getModelContainer();
}
return workspaceContainer;
}
/**
* Indicates if a model exists in the workspace with the specified UUID.
*
* @param theUuid the UUID being checked
* @return <code>true</code> if a model exists; <code>false</code> otherwise.
* @throws CoreException if problem getting project resources
* @throws ModelWorkspaceException if problem getting ModelResource or UUID of a model
*/
public static boolean isModelInWorkspace( String theUuid ) throws CoreException, ModelWorkspaceException {
if (theUuid == null || theUuid.length() == 0) {
return false;
}
boolean result = false;
IWorkspace workspace = ModelerCore.getWorkspace();
IProject[] projects = workspace.getRoot().getProjects();
if ((projects != null) && (projects.length > 0)) {
PROJECT_LOOP: for (int i = 0; i < projects.length; i++) {
IResource[] resources = projects[i].members();
if ((resources != null) && (resources.length > 0)) {
for (int j = 0; j < resources.length; j++) {
if (isModelFile(resources[j])) {
ModelResource modelResource = ModelUtil.getModelResource((IFile)resources[j], false);
String uuid = modelResource.getUuid();
if ((uuid != null) && uuid.equals(theUuid)) {
result = true;
break PROJECT_LOOP;
}
}
}
}
}
}
return result;
}
/**
* Add a NotifyChangedListener NOTE: This the <code>INotifyChangedListener</code> is a non-UI listener that simplifies wiring
* of components to the EMF notification framework. !!!!! BE SURE !!!!! .... to remove your UI component as a listener also or
* it will become a memory leak.... heap hog, or whatever you want to call it.
*/
public static void addNotifyChangedListener( INotifyChangedListener listener ) {
try {
Container workspaceContainer = getWorkspaceContainer();
if (workspaceContainer == null) return;
ChangeNotifier changeNotifier = workspaceContainer.getChangeNotifier();
if (changeNotifier == null) return;
if( changeNotifier.contains(listener) ) return;
changeNotifier.addListener(listener);
//System.out.println(" >>> ModelUtilities.addNotifyChangedListener() Adding New Listener = " + listener.getClass().getSimpleName());
} catch (CoreException e) {
e.printStackTrace(System.err);
}
}
/**
* Remove a NotifyChangedListener NOTE: This the <code>INotifyChangedListener</code> is a non-UI listener that simplifies
* wiring of components to the EMF notification framework. !!!!! BE SURE !!!!! .... to remove your UI component as a listener
* also or it will become a memory leak.... heap hog, or whatever you want to call it.
*/
public static void removeNotifyChangedListener( INotifyChangedListener listener ) {
try {
getWorkspaceContainer().getChangeNotifier().removeListener(listener);
//System.out.println(" >>> ModelUtilities.addNotifyChangedListener() Removing Listener = " + listener.getClass().getSimpleName());
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
/**
* return the Designer's contribution to a property source
*
* @return
* @since 5.0
*/
public static ModelObjectPropertySourceProvider getPropertySourceProvider() {
if (propertySourceProvider == null) {
propertySourceProvider = new ModelObjectPropertySourceProvider();
}
return propertySourceProvider;
}
/**
* Determine if the specified ModelResource supports the Description property.
*
* @param modelResource
* @return
*/
public static boolean supportsModelDescription( IResource resource ) {
boolean result = false;
if (isModelFile(resource)) {
result = true;
if (ModelUtil.isXsdFile(resource)) {
result = false;
}
}
return result;
}
/**
* Set the description on the specified ModelResource.
*
* @param model
* @param description
*/
public static void setModelDescription( ModelResource modelResource,
String description ) {
if (!isReadOnly(modelResource)) {
try {
ModelAnnotation annotation = modelResource.getModelAnnotation();
if (annotation != null) {
annotation.setDescription(description);
} else {
UiConstants.Util.log(IStatus.ERROR,
getString("ModelUtilities.nullModelAnnotation", modelResource.getPath().toString())); //$NON-NLS-1$
}
} catch (ModelWorkspaceException ex) {
String message = getString("ModelUtilities.setModelDescriptionError", modelResource.toString()); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, ex, message);
}
}
}
/**
* Get the description from the specified ModelResource.
*
* @param model
* @return the description for this file. will not return null.
*/
public static String getModelDescription( ModelResource model ) {
String result = PluginConstants.EMPTY_STRING;
try {
result = model.getDescription();
} catch (ModelWorkspaceException ex) {
String message = getString("ModelUtilities.getModelDescriptionError", model.toString()); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, ex, message);
}
if (result == null) {
result = PluginConstants.EMPTY_STRING;
}
return result;
}
/**
* Return the virtual model state of the specified model resource.
*
* @param modelResource
* @return true if model resource is a virtual model.
*/
public static boolean isVirtual( ModelResource modelResource ) {
boolean virtualState = false;
if (modelResource != null) {
try {
virtualState = modelResource.getModelType().getValue() == ModelType.VIRTUAL;
} catch (ModelWorkspaceException e) {
String message = "[ModelUtilities.isVirtual()] ERROR: exception accessing ModelType"; //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, e, message);
}
}
return virtualState;
}
/**
* Return the physical model state of the specified model resource.
*
* @param modelResource
* @return true if model resource is a physical model.
*/
public static boolean isPhysical( ModelResource modelResource ) {
boolean physicalState = false;
if (modelResource != null) {
try {
physicalState = modelResource.getModelType().getValue() == ModelType.PHYSICAL;
} catch (ModelWorkspaceException e) {
String message = "[ModelUtilities.isPhysical()] ERROR: exception accessing ModelType"; //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, e, message);
}
}
return physicalState;
}
public static boolean isLogical( ModelResource modelResource ) {
boolean result = false;
if (modelResource != null) {
try {
result = modelResource.getModelType().getValue() == ModelType.LOGICAL;
} catch (ModelWorkspaceException e) {
String message = "[ModelUtilities.isVirtual()] ERROR: exception accessing ModelType"; //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, e, message);
}
}
return result;
}
public static boolean isReadOnly( ModelResource modelResource ) {
// consider it read-only until proven otherwise
boolean result = true;
if (modelResource != null) {
// the modelResource must be open in an editor or else it is read-only
if (OpenEditorMap.getInstance().isEditorOpen(modelResource)) {
// then check the read-only status on the file
result = modelResource.isReadOnly();
}
}
return result;
}
/**
* Indicates if the specified resource is a real filesystem resource. Eclipse saves workbench state when it closes. Each part
* is responsible for saving it's own state. One example is the <code>ModelExplorerResourceNavigator</code> saves the expanded
* and selected state of it's tree. If a resource is deleted outside of Eclipse, and Eclipse is restarted it will create
* <code>IResource</code>s for those deleted resources so that it can restore it's state. The corresponding
* <code>IResource</code> still indicates that it exists and is NOT a phantom. This method uses <code>java.io.File</code> to
* check existence.
*
* @param theResource the resource whose existence is being requested
* @return <code>true</code> if resource exists on the filesystem; <code>false</code> otherwise.
*/
public static boolean existsOnFilesystem( IResource theResource ) {
boolean result = false;
if (theResource != null && theResource.getLocation() != null) {
result = new File(theResource.getLocation().toOSString()).exists();
}
return result;
}
public static boolean areModelResourcesSame( EObject eObj1,
EObject eObj2 ) {
ModelResource mr1 = getModelResourceForModelObject(eObj1);
ModelResource mr2 = getModelResourceForModelObject(eObj2);
if (mr1 != null && mr2 != null && mr1.equals(mr2)) return true;
return false;
}
public static boolean supportsDiagrams( final ModelResource modelResource ) {
boolean result = false;
if (modelResource != null) {
MetamodelDescriptor md = null;
try {
md = modelResource.getPrimaryMetamodelDescriptor();
} catch (ModelWorkspaceException e) {
String message = "[ModelUtilities.supportsDiagrams()] ERROR: finding supports diagrams. Resource = " + modelResource; //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, e, message);
}
if (md != null) result = md.supportsDiagrams();
}
return result;
}
/**
* Method returns whether or not an object's model resource supports diagrams. This is determined finding a model resource for
* an arbitrary object, getting it's primary metamodel descriptor and asking the simple question. A model resource may exist
* for any <code>EObject</code>, <code>ModelResource</code>, <code>IFile</code> or <code>Resource</code>
*
* @param input
* @return <code>true</code> if model resource supports diagrams; <code>false</code> otherwise.
*/
public static boolean supportsDiagrams( Object input ) {
MetamodelDescriptor md = null;
boolean result = false;
if (input != null) {
try {
if (input instanceof EObject && ((EObject)input).eResource() != null) {
md = ModelerCore.getModelEditor().getMetamodelDescriptor((EObject)input);
} else if (input instanceof ModelResource) {
md = (MetamodelDescriptor)input;
} else if (input instanceof IFile) {
ModelResource mr = ModelUtil.getModelResource((IFile)input, false);
if (mr != null) md = mr.getPrimaryMetamodelDescriptor();
} else if (input instanceof Resource) {
ModelResource mr = getModelResource((Resource)input, false);
if (mr != null) md = mr.getPrimaryMetamodelDescriptor();
}
if (md != null) {
result = md.supportsDiagrams();
}
} catch (ModelWorkspaceException e) {
String message = "[ModelUtilities.supportsDiagrams(Object)] ERROR: finding supports diagrams. Object = " + input; //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, e, message);
}
}
return result;
}
// /**
// * Determine if the proposed model name is valid, and return an error message if it is not.
// *
// * @param proposedName
// * @return null if the name is valid, or an error message if it is not.
// */
// public static String validateModelName( String proposedName,
// String fileExtension ) {
// if (proposedName == null || proposedName.equals(PluginConstants.EMPTY_STRING)) {
// return Util.getString("ModelUtilities.zeroLengthFileMessage"); //$NON-NLS-1$
// }
//
// boolean removedValidExtension = false;
// if (proposedName.endsWith(fileExtension)) {
// proposedName = proposedName.substring(0, proposedName.lastIndexOf(fileExtension));
// removedValidExtension = true;
// }
//
// if (proposedName.indexOf('.') != -1) {
// if (!removedValidExtension) {
// return Util.getString("ModelUtilities.illegalExtensionMessage", fileExtension); //$NON-NLS-1$
// }
// }
//
// // BML TODO: Add I18n PROPERTY For zeroLengthFileMessage
// if (proposedName.equals(PluginConstants.EMPTY_STRING)) {
// return Util.getString("ModelUtilities.zeroLengthFileMessage"); //$NON-NLS-1$
// }
//
// final ValidationResultImpl result = new ValidationResultImpl(proposedName);
// CoreValidationRulesUtil.validateStringNameChars(result, proposedName, null);
// if (result.hasProblems()) {
// return result.getProblems()[0].getMessage();
// }
//
// if (fileExtension != null) {
// String reservedError = null;
// if (fileExtension.equalsIgnoreCase(DOT_MODEL_FILE_EXTENSION) || fileExtension.equalsIgnoreCase(MODEL_FILE_EXTENSION)) {
// reservedError = modelNameReservedValidation(proposedName);
//
// if (reservedError != null) {
// return reservedError;
// }
// } else if (fileExtension.equalsIgnoreCase(DOT_VDB_FILE_EXTENSION)
// || fileExtension.equalsIgnoreCase(VDB_FILE_EXTENSION)) {
// reservedError = vdbNameReservedValidation(proposedName);
//
// if (reservedError != null) {
// return reservedError;
// }
// } else if (fileExtension.equalsIgnoreCase(DOT_XSD_FILE_EXTENSION)
// || fileExtension.equalsIgnoreCase(XSD_FILE_EXTENSION)) {
// reservedError = schemaNameReservedValidation(proposedName);
//
// if (reservedError != null) {
// return reservedError;
// }
// }
// }
//
// return null;
// }
/**
* Determine if the proposed model name is reserved name or not, and return an error message if it IS.
*
* @param proposedName
* @return null if the name is valid, or an error message if it is not.
*/
public static String modelNameReservedValidation( String proposedName ) {
boolean invalid = ResourceNameUtil.isReservedModelName(proposedName);
if (invalid) {
return Util.getString("ModelUtilities.modelNameIsReservedError", proposedName); //$NON-NLS-1$
}
return null;
}
/**
* Determine if the proposed schema model name is reserved name or not, and return an error message if it IS.
*
* @param proposedName
* @return null if the name is valid, or an error message if it is not.
*/
public static String schemaNameReservedValidation( String proposedName ) {
boolean invalid = ResourceNameUtil.isReservedSchemaName(proposedName);
if (invalid) {
return Util.getString("ModelUtilities.schemaNameIsReservedError", proposedName); //$NON-NLS-1$
}
return null;
}
/**
* Determine if the proposed schema model name is reserved name or not, and return an error message if it IS.
*
* @param proposedName
* @return null if the name is valid, or an error message if it is not.
*/
public static String vdbNameReservedValidation( String proposedName ) {
boolean invalid = ResourceNameUtil.isReservedVdbName(proposedName);
if (invalid) {
return Util.getString("ModelUtilities.vdbNameIsReservedError", proposedName); //$NON-NLS-1$
}
return null;
}
/**
* Method returns list of IResources defined by ModelResource import list. Only those resources that are open in the current
* workspace will be returned.
*
* @see allDependenciesOpenInWorkspace(ModelResource targetModelResource) to assess whether or not the returned list is
* complete or not.
* @param targetIFile
* @return
* @since 4.2
*/
public static Collection getResourcesUsedBy( IResource targetIFile ) {
if (targetIFile == null) {
return Collections.EMPTY_LIST;
}
List modelImports = null;
Collection result = Collections.EMPTY_LIST;
ModelResource targetModelResource = null;
try {
// Find Model Resource
targetModelResource = ModelUtil.getModelResource((IFile)targetIFile, false);
if (targetModelResource != null) {
modelImports = targetModelResource.getModelImports();
}
} catch (ModelWorkspaceException err) {
String message = Util.getString("ModelUtilities.errorFindingImports", targetModelResource); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err, message);
}
if (modelImports != null && !modelImports.isEmpty()) {
result = new ArrayList(modelImports.size());
for (Iterator iter = modelImports.iterator(); iter.hasNext();) {
Object importObject = iter.next();
String modelPath = null;
if (importObject instanceof ModelImport) {
modelPath = ((ModelImport)importObject).getPath();
} else if (importObject instanceof ResourceImportRecord) {
modelPath = ((ResourceImportRecord)importObject).getImportedPath();
}
// If the URI is to the Teiid Designer built-in datatypes resource or to one
// of the Emf XMLSchema resources then continue since there is no
// ModelReference to add.
if (modelPath == null || WorkspaceResourceFinderUtil.isGlobalResource(modelPath)) {
continue;
}
// Verify that the model has an IResource
IResource resource = WorkspaceResourceFinderUtil.findIResource(modelPath);
if (resource != null && !resource.equals(targetIFile)) {
result.add(resource);
}
}
}
if (result.isEmpty()) return Collections.EMPTY_LIST;
return result;
}
/**
* Method returns list of ModelResources defined by ModelResource import list. Only those resources that are open in the
* current workspace will be returned.
*
* @see allDependenciesOpenInWorkspace(ModelResource targetModelResource) to assess whether or not the returned list is
* complete or not.
* @param targetModelResource
* @return
* @since 4.2
*/
public static Collection getResourcesUsedBy( ModelResource targetModelResource ) {
if (targetModelResource == null) {
return Collections.EMPTY_LIST;
}
List modelImports = null;
Collection result = Collections.EMPTY_LIST;
try {
modelImports = targetModelResource.getModelImports();
} catch (ModelWorkspaceException err) {
String message = Util.getString("ModelUtilities.errorFindingImports", targetModelResource); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err, message);
}
if (modelImports != null && !modelImports.isEmpty()) {
result = new ArrayList(modelImports.size());
for (Iterator iter = modelImports.iterator(); iter.hasNext();) {
Object importObject = iter.next();
String modelPath = null;
if (importObject instanceof ModelImport) {
modelPath = ((ModelImport)importObject).getPath();
} else if (importObject instanceof ResourceImportRecord) {
modelPath = ((ResourceImportRecord)importObject).getImportedPath();
}
// If the URI is to the Teiid Designer built-in datatypes resource or to one
// of the Emf XMLSchema resources then continue since there is no
// ModelReference to add.
if (modelPath == null || WorkspaceResourceFinderUtil.isGlobalResource(modelPath)) {
continue;
}
// Verify that the model has an IResource
IResource resource = WorkspaceResourceFinderUtil.findIResource(modelPath);
ModelResource mr = null;
if (resource != null) {
try {
mr = ModelUtil.getModelResource((IFile)resource, false);
} catch (ModelWorkspaceException err1) {
String message = Util.getString("ModelUtilities.errorFindingModelResource", resource);//$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err1, message);
}
}
if (mr != null && !mr.equals(targetModelResource)) result.add(mr);
}
}
if (result.isEmpty()) return Collections.EMPTY_LIST;
return result;
}
/**
* Method returns list of ModelResources defined by ModelResource import list. Only those resources that are open in the
* current workspace will be returned.
*
* @see allDependenciesOpenInWorkspace(ModelResource targetModelResource) to assess whether or not the returned list is
* complete or not.
* @param targetModelResource
* @return
* @since 4.2
*/
public static boolean allDependenciesOpenInWorkspace( ModelResource targetModelResource ) {
if (targetModelResource == null) {
return true;
}
boolean result = true;
List modelImports = null;
try {
modelImports = targetModelResource.getModelImports();
} catch (ModelWorkspaceException err) {
String message = "[ModelUtilities.allDependenciesOpenInWorkspace()] ERROR: finding model inports. Resource = " + targetModelResource; //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err, message);
}
if (modelImports != null && !modelImports.isEmpty()) {
for (Iterator iter = modelImports.iterator(); iter.hasNext();) {
Object importObject = iter.next();
String modelPath = null;
if (importObject instanceof ModelImport) {
modelPath = ((ModelImport)importObject).getPath();
} else if (importObject instanceof ResourceImportRecord) {
modelPath = ((ResourceImportRecord)importObject).getImportedPath();
}
// If the URI is to the Teiid Designer built-in datatypes resource or to one
// of the Emf XMLSchema resources then continue since there is no
// ModelReference to add.
if (modelPath == null || WorkspaceResourceFinderUtil.isGlobalResource(modelPath)) {
continue;
}
// Verify that the model has an IResource
IResource resource = WorkspaceResourceFinderUtil.findIResource(modelPath);
ModelResource mr = null;
if (resource != null) {
try {
mr = ModelUtil.getModelResource((IFile)resource, false);
} catch (ModelWorkspaceException err1) {
String message = "[ModelUtilities.allDependenciesOpenInWorkspace()] ERROR: finding model resource. IFile = " + resource; //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err1, message);
}
if (mr == null) result = false;
} else {
result = false;
}
if (!result) break;
}
}
return result;
}
/**
* Method returns if one model resource is a dependent of another.
*
* @param targetModelResource
* @param dependentModelResource
* @return true of dependent model resource, false if not.
* @since 4.2
*/
public static boolean isDependent( ModelResource targetModelResource,
ModelResource dependentModelResource ) {
if (targetModelResource == null) {
return false;
}
if (getResourcesUsedBy(targetModelResource).contains(dependentModelResource)) return true;
return false;
}
/**
* Method returns list of ModelResources defined by ModelResource import list. Only those resources that are open in the
* current workspace will be returned.
*
* @see allDependenciesOpenInWorkspace(ModelResource targetModelResource) to assess whether or not the returned list is
* complete or not.
* @param targetModelResource
* @param dependentModelResource
* @return true of dependent model resource, false if not.
* @since 4.2
*/
public static boolean isDependent( IResource targetResource,
IResource dependentResource ) {
if (targetResource == null) {
return false;
}
if (getResourcesUsedBy(targetResource).contains(dependentResource)) return true;
return false;
}
/**
* Checks for the following conditions on all model files: 1) Must exist in the workspace 2) Must have been validated since
* last save 3) Must not have any validation errors 4) If dirty, notify user and allow chance to cancel Also, if no models are
* stale, the method returns false.
*
* @return true if the action may proceed, otherwise false.
* @since 4.2
*/
public static boolean verifyWorkspaceValidationState( Collection iFiles,
Object source,
String failString ) {
boolean result = true;
Collection dirtyModels = ModelEditorManager.getDirtyResources();
// iterate through the models, as long as result remains TRUE
for (Iterator iter = iFiles.iterator(); iter.hasNext() && result;) {
final IFile file = (IFile)iter.next();
// each file must exist in the workspace
if (file == null) {
// do nothing. Shouldn't get here.
} else if (!file.exists()) {
// Cannot find file in the workspace - cannot continue
final String message = getString(FILE_DOES_NOT_EXIST_MSG_KEY, file.getFullPath().makeRelative().toString())
+ failString;
MessageDialog.openError(null, FILE_DOES_NOT_EXIST_TITLE, message);
result = false;
} else {
if (!file.getProject().isOpen()) {
// must be in an open project
final String message = getString(CLOSED_PROJECT_MSG_KEY, file.getFullPath().makeRelative().toString())
+ failString;
MessageDialog.openError(null, CLOSED_PROJECT_TITLE, message);
result = false;
} else if (dirtyModels.contains(file)) {
// see if the user wants to save changes first
final String message = getString(MODEL_CHANGES_PENDING_MSG_KEY, file.getFullPath().makeRelative().toString())
+ failString;
MessageDialog.openError(null, MODEL_CHANGES_PENDING_TITLE, message);
result = false;
// MessageDialog dialog = new MessageDialog(null,
// MODEL_CHANGES_PENDING_TITLE,
// null, // accept the default window icon
// message,
// MessageDialog.QUESTION,
// new String[] {IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL},
// 0 );
//
// result = dialog.open() == MessageDialog.OK; //MessageDialog.openQuestion(null, MODEL_CHANGES_PENDING_TITLE,
// message);
} else if (requiresValidation(file)) {
// the file must have been validated since last save
final String message = getString(MODEL_NOT_VALIDATED_MSG_KEY, file.getFullPath().makeRelative().toString())
+ failString;
MessageDialog.openError(null, MODEL_NOT_VALIDATED_TITLE, message);
result = false;
} else if (hasErrors(file, source)) {
// the file must not have any errors
final String message = getString(MODEL_ERRORS_MSG_KEY, file.getFullPath().makeRelative().toString())
+ failString;
MessageDialog.openError(null, MODEL_ERRORS_TITLE, message);
result = false;
}
}
}
return result;
}
/**
* Checks for the following conditions on all model files: 1) Must exist in the workspace 2) Must have been validated since
* last save 3) Must not have any validation errors 4) If dirty, notify user and allow chance to cancel Also, if no models are
* stale, the method returns false. This method will not check dependencies.
*
* @return true if the action may proceed, otherwise false.
* @since 4.2
* @see #verifyWorkspaceValidationState(IFile, Object, String, boolean)
*/
public static boolean verifyWorkspaceValidationState( IFile iFile,
Object source,
String failString ) {
return verifyWorkspaceValidationState(iFile, source, failString, false);
}
/**
* Checks for the following conditions on all model files: 1) Must exist in the workspace 2) Must have been validated since
* last save 3) Must not have any validation errors 4) If dirty, notify user and allow chance to cancel Also, if no models are
* stale, the method returns false.
*
* @return true if the action may proceed, otherwise false.
* @since 4.2
*/
public static boolean verifyWorkspaceValidationState( IFile iFile,
Object source,
String failString,
boolean checkDependencies ) {
return verifyWorkspaceValidationState(iFile, source, failString, checkDependencies, null, new ArrayList());
}
/**
* Checks for the following conditions on all model files: 1) Must exist in the workspace 2) Must have been validated since
* last save 3) Must not have any validation errors 4) If dirty, notify user and allow chance to cancel Also, if no models are
* stale, the method returns false.
*
* @param instigator the name of the file or process causing the check for dependencies. Really only used when
* checkDependencies is true.
* @param theProcessedFiles the list of files that already have been verified
* @return true if the action may proceed, otherwise false.
* @since 4.2
*/
private static boolean verifyWorkspaceValidationState( IFile iFile,
Object source,
String failString,
boolean checkDependencies,
IFile instigator,
List theProcessedFiles ) {
boolean result = true;
// each file must exist in the workspace
if (iFile == null) {
// do nothing. Shouldn't get here.
result = false;
} else if (!iFile.exists()) {
// Cannot find file in the workspace - cannot continue
showVerifyErrorDialog(FILE_DOES_NOT_EXIST_TITLE, FILE_DOES_NOT_EXIST_MSG_KEY, iFile, failString, instigator);
result = false;
} else {
Collection dirtyModels = ModelEditorManager.getDirtyResources();
if (!iFile.getProject().isOpen()) {
// must be in an open project
showVerifyErrorDialog(CLOSED_PROJECT_TITLE, CLOSED_PROJECT_MSG_KEY, iFile, failString, instigator);
result = false;
} else if (dirtyModels.contains(iFile)) {
// see if the user wants to save changes first
showVerifyErrorDialog(MODEL_CHANGES_PENDING_TITLE, MODEL_CHANGES_PENDING_MSG_KEY, iFile, failString, instigator);
result = false;
} else if (requiresValidation(iFile)) {
// the file must have been validated since last save
showVerifyErrorDialog(MODEL_NOT_VALIDATED_TITLE, MODEL_NOT_VALIDATED_MSG_KEY, iFile, failString, instigator);
result = false;
} else if (hasErrors(iFile, source)) {
// the file must not have any errors
showVerifyErrorDialog(MODEL_ERRORS_TITLE, MODEL_ERRORS_MSG_KEY, iFile, failString, instigator);
result = false;
} else if (checkDependencies) { // Everything is good so far. Check dependencies?
// only want to process files that haven't been processed before or there is a possibility
// of an infinite loop when models import each other (ref Defect 19713)
if (!theProcessedFiles.contains(iFile)) {
theProcessedFiles.add(iFile);
result = verifyDependencyWorkspaceValidationState(iFile, source, failString, instigator, theProcessedFiles);
}
// no prompting here... done in above method.
} // endif -- "switch" block for different checks
} // endif -- file is null
return result;
}
/**
* @param dialogTitleText
* @param messageKey
* @param iFile the file to check
* @param failString
* @param instigator the file that started the check. Used to detected dependencies.
*/
private static void showVerifyErrorDialog( String dialogTitleText,
String messageKey,
IFile iFile,
String failString,
IFile instigator ) {
String msgStr = getString(messageKey, iFile.getFullPath().makeRelative().toString());
String fullMessage;
if (instigator != null) {
// there is a greater model that depends upon this one:
fullMessage = getString(MODEL_IMPORTED_PROBLEM_MSG_KEY, instigator.getFullPath().makeRelative().toString()) + msgStr
+ failString;
} else {
fullMessage = msgStr + failString;
} // endif
MessageDialog.openError(null, dialogTitleText, fullMessage);
}
/**
* This method analyzes the dependencies of the specified IFile.
*
* @param iFile
* @param source
* @param failString
* @param theProcessedFiles the list of files that already have been verified
* @return true if the children are in the workspace and are validated and have no errors.
* @see #verifyWorkspaceValidationState(IFile, Object, String, boolean)
*/
private static boolean verifyDependencyWorkspaceValidationState( IFile iFile,
Object source,
String failString,
IFile instigator,
List theProcessedFiles ) {
// if this is the parent of everything, set the instigator for those below:
if (instigator == null) {
instigator = iFile;
} else if (instigator.equals(iFile)) {
// stop processing -- circular dependency
return true;
} // endif
try {
// first, check that all dependencies are in the workspace:
boolean allDepsPresent = allDependenciesOpenInWorkspace(ModelUtil.getModelResource(iFile, true));
if (!allDepsPresent) {
final String message = getString(MODEL_IMPORTED_NOT_FOUND_MSG_KEY,
instigator.getFullPath().makeRelative().toString())
+ failString;
MessageDialog.openError(null, MODEL_IMPORTED_NOT_FOUND_TITLE, message);
return false;
} // endif -- deps not present in WS
} catch (ModelWorkspaceException ex) {
String message = Util.getString("ModelUtilities.errorFindingDependents", iFile); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, ex, message);
} // endtry
// everything is in an open project in the workspace; check each for validity:
Collection c = getResourcesUsedBy(iFile);
Iterator iter = c.iterator();
while (iter.hasNext()) {
IFile depFile = (IFile)iter.next();
if (!verifyWorkspaceValidationState(depFile, source, failString, true, instigator, theProcessedFiles)) { // always
// check deps
// a dependency below this one had a problem; short-cut out:
return false;
} // endif -- dependency verify problem
} // endwhile -- all dependencies
// got through everything OK, say so:
return true;
}
/**
* Method returns a collection of all resources in the workspace that are model files.
*
* @return
* @since 4.2
*/
public static Collection getAllWorkspaceResources() {
if (ModelerCore.getModelWorkspace() == null)
return Collections.emptyList();
if (ModelerCore.getWorkspace() == null || ModelerCore.getWorkspace().getRoot() == null)
return Collections.emptyList();
FileResourceCollectorVisitor visitor = new FileResourceCollectorVisitor() {
@Override
public boolean visit(IResource resource) {
if (! resource.exists() || ! getResourceFilter().accept(resource) )
return false;
IPath path = resource.getFullPath();
// Do not process file names starting with '.' since these
// are considered reserved for Eclipse specific files
if (path.lastSegment().charAt(0) == '.') {
return false;
}
if (isModelFile(resource))
addResource(resource);
return true;
}
};
WorkspaceResourceFinderUtil.getProjectFileResources(visitor);
return visitor.getFileResources();
}
/**
* Finds and returns an IResource based on a full model name with "xmi" extension
*
* @param modelNameWithExtension
* @return
* @since 5.0
*/
public static IResource findModelByName( final String modelNameWithExtension ) {
Collection allWorkspaceModels = getAllWorkspaceResources();
if (!allWorkspaceModels.isEmpty()) {
IResource theIResource = null;
for (Iterator iter = allWorkspaceModels.iterator(); iter.hasNext();) {
theIResource = (IResource)iter.next();
if (theIResource.getName().equalsIgnoreCase(modelNameWithExtension)) {
return theIResource;
}
}
}
return null;
}
/**
* Convenience method to obtain a list of ModelResource instances which contain dependencies to the input model resource
*
* @param resource
* @return Collection of ModelResource's
* @since 4.2
*/
public static Collection getResourcesThatUse( ModelResource resource ) {
Collection result = Collections.EMPTY_LIST;
IResource theResource = resource.getResource();
// Get dependants
Collection dependants = WorkspaceResourceFinderUtil.getResourcesThatUse(theResource, IResource.DEPTH_ZERO);
Iterator it = dependants.iterator();
IResource nextRes = null;
ModelResource mo = null;
try {
while (it.hasNext()) {
nextRes = (IResource)it.next();
mo = ModelUtil.getModelResource((IFile)nextRes, true);
if (mo != null) {
if (result.isEmpty()) {
result = new ArrayList();
}
result.add(mo);
}
}
} catch (ModelWorkspaceException err) {
String message = getString(MODEL_RESOURCE_NOT_FOUND_MSG_KEY, nextRes == null ? "" : nextRes.getFullPath().toString()); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err, message);
}
return result;
}
public static void getDependentPhysicalModelResources( ModelResource modelResource,
Collection resources ) throws ModelWorkspaceException {
ModelUtil.getDependentModelResources(modelResource, resources, false);
}
/**
* Convenience method to obtain a list of ModelResource instances which the input model resource depends upon
*
* @param resource
* @return Collection of ModelResource's
* @since 4.2
*/
public static Collection getDependentResources( ModelResource resource ) throws ModelWorkspaceException {
return ModelUtil.getDependentResources(resource);
}
/**
* Method returns a boolean value (true or false) for whether or not a IFile requires validation. The model may be have been
* saved with auto-build off.
*
* @param targetModelResource
* @return true if requires validation, false if not.
* @since 4.2
*/
public static boolean requiresValidation( IFile file ) {
ModelResource mr = null;
// Find Model Resource
try {
mr = ModelUtil.getModelResource(file, false);
} catch (ModelWorkspaceException err) {
String message = getString(MODEL_RESOURCE_NOT_FOUND_MSG_KEY, file.toString());
UiConstants.Util.log(IStatus.ERROR, err, message);
}
if (mr != null) {
return requiresValidation(mr);
}
// If we ever get here it's an error, so let's
return false;
}
/**
* Method returns a boolean value (true or false) for whether or not a model resource requires validation. The model may be
* have been saved with auto-build off.
*
* @param targetModelResource
* @return true if requires validation, false if not.
* @since 4.2
*/
public static boolean requiresValidation( ModelResource targetModelResource ) {
if (targetModelResource == null) return false;
// todo: (BML 12/14/04) This check is currently required because xsd files are always taked with a NOT_INDEXED during
// the build process because they need to be unloaded and reloaded. Sucks, but that's the way it is.
// There will be another defect defining that and pointing to this place to remove the next two lines!!
if (ModelUtil.isXsdFile(targetModelResource.getResource())) return false;
// sz - added the code to fix defect 15948.
boolean isIndexModified = isIndexFileLastModifiedAfterResourceFile(targetModelResource);
if ((targetModelResource.getIndexType() == ModelResource.NOT_INDEXED) && isIndexModified) {
return true;
}
return false;
}
private static boolean isIndexFileLastModifiedAfterResourceFile( ModelResource targetModelResource ) {
File rsrcIndexFile = new File(IndexUtil.INDEX_PATH, IndexUtil.getRuntimeIndexFileName(targetModelResource));
if (!rsrcIndexFile.exists()) {
return false;
}
final IPath path = ((IFile)targetModelResource.getResource()).getLocation();
long resourceLastModified = path.toFile().lastModified();
long indexLastModified = rsrcIndexFile.lastModified();
return (indexLastModified < resourceLastModified);
}
/**
* Method returns a boolean value (true or false) for whether or not a IFile has errors. The method obtains a model resource
* which has a simple hasErrors() method.
*
* @param file
* @return true if has errors, false if not.
* @since 4.2
*/
public static boolean hasErrors( IFile file,
Object source ) {
ModelResource mr = null;
boolean foundError = false;
// Find Model Resource
try {
mr = ModelUtil.getModelResource(file, false);
} catch (ModelWorkspaceException err) {
String message = getString(MODEL_RESOURCE_NOT_FOUND_MSG_KEY, file.toString());
UiConstants.Util.log(IStatus.ERROR, err, message);
}
if (mr != null) {
// return mr.hasErrors();
IMarker[] mrkrs = null;
boolean errorOccurred = false;
try {
mrkrs = mr.getResource().findMarkers(IMarker.PROBLEM, false, IResource.DEPTH_ZERO);
} catch (CoreException ex) {
Util.log(ex);
errorOccurred = true;
}
if (!errorOccurred) {
final IMarker[] markers = mrkrs;
final boolean startedTxn = ModelerCore.startTxn(false, false, null, source);
boolean succeeded = false;
try {
for (int ndx = markers.length; --ndx >= 0;) {
final Object attr = MarkerUtilities.getMarkerAttribute(markers[ndx], IMarker.SEVERITY);
if (attr == null) {
continue;
}
// Asserting attr is an Integer...
final int severity = ((Integer)attr).intValue();
if (severity == IMarker.SEVERITY_ERROR) {
foundError = true;
break;
}
}
succeeded = true;
} finally {
if (startedTxn) {
if (succeeded)
ModelerCore.commitTxn();
else
ModelerCore.rollbackTxn();
}
}
}
}
return foundError;
}
public static void initializeModelContainers( ModelResource modelResource,
String txnLabel,
Object source ) {
boolean started = ModelerCore.startTxn(false, false, txnLabel, source);
boolean succeeded = false;
try {
ModelerCore.getModelEditor().getAllContainers(modelResource.getEmfResource());
succeeded = true;
} catch (ModelWorkspaceException err) {
String message = getString("ModelUtilities.initializeModelContainersError", modelResource.toString()); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, err, message);
} finally {
if (started) {
if (succeeded) {
ModelerCore.commitTxn();
} else {
ModelerCore.rollbackTxn();
}
}
}
}
/**
* Scan all metamodels present in this model resource to see if one has the specified URI. This does not cause the model to be
* loaded.
*
* @param modelResource The ModelResource to scan
* @param uri The URI to look for
* @return
* @throws ModelWorkspaceException if there is a problem getting metamodel descriptors
*/
public static boolean hasMetamodelWithURI( ModelResource modelResource,
String uri ) throws ModelWorkspaceException {
// arg check:
if (modelResource == null || uri == null) {
return false;
} // endif
List allMetamodelDescriptors = modelResource.getAllMetamodelDescriptors();
for (int i = 0; i < allMetamodelDescriptors.size(); i++) {
MetamodelDescriptor mmdesc = (MetamodelDescriptor)allMetamodelDescriptors.get(i);
if (uri.equals(mmdesc.getNamespaceURI())) {
return true;
} // endif
} // endfor
// not found:
return false;
}
/**
* Determine if the specified ModelResource contains JDBC import information. Does not cause a model to be loaded. Due to
* defect 19206, this may not be entirely accurate if the model is not open.
*
* @param modelResource
* @return
* @throws ModelWorkspaceException
*/
public static boolean hasJdbcSource( ModelResource modelResource ) throws ModelWorkspaceException {
if (modelResource != null) {
if (!modelResource.isLoaded()) {
// not loaded, just work with header:
return hasMetamodelWithURI(modelResource, JdbcPackage.eNS_URI);
} // endif
// is loaded, go for accuracy:
try {
Resource resource = modelResource.getEmfResource();
for (Iterator iter = resource.getContents().iterator(); iter.hasNext();) {
EObject eObj = (EObject)iter.next();
if (eObj instanceof JdbcSource) {
return true;
}
}
} catch (ModelWorkspaceException err) {
Util.log(err);
WidgetUtil.showError(err.getLocalizedMessage());
}
} // endif
return false;
}
public static boolean isRelationalModel( ModelResource rsrc ) throws ModelWorkspaceException {
// defect 19183 - do not open the model while determining "relationalness"
if (rsrc == null || rsrc.getPrimaryMetamodelDescriptor() == null) {
return false;
} // endif
return RelationalPackage.eNS_URI.equals(rsrc.getPrimaryMetamodelDescriptor().getNamespaceURI());
}
/**
* Method provides common model save capability with forced update imports
*
* @param modelResource the ModelResource to save
* @param monitor the progess monitor
* @param force comes from File.setContents() and indicates the should proceed even if the resource is out of sync with the
* local file system.
* @param forceUpdateImports updates file imports before save.
* @param source the source which initiated this save
* @throws Exception if there is a problem saving the resource
* @since 5.0.2
*/
public static void saveModelResource( final ModelResource modelResource,
final IProgressMonitor monitor,
final boolean force,
final Object source ) throws Exception {
modelResource.save(monitor, force);
}
public static boolean modelIsLocked(final ModelResource modelResource) throws Exception {
if (modelResource != null ) {
ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry();
CoreModelExtensionAssistant assistant =
(CoreModelExtensionAssistant)registry.getModelExtensionAssistant(CoreModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix());
return assistant.isModelLocked(modelResource);
}
return false;
}
public static boolean isVdbSourceModel(final ModelResource modelResource) {
if (modelResource != null ) {
try {
ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry();
CoreModelExtensionAssistant assistant =
(CoreModelExtensionAssistant)registry.getModelExtensionAssistant(CoreModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix());
if( assistant != null ) {
return assistant.isVdbSourceModel(modelResource);
}
} catch (Exception ex) {
UiConstants.Util.log(IStatus.ERROR, ex, ex.getMessage());
}
}
return false;
}
public static boolean isVdbSourceModel(final IFile modelFile) {
if (modelFile != null ) {
try {
ModelResource mr = getModelResource(modelFile);
return isVdbSourceModel(mr);
} catch (Exception ex) {
UiConstants.Util.log(IStatus.ERROR, ex, ex.getMessage());
}
}
return false;
}
public static String getVdbName(final ModelResource modelResource) throws Exception {
if (modelResource != null ) {
ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry();
CoreModelExtensionAssistant assistant =
(CoreModelExtensionAssistant)registry.getModelExtensionAssistant(CoreModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix());
return assistant.getVdbName(modelResource);
}
return null;
}
/**
* Method to determine if model name exists in project or not
* @param name
* @param res
* @return
* @throws CoreException
*/
public static IStatus doesModelNameExistInProject(String name, IResource res) {
IStatus status = Status.OK_STATUS;
try {
IProject proj = res.getProject();
for( IResource iRes : proj.members() ) {
if( iRes instanceof IContainer ) {
if( ModelUtilities.containsModelWithName(name, (IContainer)iRes) ) {
return new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, Util.getString("modelNameValidation.sameNameModelExistsInProjectMessage", name)); //$NON-NLS-1$
}
} else {
if( iRes.getName().equals(name) ){
return new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, Util.getString("modelNameValidation.sameNameModelExistsInProjectMessage", name)); //$NON-NLS-1$
}
}
}
} catch (CoreException ex) {
status = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, Util.getString("sameNameModelExistsInProjectMessage", name)); //$NON-NLS-1$
UiConstants.Util.log(IStatus.ERROR, ex, ex.getMessage());
}
return status;
}
private static boolean containsModelWithName(String name, IContainer container) throws CoreException {
for (IResource res : container.members() ) {
if( res.getName().equals(name) ){
return true;
}
}
return false;
}
/**
* Retrieve a valid unique name based on the given target name.
*
* @param containerPath
* @param modelName
* @param targetName
* @param isTable
* @param overwrite
*
* @return unique model name
*/
public static String getUniqueName(String containerPath, String modelName, String targetName, boolean isTable, boolean overwrite) {
String uniqueName = targetName;
try {
IFile modelFile = getModelFile(containerPath, modelName);
if( modelFile != null ) {
ModelResource mr = getModelResourceForIFile(modelFile, false);
if( mr != null ) {
uniqueName = getUniqueName(mr, targetName, isTable, overwrite);
}
}
} catch (ModelWorkspaceException ex ) {
UiConstants.Util.log(ex);
}
return uniqueName;
}
/**
* Retrieve a valid unique name based on the given target name.
*
* @param mr
* @param targetName
* @param isTable
* @param overwrite
*
* @return unique model name
*/
public static String getUniqueName(ModelResource mr, String targetName, boolean isTable, boolean overwrite) {
String uniqueName = targetName;
if( mr != null && !overwrite ) {
RelationalStringNameValidator nameValidator = new RelationalStringNameValidator(isTable);
try {
// Load the name validator with EObject names
for( Object eObj : mr.getEObjects() ) {
String name = ModelerCore.getModelEditor().getName((EObject)eObj);
nameValidator.addExistingName(name);
}
uniqueName = nameValidator.createValidUniqueName(targetName);
} catch (ModelWorkspaceException ex) {
UiConstants.Util.log(ex);
}
}
return uniqueName;
}
/**
* Does a child {@link EObject} with the given name exist in the model
* denoted by the given path and model name.
*
* @param containerPath
* @param modelName
* @param childName
*
* @return true if object exists, false otherwise.
*/
public static boolean eObjectExists(String containerPath, String modelName, String childName) {
return getExistingEObject(containerPath, modelName, childName) != null ? true : false;
}
/**
* Get the child {@link EObject} with the given name in the model
* denoted by the given path and model name.
*
* @param containerPath
* @param modelName
* @param childName
*
* @return the child object or null if it does not exist in the model
*/
public static EObject getExistingEObject(String containerPath, String modelName, String childName) {
try {
IFile modelFile = ModelUtilities.getModelFile(containerPath, modelName);
if( modelFile != null ) {
ModelResource mr = ModelUtilities.getModelResourceForIFile(modelFile, false);
if( mr != null ) {
for( Object eObj : mr.getEObjects() ) {
String name = ModelerCore.getModelEditor().getName((EObject)eObj);
if( name.equals(childName) ) {
return (EObject)eObj;
}
}
}
}
} catch (ModelWorkspaceException ex ) {
UiConstants.Util.log(ex);
}
return null;
}
public static boolean isModelDiagramLocked(Object object) {
boolean result = false;
try {
ModelResource mr = getModelResource(object);
ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry();
CoreModelExtensionAssistant assistant =
(CoreModelExtensionAssistant)registry.getModelExtensionAssistant(CoreModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix());
final ModelAnnotation modelAnnotation = mr.getModelAnnotation();
String value = assistant.getPropertyValue(modelAnnotation, CoreModelExtensionConstants.PropertyIds.DIAGRAM_LOCKED);
result = Boolean.parseBoolean(value);
} catch (ModelWorkspaceException ex) {
UiConstants.Util.log(ex);
} catch (Exception ex) {
UiConstants.Util.log(ex);
}
return result;
}
public static void lockModelDiagrams(Object object) {
try {
ModelResource mr = getModelResource(object);
ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry();
CoreModelExtensionAssistant assistant =
(CoreModelExtensionAssistant)registry.getModelExtensionAssistant(CoreModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix());
final ModelAnnotation modelAnnotation = mr.getModelAnnotation();
assistant.setPropertyValue(modelAnnotation, CoreModelExtensionConstants.PropertyIds.DIAGRAM_LOCKED, Boolean.TRUE.toString());
} catch (ModelWorkspaceException ex) {
UiConstants.Util.log(ex);
} catch (Exception ex) {
UiConstants.Util.log(ex);
}
}
public static void unlockModelDiagrams(Object object) {
try {
ModelResource mr = getModelResource(object);
ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry();
CoreModelExtensionAssistant assistant =
(CoreModelExtensionAssistant)registry.getModelExtensionAssistant(CoreModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix());
final ModelAnnotation modelAnnotation = mr.getModelAnnotation();
assistant.setPropertyValue(modelAnnotation, CoreModelExtensionConstants.PropertyIds.DIAGRAM_LOCKED, Boolean.FALSE.toString());
} catch (ModelWorkspaceException ex) {
UiConstants.Util.log(ex);
} catch (Exception ex) {
UiConstants.Util.log(ex);
}
}
/**
* Method that warns user that model contains info that will not be copied
* @param mr
* @return
*/
public static void warnIfUnsupportedModelInfoWontBeCopied(ModelResource mr) {
if( mr == null ) return;
// Get assistants
Collection<ModelObjectExtensionAssistant> assistants = new ArrayList<ModelObjectExtensionAssistant>();
for (String namespacePrefix : ExtensionPlugin.getInstance().getRegistry().getAllNamespacePrefixes()) {
ModelExtensionAssistant assistant = ExtensionPlugin.getInstance().getRegistry().getModelExtensionAssistant(namespacePrefix);
if (assistant instanceof ModelObjectExtensionAssistant) {
assistants.add((ModelObjectExtensionAssistant)assistant);
}
}
boolean doWarn = false;
try {
// Iterate through model's eObjects and bail
Iterator<?> iter = mr.getEmfResource().getAllContents();
doWarn = false;
while (iter.hasNext()) {
final EObject eObj = (EObject) iter.next();
for( ModelObjectExtensionAssistant nextAss : assistants ) {
if( nextAss.supportsMyNamespace(eObj)) {
Properties props = nextAss.getOverriddenValues(eObj);
if( props != null && !props.isEmpty() ) doWarn = true;
if( doWarn ) break;
}
}
if( doWarn ) {
break;
}
}
} catch (ModelWorkspaceException e) {
UiConstants.Util.log(e);
} catch (Exception e) {
UiConstants.Util.log(e);
}
if( doWarn ) {
MessageDialog.openWarning(Display.getCurrent().getActiveShell(), UiConstants.Util.getString("StructuralCopyWizardPage.modelContainsExtensionPropertiesWarningTitle"), //$NON-NLS-1$
UiConstants.Util.getString("StructuralCopyWizardPage.modelContainsExtensionPropertiesWarningMsg", mr.getItemName())); //$NON-NLS-1$
}
}
}