| //------------------------------------------------------------------------------ |
| // 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.export.services; |
| |
| import java.io.File; |
| import java.io.FileFilter; |
| import java.io.UnsupportedEncodingException; |
| import java.net.URLDecoder; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.epf.common.utils.XMLUtil; |
| import org.eclipse.epf.export.ExportPlugin; |
| import org.eclipse.epf.library.edit.util.MethodLibraryPropUtil; |
| import org.eclipse.epf.persistence.MultiFileSaveUtil; |
| import org.eclipse.epf.uma.MethodElementProperty; |
| import org.eclipse.epf.uma.MethodPlugin; |
| import org.eclipse.epf.uma.UmaPackage; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| |
| |
| /** |
| * Encapsulates a method library using a DOM document. |
| * |
| * @author Jinhua Xi |
| * @author Weiping Lu |
| * @since 1.0 |
| */ |
| public class LibraryDocument { |
| |
| public static final String TAG_methodPlugins = "methodPlugins"; //$NON-NLS-1$ |
| |
| public static final String TAG_predefinedConfigurations = "predefinedConfigurations"; //$NON-NLS-1$ |
| |
| public static final String TAG_resourceDescriptors = "resourceDescriptors"; //$NON-NLS-1$ |
| |
| public static final String TAG_resourceSubManagers = "subManagers"; //$NON-NLS-1$ |
| |
| public static final String TAG_methodElementProperty = "methodElementProperty"; //$NON-NLS-1$ |
| |
| public static final String ATTR_href = "href"; //$NON-NLS-1$ |
| |
| public static final String ATTR_id = "id"; //$NON-NLS-1$ |
| |
| public static final String ATTR_uri = "uri"; //$NON-NLS-1$ |
| |
| public static final String ATTR_guid = "guid"; //$NON-NLS-1$ |
| |
| public static final String ATTR_value = "value"; //$NON-NLS-1$ |
| |
| public static final String exportFile = "export.xmi"; //$NON-NLS-1$ |
| |
| public static final String libraryFile = "library.xmi"; //$NON-NLS-1$ |
| |
| public static final String ATTR_name = "name"; //$NON-NLS-1$ |
| |
| protected File libFile; |
| |
| protected Document document; |
| |
| protected Element libTag = null; |
| |
| protected Element resTag = null; |
| |
| private HashMap guidToUriMap = null; |
| |
| private Map<String, String> guidToPlugNameMap; |
| |
| private int synFreeLibIx = -1; //-1: unset, 0: false, 1: true; |
| |
| /** |
| * Creates a new instance. |
| */ |
| public LibraryDocument(File libFile) throws Exception { |
| this.libFile = libFile; |
| init(); |
| } |
| |
| private void init() throws Exception { |
| this.document = XMLUtil.loadXml(libFile); |
| |
| Element root = document.getDocumentElement(); |
| NodeList nodes = root.getElementsByTagName("org.eclipse.epf.uma:MethodLibrary"); //$NON-NLS-1$ |
| if (nodes != null && nodes.getLength() > 0) { |
| libTag = (Element) nodes.item(0); |
| } |
| |
| nodes = root |
| .getElementsByTagName("org.eclipse.epf.uma.resourcemanager:ResourceManager"); //$NON-NLS-1$ |
| if (nodes != null && nodes.getLength() > 0) { |
| resTag = (Element) nodes.item(0); |
| } |
| } |
| |
| /** |
| * Returns the document field |
| */ |
| public Document getDocument() { |
| return this.document; |
| } |
| |
| /** |
| * Returns the libFile field |
| */ |
| public File getFile() { |
| return libFile; |
| } |
| |
| /** |
| * Returns the libTag field |
| */ |
| public Element getLibTag() { |
| return libTag; |
| } |
| |
| /** |
| * Returns the library name |
| */ |
| public String getLibraryName() { |
| return libTag.getAttribute("name"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns the library guid |
| */ |
| public String getLibraryGuid() { |
| return libTag.getAttribute("guid"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns the resource tag |
| */ |
| public Element getResourceTag() { |
| return resTag; |
| } |
| |
| /** |
| * Removes a plugin node |
| */ |
| public void removePlugin(Element node) { |
| libTag.removeChild(node); |
| } |
| |
| /** |
| * Removes a config node |
| */ |
| public void removeConfiguration(Element node) { |
| libTag.removeChild(node); |
| } |
| |
| /** |
| * Removes a resource descriptor node |
| */ |
| public void removeResourceDescriptor(Element node) { |
| resTag.removeChild(node); |
| } |
| |
| /** |
| * Returns plugin node list |
| */ |
| public NodeList getPlugins() { |
| return libTag.getElementsByTagName(TAG_methodPlugins); |
| } |
| |
| /** |
| * Returns configuration node list |
| */ |
| public NodeList getConfigurations() { |
| return libTag.getElementsByTagName(TAG_predefinedConfigurations); |
| } |
| |
| /** |
| * Returns resource descriptor node list |
| */ |
| public NodeList getResourceDescriptors() { |
| return resTag.getElementsByTagName(TAG_resourceDescriptors); |
| } |
| |
| /** |
| * Returns resource submanager node list |
| */ |
| public NodeList getResourceSubManagers() { |
| return resTag.getElementsByTagName(TAG_resourceSubManagers); |
| } |
| |
| /** |
| * Adds a plugin node |
| */ |
| public void addPlugin(Element node) { |
| libTag.appendChild(getValidNode(node)); |
| } |
| |
| /** |
| * Adds a configuration node |
| */ |
| public void addConfiguration(Element node) { |
| libTag.appendChild(getValidNode(node)); |
| } |
| |
| /** |
| * Adds a resource node |
| */ |
| public void addResource(Element node) { |
| resTag.appendChild(getValidNode(node)); |
| } |
| |
| /** |
| * Returns a valid node |
| */ |
| public Node getValidNode(Node node) { |
| if (node.getOwnerDocument() == document) { |
| return node; |
| } |
| |
| return document.importNode(node, true); |
| } |
| |
| /** |
| * remove plugins by guid |
| * |
| * @param removeList |
| * List a list of guids |
| */ |
| public void removePlugins(List removeList) { |
| // Importing a package of plgins twice generates 2 |
| // identical plugins |
| // remove the node will cause the node list to shrink, so don't increase |
| // the index |
| NodeList nodes = getPlugins(); |
| int i = 0; |
| while (i < nodes.getLength()) { |
| Element node = (Element) nodes.item(i); |
| String guid = getGuid(node); |
| if (removeList.contains(guid)) { |
| libTag.removeChild(node); |
| } else { |
| i++; |
| } |
| } |
| } |
| |
| /** |
| * Remove the list from the configuration nodes |
| */ |
| public void removeConfigurations(List removeList) { |
| // remove the unneeded configurations |
| NodeList nodes = getConfigurations(); |
| int i = 0; |
| while (i < nodes.getLength()) { |
| Element node = (Element) nodes.item(i); |
| String guid = getGuid(node); |
| if (removeList.contains(guid)) { |
| libTag.removeChild(node); |
| } else { |
| i++; |
| } |
| } |
| } |
| |
| /** |
| * Remove the list from the resource nodes |
| */ |
| public void removeResourceEntries(List removeList) { |
| NodeList nodes = getResourceDescriptors(); |
| int i = 0; |
| while (i < nodes.getLength()) { |
| Element node = (Element) nodes.item(i); |
| String guid = node.getAttribute(ATTR_id); |
| String uri = node.getAttribute(ATTR_uri); |
| if (removeList.contains(guid)) { |
| resTag.removeChild(node); |
| |
| // check the plugin xmi file, if exists, delete the folder |
| File plugn_file = getFileFromUri(uri); |
| if (plugn_file.exists()) { |
| // delete the folder ??? |
| } |
| } else { |
| i++; |
| } |
| } |
| |
| // also remove the sub managers |
| nodes = getResourceSubManagers(); |
| i = 0; |
| while (i < nodes.getLength()) { |
| Element node = (Element) nodes.item(i); |
| String guid = getSubManagerBaseGuid(node.getAttribute(ATTR_href)); |
| if (removeList.contains(guid)) { |
| resTag.removeChild(node); |
| } else { |
| i++; |
| } |
| } |
| } |
| |
| /** |
| * get the resource uri for the resource guid |
| * @param guid |
| * @return String the uri |
| */ |
| public String getResourceUri(String guid) { |
| String uri = getUriFromGuidToUriMap(guid); |
| if (uri == null) { |
| uri = getResourceUri_(guid); |
| if (uri != null) { |
| //addToGuidToUriMap(guid, uri); |
| } |
| } |
| return uri; |
| } |
| |
| private String getResourceUri_(String guid) { |
| |
| NodeList nodes = getResourceDescriptors(); |
| for (int i = 0; i < nodes.getLength(); i++ ) { |
| Element node = (Element) nodes.item(i); |
| String id = node.getAttribute(ATTR_id); |
| String uri = node.getAttribute(ATTR_uri); |
| if ( guid.equals(id) ) { |
| return decodeUri(uri); |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Returns the decored URI. |
| */ |
| public String decodeUri(String uri) { |
| try { |
| uri = URLDecoder.decode(uri, "UTF-8"); //$NON-NLS-1$ |
| } catch (UnsupportedEncodingException e) { |
| e.printStackTrace(); |
| } |
| |
| return uri; |
| } |
| |
| /** |
| * Returns the file given the uri. |
| */ |
| public File getFileFromUri(String uri) { |
| uri = decodeUri(uri); |
| |
| int i = uri.indexOf("#"); //$NON-NLS-1$ |
| if (i > 0) { |
| uri = uri.substring(0, i); |
| } |
| |
| return new File(libFile.getParentFile(), uri); |
| } |
| |
| /** |
| * Saves the document. |
| */ |
| public void save() throws Exception { |
| saveAs(libFile.getAbsolutePath()); |
| } |
| |
| /** |
| * Saves the document in the file given by filePathName. |
| */ |
| public void saveAs(String filePathName) throws Exception { |
| XMLUtil.saveDocument(this.document, filePathName); |
| } |
| |
| /** |
| * Is the document for configutation specification export/import only? |
| */ |
| public boolean isConfigSpecsOnly() { |
| NodeList nodes = getPlugins(); |
| if (nodes == null || nodes.getLength() == 0) { |
| return true; |
| } |
| |
| for (int i = 0; i < nodes.getLength(); i++) { |
| Element node = (Element) nodes.item(i); |
| String href = node.getAttribute(LibraryDocument.ATTR_href); |
| String guid = getGuidFromHref(href); |
| String uri = getResourceUri(guid); |
| |
| // check if the resource files are there |
| File plugn_file = getFileFromUri(uri); |
| if (plugn_file.exists()) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| // static hlper methods ///////////////////////////////////// |
| /** |
| * Returns submanager's base guid. |
| */ |
| public static String getSubManagerBaseGuid(String href) { |
| final Pattern p = Pattern.compile( |
| "uma://(.*?)#(.*?)", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$ |
| Matcher m = p.matcher(href); |
| if (m.find()) { |
| return m.group(1); |
| } |
| |
| return href; |
| } |
| |
| /** |
| * Returns child value of the child tag given by childTagName. |
| */ |
| public static String getChildValue(Element tag, String childTagName) { |
| NodeList nodes = tag.getChildNodes(); |
| if (nodes == null || nodes.getLength() == 0) { |
| return ""; //$NON-NLS-1$ |
| } |
| |
| int size = nodes.getLength(); |
| for (int i = 0; i < size; i++) { |
| Node node = nodes.item(i); |
| if ((node instanceof Element) |
| && ((Element) node).getTagName().equals(childTagName)) { |
| return getNodeText((Element) node); |
| } |
| } |
| |
| return ""; //$NON-NLS-1$ |
| } |
| |
| /** |
| * text of a leaf node, without child element |
| * |
| * @param tag |
| * @return |
| */ |
| public static String getNodeText(Element tag) { |
| |
| NodeList nodes = tag.getChildNodes(); |
| if (nodes == null || nodes.getLength() == 0) { |
| return ""; //$NON-NLS-1$ |
| } |
| |
| int size = nodes.getLength(); |
| StringBuffer buffer = new StringBuffer(); |
| for (int i = 0; i < size; i++) { |
| Node node = nodes.item(i); |
| if (node.getNodeType() == Node.TEXT_NODE) { |
| buffer.append(node.getNodeValue()); |
| } |
| } |
| |
| return buffer.toString(); |
| } |
| |
| /** |
| * Returns guid from href. |
| */ |
| public static String getGuidFromHref(String href) { |
| int i = href.indexOf("#"); //$NON-NLS-1$ |
| if (i > 0) { |
| return href.substring(i + 1); |
| } |
| |
| return href; |
| } |
| |
| /** |
| * Returns guid of the node. |
| */ |
| public static String getGuid(Element node) { |
| String id = node.getAttribute("xmi:id"); //$NON-NLS-1$ |
| if ( id == null || id.length() == 0 ) { |
| String href = node.getAttribute(ATTR_href); |
| id = getGuidFromHref(href); |
| } |
| |
| return id; |
| } |
| |
| // 143033 - update config specs' importing and exporting to match with the new file format |
| protected Element getConfigNode(Element configNode) { |
| try { |
| |
| // new model defines href for configuration |
| String href = configNode.getAttribute(ATTR_href); |
| if (href == null || href.length() == 0 ) { |
| return configNode; |
| } |
| |
| String guid = getGuidFromHref(href); |
| String uri = getResourceUri(guid); |
| if ( uri == null ) { |
| return configNode; |
| } |
| |
| File source = getFileFromUri(uri); |
| Document document = XMLUtil.loadXml(source); |
| Element root = document.getDocumentElement(); |
| |
| Element configTag = null; |
| if (root.getTagName().equals("org.eclipse.epf.uma:MethodConfiguration")) //$NON-NLS-1$ |
| { |
| configTag = root; |
| } else { |
| NodeList nodes = root |
| .getElementsByTagName("org.eclipse.epf.uma:MethodConfiguration"); //$NON-NLS-1$ |
| if (nodes.getLength() > 0) { |
| configTag = (Element) nodes.item(0); |
| } |
| } |
| |
| return configTag; |
| |
| } catch (Exception e) { |
| ExportPlugin.getDefault().getLogger().logError(e); |
| } |
| |
| return configNode; |
| } |
| |
| /** |
| * Returns ConfigurationSpec instance given the element node config. |
| */ |
| public ConfigurationSpec getConfigurationSpec(Element config) { |
| ConfigurationSpec spec = new ConfigurationSpec(); |
| |
| Element configNode = getConfigNode(config); |
| spec.guid = configNode.getAttribute("xmi:id"); //$NON-NLS-1$ |
| spec.name = configNode.getAttribute("name"); //$NON-NLS-1$ |
| spec.brief_desc = configNode.getAttribute("briefDescription"); //$NON-NLS-1$ |
| |
| // get plugins |
| NodeList nodes = configNode.getElementsByTagName("methodPluginSelection"); //$NON-NLS-1$ |
| if (nodes != null) { |
| for (int i = 0; i < nodes.getLength(); i++) { |
| Element node = (Element) nodes.item(i); |
| String guid = getGuidFromHref(node.getAttribute(ATTR_href)); |
| spec.pluginIds.add(guid); |
| } |
| } |
| |
| // get packages |
| nodes = configNode.getElementsByTagName("methodPackageSelection"); //$NON-NLS-1$ |
| if (nodes != null) { |
| for (int i = 0; i < nodes.getLength(); i++) { |
| Element node = (Element) nodes.item(i); |
| String guid = getGuidFromHref(node.getAttribute(ATTR_href)); |
| spec.packageIds.add(guid); |
| } |
| } |
| |
| // get views |
| nodes = configNode.getElementsByTagName("processViews"); //$NON-NLS-1$ |
| if (nodes != null) { |
| for (int i = 0; i < nodes.getLength(); i++) { |
| Element node = (Element) nodes.item(i); |
| String guid = getGuidFromHref(node.getAttribute(ATTR_href)); |
| spec.viewIds.add(guid); |
| } |
| } |
| |
| // get meps |
| nodes = configNode.getElementsByTagName(TAG_methodElementProperty); //$NON-NLS-1$ |
| if (nodes != null) { |
| for (int i = 0; i < nodes.getLength(); i++) { |
| Element node = (Element) nodes.item(i); |
| String name = node.getAttribute(ATTR_name); |
| String value = node.getAttribute(ATTR_value); |
| MethodElementProperty mep = (MethodElementProperty) EcoreUtil |
| .create(UmaPackage.eINSTANCE.getMethodElementProperty()); |
| mep.setName(name); |
| mep.setValue(value); |
| spec.mepList.add(mep); |
| } |
| } |
| |
| return spec; |
| } |
| |
| /** |
| * Adds guid/uri pair to guidToUriMap. |
| */ |
| public void addToGuidToUriMap(String guid, String uri) { |
| if (guidToUriMap == null) { |
| guidToUriMap = new HashMap(); |
| } |
| guidToUriMap.put(guid, uri); |
| } |
| |
| /** |
| * Gets uri from guid. |
| */ |
| public String getUriFromGuidToUriMap(String guid) { |
| return guidToUriMap == null ? null : (String) guidToUriMap.get(guid); |
| } |
| |
| /** |
| * Create an instance. |
| */ |
| public static class ConfigDocVisitor { |
| public void visit(File file, Element node) { |
| } |
| } |
| |
| /** |
| * Visit configuration files given by the configuration file folder configDir. |
| */ |
| public static void visitConfigFiles(File configDir, ConfigDocVisitor visitor) { |
| FileFilter filter = new FileFilter() { |
| public boolean accept(File pathname) { |
| return !pathname.getName().equalsIgnoreCase("cvs") && //$NON-NLS-1$ |
| pathname.isDirectory() || pathname.getName().endsWith(MultiFileSaveUtil.DEFAULT_FILE_EXTENSION); |
| } |
| }; |
| File[] files = configDir.listFiles(filter); |
| if (files == null) { |
| return; |
| } |
| for (int i=0; i<files.length; i++) { |
| File file = files[i]; |
| try { |
| DocumentBuilder builder = DocumentBuilderFactory.newInstance() |
| .newDocumentBuilder(); |
| Document doc = builder.parse(file); |
| Element root = doc.getDocumentElement(); |
| visitor.visit(file, root); |
| } catch (Throwable e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| /** |
| * Build a map from pluign guids to resource manager guids. |
| */ |
| public Map buildPluginGuidToResMgrGuidMap(List pluginGuids) { |
| if (pluginGuids == null || pluginGuids.size() == 0) { |
| return null; |
| } |
| NodeList subMgrs = getResourceSubManagers(); |
| if (subMgrs == null || subMgrs.getLength() == 0) { |
| return null; |
| } |
| HashMap pluginGuidToResMgrGuidMap = new HashMap(); |
| for (int i=0; i<pluginGuids.size(); i++) { |
| String pluginGuid = (String) pluginGuids.get(i); |
| pluginGuidToResMgrGuidMap.put(pluginGuid, null); |
| } |
| boolean isEmpty = true; |
| for (int i=0; i<subMgrs.getLength(); i++) { |
| Element mgr = (Element) subMgrs.item(i); |
| String href = mgr.getAttribute(ATTR_href); |
| String pluginGuid = getSubManagerBaseGuid(href); |
| if (pluginGuidToResMgrGuidMap.containsKey(pluginGuid)) { |
| pluginGuidToResMgrGuidMap.put(pluginGuid, getGuidFromHref(href)); |
| isEmpty = false; |
| } |
| } |
| return isEmpty ? null : pluginGuidToResMgrGuidMap; |
| } |
| |
| /** |
| * Save extra info (all plugin guids and names) in libTag's MethodElementProperty |
| */ |
| public void storeExtraInfo(List<MethodPlugin> plugins) { |
| if (plugins == null) { |
| return; |
| } |
| |
| Element versionNode = document.createElement(TAG_methodElementProperty); |
| versionNode.setAttribute(ATTR_value, "0"); //$NON-NLS-1$ |
| libTag.appendChild(versionNode); |
| |
| for (Iterator<MethodPlugin> it = plugins.iterator(); it.hasNext();) { |
| MethodPlugin plug = it.next(); |
| |
| Element guidNode = document.createElement(TAG_methodElementProperty); |
| guidNode.setAttribute(ATTR_value, plug.getGuid()); |
| Element nameNode = document.createElement(TAG_methodElementProperty); |
| nameNode.setAttribute(ATTR_value, plug.getName()); |
| |
| libTag.appendChild(guidNode); |
| libTag.appendChild(nameNode); |
| } |
| |
| } |
| |
| private void recallExtraInfo() { |
| try { |
| NodeList nodes = getMethodElementProperties(); |
| if (nodes == null || nodes.getLength() == 0) { |
| return; |
| } |
| int ix = -1; |
| for (int i = 0; i < nodes.getLength(); i++) { |
| Element node = (Element) nodes.item(i); |
| String name = node.getAttribute(ATTR_name); |
| if (name ==null || name.trim().length() == 0) { |
| ix = i; |
| break; |
| } |
| } |
| if (ix == -1) { |
| return; |
| } |
| |
| Element versionNode = (Element) nodes.item(ix); |
| String versionStr = versionNode.getAttribute(ATTR_value); |
| |
| if (versionStr.equals("0")) { //$NON-NLS-1$ |
| guidToPlugNameMap = new HashMap<String, String>(); |
| for (int i = ix + 1; i < nodes.getLength();) { |
| Element node = (Element) nodes.item(i); |
| String guid = node.getAttribute(ATTR_value); |
| node = (Element) nodes.item(i + 1); |
| String name = node.getAttribute(ATTR_value); |
| guidToPlugNameMap.put(guid, name); |
| if (false) { |
| System.out.println("LD> guid: " + guid); //$NON-NLS-1$ |
| System.out.println("LD> name: " + name); //$NON-NLS-1$ |
| } |
| i += 2; |
| } |
| } |
| } catch (Throwable e) { |
| e.printStackTrace(); |
| guidToPlugNameMap = null; |
| } |
| |
| } |
| |
| /** |
| * Get guid to plugin map |
| */ |
| public Map<String, String> getGuidToPlugNameMap() { |
| if (guidToPlugNameMap == null) { |
| recallExtraInfo(); |
| } |
| return guidToPlugNameMap; |
| } |
| |
| /** |
| * Returns methodElementProperty node list |
| */ |
| private NodeList getMethodElementProperties() { |
| return libTag.getElementsByTagName(TAG_methodElementProperty); |
| } |
| |
| public boolean isSynFreeLib() { |
| if (synFreeLibIx == -1) { |
| synFreeLibIx = 0; |
| |
| NodeList nodes = getMethodElementProperties(); |
| if (nodes != null) { |
| for (int i = 0; i < nodes.getLength(); i++) { |
| Element node = (Element) nodes.item(i); |
| String name = node.getAttribute(ATTR_name); |
| if (name != null && name.equals(MethodLibraryPropUtil.Library_SynFree)) { |
| String value = node.getAttribute(ATTR_value); |
| synFreeLibIx = Boolean.parseBoolean(value) ? 1 : 0; |
| break; |
| } |
| } |
| } |
| } |
| return synFreeLibIx > 0; |
| } |
| |
| |
| } |