blob: ce642ddb5deb961d70da57c70ac0369b5f7f5eb6 [file] [log] [blame]
//------------------------------------------------------------------------------
// 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.epf.common.utils.XMLUtil;
import org.eclipse.epf.export.ExportPlugin;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.uma.MethodPlugin;
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$
protected File libFile;
protected Document document;
protected Element libTag = null;
protected Element resTag = null;
private HashMap guidToUriMap = null;
private Map<String, String> guidToPlugNameMap;
/**
* 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);
}
}
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;
}
Element versionNode = (Element) nodes.item(0);
String versionStr = versionNode.getAttribute(ATTR_value);
if (versionStr.equals("0")) { //$NON-NLS-1$
guidToPlugNameMap = new HashMap<String, String>();
for (int i = 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);
System.out.println("LD> name: " + name);
}
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);
}
}