/******************************************************************************* * Copyright (c) 2005, 2007 committers of openArchitectureWare 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: * committers of openArchitectureWare - initial API and implementation *******************************************************************************/ package org.eclipse.xtend.util.uml2ecore; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.resource.impl.URIConverterImpl; import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; import org.eclipse.emf.mwe.core.ConfigurationException; import org.eclipse.emf.mwe.core.WorkflowContext; import org.eclipse.emf.mwe.core.issues.Issues; import org.eclipse.emf.mwe.core.lib.AbstractWorkflowComponent; import org.eclipse.emf.mwe.core.monitor.ProgressMonitor; /** * @author Markus V�lter */ public class Uml2EcoreXmiWriter extends AbstractWorkflowComponent { private String inputSlot = WorkflowContext.DEFAULT_SLOT; private String outputPath; private final Log log = LogFactory.getLog(getClass()); public void setInputSlot(final String inputSlot) { this.inputSlot = inputSlot; } public String getLogMessage() { return "slot " + inputSlot; } public void setOutputPath(String p) { this.outputPath = p; } public void checkConfiguration(final Issues issues) { } protected void invokeInternal(final WorkflowContext ctx, final ProgressMonitor monitor, final Issues issues) { final Object slotContent = ctx.get(inputSlot); if (slotContent == null) { issues.addError(this, "slot '" + inputSlot + "' is empty."); return; } Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl()); ResourceSetImpl rsImpl = new ResourceSetImpl(); XmiWriterURIConverter uriConverter = new XmiWriterURIConverter(outputPath); rsImpl.setURIConverter(uriConverter); List<Resource> resources = new ArrayList(); List<String> resourceNames = new ArrayList(); if (slotContent instanceof List) { List list = (List) slotContent; for (Object object : list) { if (object instanceof EObject) { createResource(rsImpl, uriConverter, (EObject) object, resources, resourceNames); } else { issues.addError(this, "slot '" + inputSlot + "' contains non-EObject elements in the list!", object); } } } else if (slotContent instanceof EObject) { EObject model = (EObject) slotContent; createResource(rsImpl, uriConverter, model, resources, resourceNames); } else { issues.addError(this, "slot '" + inputSlot + "' neither contains an EList nor an EObject", slotContent); return; } for (int i = 0; i < resources.size(); i++) { Resource res = resources.get(i); String name = resourceNames.get(i); try { res.save(null); removeAbsoluteFileRefs(uriConverter, res, name); } catch (final IOException e) { throw new ConfigurationException(e); } } } private void createResource(ResourceSetImpl rsImpl, XmiWriterURIConverter uriConverter, EObject model, List<Resource> resources, List<String> resourceNames) { String filename = getName(model) + ".ecore"; final URI fileURI = URI.createURI(filename);// EcoreUtil2.getURI(modelFile); Resource r = rsImpl.createResource(fileURI); log.info("writing to '" + filename + "': " + model.eClass().getName() + " named " + getName(model)); r.getContents().add(model); resources.add(r); resourceNames.add(filename); } private String getName(EObject model) { return (String) model.eGet(model.eClass().getEStructuralFeature("name")); } private void removeAbsoluteFileRefs(XmiWriterURIConverter uriConverter, Resource r, String filename) { try { StringBuffer newFile = new StringBuffer(); InputStream stream = uriConverter.createInputStream(r.getURI()); BufferedReader br = new BufferedReader(new InputStreamReader(stream)); while (br.ready()) { String s = br.readLine(); s = s.replaceAll(filename + "#//", "#//"); newFile.append(s + "\n"); } br.close(); stream.close(); OutputStream s = uriConverter.createOutputStream(r.getURI()); PrintStream ps = new PrintStream(s); ps.print(newFile); } catch (IOException e) { e.printStackTrace(); } } class XmiWriterURIConverter extends URIConverterImpl { private String pathPrefix; public XmiWriterURIConverter(String pathPrefix) { this.pathPrefix = pathPrefix; } @Override protected OutputStream createFileOutputStream(String filename) throws IOException { return super.createFileOutputStream(tweakFilename(filename)); } @Override protected InputStream createFileInputStream(String filename) throws IOException { return super.createFileInputStream(tweakFilename(filename)); } private String tweakFilename(String filename) { if (pathPrefix != null) { pathPrefix = pathPrefix.replace('\\', '/'); if (!pathPrefix.endsWith("/")) pathPrefix += "/"; filename = filename.replace('\\', '/'); int lastSlashPos = filename.lastIndexOf("/"); if (lastSlashPos >= 0) { filename = filename.substring(0, lastSlashPos + 1) + pathPrefix + filename.substring(lastSlashPos + 1); } } return filename; } } }