/** * <copyright> * * Copyright (c) 2005-2006 IBM 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: * IBM - Initial API and implementation * * </copyright> * * $Id: RoseImporter.java,v 1.15 2010/02/04 20:56:24 emerks Exp $ */ package com.sap.emf.importer.moin.rose; import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.emf.codegen.ecore.genmodel.GenModel; import org.eclipse.emf.codegen.ecore.genmodel.GenPackage; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.DiagnosticException; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.Monitor; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.importer.ModelImporter; import org.eclipse.emf.converter.ConverterPlugin; import org.eclipse.emf.converter.util.ConverterUtil; import com.sap.emf.importer.moin.rose.builder.RoseUtil; import com.sap.emf.importer.moin.rose.builder.UnitTreeNode; /** * @since 2.1.0 */ public class RoseImporter extends ModelImporter { protected Map<String, String> pathMap; protected boolean noQualify = false; protected boolean unsettablePrimitive = false; protected RoseUtil roseUtil; protected UnitTreeNode unitTreeNode; protected Map<EPackage, List<String>> roseEPackageInformationMap; @Override public void dispose() { if (pathMap != null) { pathMap.clear(); pathMap = null; } if (roseEPackageInformationMap != null) { roseEPackageInformationMap.clear(); roseEPackageInformationMap = null; } super.dispose(); } @Override public String getID() { return "org.eclipse.emf.importer.moin.rose"; } public Map<String, String> getPathMap() { if (pathMap == null) { pathMap = new HashMap<String, String>(); } return pathMap; } @Override public void setModelLocation(String location) { boolean isEqual = location == null ? getModelLocation() == null : location.equals(getModelLocation()); if (!isEqual) { getPathMap().clear(); } super.setModelLocation(location); } public boolean isNoQualify() { return noQualify; } public void setNoQualify(boolean noQualify) { this.noQualify = noQualify; } public boolean isUnsettablePrimitive() { return unsettablePrimitive; } public void setUnsettablePrimitive(boolean unsettablePrimitive) { this.unsettablePrimitive = unsettablePrimitive; } public File computeRoseModelFile() { URI modelURI = getFirstModelLocationURI(true); if (modelURI != null) { File modelFile = new File(modelURI.isFile() ? modelURI.toFileString() : modelURI.toString()); if (modelFile.isFile()) { return modelFile; } } return null; } @Override public void clearEPackagesCollections() { super.clearEPackagesCollections(); roseEPackageInformationMap = null; } public Diagnostic loadPathMap(Monitor monitor) throws Exception { clearEPackagesCollections(); Diagnostic diagnostic = null; File roseModelFile = computeRoseModelFile(); if (roseModelFile == null) { diagnostic = new BasicDiagnostic(Diagnostic.ERROR, ConverterPlugin.ID, ConverterUtil.ACTION_DIALOG_NONE | ConverterUtil.ACTION_MESSAGE_SET_ERROR, RoseImporterPlugin.INSTANCE.getString("_UI_SpecifyAValidRoseModel_message"), null); } else { String roseModelAbsolutePath = roseModelFile.getAbsolutePath(); monitor.beginTask("", 2); monitor.subTask(RoseImporterPlugin.INSTANCE.getString("_UI_Loading_message", new Object []{ roseModelAbsolutePath })); Map<String, String> pathMap = getPathMap(); for (;;) { roseUtil = createRoseUtil(); roseUtil.getRoseEcoreBuilder().noQualify = noQualify; roseUtil.getRoseEcoreBuilder().unsettablePrimitive = unsettablePrimitive; roseUtil.getVariableToDirectoryMap().putAll(pathMap); unitTreeNode = roseUtil.createRoseUnitTreeAndTable(roseModelAbsolutePath, null); if (unitTreeNode == null) { diagnostic = new BasicDiagnostic(Diagnostic.ERROR, ConverterPlugin.ID, ConverterUtil.ACTION_DIALOG_NONE | ConverterUtil.ACTION_MESSAGE_SET_ERROR, RoseImporterPlugin.INSTANCE.getString("_UI_SpecifyAValidRoseModel_message"), null); } else { boolean hasSymbolWithoutValue = adjustPathMap(roseUtil); if (adjustKnownPathMapSymbols(roseModelAbsolutePath)) { continue; } if (!hasSymbolWithoutValue) { diagnostic = ConverterUtil.mergeDiagnostic(diagnostic, roseUtil.getDiagnostic()); } if (getGenModelFileName() == null) { String fileName = unitTreeNode.getNodes().size() != 1 ? roseModelFile.getName() : unitTreeNode.getNodes().get(0).getRoseFileName(); int index = fileName.lastIndexOf(File.separatorChar); if (index >= 0) { fileName = fileName.substring(index + 1); } index = fileName.lastIndexOf("."); if (index >= 0) { fileName = fileName.substring(0, index); } setGenModelFileName(fileName + ".genmodel"); } } break; } } return diagnostic != null ? diagnostic : Diagnostic.OK_INSTANCE; } protected boolean adjustPathMap(RoseUtil roseUtil) { boolean hasSymbolWithoutValue = false; Map<String, String> currentPathMap = getPathMap(); Map<String, String> pathMap = new HashMap<String, String>(); for (Map.Entry<String, String> entry : roseUtil.getVariableToDirectoryMap().entrySet()) { String symbol = entry.getKey(); if (symbol != null) { String value = entry.getValue(); if (value == null) { value = currentPathMap.get(symbol); } pathMap.put(symbol, value); hasSymbolWithoutValue = hasSymbolWithoutValue || (value == null); } } currentPathMap.clear(); currentPathMap.putAll(pathMap); return hasSymbolWithoutValue; } protected boolean adjustKnownPathMapSymbols(String roseModelAbsolutePath) { return false; } /** * Returns whether the Rose model properties includes genmodel information about a given ePackage. * This method should only be used after invoking * {@link ModelImporter#computeEPackages(Monitor)}. * @param ePackage * @return boolean */ public boolean hasRoseGenPackageProperties(EPackage ePackage) { return roseEPackageInformationMap != null && roseEPackageInformationMap.get(ePackage) != null; } @Override protected Diagnostic doComputeEPackages(Monitor monitor) throws Exception { monitor.beginTask("", 2); Diagnostic diagnostic = loadPathMap(monitor); if (diagnostic.getSeverity() == Diagnostic.OK) { if (getPathMap().values().contains(null) && roseUtil.getDiagnostic().getSeverity() != Diagnostic.OK) { diagnostic = new BasicDiagnostic(Diagnostic.ERROR, ConverterPlugin.ID, ConverterUtil.ACTION_DIALOG_NONE | ConverterUtil.ACTION_MESSAGE_SET_ERROR, RoseImporterPlugin.INSTANCE.getString("_UI_SpecifyTheSymbolLocations_message"), null); } else { roseUtil.createExtent4RoseUnitTree(unitTreeNode); roseUtil.processUnitTree(unitTreeNode); roseEPackageInformationMap = roseUtil.getEPackageToInformationMap(); diagnostic = ConverterUtil.createDiagnostic(roseUtil.getDiagnostic(), ConverterPlugin.ID, ConverterUtil.ACTION_MESSAGE_NONE); for (Map.Entry<EPackage, List<String>> entry : roseUtil.getEPackageToInformationMap().entrySet()) { List<String> information = entry.getValue(); if (information != null) { EPackageImportInfo ePackageInfo = getEPackageImportInfo(entry.getKey()); ePackageInfo.setBasePackage(information.get(0)); ePackageInfo.setPrefix(information.get(1)); } } traverseEPackages(unitTreeNode); } } monitor.done(); return diagnostic; } protected void traverseEPackages(UnitTreeNode subNode) { @SuppressWarnings("unchecked") List<EPackage> ePackagesList = (List<EPackage>)(EList<?>)subNode.getExtent(); getEPackages().addAll(ePackagesList); for (EPackage ePackage : ePackagesList) { EPackageImportInfo ePackageInfo = getEPackageImportInfo(ePackage); String ecoreFileName = null; String roseFileName = subNode.getRoseFileName(); int indexOfSlash = roseFileName.lastIndexOf(File.separator); GenPackage genPackage = getGenPackage(ePackage); if (genPackage != null) { String ePackagePath = genPackage.getEcorePackage().eResource().getURI().lastSegment(); ecoreFileName = URI.decode(ePackagePath); } else if (roseFileName.endsWith(".cat") && indexOfSlash != -1) { String baseName = roseFileName.substring(indexOfSlash + 1, roseFileName.length() - 4); int indexOfDot = baseName.lastIndexOf("."); if (indexOfDot != -1) { baseName = baseName.substring(indexOfDot + 1); } ecoreFileName = baseName + ".ecore"; } else if (subNode.getExtent().size() == 1) { ecoreFileName = subNode.getName() + ".ecore"; } else { ecoreFileName = ePackage.getName() + ".ecore"; } ePackageInfo.setEcoreFileName(ecoreFileName); } for (UnitTreeNode childTree : subNode.getNodes()) { traverseEPackages(childTree); } } @Override protected void adjustGenModel(Monitor monitor) { super.adjustGenModel(monitor); GenModel genModel = getGenModel(); String projectName = getModelProjectName(); IPath genModelPath = getGenModelPath(); URI modelURI = getModelLocationURIs().get(0); URI genModelURI = getGenModel().eResource().getURI(); genModel.getForeignModel().add(makeRelative(modelURI, genModelURI).toFileString()); IPath projectLocation = getWorkspaceRoot().getProject(projectName).getLocation(); if (projectLocation != null) { projectLocation = projectLocation.removeLastSegments(1); } else { projectLocation = getGenModelProjectLocation(); } for (Map.Entry<String, String> entry : getPathMap().entrySet()) { String value = entry.getValue(); if (value != null) { genModel.getForeignModel().add(entry.getKey()); if (new Path(value).equals(projectLocation)) { value = ".."; for (int depth = genModelPath.segmentCount(); depth > 2; --depth) { value += "/.."; } genModel.getForeignModel().add(value); } else { genModel.getForeignModel().add(value); } } } } @Override protected void handleOriginalGenModel() throws DiagnosticException { try { Iterator<String> values = getOriginalGenModel().getForeignModel().iterator(); if (values.hasNext()) { URI modelURI = null; String modelFile = values.next(); modelFile = modelFile.replace('\\', '/'); if (modelFile.endsWith(".mdl")) { URI genModelFileURI = createFileURI(getOriginalGenModelPath().toString()); modelURI = makeAbsolute(URI.createFileURI(modelFile), genModelFileURI); setModelLocation(modelURI.toString()); while (values.hasNext()) { String variable = values.next(); String value = values.next(); getPathMap().put(variable, value); } } } } catch (Exception exception) { RoseImporterPlugin.INSTANCE.log(exception); } } protected RoseUtil createRoseUtil() { RoseUtil roseUtil = new RoseUtil(createResourceSet().getURIConverter()); roseUtil.getRoseEcoreBuilder().noQualify = noQualify; roseUtil.getRoseEcoreBuilder().unsettablePrimitive = unsettablePrimitive; return roseUtil; } }