wlu: Implemented methodElementProperty management
diff --git a/1.5/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/forms/ConfigurationPage.java b/1.5/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/forms/ConfigurationPage.java
index 6ca61c7..ee0ef55 100644
--- a/1.5/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/forms/ConfigurationPage.java
+++ b/1.5/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/forms/ConfigurationPage.java
@@ -988,33 +988,13 @@
 		showErrors();					
    }
 
-	class ConfigSetPropertyCommand extends MethodElementSetPropertyCommand {		
-		public ConfigSetPropertyCommand(MethodElement element, String key, String value) {
-			super(element, key, value);
-		}
-		
-		@Override
-		public void redo() {
-			super.redo();
-			configProperties.setValue(key, value);
-		}
-		
-		@Override
-		public void undo() {
-			super.undo();
-			boolean b = configProperties.setNotifyListeners(false);
-			configProperties.setValue(key, oldValue);
-			configProperties.setNotifyListeners(b);
-		}
-	}
-
 	private void handleHidesButtonWidgetSelected(SelectionEvent e, String key) {
 		Object obj = e.getSource();
 		if (obj instanceof Button) {
 			Button button = (Button) obj;
 			String value = button.getSelection() ? Boolean.TRUE.toString()
 					: Boolean.FALSE.toString();
-			actionMgr.execute(new ConfigSetPropertyCommand(config, key, value));
+			actionMgr.execute(new MethodElementSetPropertyCommand(config, key, value));
 		}
 	}
 
diff --git a/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/command/MethodElementSetPropertyCommand.java b/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/command/MethodElementSetPropertyCommand.java
index a498d31..27f5acf 100644
--- a/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/command/MethodElementSetPropertyCommand.java
+++ b/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/command/MethodElementSetPropertyCommand.java
@@ -8,6 +8,7 @@
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
 import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper;
+import org.eclipse.epf.library.edit.util.MethodElementPropertyMgr;
 import org.eclipse.epf.uma.MethodElement;
 import org.eclipse.epf.uma.MethodElementProperty;
 import org.eclipse.epf.uma.UmaPackage;
@@ -53,13 +54,13 @@
 	}
 
 	public void redo() {
-		MethodElementProperty oldProperty = MethodElementPropertyHelper.getProperty(element, key);
+		MethodElementProperty oldProperty = MethodElementPropertyMgr.getInstance().getProperty(element, key);
 		if (oldProperty != null) {
 			oldValue = oldProperty.getValue();
 		} else {
 			oldValue = null;
 		}
-		MethodElementPropertyHelper.setProperty(element, key, value);
+		MethodElementPropertyMgr.getInstance().setProperty(element, key, value);
 
 	}
 	
