//------------------------------------------------------------------------------ // Copyright (c) 2005, 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 Corporation - initial implementation //------------------------------------------------------------------------------ package org.eclipse.epf.library.util; import java.io.File; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.epf.common.utils.FileUtil; import org.eclipse.epf.common.utils.NetUtil; import org.eclipse.epf.library.ILibraryResourceManager; import org.eclipse.epf.library.LibraryPlugin; import org.eclipse.epf.library.LibraryResources; import org.eclipse.epf.library.edit.command.MethodElementAddCommand.BasicResourceManager; import org.eclipse.epf.library.edit.meta.IMetaDef; import org.eclipse.epf.library.edit.meta.TypeDefUtil; import org.eclipse.epf.library.edit.util.TngUtil; import org.eclipse.epf.library.layout.IContentValidator; import org.eclipse.epf.persistence.FileManager; import org.eclipse.epf.uma.ContentDescription; import org.eclipse.epf.uma.DescribableElement; import org.eclipse.epf.uma.GuidanceDescription; import org.eclipse.epf.uma.MethodElement; import org.eclipse.epf.uma.MethodPlugin; import org.eclipse.epf.uma.util.ExtendedAttribute; import org.eclipse.epf.uma.util.UmaUtil; import org.eclipse.osgi.util.NLS; /** * utility class to copy attachmeents to another location * @author Jeff Hardy * @sicne 1.0 * */ public class CopyAttachmentsToNewLocation extends BasicResourceManager { private Collection modifiedResourceSet; private boolean debug; private Map elementToOldPluginMap; private MethodPlugin lastOldPlugin = null; public CopyAttachmentsToNewLocation() { debug = LibraryPlugin.getDefault().isDebugging(); } /** * Copy attachments within a library, from one plugin to another */ public Collection copyReferencedContents(Collection elements, Map elementToOldPluginMap) { lastOldPlugin = null; modifiedResourceSet = new HashSet(); if (elementToOldPluginMap == null) { return modifiedResourceSet; } this.elementToOldPluginMap = elementToOldPluginMap; Iterator iter = elements.iterator(); while (iter.hasNext()) { Object o = iter.next(); if (o instanceof Resource) { Resource r = (Resource) o; Iterator resourceIter = r.getContents().iterator(); while (resourceIter.hasNext()) { EObject e = (EObject) resourceIter.next(); HandleAttachmentsPlugin(e); } } else if (o instanceof EObject) { EObject e = (EObject) o; HandleAttachmentsPlugin(e); } } return modifiedResourceSet; } private void HandleAttachmentsPlugin(EObject e) { // handle self MethodElement elementToProcess = null; // find the old plugin, if there is one if (elementToOldPluginMap != null && (MethodPlugin) elementToOldPluginMap.get(e) != null) { lastOldPlugin = (MethodPlugin) elementToOldPluginMap.get(e); } if (lastOldPlugin != null) { if (e instanceof DescribableElement) { DescribableElement de = (DescribableElement) e; // Custom icons try { // shape icon java.net.URI shapeIconUri = de.getShapeicon(); if (shapeIconUri != null) { // To handle the shapeIcon/nodeIcon uri got changed, its relative to pluginPath. java.net.URI newShapeIconUri = handleIconURI(de, shapeIconUri); if (newShapeIconUri != null) { de.setShapeicon(newShapeIconUri); modifiedResourceSet.add(de.eResource()); } } // node icon java.net.URI nodeIconUri = de.getNodeicon(); if (nodeIconUri != null) { java.net.URI newNodeIconUri = handleIconURI(de, nodeIconUri); if (newNodeIconUri != null) { de.setNodeicon(newNodeIconUri); modifiedResourceSet.add(de.eResource()); } } } catch (Exception ex) { LibraryPlugin.getDefault().getLogger().logError(ex); } HandleAttachmentsPlugin(de.getPresentation()); return; } else if (e instanceof ContentDescription) { elementToProcess = (ContentDescription) e; } else if (e instanceof MethodElement) { elementToProcess = (MethodElement) e; } else { if (debug) { System.out .println("CopyAttachmentsToNewLocation.HandleAttachmentsPlugin: unknown type " + e); //$NON-NLS-1$ } } if (elementToProcess != null && elementToProcess.eResource() != null) { // set up ContentResourceScanner for this element // give ContentResourceScanner same directory for sourceRootPath // and targetRootPath // ILibraryManager manager = (ILibraryManager) LibraryService // .getInstance().getCurrentLibraryManager(); // // URI elementURI = manager != null ? manager.getElementRelativeURI(elementToProcess) : null; // if (elementURI == null || elementURI.segmentCount() < 1) // return; ILibraryResourceManager resMgr = ResourceHelper.getResourceMgr(elementToProcess); ILibraryResourceManager lastOldPluginResMgr = ResourceHelper.getResourceMgr(lastOldPlugin); ContentResourceScanner scanner = getScanner(elementToProcess, lastOldPlugin); // iterate thru element's content String contentPath = ResourceHelper .getElementPath((MethodElement) elementToProcess); if (contentPath == null || contentPath.length() == 0) { LibraryPlugin .getDefault() .getLogger() .logWarning( NLS.bind(LibraryResources.CopyAttachmentsToNewLocation_log_noContentPath, (new Object[] { ((MethodElement) elementToProcess).getName() }))); return; } // FIXME: this is not always correct this relative of the element's folder might have been changed // during move/copy String oldContentPath = contentPath.replaceFirst(UmaUtil .getMethodPlugin(elementToProcess).getName(), lastOldPlugin.getName()); //Commented out the following and rolled back to the above to fix a bug //with attached file in content paste. But why it was introduced? Without it //the shape and node icon appear to be working fine. //String oldContentPath = ResourceHelper // .getElementPath(lastOldPlugin); // Iterator iter = elementToProcess.eClass().getEAllAttributes() // .iterator(); Iterator iter = TypeDefUtil.getInstance().getEAllAttributes(elementToProcess).iterator(); while (iter.hasNext()) { EAttribute attrib = (EAttribute) iter.next(); // Object o = elementToProcess.eGet(attrib); Object o = TypeDefUtil.getInstance().eGet(elementToProcess, attrib); if (o instanceof String) { String content = (String) o; if (content.length() > 0) { String newContent = scanner.resolveResourcesPlugin( content, contentPath, oldContentPath); if (newContent != null && newContent.trim().length() != 0 && !content.equals(newContent)) { // elementToProcess.eSet(attrib, newContent); TypeDefUtil.getInstance().eSet(elementToProcess, attrib, newContent); modifiedResourceSet.add(elementToProcess .eResource()); } ExtendedAttribute eAtt = TypeDefUtil.getInstance().getAssociatedExtendedAttribute(attrib); if (eAtt != null && IMetaDef.attachment.equalsIgnoreCase(eAtt.getValueType())) { processAttachmentString(elementToProcess, resMgr, lastOldPluginResMgr, oldContentPath, newContent); } } } } // Template attachments // String libRoot = ResourceHelper.getVirtualLibraryRoot(elementToProcess); if (elementToProcess instanceof GuidanceDescription) { String attachmentString = ((GuidanceDescription) elementToProcess) .getAttachments(); processAttachmentString(elementToProcess, resMgr, lastOldPluginResMgr, oldContentPath, attachmentString); } } } // handle children //Iterator iter = e.eAllContents(); if (e.eContents() == null) { return; } Iterator iter = e.eContents().iterator(); while (iter.hasNext()) { EObject child = (EObject) iter.next(); HandleAttachmentsPlugin(child); } } private void processAttachmentString(MethodElement elementToProcess, ILibraryResourceManager resMgr, ILibraryResourceManager lastOldPluginResMgr, String oldContentPath, String attachmentString) { Iterator iter; List attachmentList = TngUtil .convertGuidanceAttachmentsToList(attachmentString); for (iter = attachmentList.iterator(); iter.hasNext();) { String attachment = (String) iter.next(); if (attachment != null && attachment.trim().length() > 0) { Matcher m = ResourceHelper.p_template_attachment_url.matcher(attachment); if (!m.find()) { File srcContentPath = new File(lastOldPluginResMgr.resolve(lastOldPlugin, oldContentPath)); File srcFile = new File(srcContentPath, attachment); File tgtContentPath = new File(resMgr.getPhysicalPath(elementToProcess)); File tgtFile = new File(tgtContentPath, attachment); if (!tgtFile.exists()) { FileManager.copyFile(srcFile, tgtFile); } } } } } /** * * @param de * @param iconUri * @return the new Icon URI (relative path, so its ready to be persisted to the model) * @throws URISyntaxException */ private java.net.URI handleIconURI(DescribableElement de, java.net.URI iconUri) throws URISyntaxException { java.net.URI srcUri = TngUtil.getFullPathURI(de, iconUri); String iconPath = NetUtil.decodedFileUrl(iconUri.getPath()); if(iconPath.indexOf(lastOldPlugin.getName()) < 0){ srcUri = new File(ResourceHelper.getPluginPath(lastOldPlugin) + File.separator + iconPath).toURI(); } File srcFile = new File(srcUri); java.net.URI tgtUri = new File(ResourceHelper.getPluginPath(de) + File.separator + iconPath).toURI(); File tgtFile = new File(tgtUri); if (!tgtFile.exists()) { FileManager.copyFile(srcFile, tgtFile); } java.net.URI newIconUri = new java.net.URI(NetUtil .encodeFileURL(FileUtil.getRelativePath( tgtFile, new File(ResourceHelper.getPluginPath(de))))); return newIconUri; } /** * Returns the content resource scanner for the element. */ private ContentResourceScanner getScanner(MethodElement owner, MethodPlugin sourcePlugin) { ILibraryResourceManager resMgr = ResourceHelper.getResourceMgr(owner); if ( resMgr == null ) { return null; } String rootContentPath = resMgr.getLogicalPluginPath(owner); // File src_root = new File(resMgr.getPhysicalPluginPath(owner)); // File tgt_root = src_root; File tgt_root = new File(resMgr.getPhysicalPluginPath(owner)); File src_root = new File(resMgr.getPhysicalPluginPath(sourcePlugin)); ContentResourceScanner scanner = new ContentResourceScanner(src_root, tgt_root, rootContentPath, getValidator()); return scanner; } public IContentValidator getValidator() { return null; } /** * Copy all attachments from one library to another * * @param oldLibDir * Original library root * @param newLibDir * New library root * @param xmiList * list of xmi File's (pass null to process all files in * newLibDir) * @param monitor * optional (can be null) IProgressMonitor */ public static void copyAttachmentsLibrary(String oldLibDir, String newLibDir, List xmiList, IProgressMonitor monitor) { // get list of .xmi files in newLibDir if (xmiList == null) xmiList = FileUtil.fileList(new File(newLibDir), "xmi"); //$NON-NLS-1$ if (monitor != null) monitor.subTask(LibraryResources.copyingAttachmentsTask_name); Iterator iter = xmiList.iterator(); while (iter.hasNext()) { if (monitor != null) monitor.worked(1); File xmiFile = (File) iter.next(); if (xmiFile.exists()) { // parse xmi file SAXParserXMI parser = new SAXParserXMI(null); parser.parse(xmiFile.getAbsolutePath()); // iterate thru it's elements, checking content for attachments ContentResourceScanner scanner = new ContentResourceScanner( new File(oldLibDir), new File(newLibDir), null); HandleAttachments(parser.xmiMap, scanner, xmiFile.getParent() .substring(newLibDir.length())); } } } private static void HandleAttachments(HashMap eMap, ContentResourceScanner scanner, String contentPath) { // handle self String content = SAXParserXMI.getElementContent(eMap); if (content != null) { // scan content for attachments scanner.resolveResources(content, contentPath); } // handle children Iterator iter = ((ArrayList) eMap.get("children")).iterator(); //$NON-NLS-1$ while (iter.hasNext()) { HashMap childMap = (HashMap) iter.next(); HandleAttachments(childMap, scanner, contentPath); } } }