package org.eclipse.epf.library.util; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.epf.common.utils.FileUtil; import org.eclipse.epf.library.LibraryPlugin; import org.eclipse.epf.library.LibraryServiceUtil; import org.eclipse.epf.library.configuration.ConfigurationHelper; import org.eclipse.epf.library.configuration.DefaultElementRealizer; import org.eclipse.epf.library.configuration.ElementRealizer; import org.eclipse.epf.library.edit.util.DescriptorPropUtil; import org.eclipse.epf.library.edit.util.LibraryEditUtil; import org.eclipse.epf.library.edit.util.MethodElementPropUtil; import org.eclipse.epf.library.edit.util.MethodLibraryPropUtil; import org.eclipse.epf.library.edit.util.MethodPluginPropUtil; import org.eclipse.epf.library.edit.util.ProcessPropUtil; import org.eclipse.epf.library.edit.util.ProcessScopeUtil; import org.eclipse.epf.library.edit.util.ProcessUtil; import org.eclipse.epf.persistence.MultiFileXMIResourceImpl; import org.eclipse.epf.services.ILibraryPersister; import org.eclipse.epf.uma.ContentDescription; import org.eclipse.epf.uma.ContentElement; import org.eclipse.epf.uma.Deliverable; import org.eclipse.epf.uma.Descriptor; import org.eclipse.epf.uma.DescriptorDescription; import org.eclipse.epf.uma.Guidance; import org.eclipse.epf.uma.MethodConfiguration; import org.eclipse.epf.uma.MethodElement; import org.eclipse.epf.uma.MethodLibrary; import org.eclipse.epf.uma.MethodPlugin; import org.eclipse.epf.uma.Process; import org.eclipse.epf.uma.Role; import org.eclipse.epf.uma.RoleDescriptor; import org.eclipse.epf.uma.Task; import org.eclipse.epf.uma.TaskDescriptor; import org.eclipse.epf.uma.UmaPackage; import org.eclipse.epf.uma.WorkProduct; import org.eclipse.epf.uma.WorkProductDescriptor; public class SynFreeProcessConverter { private boolean debug = false; private ElementRealizer realizer; private MethodConfiguration config; private ElementRealizer getRealizer() { return realizer; } private void setRealizer(ElementRealizer realizer) { this.realizer = realizer; } private Set<Resource> resouresToSave; private UmaPackage up = UmaPackage.eINSTANCE; public SynFreeProcessConverter() { } public SynFreeProcessConverter(MethodConfiguration config) { this.config = config; } private MethodConfiguration getConfig(Process proc) { return config == null ? proc.getDefaultContext() : config; } public void convertLibrary(MethodLibrary lib) throws Exception { convertLibrary(lib, true); } public void convertLibrary(MethodLibrary lib, boolean toSave) throws Exception { if (debug) { System.out.println("LD> Begin convertLibrary: " + lib); //$NON-NLS-1$ System.out.println(""); //$NON-NLS-1$ } convertLibrary_(lib, toSave); if (debug) { System.out.println("LD> End convertLibrary: " + lib); //$NON-NLS-1$ System.out.println(""); //$NON-NLS-1$ } } private void convertLibrary_(MethodLibrary lib, boolean toSave) throws Exception { if (lib == null) { return; } List<MethodPlugin> plugins = lib.getMethodPlugins(); if (toSave) { resouresToSave = new HashSet<Resource>(); } for (int i = 0; i < plugins.size(); i++) { convertPlugin(plugins.get(i), false); } MethodLibraryPropUtil propUtil = MethodLibraryPropUtil .getMethodLibraryPropUtil(); propUtil.setSynFree(lib, true); if (toSave) { resouresToSave.add(lib.eResource()); save(); } } public void convertPlugin(MethodPlugin plugin, boolean toSave) throws Exception { if (plugin == null) { return; } if (debug) { System.out.println("LD> convertPlugin: " + plugin); //$NON-NLS-1$ System.out.println(""); //$NON-NLS-1$ } if (toSave) { resouresToSave = new HashSet<Resource>(); } Set<Process> processes = LibraryEditUtil.getInstance() .collectProcesses(plugin); for (Process proc : processes) { convertProcess(proc, false); } MethodPluginPropUtil propUtil = MethodPluginPropUtil .getMethodPluginPropUtil(); propUtil.setSynFree(plugin, true); if (resouresToSave != null) { Resource res = plugin.eResource(); if (res != null) { resouresToSave.add(res); } } if (toSave) { save(); } } public void convertProcess(Process proc, boolean toSave) throws Exception { if (proc == null) { return; } if (proc.getDefaultContext() == null) { ProcessScopeUtil.getInstance().loadScope(proc); } if (proc.getDefaultContext() == null) { return; } if (debug) { System.out.println("LD> convertProcess: " + proc); //$NON-NLS-1$ System.out.println(""); //$NON-NLS-1$ } MethodConfiguration c = getConfig(proc); ElementRealizer r = DefaultElementRealizer.newElementRealizer(c); setRealizer(r); Set<Descriptor> descriptors = LibraryEditUtil.getInstance() .collectDescriptors(proc); if (toSave) { resouresToSave = new HashSet<Resource>(); } for (Descriptor des : descriptors) { convert(proc, des); } ProcessPropUtil.getProcessPropUtil().setSynFree(proc, true); if (resouresToSave != null) { Resource res = proc.eResource(); if (res != null) { resouresToSave.add(res); } } if (toSave) { save(); } } private void convert(Process proc, Descriptor des) { boolean oldDeliver = des.eDeliver(); try { if (oldDeliver) { des.eSetDeliver(false); } convert_(proc, des); } finally { if (oldDeliver) { des.eSetDeliver(oldDeliver); } } } private void convert_(Process proc, Descriptor des) { Resource res = des.eResource(); if (res == null) { return; } if (debug) { System.out.println("LD> convert: " + des); //$NON-NLS-1$ } if (des instanceof TaskDescriptor) { convertTd(proc, (TaskDescriptor) des); } else if (des instanceof RoleDescriptor) { convertRd(proc, (RoleDescriptor) des); } else if (des instanceof WorkProductDescriptor) { convertWpd(proc, (WorkProductDescriptor) des); } convertGuidances(proc, des); convertTextAttributes(proc, des); if (resouresToSave != null) { resouresToSave.add(res); } } public static boolean equalsIgnoreSuffixNumber(String eString, String dString) { if (eString == null) { return dString == null; } if (dString == null) { return false; } if (dString.equals(eString)) { return true; } if (dString.startsWith(eString + "_")) { //$NON-NLS-1$ int ix = eString.length() + 1; String str = dString.substring(ix); try { int n = Integer.parseInt(str); return n >= 0; } catch (Exception e) { return false; } } return false; } private void convertTextAttributes(Process proc, Descriptor des) { DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil(); ContentElement element = (ContentElement) propUtil.getLinkedElement(des); if (element == null) { return; } if (propUtil.hasNoValue(des.getName())) { des.setName(element.getName()); // } else if (!des.getName().equals(element.getName())) { } else if (! equalsIgnoreSuffixNumber(element.getName(), des.getName())) { propUtil.setNameRepalce(des, true); } String elementStrValue = ConfigurationHelper.getPresentationName(element, getConfig(proc)); if (propUtil.hasNoValue(des.getPresentationName())) { des.setPresentationName(element.getPresentationName()); // } else if (!des.getPresentationName().equals( // element.getPresentationName())) { } else if (! equalsIgnoreSuffixNumber(element.getPresentationName(), des.getPresentationName())) { propUtil.setPresentationNameRepalce(des, true); } elementStrValue = (String) ConfigurationHelper .calcAttributeFeatureValue(element, up .getMethodElement_BriefDescription(), getConfig(proc)); if (propUtil.hasNoValue(des.getBriefDescription())) { des.setBriefDescription(elementStrValue); } else if (!des.getBriefDescription().equals( elementStrValue)) { propUtil.setBriefDesRepalce(des, true); } ContentDescription ePrentation = element.getPresentation(); DescriptorDescription dPrentation = (DescriptorDescription) des .getPresentation(); boolean oldDeliver = dPrentation.eDeliver(); try { if (oldDeliver) { dPrentation.eSetDeliver(false); } elementStrValue = (String) ConfigurationHelper .calcAttributeFeatureValue(ePrentation, element, up .getContentDescription_MainDescription(), getConfig(proc)); if (propUtil.hasNoValue(dPrentation.getRefinedDescription())) { dPrentation.setRefinedDescription(elementStrValue); } else if (!dPrentation.getRefinedDescription().equals( elementStrValue)) { propUtil.setMainDesRepalce(des, true); } elementStrValue = (String) ConfigurationHelper .calcAttributeFeatureValue(ePrentation, element, up .getContentDescription_KeyConsiderations(), getConfig(proc)); if (propUtil.hasNoValue(dPrentation.getKeyConsiderations())) { dPrentation.setKeyConsiderations(elementStrValue); } else if (!dPrentation.getKeyConsiderations().equals( elementStrValue)) { propUtil.setKeyConsiderRepalce(des, true); } } finally { if (oldDeliver) { dPrentation.eSetDeliver(oldDeliver); } } } private void convertTd(Process proc, TaskDescriptor td) { Task task = (Task) getLinkedElement(td); if (task == null) { return; } convertManyEReference(proc, td, task, up .getTaskDescriptor_PerformedPrimarilyBy(), up .getTaskDescriptor_PerformedPrimarilyByExcluded(), up .getTask_PerformedBy()); convertManyEReference(proc, td, task, up .getTaskDescriptor_AdditionallyPerformedBy(), up .getTaskDescriptor_AdditionallyPerformedByExclude(), up .getTask_AdditionallyPerformedBy()); convertManyEReference(proc, td, task, up.getTaskDescriptor_MandatoryInput(), up.getTaskDescriptor_MandatoryInputExclude(), up .getTask_MandatoryInput()); convertManyEReference(proc, td, task, up.getTaskDescriptor_OptionalInput(), up.getTaskDescriptor_OptionalInputExclude(), up .getTask_OptionalInput()); convertManyEReference(proc, td, task, up.getTaskDescriptor_Output(), up .getTaskDescriptor_OutputExclude(), up.getTask_Output()); convertManyEReference(proc, td, task, up.getTaskDescriptor_SelectedSteps(), up.getTaskDescriptor_SelectedStepsExclude(), up.getTask_Steps()); } private void convertManyEReference(Process proc, Descriptor ownerDescriptor, MethodElement ownerLinkedElement, EReference dFeature, EReference dFeatureExclude, EReference efeature) { DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil(); List<MethodElement> elements = ConfigurationHelper.calc0nFeatureValue( ownerLinkedElement, efeature, getRealizer()); List<MethodElement> descriptors = ConfigurationHelper .calc0nFeatureValue(ownerDescriptor, dFeature, getRealizer()); // exclude list and local list List<MethodElement> excludeList = (List<MethodElement>) ownerDescriptor .eGet(dFeatureExclude); List<Descriptor> localList = new ArrayList<Descriptor>(); Set<MethodElement> elementSet = new HashSet<MethodElement>(); if (elements != null && !elements.isEmpty()) { elementSet.addAll(elements); } List<MethodElement> linkedElements = new ArrayList<MethodElement>(); Set<MethodElement> linkedElementSet = new HashSet<MethodElement>(); if (descriptors != null) { for (MethodElement des : descriptors) { if (des instanceof Descriptor) { Descriptor d = (Descriptor) des; MethodElement linkedElement = getLinkedElement(d); if (linkedElement == null) { localList.add(d); } else { linkedElementSet.add(linkedElement); if (elementSet.contains(linkedElement)) { propUtil.setCreatedByReference(d, true); } else { localList.add(d); } } } else { linkedElementSet.addAll(descriptors); break; } } } for (MethodElement element : elements) { if (!linkedElementSet.contains(element)) { excludeList.add(element); } } // Handle localList for (Descriptor des : localList) { propUtil.addLocalUse(des, ownerDescriptor, dFeature); } } private void convertGuidances(Process proc, Descriptor des) { MethodElement element = ProcessUtil.getAssociatedElement(des); if (element == null) { return; } Map<EReference, EReference> refMap = LibraryEditUtil.getInstance() .getGuidanceRefMap(getLinkedElementType(des)); if (refMap == null) { return; } MethodElementPropUtil propUtil = MethodElementPropUtil.getMethodElementPropUtil(); Set<Guidance> elementGuidanceSet = new HashSet<Guidance>(); Set<Guidance> descripGuidanceSet = new HashSet<Guidance>(); for (Map.Entry<EReference, EReference> entry : refMap.entrySet()) { EReference elementRef = entry.getKey(); EReference descripRef = entry.getValue(); Object elementValue = ConfigurationHelper.calc0nFeatureValue( element, elementRef, getRealizer()); Object descripValue = ConfigurationHelper.calc0nFeatureValue( des, descripRef, getRealizer()); if (elementValue instanceof List) { List list = (List) elementValue; if (!list.isEmpty()) { elementGuidanceSet.addAll((List) elementValue); } // Object rawDescripValue = des.eGet(descripRef); Object rawDescripValue = list.isEmpty() ? null : propUtil.eGet(des, descripRef, true); if (rawDescripValue instanceof List) { List rawList = (List) rawDescripValue; Set<Guidance> rewDescripGuidanceSet = new HashSet<Guidance>(rawList); for (Guidance g : (List<Guidance>) list) { if (! rewDescripGuidanceSet.contains(g)) { rawList.add(g); } } } } if (descripValue instanceof List) { List list = (List) descripValue; if (!list.isEmpty()) { descripGuidanceSet.addAll((List) descripValue); } } } // for (Guidance g : elementGuidanceSet) { // if (!descripGuidanceSet.contains(g)) { // des.getGuidanceExclude().add(g); // } // } for (Guidance g : descripGuidanceSet) { if (!elementGuidanceSet.contains(g)) { des.getGuidanceAdditional().add(g); } } } private void convertRd(Process proc, RoleDescriptor rd) { Role role = (Role) getLinkedElement(rd); if (role == null) { return; } convertManyEReference(proc, rd, role, up.getRoleDescriptor_ResponsibleFor(), up.getRoleDescriptor_ResponsibleForExclude(), up .getRole_ResponsibleFor()); } private void convertWpd(Process proc, WorkProductDescriptor wpd) { WorkProduct wp = (WorkProduct) getLinkedElement(wpd); if (wp == null) { return; } if (wp instanceof Deliverable) { convertManyEReference(proc, wpd, wp, up .getWorkProductDescriptor_DeliverableParts(), up .getWorkProductDescriptor_DeliverablePartsExclude(), up .getDeliverable_DeliveredWorkProducts()); } } private void save() throws Exception { ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil .getCurrentPersister().getFailSafePersister(); try { List<String> modifiedFiles = new ArrayList<String>(); for (Resource res : resouresToSave) { String path = res.getURI().toFileString(); modifiedFiles.add(path); } IStatus status = FileUtil.syncExecCheckModify(modifiedFiles); // To do: check status and handle bad status here. // For now, leave the following catch to handle bad status for (Iterator<Resource> it = resouresToSave.iterator(); it .hasNext();) { MultiFileXMIResourceImpl res = (MultiFileXMIResourceImpl) it .next(); res.setModified(true); persister.save(res); } persister.commit(); } catch (Exception e) { persister.rollback(); LibraryPlugin.getDefault().getLogger().logError(e); String msg = "Cannot save file during converions. Likely caused by some file being read-only."; //$NON-NLS-1$ LibraryPlugin.getDefault().getLogger().logInfo(msg); throw e; } finally { } } private MethodElement getLinkedElement(Descriptor des) { MethodElement element = DescriptorPropUtil.getDesciptorPropUtil() .getLinkedElement(des); if (element == null) { return null; } return ConfigurationHelper.getCalculatedElement(element, getRealizer()); } public static EClass getLinkedElementType(Descriptor des) { if (des instanceof TaskDescriptor) { return UmaPackage.eINSTANCE.getTask(); } if (des instanceof RoleDescriptor) { return UmaPackage.eINSTANCE.getRole(); } if (des instanceof WorkProductDescriptor) { return UmaPackage.eINSTANCE.getWorkProduct(); } throw new UnsupportedOperationException(); } }