001: package model;
002:
003: import java.io.IOException;
004: import java.util.ArrayList;
005: import java.util.Collection;
006: import java.util.HashMap;
007: import java.util.Map;
008:
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011: import org.eclipse.emf.common.util.URI;
012: import org.eclipse.emf.ecore.EObject;
013: import org.eclipse.emf.ecore.resource.Resource;
014: import org.eclipse.emf.ecore.util.EcoreUtil;
015: import org.eclipse.emf.ecore.xmi.XMIResource;
016: import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
017: import org.openarchitectureware.workflow.WorkflowContext;
018: import org.openarchitectureware.workflow.WorkflowInterruptedException;
019: import org.openarchitectureware.workflow.issues.Issues;
020: import org.openarchitectureware.workflow.monitor.ProgressMonitor;
021:
022: public class Writer extends AbstractEmfWorkflowComponent {
023:
024: private Log log = LogFactory.getLog(getClass());
025:
026: private boolean OPTION_SCHEMA_LOCATION = true;
027:
028: public void setOPTION_SCHEMA_LOCATION(boolean option_schema_location) {
029: OPTION_SCHEMA_LOCATION = option_schema_location;
030: }
031:
032: private boolean OPTION_SCHEMA_LOCATION_IMPLEMENTATION = true;
033:
034: private boolean multipleResourcesInCaseOfList = false;
035:
036: private boolean cloneSlotContents = false;
037:
038: public void setMultipleResourcesInCaseOfList(boolean b) {
039: multipleResourcesInCaseOfList = b;
040: }
041:
042: public void setCloneSlotContents(boolean b) {
043: this .cloneSlotContents = b;
044: }
045:
046: public void setOPTION_SCHEMA_LOCATION_IMPLEMENTATION(
047: boolean option_schema_location_implementation) {
048: OPTION_SCHEMA_LOCATION_IMPLEMENTATION = option_schema_location_implementation;
049: }
050:
051: @SuppressWarnings("unchecked")
052: public void invoke(WorkflowContext ctx, ProgressMonitor monitor,
053: Issues issues) {
054:
055: Object slotContent = ctx.get(getModelSlot());
056: if (slotContent == null) {
057: issues.addError(this , "slot '" + getModelSlot()
058: + "' is empty.");
059: return;
060: }
061: if (!(slotContent instanceof Collection<?> || slotContent instanceof EObject)) {
062: issues.addError(this , "slot '" + getModelSlot()
063: + "' neither contains an EList nor an EObject",
064: slotContent);
065: return;
066: }
067:
068: if (slotContent instanceof EObject) {
069: EObject sc = (EObject) slotContent;
070: if (cloneSlotContents) {
071: if (sc.eResource() == null) {
072: issues
073: .addWarning(
074: this ,
075: "model in slot '"
076: + getModelSlot()
077: + "' is not yet associated with a resource; cloning it is most likely an error!");
078: } else {
079: EcoreUtil.Copier copier = new EcoreUtil.Copier();
080: EObject copy = copier.copy(sc);
081: copier.copyReferences();
082: slotContent = copy;
083: }
084: } else {
085: if (sc.eResource() != null) {
086: issues
087: .addWarning(
088: this ,
089: "the element in slot '"
090: + getModelSlot()
091: + "' is already contained in a resource and will be taken out of that resource!");
092: }
093: }
094: }
095:
096: Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap()
097: .put("*", new XMIResourceFactoryImpl());
098:
099: if (!multipleResourcesInCaseOfList) {
100: Resource r = getResourceSet().createResource(
101: URI.createURI(getUri()));
102: if (slotContent instanceof Collection<?>) {
103: r.getContents().addAll((Collection) slotContent);
104: } else {
105: r.getContents().add((EObject) slotContent);
106: }
107: write(r);
108: } else {
109: if (slotContent instanceof Collection<?>) {
110: Collection coll = (Collection) slotContent;
111: Collection<Resource> resources = new ArrayList<Resource>();
112: for (Object object : coll) {
113: EObject eo = (EObject) object;
114: Resource r = getResourceSet().createResource(
115: URI.createURI(createResourceName(eo)));
116: r.getContents().add(eo);
117: resources.add(r);
118: }
119: for (Resource r : resources) {
120: write(r);
121: }
122: } else {
123: Resource r = getResourceSet().createResource(
124: URI.createURI(getUri()));
125: r.getContents().add((EObject) slotContent);
126: write(r);
127: }
128: }
129: }
130:
131: private String createResourceName(EObject eo) {
132: return getUri() + (getUri().endsWith("/") ? "" : "/")
133: + getName(eo) + ".ecore";
134: }
135:
136: private String getName(EObject model) {
137: return (String) model.eGet(model.eClass()
138: .getEStructuralFeature("name"));
139: }
140:
141: private void write(Resource r) {
142: try {
143: Map<String, Object> options = new HashMap<String, Object>();
144: if (OPTION_SCHEMA_LOCATION)
145: options.put(XMIResource.OPTION_SCHEMA_LOCATION,
146: Boolean.TRUE);
147: if (OPTION_SCHEMA_LOCATION_IMPLEMENTATION)
148: options
149: .put(
150: XMIResource.OPTION_SCHEMA_LOCATION_IMPLEMENTATION,
151: Boolean.TRUE);
152: r.save(options);
153: } catch (final IOException e) {
154: log.error("Problems writing xmi file to " + getUri()
155: + " : " + e.getMessage());
156: throw new WorkflowInterruptedException(
157: "Problems writing xmi file to " + getUri() + " : "
158: + e.getMessage());
159: }
160: }
161:
162: @Override
163: public String getLogMessage() {
164: return "Writing model to " + uri;
165: }
166:
167: }
|