/* * 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.vdb; import java.io.File; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.teiid.core.designer.util.FileUtils; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.container.ResourceFinder; import org.teiid.designer.core.index.Index; import org.teiid.designer.core.index.IndexUtil; import org.teiid.designer.vdb.manifest.EntryElement; import org.teiid.designer.vdb.manifest.ProblemElement; import org.teiid.designer.vdb.manifest.PropertyElement; import org.teiid.designer.vdb.manifest.Severity; /** * */ public abstract class VdbIndexedEntry extends VdbEntry { /** * */ public class Problem { private final int severity; private final String message; private final String location; Problem( final IMarker marker ) { this.severity = marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING); this.message = marker.getAttribute(IMarker.MESSAGE, null); this.location = marker.getAttribute(IMarker.LOCATION, null); } Problem( final ProblemElement problem ) { this.severity = problem.getSeverity() == Severity.ERROR ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING; this.message = problem.getMessage(); this.location = problem.getLocation(); } /** * @return location */ public String getLocation() { return location; } /** * @return message */ public String getMessage() { return message; } /** * @return severity */ public int getSeverity() { return severity; } } /** * Index Folder */ protected static final String INDEX_FOLDER = "runtime-inf/"; //$NON-NLS-1$ private final String indexName; private final Set<Problem> problems = new HashSet<Problem>(); /** * @param vdb * @param element * @throws Exception */ public VdbIndexedEntry(XmiVdb vdb, EntryElement element) throws Exception { super(vdb, element); String indexName = null; for (final PropertyElement property : element.getProperties()) { final String name = property.getName(); if (EntryElement.INDEX_NAME.equals(name)) indexName = property.getValue(); } this.indexName = indexName; } /** * @param vdb * @param name * @throws Exception */ public VdbIndexedEntry(XmiVdb vdb, IPath name) throws Exception { super(vdb, name); indexName = IndexUtil.getRuntimeIndexFileName(findFileInWorkspace()); } @Override public XmiVdb getVdb() { return (XmiVdb) super.getVdb(); } @Override public void setVdb(Vdb vdb) { if (vdb instanceof XmiVdb) { super.setVdb(vdb); return; } throw new UnsupportedOperationException(); } /** * Clean the entry */ protected void clean() { // Clear problems problems.clear(); getIndexFile().delete(); } /** * @return finder * @throws Exception */ protected ResourceFinder getFinder() throws Exception { return ModelerCore.getModelContainer().getResourceFinder(); } /** * @return resource associated with model * @throws Exception */ protected Resource findModel() throws Exception { IResource resource = ModelerCore.getWorkspace().getRoot().findMember(getPath()); // model not found in workspace if (resource == null) { return null; } Resource emfResource = getFinder().findByURI(URI.createFileURI(resource.getLocation().toString()), false); // as a last resort force loading the resource if (emfResource == null) { emfResource = ModelerCore.getModelContainer().getResource(URI.createFileURI(resource.getLocation().toString()), true); } return emfResource; } /** * @return index file */ protected File getIndexFile() { return new File(getVdb().getStagingFolder(), INDEX_FOLDER + indexName); } /** * @return indexName */ public String getIndexName() { return indexName; } /** * @return the immutable set of problems associated with this model entry */ public final Set<Problem> getProblems() { return Collections.unmodifiableSet(problems); } /** * @param problem */ protected void addProblem(Problem problem) { problems.add(problem); } /** * @throws Exception */ protected void synchronizeIndex() throws Exception { final IFile workspaceFile = findFileInWorkspace(); if (workspaceFile == null) return; // Clear problems problems.clear(); getIndexFile().delete(); // Build model if necessary // Get Index File and check time/date to see if we need to rebuild or not IPath indexPath = new Path(IndexUtil.INDEX_PATH + indexName); // File indexFile = indexPath.toFile(); long indexDate = -1; if (indexFile.exists()) { indexDate = indexFile.lastModified(); } if (workspaceFile.getLocalTimeStamp() > indexDate) { // Note that this will index and validate the model in the workspace getVdb().getBuilder().buildResources(new NullProgressMonitor(), Collections.singleton(workspaceFile), ModelerCore.getModelContainer(), false); } // Copy snapshot of workspace file index to VDB folder // TODO: If index name of workspace file can change (?), we have to delete the old index and update our index name final Index index = IndexUtil.getIndexFile(indexName, IndexUtil.INDEX_PATH + indexName, getPath().lastSegment()); FileUtils.copy(index.getIndexFile(), getIndexFile().getParentFile(), true); problems.clear(); // Synchronize model problems IMarker[] markers = workspaceFile.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE); if (markers != null) { for (final IMarker marker : markers) { Object attr = marker.getAttribute(IMarker.SEVERITY); 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)); } } } } /** * {@inheritDoc} * * @see org.teiid.designer.vdb.VdbEntry#save(java.util.zip.ZipOutputStream) */ @Override public void save( final ZipOutputStream out) throws Exception { super.save(out); // Save model index save(out, new ZipEntry(INDEX_FOLDER + getIndexName()), getIndexFile()); if (!getVdb().isPreview()) { // Convert problems for this model entry to markers on the VDB file final IFile vdbFile = getVdb().getSourceFile(); if (vdbFile.exists()) { for (final Problem problem : getProblems()) { final IMarker marker = vdbFile.createMarker(IMarker.PROBLEM); marker.setAttribute(IMarker.SEVERITY, problem.getSeverity()); marker.setAttribute(IMarker.MESSAGE, problem.getMessage()); marker.setAttribute(IMarker.LOCATION, getPath().toString() + '/' + problem.getLocation()); } } } } }