Index: src/org/teiid/designer/vdb/VdbModelEntry.java =================================================================== --- src/org/teiid/designer/vdb/VdbModelEntry.java (revision 1270) +++ src/org/teiid/designer/vdb/VdbModelEntry.java (working copy) @@ -11,8 +11,9 @@ import static org.teiid.designer.vdb.Vdb.Event.MODEL_SOURCE_NAME; import static org.teiid.designer.vdb.Vdb.Event.MODEL_TRANSLATOR; import static org.teiid.designer.vdb.Vdb.Event.MODEL_VISIBLE; - import java.io.File; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; @@ -22,16 +23,13 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; - import net.jcip.annotations.ThreadSafe; - import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.teiid.designer.datatools.connection.ConnectionInfoHelper; @@ -40,7 +38,6 @@ import org.teiid.designer.vdb.manifest.PropertyElement; import org.teiid.designer.vdb.manifest.Severity; import org.teiid.designer.vdb.manifest.SourceElement; - import com.metamatrix.core.modeler.CoreModelerPlugin; import com.metamatrix.core.modeler.util.FileUtils; import com.metamatrix.core.util.StringUtilities; @@ -75,20 +72,27 @@ private final AtomicReference jndiName = new AtomicReference(); private transient ModelElement element; + /** + * Constructs a model entry and adds it to the specified VDB. Callers of this method should call + * {@link #synchronizeModelEntry(IProgressMonitor)} immediately after constructing the model entry. + * + * @param vdb the VDB where the resource is be added to (may not be null) + * @param name the resource path (may not be null) + * @param monitor the progress monitor or null + */ VdbModelEntry( final Vdb vdb, final IPath name, final IProgressMonitor monitor ) { super(vdb, name, monitor); indexName = IndexUtil.getRuntimeIndexFileName(findFileInWorkspace()); - synchronizeModelEntry(monitor); final Resource model = findModel(); builtIn = getFinder().isBuiltInResource(model); if (ModelUtil.isXmiFile(model)) { final EmfResource emfModel = (EmfResource)model; type = emfModel.getModelType(); - + // TODO: Backing out the auto-set visibility to FALSE for physical models (Preview won't work) - //visible.set(false); + // visible.set(false); // TODO: re-visit in 7.1 // For now, we're removing the assumption that the user will want to seed the VDB model entry with the model's // Description. From a UI standpoint, if the description contains multiple lines, then the row height @@ -105,15 +109,15 @@ jndiName.set(defaultName); } // TODO: Backing out the auto-set visibility to FALSE for physical models (Preview won't work) - //if( ModelUtil.isVirtual(emfModel) ) { - visible.set(true); - //} + // if( ModelUtil.isVirtual(emfModel) ) { + visible.set(true); + // } } else type = ModelType.TYPE_LITERAL; - if( this.translator.get() == null ) { - this.translator.set(EMPTY_STR); + if (this.translator.get() == null) { + this.translator.set(EMPTY_STR); } - if( this.description.get() == null ) { - this.description.set(EMPTY_STR); + if (this.description.get() == null) { + this.description.set(EMPTY_STR); } } @@ -124,19 +128,19 @@ this.element = element; type = ModelType.get(element.getType()); visible.set(element.isVisible()); - if( element.getSources() != null && !element.getSources().isEmpty()) { - for (final SourceElement source : element.getSources()) { - this.source.set(source.getName()); - this.translator.set(source.getTranslatorName() == null ? StringUtilities.EMPTY_STRING : source.getTranslatorName()); - this.jndiName.set(source.getJndiName()); - break; // TODO: support multi-source bindings - } + if (element.getSources() != null && !element.getSources().isEmpty()) { + for (final SourceElement source : element.getSources()) { + this.source.set(source.getName()); + this.translator.set(source.getTranslatorName() == null ? StringUtilities.EMPTY_STRING : source.getTranslatorName()); + this.jndiName.set(source.getJndiName()); + break; // TODO: support multi-source bindings + } } else { - this.translator.set(EMPTY_STR); - //this.jndiName.set(EMPTY_STR); - //this.source.set(EMPTY_STR); + this.translator.set(EMPTY_STR); + // this.jndiName.set(EMPTY_STR); + // this.source.set(EMPTY_STR); } - for (final ProblemElement problem : element.getProblems()) + for (final ProblemElement problem : element.getProblems()) problems.add(new Problem(problem)); boolean builtIn = false; String indexName = null; @@ -169,14 +173,27 @@ @Override final void dispose() { super.dispose(); - for (final VdbModelEntry entry : importedBy) + + // remove the imported by models + Collection importedByModels = new ArrayList(importedBy); + + for (final VdbModelEntry entry : importedByModels) { + importedBy.remove(entry); getVdb().removeEntry(entry); + } + clean(); } private Resource findModel() { - return getFinder().findByURI(URI.createFileURI(ResourcesPlugin.getWorkspace().getRoot().getLocation().append(getName()).toString()), - false); + IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(getName()); + + // model not found in workspace + if (resource == null) { + return null; + } + + return getFinder().findByURI(URI.createFileURI(resource.getLocation().toString()), false); } private ResourceFinder getFinder() { @@ -283,7 +300,7 @@ super.save(out, monitor); // Save model index save(out, new ZipEntry(INDEX_FOLDER + indexName), getIndexFile(), monitor); - + if (!getVdb().isPreview()) { try { // Convert problems for this model entry to markers on the VDB file @@ -354,47 +371,55 @@ super.synchronize(monitor); } - private void synchronizeModelEntry( final IProgressMonitor monitor ) { + void synchronizeModelEntry( final IProgressMonitor monitor ) { final IFile workspaceFile = findFileInWorkspace(); if (workspaceFile == null) return; clean(); try { - final Resource model = findModel(); + final Resource model = findModel(); if (getVdb().isPreview() && ModelUtil.isPhysical(model)) { final ModelResource mr = ModelerCore.getModelEditor().findModelResource(workspaceFile); final String translator = new ConnectionInfoHelper().getTranslatorName(mr); this.translator.set(translator == null ? EMPTY_STR : translator); } - + // Build model if necessary ModelBuildUtil.buildResources(monitor, Collections.singleton(workspaceFile), ModelerCore.getModelContainer(), false); // Synchronize model problems for (final IMarker marker : workspaceFile.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE)) { Object attr = marker.getAttribute(IMarker.SEVERITY); - if( attr == null ) { - continue; + if (attr == null) { + continue; } // Asserting attr is an Integer... final int severity = ((Integer)attr).intValue(); if (severity == IMarker.SEVERITY_ERROR || severity == IMarker.SEVERITY_WARNING) { - problems.add(new Problem(marker)); + problems.add(new Problem(marker)); } } // Also add imported models if not a preview if (!getVdb().isPreview()) { - final IPath workspace = ResourcesPlugin.getWorkspace().getRoot().getLocation(); - for (final Resource importedModel : getFinder().findReferencesFrom(model, true, false)) { - // TODO: Does this work for the datatypes model? - final IPath name = Path.fromOSString(importedModel.getURI().toFileString()).makeRelativeTo(workspace).makeAbsolute(); - VdbModelEntry importedEntry = null; - for (final VdbModelEntry entry : getVdb().getModelEntries()) - if (name.equals(entry.getName())) { - importedEntry = entry; - break; + Resource[] refs = getFinder().findReferencesFrom(model, true, false); + + if (refs != null) { + for (final Resource importedModel : refs) { + // TODO: Does this work for the datatypes model? + java.net.URI uri = java.net.URI.create(importedModel.getURI().toString()); + IFile[] modelFiles = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(uri); + final IPath name = modelFiles[0].getFullPath(); + VdbModelEntry importedEntry = null; + + for (final VdbModelEntry entry : getVdb().getModelEntries()) { + if (name.equals(entry.getName())) { + importedEntry = entry; + break; + } } - if (importedEntry == null) importedEntry = getVdb().addModelEntry(name, monitor); - imports.add(importedEntry); - importedEntry.importedBy.add(this); + + if (importedEntry == null) importedEntry = getVdb().addModelEntry(name, monitor); + imports.add(importedEntry); + importedEntry.importedBy.add(this); + } } } // Copy snapshot of workspace file index to VDB folder Index: src/org/teiid/designer/vdb/Vdb.java =================================================================== --- src/org/teiid/designer/vdb/Vdb.java (revision 1270) +++ src/org/teiid/designer/vdb/Vdb.java (working copy) @@ -25,7 +25,6 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; - import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; @@ -33,9 +32,7 @@ import javax.xml.bind.Unmarshaller; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; - import net.jcip.annotations.ThreadSafe; - import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; @@ -51,7 +48,6 @@ import org.teiid.designer.vdb.manifest.PropertyElement; import org.teiid.designer.vdb.manifest.VdbElement; import org.xml.sax.SAXException; - import com.metamatrix.core.modeler.util.FileUtils; import com.metamatrix.core.modeler.util.OperationUtil; import com.metamatrix.core.modeler.util.OperationUtil.Unreliable; @@ -146,7 +142,7 @@ for (final VdbModelEntry entry : modelEntries) entry.initializeImports(); for (final DataRoleElement element : manifest.getDataPolicies()) { - dataPolicyEntries.add(new VdbDataRole(Vdb.this, element)); + dataPolicyEntries.add(new VdbDataRole(Vdb.this, element)); } } else FileUtils.copy(entryStream, new File(getFolder(), zipEntry.getName())); } @@ -156,7 +152,7 @@ this.preview = previewable[0]; this.version = vdbVersion[0]; } - + /** * @param file * @param monitor @@ -166,8 +162,6 @@ this(file, false, monitor); } - - /** * @param dataPolicy * @param monitor @@ -175,13 +169,13 @@ */ public final VdbDataRole addDataPolicy( final DataRole dataPolicy, - final IProgressMonitor monitor ) { - VdbDataRole policy = new VdbDataRole(this, dataPolicy, monitor); - dataPolicyEntries.add(policy); - setModified(this, Event.DATA_POLICY_ADDED, policy, null); - return policy; + final IProgressMonitor monitor ) { + VdbDataRole policy = new VdbDataRole(this, dataPolicy, monitor); + dataPolicyEntries.add(policy); + setModified(this, Event.DATA_POLICY_ADDED, policy, null); + return policy; } - + /** * @param listener */ @@ -217,7 +211,18 @@ */ public final VdbModelEntry addModelEntry( final IPath name, final IProgressMonitor monitor ) { - return addEntry(new VdbModelEntry(this, name, monitor), modelEntries, monitor); + VdbModelEntry modelEntry = new VdbModelEntry(this, name, monitor); + VdbModelEntry addedEntry = addEntry(modelEntry, modelEntries, monitor); + + // entry did not exist in VDB + if (modelEntry == addedEntry) { + modelEntry.synchronizeModelEntry(monitor); + } else { + // entry already existed in VDB + modelEntry = addedEntry; + } + + return modelEntry; } /** @@ -242,7 +247,7 @@ public final Set getDataPolicyEntries() { return Collections.unmodifiableSet(dataPolicyEntries); } - + /** * @return description */ @@ -286,7 +291,7 @@ if (!entry.isBuiltIn()) entries.add(entry); return Collections.unmodifiableSet(entries); } - + /** * Method to return the File objects associated with each model in this VDB. * The intention is to allow the Data Policy wizard to display contents of these models in EMF form so users can @@ -295,14 +300,14 @@ * @return the immutable list of model files within this VDB */ public final Collection getModelFiles() { - final Collection modelFiles = new ArrayList(); - - for( VdbModelEntry modelEntry : getModelEntries()) { - IPath modelPath = new Path(folder.getAbsolutePath() + modelEntry.getName()); - modelFiles.add(modelPath.toFile()); - } - - return Collections.unmodifiableCollection(modelFiles); + final Collection modelFiles = new ArrayList(); + + for (VdbModelEntry modelEntry : getModelEntries()) { + IPath modelPath = new Path(folder.getAbsolutePath() + modelEntry.getName()); + modelFiles.add(modelPath.toFile()); + } + + return Collections.unmodifiableCollection(modelFiles); } /** @@ -318,14 +323,14 @@ public final boolean isModified() { return modified.get(); } - + /** * @return true if this is a Preview VDB */ public final boolean isPreview() { return preview; } - + /** * @return the problem markers (never null) * @throws Exception if there is a problem obtaining the problem markers @@ -333,7 +338,7 @@ public IMarker[] getProblems() throws Exception { return file.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE); } - + /** * @return the VDB version */ @@ -358,11 +363,11 @@ final Object oldValue, final Object newValue ) { PropertyChangeEvent event = null; - if( !isPreview() ) { - for (final PropertyChangeListener listener : listeners) { - if (event == null) event = new PropertyChangeEvent(this, propertyName, oldValue, newValue); - listener.propertyChange(event); - } + if (!isPreview()) { + for (final PropertyChangeListener listener : listeners) { + if (event == null) event = new PropertyChangeEvent(this, propertyName, oldValue, newValue); + listener.propertyChange(event); + } } } @@ -382,7 +387,7 @@ else entries.remove(entry); setModified(this, Event.ENTRY_REMOVED, entry, null); } - + /** * @param policy */ @@ -437,16 +442,13 @@ // Clear all problem markers on VDB file for (final IMarker marker : file.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE)) marker.delete(); - + // Save entries for (final VdbEntry entry : entries) - if( entry instanceof VdbEntry ) { - ((VdbEntry)entry).save(out, monitor); - } - + entry.save(out, monitor); for (final VdbModelEntry entry : modelEntries) entry.save(out, monitor); - + // Close zip output stream so its fully writen and any locks are removed. out.close(); out = null; @@ -563,20 +565,20 @@ * physical model entry's {@link VdbModelEntry#getJndiName() JNDI name} changes */ public static final String MODEL_JNDI_NAME = "modelEntry.jndiName"; //$NON-NLS-1$ - - /** + + /** * The property name sent in events to {@link #addChangeListener(PropertyChangeListener) change listeners} when an data policy is * added to a VDB - * - * @see #addDataPolicy(DataRole, IProgressMonitor) - */ - public static final String DATA_POLICY_ADDED = "dataPolicyAdded"; //$NON-NLS-1$ - - /** - * The property name sent in events to {@link #addChangeListener(PropertyChangeListener) change listeners} when an - * {@link #removeDataPolicy(VdbDataRole) entry is removed} from a VDB - */ - public static final String DATA_POLICY_REMOVED = "dataPolicyRemoved"; //$NON-NLS-1$ + * + * @see #addDataPolicy(DataRole, IProgressMonitor) + */ + public static final String DATA_POLICY_ADDED = "dataPolicyAdded"; //$NON-NLS-1$ + + /** + * The property name sent in events to {@link #addChangeListener(PropertyChangeListener) change listeners} when an + * {@link #removeDataPolicy(VdbDataRole) entry is removed} from a VDB + */ + public static final String DATA_POLICY_REMOVED = "dataPolicyRemoved"; //$NON-NLS-1$ /** * The property name sent in events to {@link #addChangeListener(PropertyChangeListener) change listeners} when a VDB is