diff --git a/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/MethodElementProperties.java b/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/MethodElementProperties.java
new file mode 100644
index 0000000..bd409f4
--- /dev/null
+++ b/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/MethodElementProperties.java
@@ -0,0 +1,147 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 20087 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.edit.util;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.epf.library.edit.util.MethodElementPropertyMgr.ChangeEvent;
+import org.eclipse.epf.library.edit.util.MethodElementPropertyMgr.ChangeEventListener;
+import org.eclipse.epf.uma.MethodElement;
+import org.eclipse.epf.uma.MethodElementProperty;
+import org.eclipse.epf.uma.UmaFactory;
+import org.eclipse.epf.uma.UmaPackage;
+
+/**
+ *  Class managing cached method element properties
+ * 
+ * @author Weiping Lu - May 10, 2008
+ * @since 1.5
+ */
+public class MethodElementProperties extends AdapterImpl {
+
+	private MethodElement element;
+	private ListenerList listeners = new ListenerList();
+	private Set<String> propNameSet = new LinkedHashSet<String>();
+	private Map<String, List<MethodElementProperty>> propertyMap;
+	
+	public MethodElementProperties(MethodElement element, String[] propNameArray) {
+		this.element = element;
+		if (propNameArray != null) {
+			for (int i = 0; i < propNameArray.length; i++) {
+				propNameSet.add(propNameArray[i]);
+			}
+		}		
+		propertyMap = MethodElementPropertyHelper.getPropertyMap(element, getPropNameSet());
+	}
+	
+	protected Set<String> getPropNameSet() {
+		return  propNameSet;
+	}
+	
+
+	public boolean propNameRegistered(String propName) {
+		return getPropNameSet() != null && getPropNameSet().contains(propName);
+	}
+	
+	public void notifyChanged(Notification msg) {
+		Object obj = msg.getNotifier();
+		MethodElementProperty meProp = null;
+		if (obj instanceof MethodElementProperty) {
+			meProp = (MethodElementProperty) obj;
+		} else if (obj == element) {
+			if (msg.getFeature() != UmaPackage.eINSTANCE
+					.getMethodElement_MethodElementProperty()) {
+				return;
+			}
+		} else {
+			return;
+		}
+		
+		//To be implemented: do nothing for now
+
+	}
+	
+	public MethodElementProperty getProperty(String propName) {
+		List<MethodElementProperty> propList = propertyMap.get(propName);
+		return propList == null || propList.isEmpty() ? null : propList.get(0);
+	}
+	
+	public void setProperty(String propName, String propValue) {
+		List<MethodElementProperty> propList = propertyMap.get(propName);
+		if (propList == null) {
+			propList = new ArrayList<MethodElementProperty>();
+			propertyMap.put(propName, propList);
+		}
+		MethodElementProperty prop = propList.isEmpty() ? null : propList.get(0);
+		if (prop == null) {
+			prop = UmaFactory.eINSTANCE.createMethodElementProperty();
+			prop.setName(propName);
+			element.getMethodElementProperty().add(prop);
+			if (propList.isEmpty()) {
+				propList.add(prop);
+			}
+		}
+		String oldValue = prop.getValue();		
+		if (equal(oldValue, propValue)) {
+			return;
+		}
+		prop.setValue(propValue);		
+		notifyListeners(new ChangeEvent(prop, oldValue, propValue));
+	}
+	
+	public boolean getBooleanValue(String propName) {
+		MethodElementProperty prop = getProperty(propName);
+		if (prop == null) {
+			return false;
+		}
+		String value = prop.getValue();
+		return Boolean.TRUE.toString().equals(prop.getValue());
+	}
+	
+	private boolean equal(Object a, Object b) {
+		if (a != null) {
+			return a.equals(b);
+		}		
+		return b == null;
+	}
+		
+	public void addListener(ChangeEventListener listener) {
+		this.listeners.add(listener);
+	}
+	
+	public void removeListener(ChangeEventListener listener) {
+		this.listeners.remove(listener);
+	}
+	
+	private void notifyListeners(ChangeEvent event) {
+		for (Object o : listeners.getListeners()) {
+			if (o instanceof ChangeEventListener)
+				((ChangeEventListener) o).notifyChange(event);
+		}
+	}	
+	
+	public void dispose() {
+		element = null;
+		listeners = null;
+		propNameSet = null;
+		propertyMap = null;
+		
+		//To do: remove from this adapter from all attached Notifier objects
+	}
+		
+}
diff --git a/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/MethodElementPropertyMgr.java b/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/MethodElementPropertyMgr.java
new file mode 100644
index 0000000..2040a84
--- /dev/null
+++ b/1.5/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/MethodElementPropertyMgr.java
@@ -0,0 +1,110 @@
+//------------------------------------------------------------------------------
+// Copyright (c) 2005, 20087 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.edit.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.epf.uma.MethodElement;
+import org.eclipse.epf.uma.MethodElementProperty;
+
+/**
+ * Class managing method element properties
+ * 
+ * @author Weiping Lu - May 10, 2008
+ * @since 1.5
+ */
+public class MethodElementPropertyMgr {
+
+	private static MethodElementPropertyMgr instance = new MethodElementPropertyMgr();
+
+	private Map<MethodElement, MethodElementProperties> registeredMap = 
+							new HashMap<MethodElement, MethodElementProperties>();
+
+	private ListenerList listeners = new ListenerList();
+	
+	private MethodElementPropertyMgr() {
+	}
+
+	public static MethodElementPropertyMgr getInstance() {
+		return instance;
+	}
+
+	public MethodElementProperties register(MethodElement element,
+			String[] propNames) {
+		MethodElementProperties props = new MethodElementProperties(element, propNames);
+		register(element, props);
+		return props;
+	}
+	
+	public void register(MethodElement element,
+			MethodElementProperties props) {
+		unregister(element);
+		registeredMap.put(element, props);
+	}
+
+	public MethodElementProperties unregister(MethodElement element) {
+		MethodElementProperties props = registeredMap.remove(element);
+		if (props != null) {
+			props.dispose();
+		}		
+		return props;
+	}
+	
+	public MethodElementProperty getProperty(MethodElement e, String propName) {
+		MethodElementProperties props = registeredMap.get(e);
+		if (props != null && props.propNameRegistered(propName)) {
+			return props.getProperty(propName);
+		} 			
+		return MethodElementPropertyHelper.getProperty(e, propName);
+	}
+	
+	public void setProperty(MethodElement e, String propName, String propValue) {
+		MethodElementProperties props = registeredMap.get(e);
+		if (props != null && props.propNameRegistered(propName)) {
+			props.setProperty(propName, propValue);
+		} else {
+			MethodElementPropertyHelper.setProperty(e, propName, propValue);
+		}
+	}
+		
+	public void addListener(ChangeEventListener listener) {
+		listeners.add(listener);
+	}
+	
+	public void removeListener(ChangeEventListener listener) {
+		listeners.remove(listener);
+	}
+
+
+	public static class ChangeEventListener {
+		public void notifyChange(ChangeEvent event) {
+		}
+	}
+
+	public static class ChangeEvent {
+		public String propName;
+		public MethodElementProperty propElement;
+		public String oldValue;
+		public String newValue;
+		public ChangeEvent(String propName, String oldValue, String newValue) {
+			this.propElement = propElement;
+			this.oldValue = oldValue;
+			this.newValue = newValue;
+		}
+		public ChangeEvent(MethodElementProperty propElement, String oldValue, String newValue) {
+			this(propElement == null ? null : propElement.getName(), oldValue, newValue);
+			this.propElement = propElement;
+		}
+	}
+
+}
diff --git a/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/ConfigurationManager.java b/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/ConfigurationManager.java
index 9101fc0..30fde4b 100644
--- a/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/ConfigurationManager.java
+++ b/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/ConfigurationManager.java
@@ -18,6 +18,7 @@
 import org.eclipse.epf.library.configuration.ConfigurationProperties;
 import org.eclipse.epf.library.configuration.closure.ConfigurationClosure;
 import org.eclipse.epf.library.configuration.closure.DependencyManager;
