/******************************************************************************* * Copyright (c) 2008, 2014 Borland Software Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Borland Software Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.m2m.internal.qvt.oml.editor.ui.completion.collectors; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import lpg.runtime.IToken; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceProxy; import org.eclipse.core.resources.IResourceProxyVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.m2m.internal.qvt.oml.editor.ui.Activator; import org.eclipse.m2m.internal.qvt.oml.editor.ui.completion.CategoryImageConstants; import org.eclipse.m2m.internal.qvt.oml.editor.ui.completion.CompletionProposalUtil; import org.eclipse.m2m.internal.qvt.oml.editor.ui.completion.QvtCompletionData; import org.eclipse.m2m.internal.qvt.oml.editor.ui.completion.QvtCompletionProposal; import org.eclipse.m2m.internal.qvt.oml.emf.util.mmregistry.MetamodelRegistry; import org.eclipse.m2m.internal.qvt.oml.emf.util.mmregistry.WorkspaceMetamodelProvider; import org.eclipse.m2m.internal.qvt.oml.emf.util.urimap.MModelURIMapFactory; import org.eclipse.m2m.internal.qvt.oml.emf.util.urimap.MModelURIMapPackage; import org.eclipse.m2m.internal.qvt.oml.emf.util.urimap.MappingContainer; import org.eclipse.m2m.internal.qvt.oml.emf.util.urimap.MetamodelURIMappingHelper; import org.eclipse.m2m.internal.qvt.oml.emf.util.urimap.URIMapping; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.graphics.Image; /** * @author Aleksandr Igdalov * Created on Jul 4, 2007 */ public class WorkspaceMetamodelCollector extends AbstractMetamodelCollector { public void addPropoposals(Collection<ICompletionProposal> proposals, QvtCompletionData data) { List<IPath> workspaceMetamodels = collectWorkspaceMetamodels(); for (IPath workspaceMetamodel : workspaceMetamodels) { QvtCompletionProposal proposal = createCompletionProposal(workspaceMetamodel, data); proposals.add(proposal); } } public static final QvtCompletionProposal createCompletionProposal(final IPath workspaceMetamodelPath, final QvtCompletionData data) { IToken currentToken = data.getCurrentToken(); int offset = data.getOffset(); int replacementOffset = (currentToken == null) ? offset : currentToken.getStartOffset(); int replacementLength = offset - replacementOffset; String displayString = workspaceMetamodelPath.toString(); Image image = CompletionProposalUtil.getImage(CategoryImageConstants.PACKAGE); return new QvtCompletionProposal(null, replacementOffset, replacementLength, -1, image, displayString, null, null) { @Override public void apply(IDocument document) { URI resURI = URI.createPlatformResourceURI(workspaceMetamodelPath.toString(), false); EPackage pack = loadPackage(resURI); if (pack == null) { data.showError(NLS.bind(Messages.WorkspaceMetamodelCollector_EPackageLoadError, workspaceMetamodelPath)); } else if ((pack.getName() == null) || (pack.getNsURI() == null)) { data.showError(NLS.bind(Messages.WorkspaceMetamodelCollector_EPackageNameOrNsUriIsNull, workspaceMetamodelPath)); } else { addToSettings(data, resURI, pack); String replacementString = getProposalString(data, pack); setReplacementString(replacementString); setCursorPosition(replacementString.length()); super.apply(document); } } }; } private static List<IPath> collectWorkspaceMetamodels() { final List<IPath> result = new ArrayList<IPath>(); try { ResourcesPlugin.getWorkspace().getRoot().accept(new IResourceProxyVisitor() { public boolean visit(IResourceProxy proxy) throws CoreException { if(proxy.getType() == IResource.FILE && MetamodelRegistry.isMetamodelFileName(proxy.getName())) { result.add(proxy.requestFullPath()); } return true; } }, IResource.NONE); } catch (CoreException e) { Activator.log(e); } return result; } private static EPackage loadPackage(URI uri) { ResourceSet rs = new ResourceSetImpl(); Resource res = rs.getResource(uri, true); return WorkspaceMetamodelProvider.getFirstEPackageContent(res); } private static void addToSettings(QvtCompletionData data, URI resURI, EPackage pack) { URI cFile = data.getCFile().getURI(); if(!cFile.isPlatformResource()) { return; } String wsRelativePath = cFile.toPlatformString(true); IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(wsRelativePath)); if (resource != null) { IProject project = resource.getProject(); if (project != null) { MappingContainer uriMap = loadMappings(project); URIMapping mapping = createMapping(resURI, pack); removeOldMapping(uriMap, mapping); uriMap.getMapping().add(mapping); saveMappings(uriMap, project); } } } private static URIMapping createMapping(URI resURI, EPackage pack) { URIMapping mapping = MModelURIMapFactory.eINSTANCE.createURIMapping(); mapping.setSourceURI(pack.getNsURI()); mapping.setTargetURI(resURI.toString()); return mapping; } private static void removeOldMapping(MappingContainer uriMap, URIMapping pattern) { for (URIMapping mapping : uriMap.getMapping()) { if ((pattern.getSourceURI().equals(mapping.getSourceURI())) || (pattern.getTargetURI().equals(mapping.getTargetURI()))) { uriMap.getMapping().remove(mapping); break; } } } private static MappingContainer loadMappings(IProject project) { // ensure mapping package gets into registry before loading MModelURIMapPackage.eINSTANCE.getNsURI(); Resource res = MetamodelURIMappingHelper.createMappingResource(project); try { if(MetamodelURIMappingHelper.hasMappingResource(project)) { res.load(null); } } catch (IOException e) { Activator.log(e); } return res.getContents().isEmpty() ? MetamodelURIMappingHelper.createNewMappings(res) : MetamodelURIMappingHelper.getMappings(res); } private static void saveMappings(MappingContainer uriMap, IProject project) { Resource res = uriMap.eResource(); try { res.save(null); } catch (IOException e) { Activator.log(e); } if(project != null) { try { IFile mappingFile = MetamodelURIMappingHelper.getMappingFileHandle(project); mappingFile.refreshLocal(IResource.DEPTH_ZERO, null); } catch (CoreException e) { Activator.log(e); } } } }