/** * <copyright> * * Copyright (c) 2002-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: RoseUtil.java,v 1.8 2006/12/28 06:56:06 marcelop Exp $ */ package com.sap.emf.importer.moin.rose.builder; import java.io.File; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.eclipse.emf.common.util.BasicDiagnostic; import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.URIConverter; import com.sap.emf.importer.moin.rose.RoseImporterPlugin; import com.sap.emf.importer.moin.rose.parser.RoseLexer; import com.sap.emf.importer.moin.rose.parser.RoseLoader; import com.sap.emf.importer.moin.rose.parser.RoseNode; import com.sap.emf.importer.moin.rose.parser.RoseParser; import com.sap.emf.importer.moin.rose.parser.Util; /** * Provide functions to process a rose file. */ public class RoseUtil { protected Map<String, Object> quidTable = new HashMap<String, Object>(); protected Map<String, Object> nameTable = new HashMap<String, Object>(); protected Map<Object, List<String>> superTable = new HashMap<Object, List<String>>(); protected Map<EReference, String> refTable = new HashMap<EReference, String>(); protected Map<EObject, String> typeTable = new LinkedHashMap<EObject, String>(); protected Map<String, String> variableToDirectoryMap = new HashMap<String, String>(); protected Map<String, String> packageNameToNSNameMap = new HashMap<String, String>(); protected Map<String, String> packageNameToNSURIMap = new HashMap<String, String>(); protected Map<EPackage, List<String>> ePackageToInformationMap = new HashMap<EPackage, List<String>>(); protected URIConverter uriConverter; public RoseUtil(URIConverter uriConverter) { this.uriConverter = uriConverter; } BasicDiagnostic basicDiagnostic = new BasicDiagnostic( RoseImporterPlugin.getPlugin().getBundle().getSymbolicName(), 0, RoseImporterPlugin.INSTANCE.getString("_UI_ProblemsWereEncounteredLoadingTheRoseModel_message"), null); protected RoseEcoreBuilder roseEcoreBuilder = new RoseEcoreBuilder(this); public RoseEcoreBuilder getRoseEcoreBuilder() { return roseEcoreBuilder; } public UnitTreeNode createRoseUnitTreeAndTable(String fileNameNodeValue, UnitTreeNode topNode) throws Exception { String fileName = resolveFileName(fileNameNodeValue); // Store the base name for relative .cat file references. // if (topNode == null) { int index = fileName.lastIndexOf(File.separator); if (index != -1) { variableToDirectoryMap.put(null, fileName.substring(0, index + 1)); } } // read mdl file... RoseLoader loader = new RoseLoader(fileName, uriConverter); try { if (loader.isValid()) { basicDiagnostic = new BasicDiagnostic( RoseImporterPlugin.getPlugin().getBundle().getSymbolicName(), 1, RoseImporterPlugin.INSTANCE.getString("_UI_ProblemsWereEncounteredConvertingTheRoseModel_message"), null); RoseLexer lexer = new RoseLexer(loader); RoseParser parser = new RoseParser(lexer, true, true); parser.parse(); RoseNode modelTree = parser.getModelTree(); UnitTreeBuilder unitTreeBuilder = new UnitTreeBuilder(this); if (topNode == null) { String qualifier; // special case, traverse cat file or mdl file // UnitTreeNode unitTree = null; if (modelTree.getKey().equals("") && (Util.getType(modelTree.getValue())).equals(RoseStrings.CLASS_CATEGORY)) { // this is the case that starting process rose file by passing cat file name // this is a special case. // normally, user should pass mdl file instead of cat file // // file is a cat file // modelTree did contain quid info String quid = modelTree.getRoseId(); quid = quid.substring(1, quid.length() - 1); unitTree = new UnitTreeNode(Util.getName(modelTree.getValue()), quid, fileName); String objName = Util.getName(modelTree.getValue()); TableObject obj = new TableObject(objName, quid, unitTree); quidTable.put(quid, obj); nameTable.put(objName, obj); qualifier = objName; } else { // file is a mdl file // // get model name int ind_1 = fileName.lastIndexOf(System.getProperty("file.separator")); int ind_2 = fileName.lastIndexOf("."); String modelName; if (ind_2 != -1) modelName = fileName.substring(ind_1 + 1, ind_2); else modelName = fileName.substring(ind_1 + 1, fileName.length()); //if (!modelName.toLowerCase().endsWith("model")) // modelName = modelName + "model"; String quid = modelTree.getRoseId(); if (quid != null) { quid = quid.substring(1, quid.length() - 1); unitTree = new UnitTreeNode(modelName, quid, fileName); } else { unitTree = new UnitTreeNode(modelName, "", fileName); } qualifier = null; } // starting traverse file and build unit tree and table info unitTreeBuilder.traverse(qualifier, modelTree, unitTree); return unitTree; } else { // cat(unit) file referenced by mdl file String quid = modelTree.getRoseId(); if (quid != null) { quid = quid.substring(1, quid.length() - 1); topNode.setQUID(quid); } String objName = Util.getName(modelTree.getValue()); TableObject obj = new TableObject(objName, quid, topNode); quidTable.put(quid, obj); nameTable.put(objName, obj); unitTreeBuilder.traverse(objName, modelTree, topNode); return null; } } else { basicDiagnostic.add( new BasicDiagnostic(Diagnostic.INFO, RoseImporterPlugin.getPlugin().getBundle().getSymbolicName(), 0, RoseImporterPlugin.INSTANCE.getString("_UI_TheUnitResolvesTo_message", new Object []{ Util.trimQuotes(fileNameNodeValue), fileName }), null)); return null; } } finally { loader.close(); } } public void showRoseUnitTree(UnitTreeNode unitTree) { if (unitTree != null) { System.out.println(" "); System.out.println("======= Unit Tree Info ============="); System.out.println("[0]: " + unitTree.getName() + ", " + unitTree.getQUID() + ", " + unitTree.getRoseFileName() + ", " + unitTree.getEcoreFileName()); int i = 1; traverseOut(unitTree, i); } if (quidTable.size() > 0) { System.out.println("=========== Class Info ============"); Iterator<String> it = quidTable.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); TableObject obj = (TableObject)quidTable.get(key); System.out.println(key + ",\t" + obj.getName() + ",\t" + obj.getContainer().getEcoreFileName()); } } } protected void traverseOut(UnitTreeNode tree, int index) { List<UnitTreeNode> nodes = tree.getNodes(); if (nodes.size() > 0) { for (int i = 0; i < nodes.size(); i++) { UnitTreeNode node = nodes.get(i); System.out.println("[" + index + "]: " + node.getName() + ", " + node.getQUID() + ", " + node.getEcoreFileName()); traverseOut(node, index + 1); } } } public void createExtent4RoseUnitTree(UnitTreeNode unitTree) { if (unitTree != null) { checkConflictFileName(unitTree); createExtent(unitTree); } refTable.clear(); } public void checkConflictFileName(UnitTreeNode unitTree) { String rootEcoreFileName = unitTree.getEcoreFileName(); if (checkFileName(unitTree, rootEcoreFileName)) { int index = rootEcoreFileName.lastIndexOf("."); if (index != -1) { rootEcoreFileName = rootEcoreFileName.substring(0, index) + "model" + rootEcoreFileName.substring(index, rootEcoreFileName.length()); } unitTree.setEcoreFileName(rootEcoreFileName); } } public boolean checkFileName(UnitTreeNode unitTree, String name) { List<UnitTreeNode> nodes = unitTree.getNodes(); for (int i = 0; i < nodes.size(); i++) { UnitTreeNode node = nodes.get(i); if (node.getEcoreFileName().equals(name) || checkFileName(node, name)) { return true; } } return false; } public void createExtent(UnitTreeNode unitTree) { EList<EObject> ext = new BasicEList<EObject>(); unitTree.setExtent(ext); List<UnitTreeNode> nodes = unitTree.getNodes(); for (int i = 0; i < nodes.size(); i++) { createExtent(nodes.get(i)); } } public void processUnitTree(UnitTreeNode unitTree) throws Exception { if (unitTree != null) { loadTree(null, unitTree); String packageName = unitTree.getEcoreFileName(); int fileSeparatorIndex = packageName.lastIndexOf(File.separator); if (fileSeparatorIndex != -1) { packageName = packageName.substring(fileSeparatorIndex + 1); } int dotIndex = packageName.lastIndexOf("."); if (dotIndex != -1) { packageName = packageName.substring(0, dotIndex); } roseEcoreBuilder.createEPackageForRootClasses(unitTree.getExtent(), unitTree.getRoseNode(), packageName); roseEcoreBuilder.setEEnums(); roseEcoreBuilder.setEReferences(); roseEcoreBuilder.setSuper(); roseEcoreBuilder.setETypeClassifier(); roseEcoreBuilder.processDefferendConstraints(); setIDs(unitTree); validate(unitTree); } } protected void setIDs(UnitTreeNode node) throws Exception { for (EObject eObject : node.getExtent()) { roseEcoreBuilder.setIDs(null, eObject); } // Process the children of the UnitTreeNode recursively. // for (UnitTreeNode subNode : node.getNodes()) { setIDs(subNode); } } protected void validate(UnitTreeNode node) throws Exception { // Process the contents of the extent // for (EObject eObject : node.getExtent()) { roseEcoreBuilder.validate(eObject); } // Process the children of the UnitTreeNode recursively. // for (UnitTreeNode subNode : node.getNodes()) { validate(subNode); } } protected void loadTree(RoseNode containingNode, UnitTreeNode node) throws Exception { // Load the Rose .mdl or .cat file, and create mappings for the objects. // String roseFile = node.getRoseFileName(); RoseLoader loader = new RoseLoader(roseFile, uriConverter); try { if (loader.isValid()) { RoseLexer lexer = new RoseLexer(loader); RoseParser parser = new RoseParser(lexer, true, true); parser.parse(); RoseNode modelTree = parser.getModelTree(); modelTree.setNode(node.getExtent()); // This sets the parent so that the nodes can traverse to the root to find default eCore settings. // if (containingNode != null) { modelTree.setParent(containingNode); } containingNode = modelTree; // Start second traverse to create mapping objects in memory. // RoseWalker roseWalker = new RoseWalker(modelTree); roseWalker.traverse(roseEcoreBuilder); } } finally { loader.close(); } // Process the children of the UnitTreeNode recursively. // for (UnitTreeNode subNode : node.getNodes()) { loadTree(containingNode, subNode); } } public void saveEcoreFiles(ResourceSet resourceSet) throws Exception { for (Resource resource : resourceSet.getResources()) { resource.save(Collections.EMPTY_MAP); } } public void createResource(UnitTreeNode tree, ResourceSet resourceSet) { EList<EObject> ext = tree.getExtent(); if (ext.size() > 0) { String ecoreFileName = tree.getEcoreFileName(); URI ecoreURI = URI.createURI(ecoreFileName); Resource res = Resource.Factory.Registry.INSTANCE.getFactory(ecoreURI).createResource(ecoreURI); res.getContents().addAll(tree.getExtent()); resourceSet.getResources().add(res); } List<UnitTreeNode> nodes = tree.getNodes(); for (int i = 0; i < nodes.size(); i++) { createResource(nodes.get(i), resourceSet); } } public String resolveFileName(String name) { name = Util.trimQuotes(name); name = Util.updateFileName(name, "\\\\"); name = Util.updateFileName(name, "\\"); name = Util.updateFileName(name, "/"); String result = ""; int index; while ((index = name.indexOf(File.separator)) != -1) { String directoryName = name.substring(0, index); if (directoryName.startsWith("$")) //directoryName.length() > 0 && directoryName.charAt(0) == '$') { String variableName = directoryName.substring(1); directoryName = variableToDirectoryMap.get(variableName); if (directoryName == null) { variableToDirectoryMap.put(variableName, null); directoryName = ""; } } result += directoryName + File.separator; name = name.substring(index + 1); } result += name; if (result.indexOf(":") == -1 && !result.startsWith(File.separator)) { String baseName = variableToDirectoryMap.get(null); if (baseName != null) { result = baseName + result; } } return result; } public Map<String, String> getVariableToDirectoryMap() { return variableToDirectoryMap; } public Map<String, String> getPackageNameToNSNameMap() { return packageNameToNSNameMap; } public Map<String, String> getPackageNameToNSURIMap() { return packageNameToNSURIMap; } public Map<EPackage, List<String>> getEPackageToInformationMap() { return ePackageToInformationMap; } public Diagnostic getDiagnostic() { return basicDiagnostic; } public void addDiagnostic(Diagnostic diagnostic) { basicDiagnostic.add(diagnostic); } }