+import org.eclipse.epf.library.edit.util.MethodElementPropertyMgr;
 import org.eclipse.epf.library.layout.ElementLayoutManager;
 import org.eclipse.epf.uma.MethodConfiguration;
 import org.eclipse.epf.uma.MethodLibrary;
@@ -68,7 +69,8 @@
 		this.config = config;
 		configData = ConfigurationData.newConfigurationData(config);
 		
-		configProps = new ConfigurationProperties(config); 
+		configProps = new ConfigurationProperties(config);
+		MethodElementPropertyMgr.getInstance().register(config, configProps);
 
 		library = LibraryServiceUtil.getMethodLibrary(config);
 
@@ -187,6 +189,7 @@
 		dependencyManager = null;
 		layoutManager = null;
 		closure = null;
+		MethodElementPropertyMgr.getInstance().unregister(config);
 		configProps = null;
 	}
 
diff --git a/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/configuration/ConfigurationProperties.java b/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/configuration/ConfigurationProperties.java
index 1ff17cd..e7df3e1 100644
--- a/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/configuration/ConfigurationProperties.java
+++ b/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/configuration/ConfigurationProperties.java
@@ -10,11 +10,10 @@
 //------------------------------------------------------------------------------
 package org.eclipse.epf.library.configuration;
 
-import org.eclipse.core.runtime.ListenerList;
 import org.eclipse.epf.library.configuration.closure.IConfigurationError;
+import org.eclipse.epf.library.edit.util.MethodElementProperties;
 import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper;
 import org.eclipse.epf.uma.MethodConfiguration;
-import org.eclipse.epf.uma.MethodElementProperty;
 
 /**
  *  Class managing cached configuration properties
@@ -22,46 +21,19 @@
  * @author Weiping Lu - Mar 19, 2008
  * @since 1.5
  */
