/*
* 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.core.util;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xsd.XSDAnnotation;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.util.XSDResourceImpl;
import org.teiid.core.designer.ModelerCoreException;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.core.metamodel.aspect.AspectManager;
import org.teiid.designer.core.metamodel.aspect.ImportsAspect;
import org.teiid.designer.core.resource.EmfResource;
import org.teiid.designer.core.workspace.ModelResource;
import org.teiid.designer.core.workspace.ModelWorkspaceException;
import org.teiid.designer.metamodels.core.ModelAnnotation;
import org.teiid.designer.metamodels.core.ModelImport;
/**
* @since 8.0
*/
public class ImportUtilities {
/**
* Method to add an import for an external resource to a resource. If an import already exists for the external resource, the
* method returns FALSE. If an import is missing, one is created and TRUE is returned.
* @param resource
* @param externalResource
* @return wasAdded TRUE if import was created, FALSE if not.
* @since 5.0
*/
public static boolean addMissingImport(final Resource resource, final Resource externalResource) {
// Note: Some model builders utilize transient resources, which would result in bogus imports after the merge processor
// is completed. SO, for now, we'll check for isRelative() and NOT add missing imports for these cases. The MergeProcessorImpl
// will STILL do it's own rebuildImports().
if (externalResource == null || resource.getURI().isRelative() || externalResource.getURI().isRelative()) {
return false;
}
boolean wasAdded = false;
if( resource instanceof EmfResource ) {
ModelImport existingImport = ModelerCore.getModelEditor().findModelImport((EmfResource)resource, externalResource);
if( existingImport == null ) {
try {
wasAdded = ModelerCore.getModelEditor().addModelImport((EmfResource)resource, externalResource);
if( wasAdded ) {
addMissingDependentImports(resource, externalResource);
}
} catch (ModelerCoreException e) {
ModelerCore.Util.log(e);
}
}
}
return wasAdded;
}
private static void addMissingDependentImports(final Resource resource, Resource externalResource) {
ModelResource depResource = null;
if( externalResource instanceof XSDResourceImpl && ((XSDResourceImpl)externalResource).getSchema() != null ) {
// Get all the content
Iterator iter = ((XSDResourceImpl)externalResource).getSchema().getContents().iterator();
while( iter.hasNext()) {
// For each of the EObjects, get the import Aspect
EObject eobject = (EObject) iter.next();
// Skip annotations
if (eobject instanceof XSDAnnotation) {
continue;
}
// Break if named component found since all imports, includes, and redefines must appear before these
if (eobject instanceof XSDNamedComponent) {
break;
}
ImportsAspect importsAspect = AspectManager.getModelImportsAspect(eobject);
if (importsAspect != null) {
// If imports Aspect is not null, get the import path
IPath importPath = importsAspect.getModelPath(eobject);
if( importPath != null ) {
depResource = ModelerCore.getModelWorkspace().findModelResource(importPath);
}
}
}
}
if( depResource != null ) {
try {
addMissingImport(resource, depResource.getEmfResource());
} catch (ModelerCoreException e) {
ModelerCore.Util.log(e);
}
}
}
/**
*
* @param resource
* @param externalResource
* @return
* @since 5.0
*/
public static boolean removeExistingImport(final Resource resource, final Resource externalResource) {
// Note: Some model builders utilize transient resources, which would result in bogus imports after the merge processor
// is completed. SO, for now, we'll check for isRelative() and NOT add missing imports for these cases. The MergeProcessorImpl
// will STILL do it's own rebuildImports().
if (externalResource == null || resource.getURI().isRelative() || externalResource.getURI().isRelative()) {
return false;
}
boolean wasRemoved = false;
if( resource instanceof EmfResource ) {
ModelImport existingImport = ModelerCore.getModelEditor().findModelImport((EmfResource)resource, externalResource);
if( existingImport != null ) {
try {
ModelAnnotation modelWithImports = ((EmfResource)resource).getModelAnnotation();
if (modelWithImports != null) {
ModelerCore.getModelEditor().removeValue(modelWithImports, existingImport, modelWithImports.getModelImports() );
wasRemoved = true;
}
if( wasRemoved ) {
addMissingDependentImports(resource, externalResource);
}
} catch (ModelerCoreException e) {
ModelerCore.Util.log(e);
}
}
}
return wasRemoved;
}
/**
* Method to add missing imports to an EmfResource given a target object. The target object can be either an EObject, Resource,
* ModelResource or a list of any of them . In all cases, the method will recursively walk the contents of the object looking
* for external referenced resources. If any are detected, the method looks for existing imports for the resources and adds them
* if they are missing.
* NOTE: This method makes no checks for read-only state of resource.
* @param target
* @since 5.0
*/
public static boolean addMissingImports(final Resource notifyingResource, final Object target) {
Collection externalResources = ExternalResourceImportsHelper.findExternalResourceReferences(notifyingResource, target);
boolean result = false;
if( ! externalResources.isEmpty() ) {
Resource targetResource = null;
if( target instanceof EObject ) {
targetResource = ((EObject)target).eResource();
} else if( target instanceof Resource ) {
targetResource = (Resource)target;
} else if( target instanceof ModelResource ) {
try {
targetResource = ((ModelResource)target).getEmfResource();
} catch (ModelWorkspaceException theException) {
ModelerCore.Util.log(IStatus.ERROR, theException, theException.getLocalizedMessage());
}
}
boolean importWasAdded = false;
// Now add any missing imports on each of the
if( targetResource != null && targetResource instanceof EmfResource ) {
for( Iterator iter = externalResources.iterator(); iter.hasNext(); ) {
importWasAdded = addMissingImport(targetResource, (Resource)iter.next());
if( importWasAdded) {
result = true;
}
}
}
}
return result;
}
}