blob: aa5a215c76dd7658d7c6f0752eaddc356f9cc684 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Ericsson AB 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:
* Ericsson AB - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.reviews.r4e.internal.transform.impl;
import java.util.Collection;
import java.util.Iterator;
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.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
import org.eclipse.mylyn.reviews.frame.core.model.ReviewState;
import org.eclipse.mylyn.reviews.frame.core.model.TaskReference;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EAnomaly;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EAnomalyType;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EComment;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFormalReview;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EItem;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EMeetingData;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReview;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewDecision;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewGroup;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EReviewPhaseInfo;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EUser;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.IModelReader;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.IModelWriter;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.IRWUserBasedRes.ResourceType;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.Persistence.RModelFactoryExt;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.impl.CompatibilityException;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.impl.ResourceHandlingException;
import org.eclipse.mylyn.reviews.r4e.core.model.serial.impl.SerializeFactory;
import org.eclipse.mylyn.reviews.r4e.internal.transform.Activator;
import org.eclipse.mylyn.reviews.r4e.internal.transform.ModelTransform;
import org.eclipse.mylyn.reviews.r4e.internal.transform.resources.ReviewGroupRes;
import org.eclipse.mylyn.reviews.r4e.internal.transform.resources.ReviewRes;
import org.eclipse.mylyn.reviews.r4e.internal.transform.resources.TransResFactory;
import org.eclipse.mylyn.reviews.r4e.internal.transform.serial.impl.TResSerializeFactory;
/**
* @author Alvaro Sanchez-Leon
*/
public class ModelTransformImpl implements ModelTransform {
IModelWriter fWriter = TResSerializeFactory.getWriter();
IModelReader fReader = TResSerializeFactory.getReader();
RModelFactoryExt fModelFactory = SerializeFactory.getModelExtension();
TransResFactory fModelResFactory = TransResFactory.eINSTANCE;
/**
* @throws ResourceHandlingException
*/
public ReviewGroupRes createReviewGroupRes(URI aFolderPath, String aGroupName, String aFilePrefix)
throws ResourceHandlingException {
URI fileGroupURI = fWriter.createResourceURI(aFilePrefix, aFolderPath, ResourceType.GROUP);
// create a new ResourceSet and resource for the given group
Resource resource = fWriter.createResourceSetWithResource(fileGroupURI);
ReviewGroupRes group = TransResFactory.eINSTANCE.createReviewGroupRes();
resource.getContents().add(group);
URI uri = group.eResource().getURI().trimSegments(1);
// Update the resource
group.setName(aGroupName);
group.setFilesPrefix(aFilePrefix);
group.setFolder(URI.decode(uri.devicePath().toString()));
fWriter.saveResource(resource);
return group;
}
public ReviewGroupRes openReviewGroupRes(URI aResourcePath) throws ResourceHandlingException {
ReviewGroupRes group = fReader.deserializeTopElement(aResourcePath, ReviewGroupRes.class);
// Build the mapping references to anomaly types
EList<R4EAnomalyType> anomTypes = group.getAvailableAnomalyTypes();
for (R4EAnomalyType r4eAnomalyType : anomTypes) {
group.getAnomalyTypeKeyToReference().put(r4eAnomalyType.getType(), r4eAnomalyType);
}
URI resUri = group.eResource().getURI().trimSegments(1);
// update the transient value of folder
group.setFolder(URI.decode(resUri.devicePath().toString()));
return group;
}
public String closeReviewGroupRes(ReviewGroupRes aReviewGroup) {
StringBuilder sb = new StringBuilder();
// Obtain all resources
Resource resource = aReviewGroup.eResource();
if (resource == null) {
sb.append("Attempting to close a review group with no associated resource"); //$NON-NLS-1$
Activator.fTracer.traceDebug(sb.toString());
return sb.toString();
}
ResourceSet resSet = resource.getResourceSet();
if (resSet == null) {
sb.append("Attempting to close a review group with no associated resource set"); //$NON-NLS-1$
Activator.fTracer.traceDebug(sb.toString());
return sb.toString();
}
EList<Resource> resList = resSet.getResources();
// unload then all
for (Resource res : resList) {
res.unload();
}
return null;
}
/**
* Transform the original review to concatenate a copy of the contents on a separate model within a consolidated
* resource
*
* @throws ResourceHandlingException
* @throws CompatibilityException
*/
public ReviewRes transformReview(URI aOigReviewGroup, URI aDstReviewGroup, String aOigReviewName)
throws ResourceHandlingException, CompatibilityException {
//Open original model
R4EReviewGroup origGroup = RModelFactoryExt.eINSTANCE.openR4EReviewGroup(aOigReviewGroup);
//Open original review
R4EReview origReview = RModelFactoryExt.eINSTANCE.openR4EReview(origGroup, aOigReviewName);
//Open destination group
ReviewGroupRes destGroup = openReviewGroupRes(aDstReviewGroup);
ResourceSet destResSet = destGroup.eResource().getResourceSet();
//Retrieve the file prefix, selected for the group
String filePrefix = destGroup.getFilesPrefix();
//Make sure a review with this name does not already exists
EList<ReviewRes> existingReviews = destGroup.getReviewsRes();
for (Object element : existingReviews) {
ReviewRes reviewRes = (ReviewRes) element;
if (reviewRes.getName().equals(aOigReviewName)) {
StringBuilder sb = new StringBuilder("A review with this name already exists in destination Group: " //$NON-NLS-1$
+ aOigReviewName);
throw new ResourceHandlingException(sb.toString());
}
}
//Create the extended review instance
ReviewRes destReview = fModelResFactory.createReviewRes();
//Create Review resource if it does not exist yet
Resource destReviewResource = null;
if (existingReviews == null || existingReviews.size() == 0) {
URI containerPath = destGroup.eResource().getURI().trimSegments(1);
URI destReviewURI = fWriter.createResourceURI(filePrefix, containerPath, ResourceType.REVIEW);
destReviewResource = destResSet.createResource(destReviewURI);
} else {
destReviewResource = existingReviews.get(0).eResource();
}
//Add the review to the ReviewGroup
destGroup.getReviewsRes().add(destReview);
//Make sure the new destination review is associated to a valid resource
destReviewResource.getContents().add(destReview);
adaptReview(origReview, destReview, destGroup);
//save the review resource
fWriter.saveResources(destGroup.eResource().getResourceSet());
return destReview;
}
private void adaptReview(R4EReview origReview, ReviewRes destReview, ReviewGroupRes destGroup) {
Copier copier = new Copier();
Collection<R4EUser> origUsersList = origReview.getUsersMap().values();
//copy review data from original element to the extended review element
copyReviewData(origReview, destReview, copier);
Resource destResource = destReview.eResource();
R4EUser createdBy = origReview.getCreatedBy();
EList<R4EUser> users = destReview.getUsersRes();
//clone all users to new destination resource, this will make sure that back reference from children to any user will point to the updated resource
for (R4EUser oUser : origUsersList) {
R4EUser dUser = (R4EUser) copyToResource(destResource, oUser, copier);
//move the user to the destination review
users.add(dUser);
//Associate the user to a new destination serialisation resource
destResource.getContents().add(dUser);
//find created by user and update the reference in the destination review
if (oUser == createdBy) {
destReview.setCreatedBy(dUser);
}
}
//Update all references in the copied elements
copier.copyReferences();
//The review is a new element extended from original review.
//Refresh all review references in the underneath structure to
//point to the extended one.
EList<R4EUser> destUsers = destReview.getUsersRes();
for (R4EUser user : destUsers) {
//update it at the user
user.setReviewInstance(destReview);
EList<R4EComment> comments = user.getAddedComments();
for (R4EComment comment : comments) {
if (comment instanceof R4EAnomaly) {
R4EAnomaly anomaly = (R4EAnomaly) comment;
//Update of Review instance at the anomaly level
anomaly.setReview(destReview);
}
}
EList<R4EItem> items = user.getAddedItems();
for (R4EItem item : items) {
//update of review instance at review item level
item.setReview(destReview);
}
}
}
/**
* @param destResource
* @param eObject
*/
private void associateToResource(Resource destResource, EObject eObject) {
//Migrate the object itself
destResource.getContents().add(eObject);
//Migrate the direct contents as well
for (Iterator<Object> iterator = EcoreUtil.getAllContents(eObject, true); iterator.hasNext();) {
Object child = iterator.next();
if (child instanceof EObject) {
EObject eobject = (EObject) child;
destResource.getContents().add(eobject);
}
}
}
private EObject copyToResource(Resource resource, EObject source, Copier copier) {
EObject copyOfObject = copier.copy(source);
associateToResource(resource, copyOfObject);
return copyOfObject;
}
/**
* @param origReview
* @param destReview
* @param copier
*/
private void copyReviewData(R4EReview origReview, ReviewRes destReview, Copier copier) {
Resource res = destReview.eResource();
//copy EObject references
if (origReview.getActiveMeeting() != null) {
R4EMeetingData meetingData = (R4EMeetingData) copyToResource(res, origReview.getActiveMeeting(), copier);
destReview.setActiveMeeting(meetingData);
}
if (origReview.getAnomalyTemplate() != null) {
R4EAnomaly anomalyTemplate = (R4EAnomaly) copyToResource(res, origReview.getAnomalyTemplate(), copier);
destReview.setAnomalyTemplate(anomalyTemplate);
}
if (origReview.getDecision() != null) {
R4EReviewDecision decision = (R4EReviewDecision) copyToResource(res, origReview.getDecision(), copier);
destReview.setDecision(decision);
}
if (origReview.getReviewTask() != null) {
TaskReference taskRef = (TaskReference) copyToResource(res, origReview.getReviewTask(), copier);
destReview.setReviewTask(taskRef);
}
if (origReview.getState() != null) {
ReviewState state = (ReviewState) copyToResource(res, origReview.getState(), copier);
destReview.setState(state);
}
//associate java types
destReview.setType(origReview.getType());
destReview.setEnabled(origReview.isEnabled());
destReview.setEndDate(origReview.getEndDate());
destReview.setDueDate(origReview.getDueDate());
destReview.setEntryCriteria(origReview.getEntryCriteria());
destReview.setExtraNotes(origReview.getExtraNotes());
destReview.setName(origReview.getName());
destReview.setObjectives(origReview.getObjectives());
destReview.setProject(origReview.getProject());
destReview.setReferenceMaterial(origReview.getReferenceMaterial());
destReview.setStartDate(origReview.getStartDate());
destReview.setFragmentVersion(origReview.getFragmentVersion());
//copy review components
EList<String> components = origReview.getComponents();
for (Object element : components) {
String component = (String) element;
destReview.getComponents().add(component);
}
if (origReview instanceof R4EFormalReview) {
R4EFormalReview formalRevOrig = (R4EFormalReview) origReview;
EList<R4EReviewPhaseInfo> phases = formalRevOrig.getPhases();
if (phases != null) {
R4EReviewPhaseInfo currentPhase = formalRevOrig.getCurrent();
R4EReviewPhaseInfo[] movingPhases = phases.toArray(new R4EReviewPhaseInfo[0]);
for (R4EReviewPhaseInfo phaseInfo : movingPhases) {
R4EReviewPhaseInfo phaseInfoCopy = (R4EReviewPhaseInfo) copyToResource(res, phaseInfo, copier);
destReview.getPhases().add(phaseInfoCopy);
//Current phase found
if (phaseInfo == currentPhase) {
destReview.setCurrent(phaseInfoCopy);
}
}
}
}
}
}