-public class ConfigurationProperties {
-
-	private MethodConfiguration config;
-	private boolean hideWarnings = false;
-	private boolean hideErrors = false;
-	private boolean hideInfos = false;
-	private boolean notifyingListeners = true;
-	private ListenerList listeners = new ListenerList();
+public class ConfigurationProperties extends MethodElementProperties {
 	
 	public ConfigurationProperties(MethodConfiguration config) {
-		this.config = config;
-		loadFromConfiguration();
+		super(config, getPropStrings());		
 	}
 			
-	private String[] getHidePropStrings() {
+	private static String[] getPropStrings() {
 		String[] hideProps = { MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_ERRORS,
 				MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_WARNINGS,
 				MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_INFOS};
 		return hideProps;
 	}
 	
-	public void loadFromConfiguration() {
-		String[] hideProps = getHidePropStrings();
-		
-		boolean oldNotifyingListeners = setNotifyListeners(false);
-		for (int i = 0; i < hideProps.length; i++) {
-			MethodElementProperty prop = MethodElementPropertyHelper.getProperty(config, hideProps[i]);
-			String value = prop == null ? Boolean.FALSE.toString() : prop.getValue();
-			boolean b = Boolean.TRUE.toString().equals(value);
-			if (i == 0) {
-				setHideErrors(b);
-			} else if (i == 1) {
-				setHideWarnings(b);
-			} else if (i == 2) {
-				setHideInfos(b);
-			}
-		}
-		setNotifyListeners(oldNotifyingListeners);
-	}
-	
 	public boolean toHide(IConfigurationError error) {
 		if (error.isError()) {
 			return isHideErrors();
@@ -73,86 +45,15 @@
 	}
 
 	public boolean isHideWarnings() {
-		return hideWarnings;
-	}
-	public void setHideWarnings(String value) {
-		setHideWarnings(Boolean.TRUE.toString().equals(value));
-	}
-	public void setHideWarnings(boolean hideWarnings) {
-		if (this.hideWarnings != hideWarnings) {
-			this.hideWarnings = hideWarnings;
-			notifyListeners();
-		}
+		return getBooleanValue(MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_WARNINGS);
 	}
 	
 	public boolean isHideErrors() {
-		return hideErrors;
-	}
-	public void setHideErrors(String value) {
-		setHideErrors(Boolean.TRUE.toString().equals(value));
-	}
-	public void setHideErrors(boolean hideErrors) {
-		if (this.hideErrors != hideErrors) {
-			this.hideErrors = hideErrors;
-			notifyListeners();
-		}
+		return getBooleanValue(MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_ERRORS);
 	}
 
 	public boolean isHideInfos() {
-		return hideInfos;
+		return getBooleanValue(MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_INFOS);
 	}
-	public void setHideInfos(String value) {
-		setHideInfos(Boolean.TRUE.toString().equals(value));
-	}
-	public void setHideInfos(boolean hideInfos) {
-		if (this.hideInfos != hideInfos) {
-			this.hideInfos = hideInfos;
-			notifyListeners();
-		}
-	}
-
-	public void addListeners(Listener listener) {
-		this.listeners.add(listener);
-	}
-	
-	public void removeListeners(Listener listener) {
-		this.listeners.remove(listener);
-	}
-	
-	private void notifyListeners() {
-		if (! getNotifyingListeners()) {
-			return;
-		}
-		for (Object o : listeners.getListeners()) {
-			if (o instanceof Listener)
-				((Listener)o).fireEvent();
-		}
-	}
-	
-	public static class Listener {
-		public void fireEvent() {			
-		}
-	}
-	
-	private boolean getNotifyingListeners() {
-		return notifyingListeners;
-	}
-	
-	//return old value
-	public boolean setNotifyListeners(boolean b) {
-		boolean oldValue = notifyingListeners;
-		notifyingListeners = b;
-		return oldValue;
-	}
-	
-	public void setValue(String key, String value) {
-		if (key.equals(MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_ERRORS)) {
-			setHideErrors(value);
-		} else if (key.equals(MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_WARNINGS)) {
-			setHideWarnings(value);
-		} else if (key.equals(MethodElementPropertyHelper.CONFIG_PROPBLEM_HIDE_INFOS)) {
-			setHideInfos(value);
-		}
-	}
-	
+		
 }
diff --git a/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/configuration/closure/ConfigurationClosure.java b/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/configuration/closure/ConfigurationClosure.java
index 970b79c..2540596 100644
--- a/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/configuration/closure/ConfigurationClosure.java
+++ b/1.5/plugins/org.eclipse.epf.library/src/org/eclipse/epf/library/configuration/closure/ConfigurationClosure.java
@@ -28,6 +28,8 @@
 import org.eclipse.epf.library.configuration.ConfigurationHelper;
 import org.eclipse.epf.library.configuration.ConfigurationProperties;
 import org.eclipse.epf.library.edit.command.IActionManager;
+import org.eclipse.epf.library.edit.util.MethodElementPropertyMgr;
+import org.eclipse.epf.library.edit.util.MethodElementPropertyMgr.ChangeEvent;
 import org.eclipse.epf.library.util.LibraryUtil;
 import org.eclipse.epf.uma.MethodConfiguration;
 import org.eclipse.epf.uma.MethodElement;
@@ -74,7 +76,7 @@
 	
 	private List<ClosureListener> listeners;
 
-	private ConfigurationProperties.Listener configPropListener;
+	private MethodElementPropertyMgr.ChangeEventListener configPropListener;
 	/**
 	 * Creates a new instance.
 	 * 
@@ -94,12 +96,12 @@
 			dependencyManager = configManager.getDependencyManager();
 			
 			ConfigurationProperties props = configManager.getConfigurationProperties();
-			configPropListener = new ConfigurationProperties.Listener() {
-				public void fireEvent() {
+			configPropListener = new MethodElementPropertyMgr.ChangeEventListener() {
+				public void notifyChange(ChangeEvent event) {
 					refreshErrormarks();
 				}
 			};			
-			props.addListeners(configPropListener);
+			props.addListener(configPropListener);
 		}
 
 		// configuration changed, re-build the analyze the configuration for errors
@@ -1000,7 +1002,7 @@
 		
 		if (configManager != null) {
 			ConfigurationProperties props = configManager.getConfigurationProperties();			
-			props.removeListeners(configPropListener);
+			props.removeListener(configPropListener);
 		}
 				
 		configManager = null;