Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal')
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/Activator.java33
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/Binding.java310
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/BindingExpressionPath.java197
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/BindingGate.java406
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/Core.java917
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DataBindingTrack.java202
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DynamicBinding.java226
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DynamicValueBinding.java64
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/IEventController.java33
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MetaclassManager.java162
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MetaclassService.java150
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MultiBinding.java222
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/ScopeKeeper.java263
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/ScopeManager.java485
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/UIResource.java26
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/UpdateSourceTrigger.java45
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/AbstractMenuItemObservableValue.java63
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/MenuItemEnabledObservableValue.java42
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/MenuItemSelectionObservableValue.java42
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ClassLoaderUtil.java143
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/DocumentObjectSorter.java93
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/LoggerManager.java40
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/NamespaceHelper.java44
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ObjectUtil.java399
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ObservableValueManager.java85
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/TableEditorHelper.java63
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/UserData.java699
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/Attribute.java55
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DocumentObject.java240
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DocumentRoot.java463
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/Element.java261
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/ElementHandler.java797
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/ElementManager.java413
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/XDataHandler.java95
34 files changed, 7778 insertions, 0 deletions
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/Activator.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/Activator.java
new file mode 100644
index 00000000000..16d5497f646
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/Activator.java
@@ -0,0 +1,33 @@
+package org.eclipse.papyrus.xwt.internal;
+
+import org.eclipse.papyrus.xwt.IXWTInitializer;
+import org.eclipse.papyrus.xwt.IXWTLoader;
+import org.eclipse.papyrus.xwt.XWT;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator, IXWTInitializer {
+
+ private boolean initialized;
+
+ public void start(BundleContext context) throws Exception {
+ initialized = false;
+ XWT.addInitializer(this);
+ XWT.runOnUIThread(new Runnable() {
+
+ public void run() {
+ }
+ });
+ }
+
+ public void initialize(IXWTLoader loader) {
+ initialized = true;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ }
+
+ public boolean isInitialized() {
+ return initialized;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/Binding.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/Binding.java
new file mode 100644
index 00000000000..fcfd5b3c162
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/Binding.java
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.xwt.IDataProvider;
+import org.eclipse.papyrus.xwt.IValidationRule;
+import org.eclipse.papyrus.xwt.IValueConverter;
+import org.eclipse.papyrus.xwt.XWT;
+import org.eclipse.papyrus.xwt.XWTException;
+import org.eclipse.papyrus.xwt.core.IBinding;
+import org.eclipse.papyrus.xwt.core.IDynamicBinding;
+import org.eclipse.papyrus.xwt.databinding.ControlDataBinding;
+import org.eclipse.papyrus.xwt.databinding.DataBinding;
+import org.eclipse.papyrus.xwt.internal.utils.UserData;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Generic Binding definition
+ *
+ * @author yyang (yves.yang@soyatec.com)
+ */
+public class Binding extends DynamicBinding {
+
+ public static Binding[] EMPTY_ARRAY = new Binding[0];
+
+ private String path;
+
+ private Object source;
+
+ private String elementName;
+
+ private IValueConverter converter;
+
+ private IValidationRule[] validationRules = IValidationRule.EMPTY_ARRAY;
+
+ private IObservable observableSource;
+
+ public Binding() {
+ super();
+ }
+
+ /**
+ * <p>
+ * Default
+ * </p>
+ *
+ */
+ private UpdateSourceTrigger updateSourceTrigger = UpdateSourceTrigger.Default;
+
+ private BindingExpressionPath pathSegments;
+
+ public BindingExpressionPath getPathPropertySegments() {
+ if(pathSegments == null) {
+ pathSegments = new BindingExpressionPath(getPath());
+ }
+ return pathSegments;
+ }
+
+ public UpdateSourceTrigger getUpdateSourceTrigger() {
+ return updateSourceTrigger;
+ }
+
+ public void setUpdateSourceTrigger(UpdateSourceTrigger updateSourceTrigger) {
+ this.updateSourceTrigger = updateSourceTrigger;
+ }
+
+ public IValueConverter getConverter() {
+ return converter;
+ }
+
+ public void setConverter(IValueConverter converter) {
+ this.converter = converter;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public Object getSource() {
+ return source;
+ }
+
+ public void setSource(Object source) {
+ this.source = source;
+ if(this.source instanceof IObservable) {
+ this.observableSource = (IObservable)this.source;
+ }
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getElementName() {
+ return elementName;
+ }
+
+ public void setElementName(String elementName) {
+ this.elementName = elementName;
+ }
+
+ protected Object getSourceObject() {
+ if(source != null) {
+ return source;
+ } else if(elementName != null) {
+ return XWT.findElementByName(getControl(), elementName);
+ }
+ return null;
+ }
+
+ protected boolean isSelfBinding(Object data) {
+ if(data != this) {
+ return false;
+ }
+ Binding binding = (Binding)data;
+ return BindingExpressionPath.isEmptyPath(binding.getPath());
+ }
+
+ public Object createBoundSource() {
+ Object control = getControl();
+ Object source = getSourceObject();
+ if(source == null) {
+ source = XWT.getDataContext(control, IDynamicBinding.class);
+ Object localDataContext = UserData.getLocalDataContext(control);
+ if(localDataContext == this) {
+ return source;
+ }
+ }
+ if(source instanceof IDynamicBinding) {
+ Object value = ((IDynamicBinding)source).createBoundSource();
+ if(value != null && path != null) {
+ Widget widget = UserData.getWidget(value);
+ if(widget == null) {
+ widget = UserData.getWidget(control);
+ }
+ return ScopeManager.observeValue(widget, value, getPathPropertySegments(), getUpdateSourceTrigger());
+ }
+ }
+ if(source != null && !BindingExpressionPath.isEmptyPath(path)) {
+ Widget widget = UserData.getWidget(source);
+ if(widget == null) {
+ widget = UserData.getWidget(control);
+ }
+ return ScopeManager.observeValue(widget, source, getPathPropertySegments(), getUpdateSourceTrigger());
+ }
+ return source;
+ }
+
+ public boolean isSourceControl() {
+ Object source = getSourceObject();
+ if(source == null) {
+ Object dataContextHost = getDataContextHost();
+ if(dataContextHost != null) {
+ source = UserData.getLocalDataContext(dataContextHost);
+ }
+ }
+
+ if(source instanceof IDynamicBinding) {
+ return ((IDynamicBinding)source).isSourceControl();
+ }
+ if(source instanceof IBinding) {
+ source = ((IBinding)source).getValue(null);
+ }
+
+ if(path == null) {
+ return false;
+ }
+
+ int index = BindingExpressionPath.lastIndexOf(path);
+ if(index == -1) {
+ return (source instanceof Control || source instanceof Viewer);
+ }
+
+ if(source instanceof IDataProvider) {
+ return false;
+ }
+ String parentPath = path.substring(0, index);
+ IObservable observable = ScopeManager.observeValue(getControl(), source, parentPath, getUpdateSourceTrigger());
+ if(observable != null) {
+ IObservableValue observableValue = (IObservableValue)observable;
+ Object type = observableValue.getValueType();
+ if(type != null) {
+ return UserData.isUIElementType(type);
+ }
+ }
+ return false;
+ }
+
+ public Object getValue(Class<?> targetType) {
+ Object dataContext = getSourceObject();
+ if(dataContext == null) {
+ Object dataContextHost = getDataContextHost();
+ if(dataContextHost != null) {
+ dataContext = UserData.getLocalDataContext(dataContextHost);
+ if(dataContext instanceof IDynamicBinding) {
+ IDynamicBinding dynamicBinding = (IDynamicBinding)dataContext;
+ Object boundSource = dynamicBinding.createBoundSource();
+ if(boundSource != null) {
+ dataContext = boundSource;
+ }
+ }
+ }
+ }
+
+ // direct binding
+ if(dataContext instanceof IBinding) {
+ dataContext = ((IBinding)dataContext).getValue(null);
+ }
+
+ IDataProvider dataProvider = getDataProvider(dataContext);
+
+ try {
+ if(isSourceControl()) {
+ ControlDataBinding controlDataBinding = new ControlDataBinding(dataContext, this, dataProvider);
+ return controlDataBinding.getValue(targetType);
+ }
+ } catch (XWTException e) {
+ // in case the property cannot be bound. return value
+ }
+
+ DataBinding dataBinding = null;
+ if(dataProvider != null && (path != null || dataContext instanceof IObservable)) {
+ dataBinding = new DataBinding(this, dataProvider);
+ }
+ if(dataBinding != null) {
+ return dataBinding.getValue(targetType);
+ }
+ return convertedValue(dataContext);
+ }
+
+ private Object convertedValue(Object value) {
+ IValueConverter converter = getConverter();
+ if(converter != null) {
+ value = converter.convert(value);
+ }
+ return value;
+ }
+
+ public boolean isSourcePropertyReadOnly() {
+ IDataProvider dataProvider = getDataProvider();
+ try {
+ return ScopeManager.isPropertyReadOnly(dataProvider, getPathPropertySegments());
+ } catch (XWTException e) {
+ }
+ return false;
+ }
+
+ public IObservable getObservableSource() {
+ return observableSource;
+ }
+
+ public void setObservableSource(IObservable observableSource) {
+ this.observableSource = observableSource;
+ }
+
+ /**
+ * Returns the validationRules for the binding
+ *
+ * @return the array of validationRules
+ */
+ public IValidationRule[] getValidationRules() {
+ return this.validationRules;
+ }
+
+ /**
+ * Sets a single validationRule
+ *
+ * @param validator
+ */
+ public IValidationRule getValidationRule() {
+ if(this.validationRules != null && this.validationRules.length > 0) {
+ return this.validationRules[0];
+ }
+ return null;
+ }
+
+ /**
+ * Set the validationRules for the binding
+ *
+ * @param validators
+ */
+ public void setValidationRules(IValidationRule[] validationRules) {
+ this.validationRules = validationRules;
+ }
+
+ /**
+ * Sets a single validationRule
+ *
+ * @param validator
+ */
+ public void setValidationRule(IValidationRule validationRule) {
+ this.validationRules = new IValidationRule[]{ validationRule };
+ }
+
+ public void reset() {
+ observableSource = null;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/BindingExpressionPath.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/BindingExpressionPath.java
new file mode 100644
index 00000000000..975ce2bd512
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/BindingExpressionPath.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.util.ArrayList;
+import java.util.Stack;
+
+import org.eclipse.papyrus.xwt.XWTException;
+import org.eclipse.papyrus.xwt.metadata.ModelUtils;
+
+public class BindingExpressionPath {
+
+ protected String fullPath;
+
+ protected String stripedPath;
+
+ protected String[] segments;
+
+ public BindingExpressionPath(String value) {
+ if(value == null) {
+ return;
+ }
+ this.fullPath = value;
+ this.stripedPath = null;
+
+ int level = 0;
+ Stack<Character> separators = new Stack<Character>();
+ ArrayList<String> collector = new ArrayList<String>();
+ int start = 0;
+ int stripStart = 0;
+ int stripEnd = 0;
+ char[] array = value.toCharArray();
+ for(int i = 0; i < array.length; i++) {
+ switch(array[i]) {
+ case '}':
+ {
+ Character character = separators.pop();
+ if(character.charValue() != '{') {
+ throw new XWTException("Syntax error is binding expression " + value + " at " + i);
+ }
+ }
+ level--;
+ break;
+ case ']':
+ {
+ Character character = separators.pop();
+ if(character.charValue() != '[') {
+ throw new XWTException("Syntax error is binding expression " + value + " at " + i);
+ }
+ }
+ level--;
+ break;
+ case ')':
+ {
+ Character character = separators.pop();
+ if(character.charValue() != '(') {
+ throw new XWTException("Syntax error is binding expression " + value + " at " + i);
+ }
+ }
+ level--;
+ if(level == 0) {
+ stripEnd = i - 1;
+ }
+ break;
+ case '(':
+ if(level == 0) {
+ stripStart = i + 1;
+ }
+ separators.push(array[i]);
+ level++;
+ break;
+ case '{':
+ case '[':
+ separators.push(array[i]);
+ level++;
+ break;
+ case '.':
+ if(level == 0) {
+ String element = value.substring(start, i);
+ element = ModelUtils.normalizePropertyName(element);
+ collector.add(element);
+ updateStripped(value, stripStart, stripEnd, element);
+ start = i + 1;
+ }
+ break;
+ }
+ }
+ if(level == 0) {
+ String element = value.substring(start, array.length);
+ element = ModelUtils.normalizePropertyName(element);
+ collector.add(element);
+
+ updateStripped(value, stripStart, stripEnd, element);
+ }
+
+ segments = collector.toArray(new String[collector.size()]);
+ }
+
+ private void updateStripped(String value, int stripStart, int stripEnd, String element) {
+ if(stripStart != 0) {
+ element = value.substring(stripStart, stripEnd + 1);
+ int index = element.lastIndexOf('.');
+ if(index != -1) {
+ element = element.substring(index + 1);
+ }
+ element = ModelUtils.normalizePropertyName(element);
+ }
+
+ if(this.stripedPath == null) {
+ this.stripedPath = element;
+ } else {
+ this.stripedPath += "." + element;
+ }
+ }
+
+ public String getFullPath() {
+ return fullPath;
+ }
+
+ public String getStripedPath() {
+ return stripedPath;
+ }
+
+ public String[] getSegments() {
+ return segments;
+ }
+
+ public boolean isEmptyPath() {
+ return isEmptyPath(getFullPath());
+ }
+
+ public static boolean isEmptyPath(String value) {
+ return value == null || value.trim().length() == 0 || ".".equals(value.trim());
+ }
+
+ public static int lastIndexOf(String value) {
+ int level = 0;
+ Stack<Character> separators = new Stack<Character>();
+ char[] array = value.toCharArray();
+ for(int i = array.length - 1; i >= 0; i--) {
+ switch(array[i]) {
+ case '{':
+ {
+ Character character = separators.pop();
+ if(character.charValue() != '}') {
+ throw new XWTException("Syntax error is binding expression " + value + " at " + i);
+ }
+ }
+ level--;
+ break;
+ case '[':
+ {
+ Character character = separators.pop();
+ if(character.charValue() != '}') {
+ throw new XWTException("Syntax error is binding expression " + value + " at " + i);
+ }
+ }
+ level--;
+ break;
+ case '(':
+ {
+ Character character = separators.pop();
+ if(character.charValue() != ')') {
+ throw new XWTException("Syntax error is binding expression " + value + " at " + i);
+ }
+ }
+ level--;
+ break;
+ case '}':
+ case ']':
+ case ')':
+ separators.push(array[i]);
+ level++;
+ break;
+ case '.':
+ if(level == 0) {
+ return i;
+ }
+ break;
+ }
+
+ if(array[i] == '.') {
+ }
+ }
+ return -1;
+ }
+
+
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/BindingGate.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/BindingGate.java
new file mode 100644
index 00000000000..b5ff8b15466
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/BindingGate.java
@@ -0,0 +1,406 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.UpdateListStrategy;
+import org.eclipse.core.databinding.UpdateSetStrategy;
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.papyrus.xwt.IDataBindingInfo;
+import org.eclipse.papyrus.xwt.IDataProvider;
+import org.eclipse.papyrus.xwt.IValidationRule;
+import org.eclipse.papyrus.xwt.IValueConverter;
+import org.eclipse.papyrus.xwt.InverseValueConverter;
+import org.eclipse.papyrus.xwt.XWT;
+import org.eclipse.papyrus.xwt.databinding.IBindingContext;
+import org.eclipse.papyrus.xwt.internal.utils.ObjectUtil;
+import org.eclipse.papyrus.xwt.validation.InverseValidationRule;
+
+/**
+ * @author jliu <jin.liu@soyatec.com>
+ */
+public class BindingGate {
+
+ public static final UpdateSetStrategy POLICY_UPDATE = new UpdateSetStrategy(UpdateSetStrategy.POLICY_UPDATE);
+
+ private final IBindingContext dataBindingContext;
+
+ public BindingGate(IBindingContext dataBindingContext) {
+ super();
+ this.dataBindingContext = dataBindingContext;
+ }
+
+ public Binding bind(IObservableValue source, IObservableValue target) {
+ return bind(source, target, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core.
+ * databinding.observable.value.IObservableValue,
+ * org.eclipse.core.databinding.observable.value.IObservableValue)
+ */
+ public Binding bind(IObservable source, IObservable target, IDataBindingInfo dataBinding) {
+ if(source instanceof IObservableValue && target instanceof IObservableValue) {
+ return bindValue((IObservableValue)source, (IObservableValue)target, dataBinding);
+ } else if(source instanceof IObservableSet && target instanceof IObservableSet) {
+ IValueConverter converter = null;
+ int sourceToTargetPolicy = UpdateSetStrategy.POLICY_UPDATE;
+ int targetToSourcePolicy = UpdateSetStrategy.POLICY_UPDATE;
+ // Set policy to UpdateValueStrategy.
+ if(dataBinding != null) {
+ switch(dataBinding.getMode()) {
+ case OneWay:
+ targetToSourcePolicy = UpdateSetStrategy.POLICY_NEVER;
+ break;
+ case OneTime:
+ sourceToTargetPolicy = UpdateSetStrategy.POLICY_NEVER;
+ targetToSourcePolicy = UpdateSetStrategy.POLICY_NEVER;
+ break;
+ default:
+ break;
+ }
+ converter = dataBinding.getConverter();
+ }
+ UpdateSetStrategy sourceToTarget = new UpdateSetStrategy(sourceToTargetPolicy);
+ UpdateSetStrategy targetToSource = new UpdateSetStrategy(targetToSourcePolicy);
+ return bindSet((IObservableSet)target, (IObservableSet)source, targetToSource, sourceToTarget, converter);
+ } else if(source instanceof IObservableList && target instanceof IObservableList) {
+ IValueConverter converter = null;
+ int sourceToTargetPolicy = UpdateListStrategy.POLICY_UPDATE;
+ int targetToSourcePolicy = UpdateListStrategy.POLICY_UPDATE;
+ // Set policy to UpdateValueStrategy.
+ if(dataBinding != null) {
+ switch(dataBinding.getMode()) {
+ case OneWay:
+ targetToSourcePolicy = UpdateListStrategy.POLICY_NEVER;
+ break;
+ case OneTime:
+ sourceToTargetPolicy = UpdateListStrategy.POLICY_NEVER;
+ targetToSourcePolicy = UpdateListStrategy.POLICY_NEVER;
+ break;
+ default:
+ break;
+ }
+ converter = dataBinding.getConverter();
+ }
+ UpdateListStrategy sourceToTarget = new UpdateListStrategy(sourceToTargetPolicy);
+ UpdateListStrategy targetToSource = new UpdateListStrategy(targetToSourcePolicy);
+ return bindList((IObservableList)target, (IObservableList)source, targetToSource, sourceToTarget, converter);
+ }
+ throw new IllegalStateException();
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core.
+ * databinding.observable.value.IObservableValue,
+ * org.eclipse.core.databinding.observable.value.IObservableValue)
+ */
+ public Binding bindList(IObservableList source, IObservableList target, UpdateListStrategy sourceToTarget, UpdateListStrategy targetToSource, IValueConverter converter) {
+ if(converter != null) {
+ return bindList(source, target, sourceToTarget, targetToSource, converter, new InverseValueConverter(converter));
+ } else {
+ return bindList(source, target, sourceToTarget, targetToSource, null, null);
+ }
+ }
+
+ /**
+ *
+ * @param source
+ * @param target
+ * @param sourceToTarget
+ * if it is null, the default converter will be update policy
+ * @param targetToSource
+ * if it is null, the default converter will be update policy
+ * @param sourceToTargetConvertor
+ * if it is null, the default converter will be used
+ * @param targetToSourceConvertor
+ * if it is null, the default converter will be used
+ */
+ public Binding bindList(IObservableList source, IObservableList target, UpdateListStrategy sourceToTarget, UpdateListStrategy targetToSource, IConverter sourceToTargetConvertor, IConverter targetToSourceConvertor) {
+ if(source != null && target != null) {
+ if(sourceToTarget == null) {
+ sourceToTarget = new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE);
+ }
+ if(targetToSource == null) {
+ targetToSource = new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE);
+ }
+
+ if(sourceToTargetConvertor != null) {
+ sourceToTarget.setConverter(sourceToTargetConvertor);
+ }
+
+ if(targetToSourceConvertor != null) {
+ targetToSource.setConverter(targetToSourceConvertor);
+ }
+
+ this.dataBindingContext.bindList(target, source, targetToSource, sourceToTarget);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core.
+ * databinding.observable.value.IObservableValue,
+ * org.eclipse.core.databinding.observable.value.IObservableValue)
+ */
+ public Binding bindSet(IObservableSet source, IObservableSet target, UpdateSetStrategy sourceToTarget, UpdateSetStrategy targetToSource, IValueConverter converter) {
+ if(converter != null) {
+ return bindSet(source, target, sourceToTarget, targetToSource, converter, new InverseValueConverter(converter));
+ } else {
+ return bindSet(source, target, sourceToTarget, targetToSource, null, null);
+ }
+ }
+
+ /**
+ *
+ * @param source
+ * @param target
+ * @param sourceToTarget
+ * if it is null, the default converter will be update policy
+ * @param targetToSource
+ * if it is null, the default converter will be update policy
+ * @param sourceToTargetConvertor
+ * if it is null, the default converter will be used
+ * @param targetToSourceConvertor
+ * if it is null, the default converter will be used
+ */
+ public Binding bindSet(IObservableSet source, IObservableSet target, UpdateSetStrategy sourceToTarget, UpdateSetStrategy targetToSource, IConverter sourceToTargetConvertor, IConverter targetToSourceConvertor) {
+ if(source != null && target != null) {
+ if(sourceToTarget == null) {
+ sourceToTarget = new UpdateSetStrategy(UpdateSetStrategy.POLICY_UPDATE);
+ }
+ if(targetToSource == null) {
+ targetToSource = new UpdateSetStrategy(UpdateSetStrategy.POLICY_UPDATE);
+ }
+
+ if(sourceToTargetConvertor != null) {
+ sourceToTarget.setConverter(sourceToTargetConvertor);
+ }
+
+ if(targetToSourceConvertor != null) {
+ targetToSource.setConverter(targetToSourceConvertor);
+ }
+
+ this.dataBindingContext.bindSet(target, source, targetToSource, sourceToTarget);
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param source
+ * @param target
+ * @param sourceToTarget
+ * if it is null, the default converter will be update policy
+ * @param targetToSource
+ * if it is null, the default converter will be update policy
+ * @param sourceToTargetConvertor
+ * if it is null, the default converter will be used
+ * @param targetToSourceConvertor
+ * if it is null, the default converter will be used
+ */
+ public Binding bind(IObservableList source, IObservableList target, UpdateListStrategy sourceToTarget, UpdateListStrategy targetToSource, IConverter sourceToTargetConvertor, IConverter targetToSourceConvertor) {
+ if(source != null && target != null) {
+ if(sourceToTarget == null) {
+ sourceToTarget = new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE);
+ }
+ if(targetToSource == null) {
+ targetToSource = new UpdateListStrategy(UpdateListStrategy.POLICY_UPDATE);
+ }
+
+ if(sourceToTargetConvertor != null) {
+ sourceToTarget.setConverter(sourceToTargetConvertor);
+ }
+
+ if(targetToSourceConvertor != null) {
+ targetToSource.setConverter(targetToSourceConvertor);
+ }
+
+ this.dataBindingContext.bindList(target, source, targetToSource, sourceToTarget);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core.
+ * databinding.observable.value.IObservableValue,
+ * org.eclipse.core.databinding.observable.value.IObservableValue)
+ */
+ private Binding bindValue(IObservableValue source, IObservableValue target, IDataBindingInfo dataBinding) {
+ IValueConverter converter = null;
+ IValidationRule[] validators = null;
+ int sourceToTargetPolicy = UpdateValueStrategy.POLICY_UPDATE;
+ int targetToSourcePolicy = UpdateValueStrategy.POLICY_UPDATE;
+ // Set policy to UpdateValueStrategy.
+ if(dataBinding != null) {
+ switch(dataBinding.getMode()) {
+ case OneWay:
+ targetToSourcePolicy = UpdateValueStrategy.POLICY_NEVER;
+ break;
+ case OneTime:
+ sourceToTargetPolicy = UpdateValueStrategy.POLICY_NEVER;
+ targetToSourcePolicy = UpdateValueStrategy.POLICY_NEVER;
+ break;
+ default:
+ break;
+ }
+ converter = dataBinding.getConverter();
+ validators = dataBinding.getValidators();
+ }
+ UpdateValueStrategy sourceToTarget = new UpdateValueStrategy(sourceToTargetPolicy);
+ UpdateValueStrategy targetToSource = new UpdateValueStrategy(targetToSourcePolicy);
+
+ bindValidators(validators, sourceToTarget, targetToSource);
+
+ return bind(source, target, sourceToTarget, targetToSource, converter);
+ }
+
+ private void bindValidators(IValidationRule[] validators, UpdateValueStrategy sourceToTarget, UpdateValueStrategy targetToSource) {
+ if(validators != null) {
+ for(IValidationRule validator : validators) {
+ switch(validator.getBindingMode()) {
+ case SourceToTarget:
+ addValidatorToStrategy(sourceToTarget, validator);
+ break;
+ case TargetToSource:
+ addValidatorToStrategy(targetToSource, new InverseValidationRule(validator));
+ break;
+ case Both:
+ default:
+ addValidatorToStrategy(sourceToTarget, validator);
+ addValidatorToStrategy(targetToSource, new InverseValidationRule(validator));
+ }
+ }
+ }
+ }
+
+ private void addValidatorToStrategy(UpdateValueStrategy strategy, IValidationRule validator) {
+ switch(validator.getPhase()) {
+ case AfterGet:
+ strategy.setAfterGetValidator(validator);
+ break;
+ case AfterConvert:
+ strategy.setAfterConvertValidator(validator);
+ break;
+ case BeforeSet:
+ default:
+ strategy.setBeforeSetValidator(validator);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.databinding.IBindingContext#bind(org.eclipse.core.
+ * databinding.observable.value.IObservableValue,
+ * org.eclipse.core.databinding.observable.value.IObservableValue)
+ */
+ public Binding bind(IObservableValue source, IObservableValue target, UpdateValueStrategy sourceToTarget, UpdateValueStrategy targetToSource, IValueConverter converter) {
+ if(converter != null) {
+ return bind(source, target, sourceToTarget, targetToSource, converter, new InverseValueConverter(converter));
+ } else {
+ return bind(source, target, sourceToTarget, targetToSource, null, null);
+ }
+ }
+
+ /**
+ *
+ * @param source
+ * @param target
+ * @param sourceToTarget
+ * if it is null, the default converter will be update policy
+ * @param targetToSource
+ * if it is null, the default converter will be update policy
+ * @param sourceToTargetConvertor
+ * if it is null, the default converter will be used
+ * @param targetToSourceConvertor
+ * if it is null, the default converter will be used
+ */
+ public Binding bind(IObservableValue source, IObservableValue target, UpdateValueStrategy sourceToTarget, UpdateValueStrategy targetToSource, IConverter sourceToTargetConvertor, IConverter targetToSourceConvertor) {
+ if(source != null && target != null) {
+ if(sourceToTarget == null) {
+ sourceToTarget = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE);
+ }
+ if(targetToSource == null) {
+ targetToSource = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE);
+ }
+
+ // Add converter to UpdateValueStrategy.
+ IDataProvider sourceDataProvider = XWT.findDataProvider(source);
+ Object sourceValueType = sourceDataProvider.getDataType(null);
+ if(sourceValueType == null) {
+ sourceValueType = Object.class;
+ }
+ IDataProvider targetDataProvider = XWT.findDataProvider(target);
+ Object targetValueType = targetDataProvider.getDataType(null);
+ if(targetValueType == null) {
+ targetValueType = Object.class;
+ }
+ Class<?> sourceType = (sourceValueType instanceof Class<?>) ? (Class<?>)sourceValueType : sourceValueType.getClass();
+ Class<?> targetType = (targetValueType instanceof Class<?>) ? (Class<?>)targetValueType : targetValueType.getClass();
+ if(sourceType == null) {
+ sourceType = Object.class;
+ } else {
+ sourceType = ObjectUtil.normalizedType(sourceType);
+ }
+
+ if(targetType == null) {
+ targetType = Object.class;
+ } else {
+ targetType = ObjectUtil.normalizedType(targetType);
+ }
+
+ if(sourceToTarget.getUpdatePolicy() != UpdateValueStrategy.POLICY_NEVER) {
+ if(sourceToTargetConvertor != null) {
+ sourceToTarget.setConverter(sourceToTargetConvertor);
+ } else if(!targetType.isAssignableFrom(sourceType)) {
+ IConverter m2t = XWT.findConvertor(sourceType, targetType);
+ if(m2t != null) {
+ sourceToTarget.setConverter(m2t);
+ }
+ }
+ }
+
+ if(targetToSource.getUpdatePolicy() != UpdateValueStrategy.POLICY_NEVER) {
+ if(targetToSourceConvertor != null) {
+ targetToSource.setConverter(targetToSourceConvertor);
+ } else if(!sourceType.isAssignableFrom(targetType)) {
+ IConverter t2m = XWT.findConvertor(targetType, sourceType);
+ if(t2m != null) {
+ targetToSource.setConverter(t2m);
+ }
+ }
+ }
+
+ this.dataBindingContext.bindValue(target, source, targetToSource, sourceToTarget);
+ }
+ return null;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/Core.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/Core.java
new file mode 100644
index 00000000000..9873fb8cbb1
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/Core.java
@@ -0,0 +1,917 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.xwt.DefaultLoadingContext;
+import org.eclipse.papyrus.xwt.ICLRFactory;
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.IDataProvider;
+import org.eclipse.papyrus.xwt.IDataProviderFactory;
+import org.eclipse.papyrus.xwt.ILoadingContext;
+import org.eclipse.papyrus.xwt.ILogger;
+import org.eclipse.papyrus.xwt.IMetaclassFactory;
+import org.eclipse.papyrus.xwt.INamespaceHandler;
+import org.eclipse.papyrus.xwt.IStyle;
+import org.eclipse.papyrus.xwt.IUIResource;
+import org.eclipse.papyrus.xwt.IXWTLoader;
+import org.eclipse.papyrus.xwt.Tracking;
+import org.eclipse.papyrus.xwt.callback.IBeforeParsingCallback;
+import org.eclipse.papyrus.xwt.converters.ObjectToObject;
+import org.eclipse.papyrus.xwt.converters.StringToEnum;
+import org.eclipse.papyrus.xwt.core.IElementLoaderFactory;
+import org.eclipse.papyrus.xwt.core.IRenderingContext;
+import org.eclipse.papyrus.xwt.core.IVisualElementLoader;
+import org.eclipse.papyrus.xwt.dataproviders.ObjectDataProvider;
+import org.eclipse.papyrus.xwt.input.ICommand;
+import org.eclipse.papyrus.xwt.internal.xml.Attribute;
+import org.eclipse.papyrus.xwt.internal.xml.DocumentObject;
+import org.eclipse.papyrus.xwt.internal.xml.DocumentRoot;
+import org.eclipse.papyrus.xwt.internal.xml.Element;
+import org.eclipse.papyrus.xwt.internal.xml.ElementManager;
+import org.eclipse.papyrus.xwt.javabean.ValueConvertorRegister;
+import org.eclipse.papyrus.xwt.metadata.IMetaclass;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+public class Core {
+
+ static public final Object[] EMPTY_ARRAY = new Object[0];
+
+ public static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+ static public final String DEFAULT_STYLES_KEY = "XWT.DefaultStyles";
+
+ static public boolean TRACE_BENCH = false;
+
+ private HashMap<Class<?>, Object> registrations;
+
+ private HashMap<DocumentObject, IVisualElementLoader> elementsLoaders = new HashMap<DocumentObject, IVisualElementLoader>();
+
+ private MetaclassService metaclassService;
+
+ private IElementLoaderFactory loaderFactory;
+
+ private ILoadingContext _loadingContext = null;
+
+ private ICLRFactory clrFactory = null;
+
+ private Set<Tracking> trackingSet = new HashSet<Tracking>();
+
+ private Map<String, ICommand> commands = new HashMap<String, ICommand>();
+
+ private Map<String, INamespaceHandler> nsHandlers = new HashMap<String, INamespaceHandler>();
+
+ private ILogger logger;
+
+ private Collection<IStyle> defaultStyles = new ArrayList<IStyle>();
+
+ private static LinkedHashMap<String, IDataProviderFactory> dataProviderFactories = new LinkedHashMap<String, IDataProviderFactory>();
+
+ private Collection<Class<?>> resolveTypes = new ArrayList<Class<?>>();
+
+ private IXWTLoader xwtLoader;
+
+ static public ILogger nullLog = new ILogger() {
+
+ private Map<Tracking, String> messageMap = new HashMap<Tracking, String>();
+
+ public void error(Throwable e) {
+ }
+
+ public void error(Throwable e, String message) {
+ }
+
+ public void message(String message) {
+ }
+
+ public void warning(String message) {
+ }
+
+ public void printInfo(String message, Tracking tracking, Set<Tracking> trackType) {
+ String printMessage = "";
+
+ if(trackType != null && trackType.size() > 0) {
+ if(trackType.contains(tracking)) {
+ printMessage = messageMap.get(tracking);
+ }
+ }
+ System.out.println(printMessage);
+ }
+
+ public void addMessage(String message, Tracking tracking) {
+ if(messageMap.containsKey(tracking)) {
+ messageMap.remove(tracking);
+ }
+ messageMap.put(tracking, message);
+ }
+
+ public void removeMessage(Tracking tracking) {
+ if(messageMap.containsKey(tracking)) {
+ messageMap.remove(tracking);
+ }
+ }
+ };
+
+ public Core(IElementLoaderFactory loaderFactory, IXWTLoader xwtLoader) {
+ this.loaderFactory = loaderFactory;
+ this.registrations = new HashMap<Class<?>, Object>();
+ this.xwtLoader = xwtLoader;
+ this.metaclassService = new MetaclassService(xwtLoader);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#getLogger()
+ */
+ public ILogger getLogger() {
+ if(logger == null) {
+ return Core.nullLog;
+ }
+ return logger;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#setLogger(org.eclipse.papyrus.xwt.ILogger)
+ */
+ public void setLogger(ILogger log) {
+ logger = log;
+ }
+
+ public ICLRFactory getCLRFactory() {
+ return clrFactory;
+ }
+
+ public void setCLRFactory(ICLRFactory clrFactory) {
+ this.clrFactory = clrFactory;
+ }
+
+ /**
+ *
+ * @param nsmapace
+ * @param handler
+ */
+ public void registerNamespaceHandler(String nsmapace, INamespaceHandler handler) {
+ nsHandlers.put(nsmapace, handler);
+ }
+
+ /**
+ *
+ * @param nsmapace
+ */
+ public void unregisterNamespaceHandler(String nsmapace) {
+ nsHandlers.remove(nsmapace);
+ }
+
+ /**
+ *
+ * @param nsmapace
+ * @return
+ */
+ public INamespaceHandler getNamespaceHandler(String nsmapace) {
+ return nsHandlers.get(nsmapace);
+ }
+
+ class ConverterService {
+
+ protected Map<Class<?>, IConverter> converters = new HashMap<Class<?>, IConverter>();
+
+ public IConverter getConverter(Class<?> type) {
+ IConverter converter = converters.get(type);
+ if(converter != null) {
+ return converter;
+ }
+
+ return null;
+ }
+
+ public void register(Class<?> type, IConverter converter) {
+ converters.put(type, converter);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#findConvertor(java.lang.Class,
+ * java.lang.Class)
+ */
+ public IConverter findConvertor(Class<?> source, Class<?> target) {
+ if(source == target || (source != Object.class && source.isAssignableFrom(target))) {
+ return ObjectToObject.instance;
+ }
+ if(String.class == source && target.isEnum()) {
+ return new StringToEnum(target);
+ }
+ ValueConvertorRegister convertorRegister = (ValueConvertorRegister)getService(ValueConvertorRegister.class);
+ if(convertorRegister == null) {
+ return null;
+ }
+ return convertorRegister.findConverter(source, target);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.IXWTLoader#registerConvertor(org.eclipse.core.databinding
+ * .conversion.IConverter)
+ */
+ public void registerConvertor(IConverter converter) {
+ Class<?> source = (Class<?>)converter.getFromType();
+ Class<?> target = (Class<?>)converter.getToType();
+ ValueConvertorRegister convertorRegister = (ValueConvertorRegister)getService(ValueConvertorRegister.class);
+ convertorRegister.register(source, target, converter);
+ }
+
+ public void registerConvertor(Class<?> converter, String methodName) {
+ try {
+ Method method = converter.getDeclaredMethod(methodName);
+ Object object = method.invoke(null);
+ if(object instanceof IConverter) {
+ registerConvertor((IConverter)object);
+ }
+ } catch (SecurityException e) {
+ } catch (IllegalArgumentException e) {
+ } catch (NoSuchMethodException e) {
+ } catch (IllegalAccessException e) {
+ } catch (InvocationTargetException e) {
+ }
+ }
+
+ public void registerConvertor(Class<?> converterType, String methodName, boolean value) {
+ IConverter converter = loadConvertor(converterType, methodName, value);
+ if(converter != null) {
+ registerConvertor(converter);
+ }
+ }
+
+ public void registerConvertor(ValueConvertorRegister convertorRegister, Class<?> source, Class<?> target, Class<?> converterType, String methodName, boolean value) {
+ IConverter converter = loadConvertor(converterType, methodName, value);
+ if(converter != null) {
+ convertorRegister.register(source, target, converter);
+ }
+ }
+
+ public IConverter loadConvertor(Class<?> converter, String methodName, boolean value) {
+ try {
+ Method method = converter.getDeclaredMethod(methodName);
+ Object object = method.invoke(null, value);
+ if(object instanceof IConverter) {
+ return (IConverter)object;
+ }
+ } catch (SecurityException e) {
+ } catch (IllegalArgumentException e) {
+ } catch (NoSuchMethodException e) {
+ } catch (IllegalAccessException e) {
+ } catch (InvocationTargetException e) {
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#getConverterService()
+ */
+ public ConverterService getConverterService() {
+ ConverterService service = (ConverterService)getService(ConverterService.class);
+ if(service == null) {
+ service = new ConverterService();
+ registerService(ConverterService.class, service);
+ service.register(Object.class, new IConverter() {
+
+ public Object convert(Object fromObject) {
+ return null;
+ }
+
+ public Object getFromType() {
+ return Object.class;
+ }
+
+ public Object getToType() {
+ return String.class;
+ }
+ });
+ }
+ return service;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.IXWTLoader#addTracking(org.eclipse.papyrus.xwt.Tracking)
+ */
+ public void addTracking(Tracking tracking) {
+ if(!trackingSet.contains(tracking)) {
+ trackingSet.add(tracking);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.IXWTLoader#isTracking(org.eclipse.papyrus.xwt.Tracking)
+ */
+ public boolean isTracking(Tracking tracking) {
+ return trackingSet.contains(tracking);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#getTrackings()
+ */
+ public Set<Tracking> getTrackings() {
+ return trackingSet;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.IXWTLoader#removeTracking(org.eclipse.papyrus.xwt.Tracking)
+ */
+ public void removeTracking(Tracking tracking) {
+ if(trackingSet.contains(tracking)) {
+ trackingSet.remove(tracking);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#registerCommand(java.lang.String,
+ * org.eclipse.papyrus.xwt.input.ICommand)
+ */
+ public void registerCommand(String name, ICommand command) {
+ commands.put(name, command);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#getCommand(java.lang.String)
+ */
+ public ICommand getCommand(String name) {
+ return commands.get(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#getCommands()
+ */
+ public Map<String, ICommand> getCommands() {
+ return commands;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#unregisterCommand(java.lang.String)
+ */
+ public void unregisterCommand(String name) {
+ commands.remove(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.IXWTLoader#addDefaultStyle(org.eclipse.papyrus.xwt.IStyle)
+ */
+ public void addDefaultStyle(IStyle style) {
+ defaultStyles.add(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.IXWTLoader#removeDefaultStyle(org.eclipse.papyrus.xwt.IStyle
+ * )
+ */
+ public void removeDefaultStyle(IStyle style) {
+ defaultStyles.remove(style);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#getDefaultStyles()
+ */
+ public Collection<IStyle> getDefaultStyles() {
+ return new ArrayList<IStyle>(defaultStyles);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.IXWTLoader#addDataProviderFactory(org.eclipse.papyrus.xwt
+ * .IDataProviderFactory)
+ */
+ public void addDataProviderFactory(String name, IDataProviderFactory dataProviderFactory) {
+ if(dataProviderFactory == null) {
+ return;
+ }
+ dataProviderFactories.put(name, dataProviderFactory);
+ registerMetaclass(dataProviderFactory.getType());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#registerMetaclass(java.lang.Class)
+ */
+ public IMetaclass registerMetaclass(Class<?> type) {
+ return registerMetaclass(type, IConstants.XWT_NAMESPACE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.IXWTLoader#removeDataProviderFactory(org.eclipse.e4
+ * .xwt.IDataProviderFactory)
+ */
+ public void removeDataProviderFactory(String name) {
+ if(name == null) {
+ return;
+ }
+ dataProviderFactories.remove(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.IXWTLoader#removeDataProviderFactory(org.eclipse.e4
+ * .xwt.IDataProviderFactory)
+ */
+ public void removeDataProviderFactory(IDataProviderFactory dataProviderFactory) {
+ if(dataProviderFactory == null) {
+ return;
+ }
+ for(String name : dataProviderFactories.keySet()) {
+ IDataProviderFactory value = dataProviderFactories.get(name);
+ if(dataProviderFactory == value) {
+ dataProviderFactories.remove(name);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#getDataProviderFactories()
+ */
+ public Collection<IDataProviderFactory> getDataProviderFactories() {
+ return dataProviderFactories.values();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#findDataProvider(java.lang.Object)
+ */
+ public IDataProvider findDataProvider(Object dataContext) {
+ if(dataContext instanceof IDataProvider) {
+ return (IDataProvider)dataContext;
+ }
+ for(IDataProviderFactory factory : dataProviderFactories.values()) {
+ IDataProvider dataProvider = factory.create(dataContext);
+ if(dataProvider != null) {
+ return dataProvider;
+ }
+ }
+ ObjectDataProvider dataProvider = new ObjectDataProvider();
+ dataProvider.setObjectInstance(dataContext);
+ return dataProvider;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#getLoadingContext()
+ */
+ public ILoadingContext getLoadingContext() {
+ if(_loadingContext == null) {
+ return DefaultLoadingContext.defaultLoadingContext;
+ }
+ return _loadingContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.e4.xwt.IXWTLoader#setLoadingContext(org.eclipse.papyrus.xwt.
+ * ILoadingContext)
+ */
+ public void setLoadingContext(ILoadingContext loadingContext) {
+ _loadingContext = loadingContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.IXWTLoader#findLoadingContext(java.lang.Object)
+ */
+ public ILoadingContext findLoadingContext(Object container) {
+ return getLoadingContext();
+ }
+
+ public IMetaclass getMetaclass(ILoadingContext context, String name, String namespace) {
+ return getMetaclassService().getMetaclass(context, name, namespace);
+ }
+
+ public IMetaclass findMetaclass(Object object) {
+ if(object instanceof Class<?>) {
+ return getMetaclassService().findMetaclass((Class<?>)object);
+ }
+ return getMetaclassService().findMetaclass(object.getClass());
+ }
+
+ public IMetaclass getMetaclass(Object object) {
+ if(object instanceof Class<?>) {
+ return getMetaclassService().getMetaclass((Class<?>)object);
+ }
+ return getMetaclassService().getMetaclass(object.getClass());
+ }
+
+ public IMetaclass getMetaclass(Object object, String namespace) {
+ if(object instanceof Class) {
+ return getMetaclassService().getMetaclass((Class<?>)object, namespace);
+ }
+ return getMetaclassService().getMetaclass(object.getClass(), namespace);
+ }
+
+ public Collection<IMetaclass> getAllMetaclasses(String namespace) {
+ return getMetaclassService().getAllMetaclasses(namespace);
+ }
+
+ public void registerMetaclass(IMetaclass metaclass, String namespace) {
+ getMetaclassService().register(metaclass, namespace);
+ }
+
+ public void registerMetaclassFactory(IMetaclassFactory metaclassFactory) {
+ getMetaclassService().registerFactory(metaclassFactory);
+ }
+
+ public IMetaclass registerMetaclass(Class<?> metaclass, String namespace) {
+ return getMetaclassService().register(metaclass, namespace);
+ }
+
+ public IMetaclass registerMetaclass(Class<?> metaclass, String namespace, IMetaclass superMetaclass) {
+ return getMetaclassService().register(metaclass, namespace, superMetaclass);
+ }
+
+ public void registerMetaclassManager(String namespace, MetaclassManager manager) {
+ getMetaclassService().register(namespace, manager);
+ }
+
+ public Object getService(Class<?> type) {
+ return this.registrations.get(type);
+ }
+
+ public void registerService(Class<?> serviceType, Object service) {
+ registrations.put(serviceType, service);
+ }
+
+ protected Object createCLRElement(IRenderingContext context, Element element, Map<String, Object> options) {
+ IVisualElementLoader loader = findElementLoader(element);
+ if(loader != null) {
+ return loader.createUIElement(element, options);
+ }
+ loader = createElementLoader(context, element);
+ Object visualObject = loader.createUIElement(element, options);
+ removeElementLoader(element);
+ return visualObject;
+ }
+
+ protected IVisualElementLoader findElementLoader(DocumentObject element) {
+ IVisualElementLoader loader = elementsLoaders.get(element);
+ if(loader != null) {
+ return loader;
+ }
+ if(element.getParent() != null) {
+ return findElementLoader(element.getParent());
+ }
+ return null;
+ }
+
+ protected IVisualElementLoader createElementLoader(IRenderingContext context, DocumentObject element) {
+ IVisualElementLoader creator = loaderFactory.createElementLoader(context, xwtLoader);
+ elementsLoaders.put(element, creator);
+ return creator;
+ }
+
+ protected void removeElementLoader(DocumentObject element) {
+ elementsLoaders.remove(element);
+ }
+
+ public Object load(ILoadingContext loadingContext, URL input, Map<String, Object> options) throws Exception {
+ return load(loadingContext, null, input, options);
+ }
+
+ public IUIResource loadAsResource(InputStream stream, URL input, IBeforeParsingCallback parsingCallback) throws Exception {
+ ElementManager manager = new ElementManager();
+ Element element = null;
+ if(stream == null) {
+ element = manager.load(input, parsingCallback);
+ } else {
+ InputStream inputStream = stream;
+ if(parsingCallback != null) {
+ int size = stream.read();
+ byte[] buffer = new byte[size];
+ stream.read(buffer);
+ String content = new String(buffer);
+ stream.close();
+ content = parsingCallback.onParsing(content);
+ inputStream = new ByteArrayInputStream(content.getBytes());
+ element = manager.load(stream, input);
+ }
+ element = manager.load(inputStream, input);
+ }
+ return new UIResource(input, element);
+ }
+
+ public Object load(ILoadingContext loadingContext, IUIResource pattern, Map<String, Object> options) throws Exception {
+ UIResource uiResource = (UIResource)pattern;
+ Control control = null;
+ ElementManager manager = new ElementManager(uiResource.getURL());
+ Element element = uiResource.getContent();
+ IRenderingContext context = new ExtensionContext(loadingContext, manager, element.getNamespace());
+ Object visual = createCLRElement(context, element, options);
+ if(visual instanceof Control) {
+ control = (Control)visual;
+ } else if(visual instanceof Viewer) {
+ control = ((Viewer)visual).getControl();
+ } else {
+ Class<?> jfaceWindow = Class.forName("org.eclipse.jface.window.Window");
+ if(jfaceWindow != null && jfaceWindow.isInstance(visual)) {
+ Method createMethod = jfaceWindow.getDeclaredMethod("create");
+ createMethod.invoke(visual);
+ Method method = jfaceWindow.getDeclaredMethod("getShell");
+ control = (Control)method.invoke(visual);
+ }
+ }
+
+ if(control instanceof Composite) {
+ Object parent = options.get(IXWTLoader.CONTAINER_PROPERTY);
+ Object designMode = options.get(IXWTLoader.DESIGN_MODE_PROPERTY);
+ if(parent instanceof Composite) {
+ Composite parentComposite = (Composite)parent;
+ if(parentComposite.getLayout() == null || designMode == Boolean.TRUE) {
+ autoLayout(parentComposite, element);
+ }
+ } else if(parent == null || designMode == Boolean.TRUE) {
+ if(control instanceof Shell) {
+ autoLayout(control, element);
+ } else {
+ autoLayout(control.getShell(), element);
+ }
+ }
+ }
+ return visual;
+ }
+
+ public Control load(ILoadingContext loadingContext, InputStream stream, URL input, Map<String, Object> options) throws Exception {
+ // Detect from url or file path.
+ long start = System.currentTimeMillis();
+ Control control = null;
+ ElementManager manager = new ElementManager();
+ if(input != null) {
+ Element element = null;
+ if(stream == null) {
+ element = manager.load(input, (IBeforeParsingCallback)options.get(IXWTLoader.BEFORE_PARSING_CALLBACK));
+ } else {
+ IBeforeParsingCallback callback = (IBeforeParsingCallback)options.get(IXWTLoader.BEFORE_PARSING_CALLBACK);
+ InputStream inputStream = stream;
+ if(callback != null) {
+ int size = stream.read();
+ byte[] buffer = new byte[size];
+ stream.read(buffer);
+ String content = new String(buffer);
+ stream.close();
+ content = callback.onParsing(content);
+ inputStream = new ByteArrayInputStream(content.getBytes());
+ element = manager.load(stream, input);
+ }
+ element = manager.load(inputStream, input);
+ }
+ IRenderingContext context = new ExtensionContext(loadingContext, manager, manager.getRootElement().getNamespace());
+ Object visual = createCLRElement(context, element, options);
+ if(TRACE_BENCH) {
+ System.out.println("Loaded: " + (System.currentTimeMillis() - start) + " " + input.toString());
+ }
+ if(visual instanceof Control) {
+ control = (Control)visual;
+ } else if(visual instanceof Viewer) {
+ control = ((Viewer)visual).getControl();
+ } else {
+ Class<?> jfaceWindow = Class.forName("org.eclipse.jface.window.Window");
+ if(jfaceWindow != null && jfaceWindow.isInstance(visual)) {
+ Method createMethod = jfaceWindow.getDeclaredMethod("create");
+ createMethod.invoke(visual);
+ Method method = jfaceWindow.getDeclaredMethod("getShell");
+ control = (Control)method.invoke(visual);
+ }
+ }
+
+ Object parent = options.get(IXWTLoader.CONTAINER_PROPERTY);
+ Object designMode = options.get(IXWTLoader.DESIGN_MODE_PROPERTY);
+ if(control instanceof Composite) {
+ if(parent instanceof Composite) {
+ Composite parentComposite = (Composite)parent;
+ if(parentComposite.getLayout() == null || designMode == Boolean.TRUE) {
+ autoLayout(parentComposite, element);
+ }
+ } else if(parent == null || designMode == Boolean.TRUE) {
+ if(control instanceof Shell) {
+ autoLayout(control, element);
+ } else {
+ autoLayoutShell(control, element);
+ }
+ }
+ } else if(control != null && (parent == null || designMode == Boolean.TRUE)) {
+ autoLayoutShell(control, element);
+ }
+ }
+ return control;
+ }
+
+ protected void autoLayout(Control composite, Element element) {
+ if(element == null) {
+ return;
+ }
+ Attribute bounds = element.getAttribute("Bounds");
+ if(bounds == null) {
+ bounds = element.getAttribute("Bounds", IConstants.XWT_NAMESPACE);
+ }
+ Attribute size = element.getAttribute("Size");
+ if(size == null) {
+ size = element.getAttribute("Size", IConstants.XWT_NAMESPACE);
+ }
+ if(bounds == null && size == null) {
+ composite.pack();
+ }
+ }
+
+ protected void autoLayoutShell(Control control, Element element) {
+ if(element == null) {
+ return;
+ }
+ Attribute bounds = element.getAttribute("Bounds");
+ if(bounds == null) {
+ bounds = element.getAttribute("Bounds", IConstants.XWT_NAMESPACE);
+ }
+ Attribute size = element.getAttribute("Size");
+ if(size == null) {
+ size = element.getAttribute("Size", IConstants.XWT_NAMESPACE);
+ }
+ if(bounds == null && size == null) {
+ control.pack();
+ } else {
+ Shell shell = control.getShell();
+ Point targetSize = control.getSize();
+ Rectangle rectangle = shell.getBounds();
+ Rectangle clientArea = shell.getClientArea();
+ targetSize.x += rectangle.width - clientArea.width;
+ targetSize.y += rectangle.height - clientArea.height;
+ shell.setSize(targetSize);
+ }
+ }
+
+ static private class ExtensionContext implements IRenderingContext {
+
+ private Map<String, Object> properties = new HashMap<String, Object>();
+
+ private URL resourcePath;
+
+ private DocumentRoot documentRoot;
+
+ private String namespace;
+
+ private String encoding;
+
+ protected ILoadingContext loadingContext;
+
+ public ExtensionContext(ILoadingContext loadingContext, ElementManager elementManager, String namespace) {
+ documentRoot = elementManager.getDocumentRoot();
+ resourcePath = documentRoot.getPath();
+ this.namespace = namespace;
+ this.loadingContext = loadingContext;
+ encoding = elementManager.getEncoding();
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public InputStream openStream(String path) throws IOException {
+ return documentRoot.openStream(path);
+ }
+
+ public URL getResourcePath() {
+ return resourcePath;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IExtensionContext#getEncoding()
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ public Object getProperty(String name) {
+ return properties.get(name);
+ }
+
+ public void setProperty(String name, Object value) {
+ properties.put(name, value);
+ }
+
+ public ILoadingContext getLoadingContext() {
+ return loadingContext;
+ }
+ }
+
+ public MetaclassService getMetaclassService() {
+ return metaclassService;
+ }
+
+ /**
+ * Check if the value of a property is to resolve.
+ *
+ * @param type
+ * type of property
+ * @return
+ */
+ public boolean isFileResolveType(Class<?> type) {
+ for(Class<?> resolveType : resolveTypes) {
+ if(resolveType.isAssignableFrom(type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Register the value of a property is to resolve.
+ *
+ * @param type
+ * type of property
+ * @return
+ */
+ public void registerFileResolveType(Class<?> type) {
+ if(!resolveTypes.contains(type)) {
+ resolveTypes.add(type);
+ }
+ }
+
+ /**
+ * Register the value of a property is to resolve.
+ *
+ * @param type
+ * type of property
+ * @return
+ */
+ public void unregisterFileResolveType(Class<?> type) {
+ resolveTypes.remove(type);
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DataBindingTrack.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DataBindingTrack.java
new file mode 100644
index 00000000000..0dc91f5d574
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DataBindingTrack.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.Tracking;
+import org.eclipse.papyrus.xwt.XWT;
+import org.eclipse.papyrus.xwt.internal.utils.LoggerManager;
+import org.eclipse.papyrus.xwt.internal.utils.ObjectUtil;
+import org.eclipse.papyrus.xwt.internal.xml.Attribute;
+import org.eclipse.papyrus.xwt.internal.xml.Element;
+import org.eclipse.papyrus.xwt.jface.JFacesHelper;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * @author liang.zhang
+ *
+ */
+public class DataBindingTrack {
+
+ private String bindingError = "";
+
+ private Set<String> errorElements = null;
+
+ private List<Element> widgetList = null;
+
+ private Map<Element, String> bindingMap;
+
+ public DataBindingTrack() {
+ widgetList = new ArrayList<Element>();
+ errorElements = new HashSet<String>();
+ bindingMap = new HashMap<Element, String>();
+ }
+
+ public void addWidgetElement(Element element) {
+ widgetList.add(element);
+ }
+
+ private void addErrorWidgetId(String elementId) {
+ errorElements.add(elementId);
+ }
+
+ private void addBindingMessageToMap(Element element, String bindingMessage) {
+ bindingMap.put(element, bindingMessage);
+ }
+
+ private int validateParentElementError(Element bindingElement) {
+ int isError = 0;
+ if(!bindingError.equals("")) {
+ Object parentObj = bindingElement.getParent();
+ while(parentObj != null) {
+ bindingElement = (Element)parentObj;
+ if(errorElements.contains(bindingElement.getId())) {
+ isError = 1;
+ break;
+ }
+ parentObj = bindingElement.getParent();
+ }
+ }
+ return isError;
+ }
+
+ private String getCurrentWidgetPosition(Element element) {
+ if(element.getParent() != null) {
+ return " " + getCurrentWidgetPosition((Element)element.getParent());
+ }
+ return "";
+ }
+
+ public String getDataBindMessage() {
+ StringBuffer message = new StringBuffer("");
+ Iterator<Element> widgetIt = widgetList.iterator();
+ Set<Element> keys = bindingMap.keySet();
+ while(widgetIt.hasNext()) {
+ Element element = widgetIt.next();
+ int parentHasError = validateParentElementError(element);
+ if(parentHasError == 0) {
+ String content = getCurrentWidgetPosition(element);
+ if(!message.toString().equals("")) {
+ content += "+ ";
+ }
+ content = content + element.getName();
+ if(XWT.isTracking(Tracking.NAME)) {
+ Attribute nameAttr = element.getAttribute("Name");
+ if(nameAttr == null) {
+ nameAttr = element.getAttribute(IConstants.XWT_X_NAMESPACE, "Name");
+ }
+ if(nameAttr != null) {
+ content += " <" + nameAttr.getContent() + ">";
+ }
+ }
+ message.append(content);
+ if(XWT.isTracking(Tracking.DATABINDING)) {
+ if(keys.contains(element)) {
+ message.append(bindingMap.get(element));
+ } else {
+ message.append("\n");
+ }
+ }
+ }
+ }
+ return message.toString();
+ }
+
+ private void setBindingErrorMessage(String bindingError) {
+ this.bindingError = bindingError;
+ }
+
+ public void tracking(Object swtObject, Element element, Object dataContext) {
+ String bindingMessage = "";
+ if(swtObject instanceof Binding) {
+ String error = "";
+ Binding newInstance = (Binding)swtObject;
+ String path = null;
+ Attribute attr = element.getAttribute("Path");
+ if(null == attr)
+ attr = element.getAttribute("path");
+ if(null != attr)
+ path = attr.getContent();
+ Object dataContext2 = null;
+ try {
+ dataContext2 = newInstance.getValue(null);
+ if(path != null && path.length() > 0) {
+ String[] paths = path.trim().split("\\.");
+ if(paths.length > 1) {
+ String path1 = "";
+ for(int i = 0; i < paths.length - 1; i++) {
+ path1 = paths[i];
+ if(dataContext2 != null) {
+ dataContext2 = getObserveData(dataContext2, path1);
+ }
+ }
+ }
+ }
+ } catch (Exception ex) {
+ addErrorWidgetId(element.getParent().getParent().getId());
+ setBindingErrorMessage("-> Error");
+ error = "-> Error";
+ }
+ if(dataContext2 != null) {
+ bindingMessage = " (DataContext=" + dataContext2.getClass().getSimpleName() + ", Path=" + path + ")" + error + "\n";
+ addBindingMessageToMap((Element)element.getParent().getParent(), bindingMessage);// bindingMap.put((Element) element.getParent().getParent(), bindingMessage);
+ }
+ } else if(swtObject instanceof Widget) {
+ addWidgetElement(element);
+ if(dataContext != null) {
+ bindingMessage = " (DataContext=" + dataContext.getClass().getSimpleName() + ")\n";
+ addBindingMessageToMap(element, bindingMessage);
+ }
+ } else if(JFacesHelper.isViewer(swtObject)) {
+ if(dataContext != null) {
+ bindingMessage = " (DataContext=" + dataContext.getClass().getSimpleName() + ")\n";
+ addBindingMessageToMap(element, bindingMessage);// bindingMap.put(element, bindingMessage);
+ }
+ } else if(element.attributeNames(IConstants.XWT_X_NAMESPACE).length > 0) {
+ // ??
+ if(element.getParent() != null && element.getParent().getParent() != null) {
+ bindingMessage = " (DataContext=" + element.getName() + ")\n";
+ addBindingMessageToMap((Element)element.getParent().getParent(), bindingMessage);// bindingMap.put((Element) element.getParent().getParent(), bindingMessage);
+ }
+ }
+ }
+
+ public static Object getObserveData(Object dataContext, String path) {
+ try {
+ Class<?> dataContextClass = dataContext.getClass();
+ Method getMethod = ObjectUtil.findGetter(dataContextClass, path, null);
+ if(getMethod != null) {
+ return getMethod.invoke(dataContext);
+ }
+ } catch (SecurityException e) {
+ LoggerManager.log(e);
+ } catch (IllegalArgumentException e) {
+ LoggerManager.log(e);
+ } catch (IllegalAccessException e) {
+ LoggerManager.log(e);
+ } catch (InvocationTargetException e) {
+ LoggerManager.log(e);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DynamicBinding.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DynamicBinding.java
new file mode 100644
index 00000000000..440121a6c8f
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DynamicBinding.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.papyrus.xwt.IDataProvider;
+import org.eclipse.papyrus.xwt.IXWTLoader;
+import org.eclipse.papyrus.xwt.XWT;
+import org.eclipse.papyrus.xwt.XWTException;
+import org.eclipse.papyrus.xwt.annotation.UIBounds;
+import org.eclipse.papyrus.xwt.core.IDynamicBinding;
+import org.eclipse.papyrus.xwt.core.IUserDataConstants;
+import org.eclipse.papyrus.xwt.databinding.BindingMode;
+import org.eclipse.papyrus.xwt.databinding.IBindingContext;
+import org.eclipse.papyrus.xwt.internal.utils.UserData;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Generic Binding definition
+ *
+ * @author yyang (yves.yang@soyatec.com)
+ */
+public abstract class DynamicBinding implements IDynamicBinding {
+
+ private Object control;
+
+ private Object host;
+
+ private BindingMode mode = BindingMode.TwoWay;
+
+ private IXWTLoader xwtLoader;
+
+ /**
+ * The name of the {@link DataBindingContext} that we will look up in static
+ * resources
+ */
+ private IBindingContext bindingContext;
+
+ /**
+ * which used to decide binding type, not only text.
+ */
+ private String type;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.xwt.core.IDynamicBinding#getContextName()
+ */
+ public IBindingContext getBindingContext() {
+ if(this.bindingContext == null) {
+ Object element = (control == null ? host : control);
+ this.bindingContext = XWT.getBindingContext(element);
+ }
+ return this.bindingContext;
+ }
+
+ public Object getHost() {
+ return host;
+ }
+
+ public void setHost(Object host) {
+ this.host = host;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.papyrus.xwt.core.IDynamicBinding#setBindingContext(IBindingContext
+ * )
+ */
+ public void setBindingContext(IBindingContext bindingContext) {
+ this.bindingContext = bindingContext;
+ }
+
+ public void setControl(Object control) {
+ this.control = control;
+ }
+
+ public Object getControl() {
+ return this.control;
+ }
+
+ /**
+ * @param type
+ * the type to set
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * @return the type
+ */
+ public String getType() {
+ return type;
+ }
+
+ public BindingMode getMode() {
+ return mode;
+ }
+
+ public void setMode(BindingMode mode) {
+ this.mode = mode;
+ }
+
+ public void setXWTLoader(IXWTLoader xwtLoader) {
+ this.xwtLoader = xwtLoader;
+ }
+
+ protected Object getDataContextHost() {
+ Object control = getControl();
+ if(control == null) {
+ return null;
+ }
+ Object data = UserData.getLocalDataContext(control);
+ if(data == null || data == this) {
+ if(data == null && UserData.hasLocalData(control, IUserDataConstants.XWT_DATACONTEXT_KEY)) {
+ return control;
+ }
+ Widget parent = UserData.getParent(control);
+ if(parent != null) {
+ return UserData.getDataContextHost(parent);
+ }
+ return null;
+ }
+ return control;
+ }
+
+ protected Object getDataContext() {
+ if(control != null) {
+ return UserData.getDataContext(control);
+ }
+ return null;
+ }
+
+ protected IDataProvider getDataProvider(Object dataContext) {
+ if(dataContext != null) {
+ if(dataContext instanceof IDataProvider) {
+ return (IDataProvider)dataContext;
+ } else {
+ return xwtLoader.findDataProvider(dataContext);
+ }
+ }
+ return null;
+ }
+
+ public IDataProvider getDataProvider() {
+ return getDataProvider(getDataContext());
+ }
+
+ protected Rectangle getControlBounds() {
+ Widget widget = (Widget)getControl();
+ if(widget instanceof Control) {
+ Control control = (Control)widget;
+ return control.getBounds();
+ }
+ Method drawMethod = findBoundsMethod(widget.getClass());
+ if(drawMethod != null) {
+ try {
+ drawMethod.setAccessible(true);
+ return (Rectangle)drawMethod.invoke(widget);
+ } catch (Exception e) {
+ throw new XWTException(e);
+ }
+ }
+ Control control = findHostControl();
+ return control.getBounds();
+ }
+
+ protected Control findHostControl() {
+ Widget widget = (Widget)getControl();
+ Control host;
+ if(widget instanceof Item) {
+ Item item = (Item)widget;
+ host = (Control)XWT.findParent(item, Control.class);
+ } else if(widget instanceof Control) {
+ host = (Control)widget;
+ } else {
+ throw new XWTException();
+ }
+ return host;
+ }
+
+ private Method findBoundsMethod(Class<?> type) {
+ for(Method method : type.getDeclaredMethods()) {
+ if(method.getAnnotation(UIBounds.class) != null && method.getTypeParameters().length == 0 && method.getReturnType() == Rectangle.class) {
+ return method;
+ }
+ }
+ Class<?> supertype = type.getSuperclass();
+ if(supertype != null && supertype != Widget.class) {
+ Method method = findBoundsMethod(supertype);
+ if(method != null) {
+ return method;
+ }
+ }
+ for(Class<?> anInterface : type.getInterfaces()) {
+ Method method = findBoundsMethod(anInterface);
+ if(method != null) {
+ return method;
+ }
+ }
+ try {
+ Method method = type.getDeclaredMethod("getBounds");
+ if(method.getReturnType() == Rectangle.class) {
+ return method;
+ }
+ } catch (Exception e) {
+ }
+ return null;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DynamicValueBinding.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DynamicValueBinding.java
new file mode 100644
index 00000000000..70d56d631ec
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/DynamicValueBinding.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import org.eclipse.papyrus.xwt.core.IDynamicValueBinding;
+import org.eclipse.papyrus.xwt.metadata.IProperty;
+
+public class DynamicValueBinding<T> extends DynamicBinding implements IDynamicValueBinding {
+
+ private T sourceValue;
+
+ private IProperty property;
+
+ private Object object;
+
+ public DynamicValueBinding(T sourceValue) {
+ this.sourceValue = sourceValue;
+ }
+
+ public IProperty getProperty() {
+ return property;
+ }
+
+ public void setProperty(IProperty property) {
+ this.property = property;
+ }
+
+ public Object getObject() {
+ return object;
+ }
+
+ public void setObject(Object object) {
+ this.object = object;
+ }
+
+ public T getSourceValue() {
+ return sourceValue;
+ }
+
+ public Object getValue(Class<?> type) {
+ return sourceValue;
+ }
+
+ public void reset() {
+ }
+
+ public Object createBoundSource() {
+ return null;
+ }
+
+ public boolean isSourceControl() {
+ return false;
+ }
+
+
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/IEventController.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/IEventController.java
new file mode 100644
index 00000000000..347e45ab5c5
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/IEventController.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.papyrus.xwt.IEventInvoker;
+import org.eclipse.papyrus.xwt.metadata.IEvent;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Widget;
+
+public interface IEventController {
+
+ boolean hasEvent(Object receiver, IEvent event);
+
+ void addEvent(int eventType, String name, IEvent event, Widget control, Object receiver, Object arg, Method method);
+
+ void addEvent(int eventType, String name, IEvent event, Widget control, Object arg, IEventInvoker eventInvoker);
+
+ void setEvent(IEvent event, Widget control, Object receiver, Object arg, Method method);
+
+ void setEvent(IEvent event, Widget control, Object arg, IEventInvoker eventInvoker);
+
+ void handleEvent(Event e);
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MetaclassManager.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MetaclassManager.java
new file mode 100644
index 00000000000..d8a5a92cd53
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MetaclassManager.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.ILoadingContext;
+import org.eclipse.papyrus.xwt.IMetaclassFactory;
+import org.eclipse.papyrus.xwt.IXWTLoader;
+import org.eclipse.papyrus.xwt.XWTException;
+import org.eclipse.papyrus.xwt.internal.utils.ClassLoaderUtil;
+import org.eclipse.papyrus.xwt.javabean.metadata.Metaclass;
+import org.eclipse.papyrus.xwt.metadata.IMetaclass;
+
+/**
+ * @author yyang (yves.yang@soyatec.com)
+ */
+public class MetaclassManager {
+
+ protected Map<String, IMetaclass> nameRegister = new HashMap<String, IMetaclass>();
+
+ protected Collection<Class<?>> classRegister = new HashSet<Class<?>>();
+
+ protected MetaclassManager parent;
+
+ protected MetaclassService service;
+
+ private IXWTLoader xwtLoader;
+
+ public MetaclassManager(MetaclassService service, MetaclassManager parent, IXWTLoader xwtLoader) {
+ this.parent = parent;
+ this.service = service;
+ this.xwtLoader = xwtLoader;
+ }
+
+ public Collection<IMetaclass> getAllMetaclasses() {
+ return nameRegister.values();
+ }
+
+ public void register(IMetaclass metaclass) {
+ Class<?> type = metaclass.getType();
+ if(classRegister.contains(type)) {
+ return;
+ }
+ String key = type.getSimpleName();
+ nameRegister.put(key, metaclass);
+ classRegister.add(type);
+ }
+
+ public IMetaclass register(Class<?> javaClass) {
+ return register(javaClass, null);
+ }
+
+ public IMetaclass register(Class<?> javaClass, IMetaclass superMetaclass) {
+ IMetaclass metaclass = getMetaclass(javaClass);
+ if(metaclass != null) {
+ return metaclass;
+ }
+ if(superMetaclass == null) {
+ Class<?> superclass = javaClass.getSuperclass();
+ if(superclass != null && superclass != Object.class) {
+ register(superclass, null);
+ }
+ superMetaclass = getMetaclass(superclass);
+ }
+ IMetaclass thisMetaclass = createMetaclass(javaClass, superMetaclass);
+ register(thisMetaclass);
+ return thisMetaclass;
+ }
+
+ protected IMetaclass createMetaclass(Class<?> javaClass, IMetaclass superMetaclass) {
+ if(service != null) {
+ IMetaclassFactory factory = service.findFactory(javaClass);
+ if(factory != null) {
+ return factory.create(javaClass, superMetaclass, xwtLoader);
+ }
+ }
+ boolean lazyLoading = false; // TODO Get value from preference
+ return new Metaclass(javaClass, superMetaclass, lazyLoading, xwtLoader);
+ }
+
+ public IMetaclass getMetaclass(ILoadingContext context, String name, String namespace) {
+ IMetaclass metaclass = nameRegister.get(name);
+ if(metaclass != null) {
+ if(namespace == null || namespace.equals(IConstants.XWT_NAMESPACE)) {
+ return metaclass;
+ }
+ if(namespace != null && namespace.startsWith(IConstants.XAML_CLR_NAMESPACE_PROTO)) {
+ String packageName = namespace.substring(IConstants.XAML_CLR_NAMESPACE_PROTO.length());
+ int index = packageName.indexOf('=');
+ if(index != -1) {
+ packageName = packageName.substring(0, index);
+ }
+ // if using default package(null), use only name as class name,
+ // else use package.class as class name
+ String className = packageName.length() == 0 ? name : (packageName + "." + name);
+ if(metaclass.getType().getName().equals(className)) {
+ return metaclass;
+ }
+ }
+ }
+ if(namespace == null || !namespace.startsWith(IConstants.XAML_CLR_NAMESPACE_PROTO)) {
+ return null;
+ }
+ String packageName = namespace.substring(IConstants.XAML_CLR_NAMESPACE_PROTO.length());
+ int index = packageName.indexOf('=');
+ if(index != -1) {
+ packageName = packageName.substring(0, index);
+ }
+ // if using default package(null), use only name as class name, else use
+ // package.class as class name
+ String className = packageName.length() == 0 ? name : (packageName + "." + name);
+ // try {
+ Class<?> type = ClassLoaderUtil.loadClass(context, className);
+ if(type == null) {
+ throw new XWTException("Cannot load " + className);
+ }
+ metaclass = register(type, null);
+ // There is no need to mapping a CLR class, since the ClassLoader will
+ // be changed.
+ nameRegister.remove(type.getSimpleName());
+ return metaclass;
+ }
+
+ public IMetaclass getMetaclass(Object object) {
+ if(object instanceof Class) {
+ return getMetaclass((Class<?>)object);
+ } else if(object instanceof String) {
+ return getMetaclass((String)object);
+ }
+ Class<?> type = object.getClass();
+ return getMetaclass(type);
+ }
+
+ public IMetaclass getMetaclass(Class<?> type) {
+ if(classRegister.contains(type)) {
+ IMetaclass metaclass = nameRegister.get(type.getSimpleName());
+ if(metaclass != null && metaclass.getType() == type) {
+ return metaclass;
+ }
+ }
+ if(parent != null) {
+ IMetaclass metaclass = parent.getMetaclass(type);
+ if(metaclass != null) {
+ return metaclass;
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MetaclassService.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MetaclassService.java
new file mode 100644
index 00000000000..7ed56b7e9db
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MetaclassService.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.ILoadingContext;
+import org.eclipse.papyrus.xwt.IMetaclassFactory;
+import org.eclipse.papyrus.xwt.IXWTLoader;
+import org.eclipse.papyrus.xwt.metadata.IMetaclass;
+
+/**
+ * @author yyang (yves.yang@soyatec.com)
+ */
+public class MetaclassService {
+
+ protected Map<String, MetaclassManager> map = new HashMap<String, MetaclassManager>();
+
+ protected ArrayList<IMetaclassFactory> factories = new ArrayList<IMetaclassFactory>();
+
+ private IXWTLoader xwtLoader;
+
+ public MetaclassService(IXWTLoader xwtLoader) {
+ this.xwtLoader = xwtLoader;
+ }
+
+ public IMetaclass getMetaclass(ILoadingContext context, String name, String namespace) {
+ MetaclassManager manager = map.get(namespace);
+ if(manager == null) {
+ manager = new MetaclassManager(this, map.get(IConstants.XWT_NAMESPACE), xwtLoader);
+ map.put(namespace, manager);
+ }
+ return manager.getMetaclass(context, name, namespace);
+ }
+
+ public IMetaclass findMetaclass(Class<?> type) {
+ MetaclassManager manager = map.get(IConstants.XWT_NAMESPACE);
+ if(manager == null) {
+ return null;
+ }
+ return manager.getMetaclass(type);
+ }
+
+ public IMetaclass getMetaclass(Class<?> type) {
+ MetaclassManager manager = map.get(IConstants.XWT_NAMESPACE);
+ if(manager == null) {
+ return null;
+ }
+ IMetaclass metaclass = manager.getMetaclass(type);
+ if(metaclass == null) {
+ String packageName = "";
+ Package packageObject = type.getPackage();
+ if(packageObject != null) {
+ packageName = packageObject.getName();
+ }
+ String key = IConstants.XAML_CLR_NAMESPACE_PROTO + ":" + packageName;
+ MetaclassManager childManager = map.get(key);
+ if(childManager == null) {
+ childManager = new MetaclassManager(this, manager, xwtLoader);
+ map.put(key, childManager);
+ }
+ metaclass = childManager.getMetaclass(type);
+ if(metaclass == null) {
+ childManager.register(type);
+ metaclass = childManager.getMetaclass(type);
+ }
+ }
+ return metaclass;
+ }
+
+ public IMetaclass getMetaclass(Class<?> type, String namespace) {
+ MetaclassManager manager = map.get(namespace);
+ if(manager == null) {
+ manager = new MetaclassManager(this, null, xwtLoader);
+ map.put(namespace, manager);
+ }
+ IMetaclass metaclass = manager.getMetaclass(type);
+ if(metaclass == null) {
+ metaclass = manager.getMetaclass(type);
+ if(metaclass == null) {
+ manager.register(type);
+ metaclass = manager.getMetaclass(type);
+ }
+ }
+ return metaclass;
+ }
+
+ public IMetaclass register(Class<?> metaclass, String namespace) {
+ MetaclassManager manager = map.get(namespace);
+ if(manager == null) {
+ throw new IllegalStateException();
+ }
+ return manager.register(metaclass);
+ }
+
+ public IMetaclass register(Class<?> metaclass, String namespace, IMetaclass superMetaclass) {
+ MetaclassManager manager = map.get(namespace);
+ if(manager == null) {
+ throw new IllegalStateException();
+ }
+ return manager.register(metaclass, superMetaclass);
+ }
+
+ public void register(IMetaclass metaclass, String namespace) {
+ MetaclassManager manager = map.get(namespace);
+ if(manager == null) {
+ manager = new MetaclassManager(this, null, xwtLoader);
+ map.put(namespace, manager);
+ }
+ manager.register(metaclass);
+ }
+
+ public Collection<IMetaclass> getAllMetaclasses(String namespace) {
+ MetaclassManager manager = map.get(namespace);
+ if(manager == null) {
+ throw new IllegalStateException();
+ }
+ return manager.getAllMetaclasses();
+ }
+
+ public void register(String namespace, MetaclassManager manager) {
+ map.put(namespace, manager);
+ }
+
+ public void registerFactory(IMetaclassFactory metaclassFactory) {
+ factories.add(metaclassFactory);
+ }
+
+ public IMetaclassFactory findFactory(Class<?> javaClass) {
+ for(int i = factories.size() - 1; i >= 0; i--) {
+ IMetaclassFactory factory = factories.get(i);
+ if(factory.isFactoryOf(javaClass)) {
+ return factory;
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MultiBinding.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MultiBinding.java
new file mode 100644
index 00000000000..615009fbc49
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/MultiBinding.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.papyrus.xwt.IDataBindingInfo;
+import org.eclipse.papyrus.xwt.IDataProvider;
+import org.eclipse.papyrus.xwt.IMultiValueConverter;
+import org.eclipse.papyrus.xwt.IValidationRule;
+import org.eclipse.papyrus.xwt.XWT;
+import org.eclipse.papyrus.xwt.XWTException;
+import org.eclipse.papyrus.xwt.converters.StringMultiValueConerter;
+import org.eclipse.papyrus.xwt.core.IDynamicBinding;
+import org.eclipse.papyrus.xwt.databinding.AggregateObservableValue;
+import org.eclipse.papyrus.xwt.databinding.IBindingContext;
+import org.eclipse.papyrus.xwt.internal.utils.LoggerManager;
+import org.eclipse.papyrus.xwt.internal.utils.UserData;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Support the aggregation of data binding
+ *
+ * @author yyang (yves.yang@soyatec.com)
+ */
+public class MultiBinding extends DynamicBinding implements IDataBindingInfo {
+
+ private Binding[] bindings = Binding.EMPTY_ARRAY;
+
+ private IMultiValueConverter valueConverter;
+
+ private IValidationRule[] valueValidators = IValidationRule.EMPTY_ARRAY;
+
+ private AggregateObservableValue observableValue;
+
+ private IObservableValue observableWidget;
+
+ private BindingExpressionPath targetPropertySegments;
+
+ /**
+ * <p>
+ * Default
+ * </p>
+ *
+ */
+ private UpdateSourceTrigger updateSourceTrigger = UpdateSourceTrigger.Default;
+
+ private BindingGate bindingGate;
+
+ public UpdateSourceTrigger getUpdateSourceTrigger() {
+ return updateSourceTrigger;
+ }
+
+ public void setUpdateSourceTrigger(UpdateSourceTrigger updateSourceTrigger) {
+ this.updateSourceTrigger = updateSourceTrigger;
+ }
+
+ public Binding[] getBindings() {
+ return bindings;
+ }
+
+ public void setBindings(Binding[] bindings) {
+ this.bindings = bindings;
+ }
+
+ public IMultiValueConverter getConverter() {
+ if(valueConverter == null) {
+ valueConverter = new StringMultiValueConerter();
+ }
+ return valueConverter;
+ }
+
+ public void setConverter(IMultiValueConverter valueConverter) {
+ this.valueConverter = valueConverter;
+ }
+
+ public boolean isSourcePropertyReadOnly() {
+ for(Binding binding : bindings) {
+ if(binding.isSourcePropertyReadOnly()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Object getValue(Class<?> targetType) {
+ if(observableValue == null) {
+ IObservableValue[] values = new IObservableValue[bindings.length];
+ for(int i = 0; i < values.length; i++) {
+ bindings[i].getValue(targetType);
+ IObservable observable = bindings[i].getObservableSource();
+ if(observable instanceof IObservableValue) {
+ values[i] = (IObservableValue)observable;
+ } else {
+ LoggerManager.log("Binding expression has a problem with " + bindings[i].getPath());
+ return null;
+ }
+ }
+
+ observableValue = new AggregateObservableValue(values, getConverter());
+ }
+
+ IObservableValue observableWidget = getObservableWidget();
+
+ IDataProvider dataProvider = getDataProvider();
+ if(dataProvider != null) {
+ BindingGate bindingGate = getBindingGate();
+ if(bindingGate != null) {
+ Object target = getControl();
+ if(target instanceof Text && getType().equalsIgnoreCase("text")) {
+ if(isSourcePropertyReadOnly()) {
+ Text text = (Text)target;
+ text.setEditable(false);
+ }
+ } else if(target instanceof Button && getType().equalsIgnoreCase("selection")) {
+ if(isSourcePropertyReadOnly()) {
+ Button button = (Button)target;
+ button.setEnabled(false);
+ }
+ } else if((target instanceof Combo || target instanceof CCombo) && getType().equalsIgnoreCase("text")) {
+ if(isSourcePropertyReadOnly()) {
+ Control control = (Control)target;
+ control.setEnabled(false);
+ }
+ } else if(target instanceof MenuItem && getType().equalsIgnoreCase("selection")) {
+ if(isSourcePropertyReadOnly()) {
+ MenuItem menuItem = (MenuItem)target;
+ menuItem.setEnabled(false);
+ }
+ }
+ }
+ bindingGate.bind(observableValue, observableWidget, this);
+ }
+
+ if(targetType == null || !targetType.isInstance(observableValue)) {
+ return observableValue.getValue();
+ }
+ return observableValue;
+ }
+
+ private BindingGate getBindingGate() {
+ if(this.bindingGate == null) {
+ IBindingContext dataBindingContext = XWT.getBindingContext(getControl());
+ this.bindingGate = new BindingGate(dataBindingContext);
+ }
+
+ return this.bindingGate;
+ }
+
+ public IObservableValue getObservableWidget() {
+ if(observableWidget == null) {
+ Object target = getControl();
+ Object host = getHost();
+ try {
+ observableWidget = ScopeManager.observeValue(target, host, getTargettPropertyExpression(), getUpdateSourceTrigger());
+ } catch (XWTException e) {
+ }
+ }
+ return observableWidget;
+ }
+
+ public Object createBoundSource() {
+ Object control = getControl();
+ Object source = XWT.getDataContext(control);
+ Object localDataContext = UserData.getLocalDataContext(control);
+ if(localDataContext == this) {
+ return source;
+ }
+
+ if(source instanceof IDynamicBinding) {
+ return ((IDynamicBinding)source).createBoundSource();
+ }
+ return source;
+ }
+
+ public boolean isSourceControl() {
+ Object source = null;
+ Object dataContextHost = getDataContextHost();
+ if(dataContextHost != null) {
+ source = UserData.getLocalDataContext(dataContextHost);
+ }
+
+ if(source instanceof IDynamicBinding) {
+ return ((IDynamicBinding)source).isSourceControl();
+ }
+ return false;
+ }
+
+ public BindingExpressionPath getTargettPropertyExpression() {
+ if(targetPropertySegments == null) {
+ targetPropertySegments = new BindingExpressionPath(getType());
+ }
+ return targetPropertySegments;
+ }
+
+ public IValidationRule[] getValidators() {
+ return valueValidators;
+ }
+
+ public void setValidators(IValidationRule[] valueValidators) {
+ this.valueValidators = valueValidators;
+ }
+
+ public void reset() {
+ for(Binding binding : bindings) {
+ binding.reset();
+ }
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/ScopeKeeper.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/ScopeKeeper.java
new file mode 100644
index 00000000000..ef5d159029c
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/ScopeKeeper.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.papyrus.xwt.internal.utils.UserData;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Widget;
+
+public class ScopeKeeper implements DisposeListener {
+
+ protected HashMap<String, Object> nameMap = new HashMap<String, Object>();
+
+ protected HashMap<Widget, HashMap<Object, HashMap<String, IObservable>>> bindingData = new HashMap<Widget, HashMap<Object, HashMap<String, IObservable>>>();
+
+ protected Widget host;
+
+ private final ScopeKeeper parent;
+
+ private ChangeListenerSupport changeListenerSupport = new ChangeListenerSupport();
+
+ class ChangeListenerSupport implements IChangeListener {
+
+ private List<IChangeListener> changeListeners = Collections.emptyList();
+
+ public void handleChange(ChangeEvent event) {
+ for(IChangeListener changeListener : changeListeners) {
+ changeListener.handleChange(event);
+ }
+
+ // notify to parent as well.
+ Widget parent = UserData.getTreeParent(host);
+ ScopeKeeper scopeKeeper = UserData.findScopeKeeper(parent);
+ if(scopeKeeper != null) {
+ scopeKeeper.fireChangeListener(event);
+ }
+ }
+
+ public boolean addChangeListener(IChangeListener listener) {
+ if(changeListeners.contains(listener)) {
+ return false;
+ }
+ if(changeListeners == Collections.EMPTY_LIST) {
+ changeListeners = new ArrayList<IChangeListener>();
+ }
+ changeListeners.add(listener);
+ return true;
+ }
+
+ public void removeChangeListener(IChangeListener listener) {
+ changeListeners.remove(listener);
+ }
+
+ public void dispose() {
+ changeListeners = null;
+ }
+ }
+
+ public ScopeKeeper(ScopeKeeper parent, Widget host) {
+ super();
+ this.parent = parent;
+ host.addDisposeListener(this);
+ this.host = host;
+ }
+
+ public void widgetDisposed(DisposeEvent e) {
+ Widget source = e.widget;
+ if(source == host) {
+ for(HashMap<Object, HashMap<String, IObservable>> hashMap : bindingData.values()) {
+ for(HashMap<String, IObservable> map : hashMap.values()) {
+ for(IObservable observable : map.values()) {
+ observable.removeChangeListener(changeListenerSupport);
+ }
+ }
+ }
+ changeListenerSupport.dispose();
+ }
+ HashMap<Object, HashMap<String, IObservable>> hashMap = bindingData.get(source);
+ if(hashMap != null) {
+ for(HashMap<String, IObservable> map : hashMap.values()) {
+ for(IObservable observable : map.values()) {
+ observable.removeChangeListener(changeListenerSupport);
+ }
+ }
+ bindingData.remove(source);
+ }
+ }
+
+ public void addNamedObject(String name, Object object) {
+ nameMap.put(name, object);
+ }
+
+ public Widget getHost() {
+ return host;
+ }
+
+ public Object getNamedObject(String name) {
+ Object object = nameMap.get(name);
+ if(object != null) {
+ return object;
+ }
+ return parent == null ? null : parent.getNamedObject(name);
+ }
+
+ public Collection<String> names() {
+ return nameMap.keySet();
+ }
+
+ public boolean containsName(String name) {
+ if(nameMap.containsKey(name)) {
+ return true;
+ }
+ return parent == null ? false : parent.containsName(name);
+ }
+
+ /**
+ * Register a change listener. The second call to register a same listener
+ * has no effect.
+ *
+ * @param listener
+ */
+ public boolean addChangeListener(IChangeListener listener) {
+ return changeListenerSupport.addChangeListener(listener);
+ }
+
+ /**
+ * Remove the registered change listener
+ *
+ * @param listener
+ */
+ public void removeChangeListener(IChangeListener listener) {
+ changeListenerSupport.removeChangeListener(listener);
+ }
+
+ public void fireChangeListener(ChangeEvent event) {
+ changeListenerSupport.handleChange(event);
+ }
+
+ void addObservableValue(Widget widget, Object data, String property, IObservable value) {
+ if(widget == null) {
+ widget = host;
+ } else {
+ widget.addDisposeListener(this);
+ }
+
+ HashMap<Object, HashMap<String, IObservable>> widgetData = bindingData.get(widget);
+ if(widgetData == null) {
+ widgetData = new HashMap<Object, HashMap<String, IObservable>>();
+ bindingData.put(widget, widgetData);
+ }
+
+ HashMap<String, IObservable> objectData = widgetData.get(data);
+ if(objectData == null) {
+ objectData = new HashMap<String, IObservable>();
+ widgetData.put(data, objectData);
+ }
+ if(objectData.containsKey(property)) {
+ throw new IllegalStateException();
+ }
+ objectData.put(property, value);
+
+ value.addChangeListener(changeListenerSupport);
+ }
+
+ IObservableValue getObservableValue(Widget control, Object data, String property) {
+ IObservable observable = getObservable(control, data, property);
+ if(observable instanceof IObservableValue) {
+ return (IObservableValue)observable;
+ }
+
+ return null;
+ }
+
+ IObservableList getObservableList(Widget control, Object data, String property) {
+ IObservable observable = getObservable(control, data, property);
+ if(observable instanceof IObservableList) {
+ return (IObservableList)observable;
+ }
+ return null;
+ }
+
+ IObservableSet getObservableSet(Widget control, Object data, String property) {
+ IObservable observable = getObservable(control, data, property);
+ if(observable instanceof IObservableSet) {
+ return (IObservableSet)observable;
+ }
+ return null;
+ }
+
+ IObservable localGetObservable(Widget control, Object data, String property) {
+ // find locally
+ for(HashMap<Object, HashMap<String, IObservable>> widgetData : bindingData.values()) {
+ if(widgetData != null) {
+ HashMap<String, IObservable> objectData = widgetData.get(data);
+ if(objectData != null) {
+ IObservable observable = objectData.get(property);
+ if(observable != null) {
+ return observable;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ IObservable getObservable(Widget control, Object data, String property) {
+ // find locally
+ IObservable observable = localGetObservable(control, data, property);
+ if(observable != null) {
+ return observable;
+ }
+
+ // find in other ScopeKeeper and then keep it in this ScopeKeeper.
+ Widget rootWidget = UserData.findRootWidget(control);
+ observable = deepFindObservable(rootWidget, data, property);
+ if(observable != null) {
+ addObservableValue(control, data, property, observable);
+ }
+ return observable;
+ }
+
+ static IObservable deepFindObservable(Widget control, Object data, String property) {
+ ScopeKeeper scopeKeeper = UserData.getLocalScopeKeeper(control);
+ if(scopeKeeper != null) {
+ IObservable observable = scopeKeeper.localGetObservable(control, data, property);
+ if(observable != null) {
+ return observable;
+ }
+ }
+ if(control instanceof Composite) {
+ Composite composite = (Composite)control;
+ for(Control child : composite.getChildren()) {
+ IObservable observable = deepFindObservable(child, data, property);
+ if(observable != null) {
+ return observable;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/ScopeManager.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/ScopeManager.java
new file mode 100644
index 00000000000..51496c5cb0b
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/ScopeManager.java
@@ -0,0 +1,485 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.list.WritableList;
+import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
+import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.property.value.IValueProperty;
+import org.eclipse.papyrus.xwt.IDataProvider;
+import org.eclipse.papyrus.xwt.XWT;
+import org.eclipse.papyrus.xwt.XWTException;
+import org.eclipse.papyrus.xwt.databinding.EventPropertyObservableValue;
+import org.eclipse.papyrus.xwt.databinding.JFaceXWTDataBinding;
+import org.eclipse.papyrus.xwt.databinding.ListToArrayObservableValue;
+import org.eclipse.papyrus.xwt.databinding.TypedViewerObservableValueDecorator;
+import org.eclipse.papyrus.xwt.dataproviders.IObjectDataProvider;
+import org.eclipse.papyrus.xwt.internal.utils.UserData;
+import org.eclipse.papyrus.xwt.javabean.metadata.properties.EventProperty;
+import org.eclipse.papyrus.xwt.metadata.IMetaclass;
+import org.eclipse.papyrus.xwt.metadata.IProperty;
+import org.eclipse.papyrus.xwt.metadata.ModelUtils;
+import org.eclipse.swt.widgets.Widget;
+
+public class ScopeManager {
+
+ public static final int AUTO = 0;
+
+ public static final int VALUE = 1;
+
+ public static final int SET = 2;
+
+ public static final int LIST = 3;
+
+ public static final int COLLECTION = 4;
+
+ public static IObservableValue observableValue(Object control, Object value, String fullPath, UpdateSourceTrigger updateSourceTrigger) {
+ try {
+ return observeValue(control, value, fullPath, updateSourceTrigger);
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ public static IObservableList observableList(Object control, Object value, String fullPath, UpdateSourceTrigger updateSourceTrigger) {
+ try {
+ return (IObservableList)observe(control, value, fullPath, updateSourceTrigger, ScopeManager.LIST);
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ public static IObservableSet observableSet(Object control, Object value, String fullPath, UpdateSourceTrigger updateSourceTrigger) {
+ try {
+ return (IObservableSet)observe(control, value, fullPath, updateSourceTrigger, ScopeManager.SET);
+ } catch (Exception e) {
+ }
+ return null;
+ }
+
+ /**
+ * Reserved only for the calling from XWTLoader
+ *
+ * @param context
+ * @param data
+ * @param propertyName
+ * @return
+ */
+ public static IObservableValue findObservableValue(Object context, Object control, Object data, String propertyName) {
+ ScopeKeeper scope = UserData.findScopeKeeper(context);
+ if(control == null) {
+ control = context;
+ }
+ return scope.getObservableValue(UserData.getWidget(control), data, propertyName);
+ }
+
+ /**
+ * Reserved only for the calling from XWTLoader
+ *
+ * @param context
+ * @param data
+ * @param propertyName
+ * @return
+ */
+ public static IObservableSet findObservableSet(Object context, Object control, Object data, String propertyName) {
+ ScopeKeeper scope = UserData.findScopeKeeper(context);
+ if(control == null) {
+ control = context;
+ }
+ return scope.getObservableSet(UserData.getWidget(control), data, propertyName);
+ }
+
+ /**
+ * Reserved only for the calling from XWTLoader
+ *
+ * @param context
+ * @param data
+ * @param propertyName
+ * @return
+ */
+ public static IObservableList findObservableList(Object context, Object control, Object data, String propertyName) {
+ ScopeKeeper scope = UserData.findScopeKeeper(context);
+ if(control == null) {
+ control = context;
+ }
+ return scope.getObservableList(UserData.getWidget(control), data, propertyName);
+ }
+
+ static class ObservableValueBuilder {
+
+ private Widget widget;
+
+ private Object control;
+
+ private Object value;
+
+ private Object elementType;
+
+ private BindingExpressionPath expressionPath;
+
+ private UpdateSourceTrigger updateSourceTrigger;
+
+ private IDataProvider dataProvider;
+
+ private String currentPath;
+
+ private int observeKind = VALUE;
+
+ public ObservableValueBuilder(Object control, Object elementType, BindingExpressionPath expressionPath, UpdateSourceTrigger updateSourceTrigger, int observeKind) {
+ this.control = control;
+ this.expressionPath = expressionPath;
+ this.elementType = elementType;
+ this.updateSourceTrigger = updateSourceTrigger;
+ this.observeKind = observeKind;
+ }
+
+ public IObservable observe(Object targetValue) {
+ this.value = targetValue;
+ widget = UserData.getWidget(control);
+ ScopeKeeper scopeManager = UserData.findScopeKeeper(widget);
+ if(scopeManager == null) {
+ return null;
+ }
+
+ if(expressionPath.getFullPath() == null) {
+ if(targetValue instanceof IObservable) {
+ return (IObservable)targetValue;
+ }
+ }
+
+ IObservable observable = scopeManager.getObservable(widget, value, expressionPath.getStripedPath());
+ if(observable != null) {
+ while(observable instanceof IObservableValue && ((IObservableValue)observable).getValue() instanceof IObservable) {
+ observable = (IObservable)((IObservableValue)observable).getValue();
+ }
+ return observable;
+ }
+ dataProvider = XWT.findDataProvider(value);
+ Object dataValue = value;
+ currentPath = null;
+ Object type = elementType;
+ String[] segments = expressionPath.getSegments();
+ if(segments == null || segments.length == 0) {
+ String segment = ModelUtils.normalizePropertyName(expressionPath.getFullPath());
+ observable = resolveObservablevalue(scopeManager, dataValue, type, segment);
+ } else {
+ if(observeKind == COLLECTION) {
+ // if the first is viewers' property
+ if(!JFaceXWTDataBinding.isViewerProperty(segments[0])) {
+ int kindValue = VALUE;
+ Object targetValueType = dataValue;
+ if(dataValue instanceof IObservableValue) {
+ targetValueType = ((IObservableValue)dataValue).getValueType();
+ }
+ Object propertyType = dataProvider.getModelService().toModelPropertyType(targetValueType, segments[0]);
+ if(propertyType instanceof Class<?>) {
+ Class<?> propertyTypeClass = (Class<?>)propertyType;
+ if(Collection.class.isAssignableFrom(propertyTypeClass) || propertyTypeClass.isArray()) {
+ kindValue = COLLECTION;
+ }
+ }
+ observeKind = kindValue;
+ }
+ }
+ int size = segments.length;
+ int lastObserveKind = observeKind;
+ observeKind = VALUE;
+ for(int i = 0; i < size; i++) {
+ String segment = segments[i];
+ if(i == (size - 1)) {
+ observeKind = lastObserveKind;
+ }
+ observable = resolveObservablevalue(scopeManager, dataValue, type, segment);
+ // Hasan: As long as this is already an IObservableValue we
+ // should look deep into the chain
+ while(observable instanceof IObservableValue && ((IObservableValue)observable).getValue() instanceof IObservable) {
+ observable = (IObservable)((IObservableValue)observable).getValue();
+ }
+ dataValue = observable;
+ if(i != size - 1) {
+ type = dataProvider.getModelService().toModelType(dataValue);
+ if(type != null) {
+ dataProvider = XWT.findDataProvider(type);
+ }
+ }
+ }
+ }
+ return observable;
+ }
+
+ private IObservable resolveObservablevalue(ScopeKeeper scopeManager, Object dataValue, Object type, String segment) {
+ if(!BindingExpressionPath.isEmptyPath(segment)) {
+ int length = segment.length();
+ if(length > 1 && segment.charAt(0) == '(' && segment.charAt(length - 1) == ')') {
+ // It is class
+ String path = segment.substring(1, segment.length() - 1);
+ int index = path.lastIndexOf('.');
+ if(index != -1) {
+ String className = path.substring(0, index);
+ segment = path.substring(index + 1);
+ type = dataProvider.getModelService().loadModelType(className);
+ if(type == null) {
+ type = dataProvider.getModelService().loadModelType(path);
+ if(type != null) {
+ segment = null;
+ }
+ }
+ if(type == null) {
+ throw new XWTException("Class " + className + " not found");
+ }
+ dataProvider = XWT.findDataProvider(type);
+ }
+ }
+ }
+ if(currentPath == null) {
+ currentPath = segment;
+ } else if(segment != null) {
+ currentPath = currentPath + '.' + segment;
+ }
+
+ IObservable segmentValue = scopeManager.getObservableValue(widget, value, currentPath);
+ try {
+ if(segmentValue == null) {
+ if(segment != null) {
+ segmentValue = createValueProperty(dataValue, segment, type);
+ if(segmentValue == null) {
+ throw new XWTException(" Property " + segment + " is not found in " + expressionPath.getFullPath());
+ // maybe to
+ // raise an
+ // exception
+ }
+ scopeManager.addObservableValue(widget, value, currentPath, segmentValue);
+ } else if(dataValue instanceof IObservable) {
+ segmentValue = (IObservable)dataValue;
+ }
+ } else if(segment == null && type != null) {
+ if(segmentValue instanceof TypedViewerObservableValueDecorator) {
+ TypedViewerObservableValueDecorator typedViewerObservableValueDecorator = (TypedViewerObservableValueDecorator)segmentValue;
+ typedViewerObservableValueDecorator.setElementType(type);
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ // Property is not found
+ String message = e.getMessage();
+ if(!message.startsWith("Could not find property with name")) {
+ throw e;
+ }
+ throw new XWTException(" Property " + segment + " is not found in " + expressionPath.getFullPath()); // maybe
+ // to
+ // raise
+ // an
+ // exception
+ }
+ return segmentValue;
+ }
+
+ protected IObservable createValueProperty(Object object, String propertyName, Object targetType) {
+ IObservable observable = null;
+ Object type = null;
+ if(targetType == null) {
+ type = dataProvider.getModelService().toModelType(object);
+ } else {
+ type = targetType;
+ }
+
+ if(UserData.getWidget(object) != null) {
+ observable = JFaceXWTDataBinding.observeWidget(object, propertyName, updateSourceTrigger, observeKind);
+ }
+
+ if(observable == null && dataProvider instanceof IObjectDataProvider) {
+ IMetaclass mateclass = XWT.getMetaclass(type);
+ IProperty property = mateclass.findProperty(propertyName);
+ if(property instanceof EventProperty) {
+ observable = new EventPropertyObservableValue(object, (EventProperty)property);
+ }
+ }
+
+ if(observable != null) {
+ return observable;
+ }
+ observable = dataProvider.observe(object, propertyName, type, observeKind);
+ if(observable instanceof IObservableValue) {
+ IObservableValue activeValue = (IObservableValue)observable;
+
+ Object valueType = activeValue.getValueType();
+ if(valueType instanceof Class<?>) {
+ // TODO maybe need to moved in IDataProvider
+ Class<?> classType = (Class<?>)valueType;
+ if(valueType != null && classType.isArray()) {
+ // Create a IObserableValue to handle the connection
+ // between
+ // Array and List
+
+ Object values = dataProvider.getData(propertyName);
+ ArrayList<Object> array = new ArrayList<Object>();
+ if(values != null) {
+ for(Object value : (Object[])values) {
+ array.add(value);
+ }
+ }
+ WritableList writableList = new WritableList(XWT.getRealm(), array, classType.getComponentType());
+
+ return new ListToArrayObservableValue(writableList, activeValue);
+ }
+ }
+ }
+ return observable;
+ }
+ }
+
+ static class ObservableFactory extends ObservableValueBuilder implements IObservableFactory {
+
+ public ObservableFactory(Object control, BindingExpressionPath expressionPath, UpdateSourceTrigger updateSourceTrigger) {
+ super(control, null, expressionPath, updateSourceTrigger, AUTO);
+ }
+
+ public IObservable createObservable(Object target) {
+ return observe(target);
+ }
+ }
+
+ public static IObservableValue observeValue(Object control, Object value, String fullPath, UpdateSourceTrigger updateSourceTrigger) {
+ return observeValue(control, value, new BindingExpressionPath(fullPath), updateSourceTrigger);
+ }
+
+ public static IObservableValue observeValue(Object control, Object value, BindingExpressionPath expressionPath, UpdateSourceTrigger updateSourceTrigger) {
+ if(value == null) {
+ value = control;
+ }
+ ObservableValueBuilder builder = new ObservableValueBuilder(control, null, expressionPath, updateSourceTrigger, ScopeManager.VALUE);
+ return (IObservableValue)builder.observe(value);
+ }
+
+ public static IObservable observe(Object control, Object value, BindingExpressionPath expressionPath, UpdateSourceTrigger updateSourceTrigger) {
+ return observe(control, value, expressionPath, updateSourceTrigger, AUTO);
+ }
+
+ public static IObservableFactory observableFactory(Object control, BindingExpressionPath expressionPath, UpdateSourceTrigger updateSourceTrigger) {
+ return new ObservableFactory(control, expressionPath, updateSourceTrigger);
+ }
+
+ public static IObservable observe(Object control, Object value, String fullPath, UpdateSourceTrigger updateSourceTrigger, int observeKind) {
+ return observe(control, value, new BindingExpressionPath(fullPath), updateSourceTrigger, observeKind);
+ }
+
+ public static IObservable observe(Object control, Object value, BindingExpressionPath expressionPath, UpdateSourceTrigger updateSourceTrigger, int observeKind) {
+ if(value == null) {
+ value = control;
+ }
+ ObservableValueBuilder builder = new ObservableValueBuilder(control, null, expressionPath, updateSourceTrigger, observeKind);
+ return builder.observe(value);
+ }
+
+ public static IObservableValue observeValue(Object control, Object value, Class<?> type, BindingExpressionPath expressionPath, UpdateSourceTrigger updateSourceTrigger) {
+ ObservableValueBuilder builder = new ObservableValueBuilder(control, type, expressionPath, updateSourceTrigger, ScopeManager.VALUE);
+ return (IObservableValue)builder.observe(value);
+ }
+
+ public static IValueProperty createValueProperty(Object control, Object type, BindingExpressionPath expressionPath) {
+ IValueProperty valueProperty = null;
+
+ String[] segments = expressionPath.getSegments();
+ if(segments == null || segments.length == 0) {
+ String segment = expressionPath.getFullPath();
+ valueProperty = doCreateValueProperty(type, segment);
+ } else {
+ for(String segment : segments) {
+ IValueProperty segmentValueProperty = doCreateValueProperty(type, segment);
+ if(valueProperty == null) {
+ valueProperty = segmentValueProperty;
+ } else {
+ valueProperty = valueProperty.value(segmentValueProperty);
+ }
+ type = valueProperty.getValueType();
+ }
+ }
+
+ return valueProperty;
+ }
+
+ protected static IValueProperty doCreateValueProperty(Object type, String fullPath) {
+ IDataProvider dataProvider = XWT.findDataProvider(type);
+ return dataProvider.createValueProperty(type, fullPath);
+ }
+
+ /**
+ * Reserved only for the calling from XWTLoader
+ *
+ * @param context
+ * @param data
+ * @param propertyName
+ * @return
+ */
+ public static boolean isPropertyReadOnly(IDataProvider dataProvider, BindingExpressionPath expressionPath) {
+ String[] segments = expressionPath.getSegments();
+ if(segments == null || segments.length == 0) {
+ String segment = expressionPath.getFullPath();
+ return dataProvider.isPropertyReadOnly(segment);
+ } else {
+ Object type = null;
+
+ int last = segments.length - 1;
+ for(int i = 0; i < last; i++) {
+ String segment = segments[i];
+ int length = segment.length();
+ if(length > 1 && segment.charAt(0) == '(' && segment.charAt(length - 1) == ')') {
+ // It is class
+ String path = segment.substring(1, segment.length() - 1);
+ int index = path.lastIndexOf('.');
+ if(index != -1) {
+ String className = path.substring(0, index);
+ segment = path.substring(index + 1);
+ type = dataProvider.getModelService().loadModelType(className);
+ if(type == null) {
+ throw new XWTException("Class " + className + " not found");
+ }
+ dataProvider = XWT.findDataProvider(type);
+ }
+ }
+
+ type = dataProvider.getDataType(segment);
+
+ if(type != null) {
+ dataProvider = XWT.findDataProvider(type);
+ if(dataProvider == null) {
+ throw new XWTException("Data probider is not found for the type " + type.toString());
+ }
+ } else {
+ throw new XWTException("Type is not found for the property " + segment);
+ }
+ }
+ String segment = segments[last];
+
+ int length = segment.length();
+ if(length > 1 && segment.charAt(0) == '(' && segment.charAt(length - 1) == ')') {
+ // It is class
+ String path = segment.substring(1, segment.length() - 1);
+ int index = path.lastIndexOf('.');
+ if(index != -1) {
+ String className = path.substring(0, index);
+ segment = path.substring(index + 1);
+ type = dataProvider.getModelService().loadModelType(className);
+ if(type == null) {
+ throw new XWTException("Class " + className + " not found");
+ }
+ dataProvider = XWT.findDataProvider(type);
+ }
+ }
+ return dataProvider.isPropertyReadOnly(segment);
+ }
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/UIResource.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/UIResource.java
new file mode 100644
index 00000000000..e139c73235b
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/UIResource.java
@@ -0,0 +1,26 @@
+package org.eclipse.papyrus.xwt.internal.core;
+
+import java.net.URL;
+
+import org.eclipse.papyrus.xwt.IUIResource;
+import org.eclipse.papyrus.xwt.internal.xml.Element;
+
+public class UIResource implements IUIResource {
+
+ protected Element content;
+
+ protected URL url;
+
+ public UIResource(URL url, Element content) {
+ this.content = content;
+ this.url = url;
+ }
+
+ public Element getContent() {
+ return content;
+ }
+
+ public URL getURL() {
+ return url;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/UpdateSourceTrigger.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/UpdateSourceTrigger.java
new file mode 100644
index 00000000000..399a682aab8
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/UpdateSourceTrigger.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.core;
+
+/**
+ * <p>
+ * Default
+ * </p>
+ * <p>
+ * The default UpdateSourceTrigger value of the binding target property. The default value for most dependency properties is PropertyChanged, while
+ * the Text property has a default value of LostFocus.
+ * </p>
+ * <p>
+ * A programmatic way to determine the default UpdateSourceTrigger value of a dependency property is to get the property metadata of the property
+ * using GetMetadata and then check the value of the DefaultUpdateSourceTrigger property.
+ * </p>
+ * <p/>
+ * <p>
+ * PropertyChanged
+ * </p>
+ * <p>
+ * Updates the binding source immediately whenever the binding target property changes.
+ * </p>
+ * <p/>
+ * <p>
+ * LostFocus
+ * </p>
+ * <p>
+ * Updates the binding source whenever the binding target element loses focus.
+ * </p>
+ *
+ * @author yyang
+ *
+ */
+public enum UpdateSourceTrigger {
+ Default, PropertyChanged, LostFocus;
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/AbstractMenuItemObservableValue.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/AbstractMenuItemObservableValue.java
new file mode 100644
index 00000000000..e6eb29617ad
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/AbstractMenuItemObservableValue.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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: *
+ * Soyatec - initial API and implementation *
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.databinding.menuitem;
+
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.MenuItem;
+
+/**
+ *
+ * @author yyang (yves.yang@soyatec.com)
+ */
+public abstract class AbstractMenuItemObservableValue extends AbstractObservableValue {
+
+ private final MenuItem menuItem;
+
+ /**
+ * Standard constructor for a MenuItem ObservableValue. Makes sure that the observable gets disposed when the MenuItem is disposed.
+ *
+ * @param widget
+ */
+ protected AbstractMenuItemObservableValue(MenuItem menuItem) {
+ this(SWTObservables.getRealm(menuItem.getDisplay()), menuItem);
+ }
+
+ /**
+ * Constructor that allows for the setting of the realm. Makes sure that the observable gets disposed when the MenuItem is disposed.
+ *
+ * @param realm
+ * @param widget
+ * @since 1.2
+ */
+ protected AbstractMenuItemObservableValue(Realm realm, MenuItem menuItem) {
+ super(realm);
+ this.menuItem = menuItem;
+ menuItem.addDisposeListener(disposeListener);
+ }
+
+ private DisposeListener disposeListener = new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ AbstractMenuItemObservableValue.this.dispose();
+ }
+ };
+
+ /**
+ * @return Returns the MenuItem.
+ */
+ public MenuItem getMenuItem() {
+ return menuItem;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/MenuItemEnabledObservableValue.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/MenuItemEnabledObservableValue.java
new file mode 100644
index 00000000000..decf0505e80
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/MenuItemEnabledObservableValue.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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: *
+ * Soyatec - initial API and implementation *
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.databinding.menuitem;
+
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.swt.widgets.MenuItem;
+
+/**
+ *
+ * @author yyang (yves.yang@soyatec.com)
+ */
+public class MenuItemEnabledObservableValue extends AbstractMenuItemObservableValue {
+
+ public MenuItemEnabledObservableValue(MenuItem menuItem) {
+ super(menuItem);
+ }
+
+ public MenuItemEnabledObservableValue(Realm realm, MenuItem menuItem) {
+ super(realm, menuItem);
+ }
+
+ @Override
+ protected Object doGetValue() {
+ return getMenuItem().getEnabled();
+ }
+
+ public Object getValueType() {
+ return Boolean.class;
+ }
+
+ protected void doSetValue(Object value) {
+ getMenuItem().setEnabled((Boolean)value);
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/MenuItemSelectionObservableValue.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/MenuItemSelectionObservableValue.java
new file mode 100644
index 00000000000..a3efcb2b0fe
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/databinding/menuitem/MenuItemSelectionObservableValue.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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: *
+ * Soyatec - initial API and implementation *
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.databinding.menuitem;
+
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.swt.widgets.MenuItem;
+
+/**
+ *
+ * @author yyang (yves.yang@soyatec.com)
+ */
+public class MenuItemSelectionObservableValue extends AbstractMenuItemObservableValue {
+
+ public MenuItemSelectionObservableValue(MenuItem menuItem) {
+ super(menuItem);
+ }
+
+ public MenuItemSelectionObservableValue(Realm realm, MenuItem menuItem) {
+ super(realm, menuItem);
+ }
+
+ @Override
+ protected Object doGetValue() {
+ return getMenuItem().getSelection();
+ }
+
+ public Object getValueType() {
+ return Boolean.class;
+ }
+
+ protected void doSetValue(Object value) {
+ getMenuItem().setSelection((Boolean)value);
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ClassLoaderUtil.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ClassLoaderUtil.java
new file mode 100644
index 00000000000..577d6f4c2a0
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ClassLoaderUtil.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.utils;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.ILoadingContext;
+import org.eclipse.papyrus.xwt.internal.xml.DocumentObject;
+import org.eclipse.papyrus.xwt.internal.xml.Element;
+
+public class ClassLoaderUtil {
+
+ static final String[] DefaultPackages = new String[]{
+ /*
+ * UIElement.class.getPackage().getName(), Validation.class.getPackage().getName(), Timeline.class.getPackage().getName(),
+ * Binding.class.getPackage().getName(),
+ */};
+
+ static public Class<?> loadClass(ILoadingContext loadingContext, String className) {
+ Class<?> type = doLoadClass(loadingContext, className);
+ if(type != null) {
+ return type;
+ }
+ int index = className.indexOf('.');
+ if(index == -1) {
+ for(String packageName : DefaultPackages) {
+ type = doLoadClass(loadingContext, packageName + "." + className);
+ if(type != null) {
+ return type;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static Class<?> doLoadClass(ILoadingContext loadingContext, String className) {
+ Class<?> type = loadingContext.loadClass(className);
+ if(type != null) {
+ return type;
+ }
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e1) {
+ }
+ return null;
+ }
+
+ static public Object loadMember(ILoadingContext loadingContext, String className, String memberName, boolean raiseException) {
+ Class<?> type = loadClass(loadingContext, className);
+ return loadMember(loadingContext, type, memberName, raiseException);
+ }
+
+ static public Object loadMember(ILoadingContext loadingContext, Class<?> type, String memberName, boolean raiseException) {
+
+ try {
+ Field field = type.getField(memberName);
+ if(raiseException && !Modifier.isStatic(field.getModifiers())) {
+ throw new IllegalStateException(type.getName() + "." + memberName + " is not static member.");
+ }
+ return field.get(null);
+ } catch (Exception e) {
+ if(e instanceof NoSuchFieldException) {
+ Method method = ObjectUtil.findGetter(type, memberName, null);
+ if(raiseException && (method == null || !Modifier.isStatic(method.getModifiers()))) {
+ throw new IllegalStateException(type.getName() + "." + memberName + " is not static member.");
+ }
+ try {
+ return method.invoke(null);
+ } catch (Exception exception) {
+ e = exception;
+ }
+ }
+ if(raiseException) {
+ e.printStackTrace();
+ throw new IllegalStateException(e);
+ }
+ }
+ return null;
+ }
+
+ static public Object loadStaticMember(ILoadingContext loadingContext, Element element) {
+ String name = element.getName();
+ String namespace = element.getNamespace();
+ Object value = doLoadMember(loadingContext, name, namespace);
+ if(value != null) {
+ return value;
+ }
+ String content = element.getContent();
+ if(content == null) {
+ DocumentObject member = element.getAttribute(IConstants.XWT_NAMESPACE, IConstants.XAML_X_STATIC_MEMBER);
+ if(member == null) {
+ member = element;
+ }
+ if(member != null) {
+ content = member.getContent();
+ if(content == null) {
+ for(DocumentObject documentObject : member.getChildren()) {
+ String ns = documentObject.getNamespace();
+ String n = documentObject.getName();
+ return doLoadMember(loadingContext, n, ns);
+ }
+ }
+ }
+ } else {
+ if(IConstants.XAML_X_STATIC.equals(name) && IConstants.XWT_X_NAMESPACE.equals(namespace)) {
+ namespace = IConstants.XWT_NAMESPACE;
+ return doLoadMember(loadingContext, content, namespace);
+ }
+ }
+ // TODO
+ return null;
+ }
+
+ protected static Object doLoadMember(ILoadingContext loadingContext, String name, String namespace) {
+ int lastIndex = name.lastIndexOf('.');
+ if(lastIndex == -1) {
+ throw new IllegalStateException("Separator '.' is missing in:" + name);
+ }
+ String className = name.substring(0, lastIndex);
+ String memberName = name.substring(lastIndex + 1);
+
+ try {
+ Class<?> type = NamespaceHelper.loadCLRClass(loadingContext, className, namespace);
+ if(type != null) {
+ return ClassLoaderUtil.loadMember(loadingContext, type, memberName, true);
+ }
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/DocumentObjectSorter.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/DocumentObjectSorter.java
new file mode 100644
index 00000000000..9330cfb1b2e
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/DocumentObjectSorter.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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: *
+ * Soyatec - initial API and implementation *
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.utils;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.papyrus.xwt.internal.xml.Attribute;
+import org.eclipse.papyrus.xwt.internal.xml.DocumentObject;
+import org.eclipse.papyrus.xwt.internal.xml.Element;
+
+public class DocumentObjectSorter {
+
+ public static List<DocumentObject> sortWithAttr(DocumentObject[] sourceArray, String attrName) {
+ return sortWithAttr(sourceArray, new AttrComparator(attrName), attrName);
+ }
+
+ public static List<DocumentObject> sortWithAttr(DocumentObject[] sourceArray, Comparator<Element> comparator, String attrName) {
+ List<DocumentObject> columnsList = new LinkedList<DocumentObject>();
+ for(DocumentObject column : sourceArray) {
+ Element columnElement = (Element)column;
+ Attribute indexAttr = columnElement.getAttribute(attrName);
+ if(indexAttr == null) {
+ columnsList.add(column);
+ }
+ }
+
+ List<Element> tempList = new LinkedList<Element>();
+ for(DocumentObject column : sourceArray) {
+ Element columnElement = (Element)column;
+ Attribute indexAttr = columnElement.getAttribute(attrName);
+ if(indexAttr != null) {
+ tempList.add(columnElement);
+ }
+ }
+
+ if(comparator == null) {
+ comparator = new AttrComparator(attrName);
+ }
+ Collections.sort(tempList, comparator);
+
+ for(Element columnElement : tempList) {
+ Attribute indexAttr = columnElement.getAttribute(attrName);
+ try {
+ int index = Integer.parseInt(indexAttr.getContent());
+ columnsList.add(index, columnElement);
+ } catch (Exception e) {
+ columnsList.add(columnsList.size(), columnElement);
+ }
+ }
+
+ return columnsList;
+ }
+
+ private static class AttrComparator implements Comparator<Element>, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String attrName;
+
+ public AttrComparator(String attrName) {
+ this.attrName = attrName;
+ }
+
+ public int compare(Element e1, Element e2) {
+ Attribute attr1 = e1.getAttribute(attrName);
+ Attribute attr2 = e2.getAttribute(attrName);
+ String compare1 = attr1.getContent();
+ String compare2 = attr2.getContent();
+ if(compare1 == null || compare2 == null) {
+ return 0;
+ }
+ try {
+ int index1 = Integer.parseInt(compare1);
+ int index2 = Integer.parseInt(compare2);
+ return index1 > index2 ? 1 : -1;
+ } catch (Exception e) {
+ return compare1.compareTo(compare2);
+ }
+ }
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/LoggerManager.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/LoggerManager.java
new file mode 100644
index 00000000000..9f70cc9512f
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/LoggerManager.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.papyrus.xwt.internal.utils;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Logger Manager.
+ *
+ * @author jliu
+ */
+public class LoggerManager {
+
+ private static Logger logger = Logger.getLogger("org.eclipse.papyrus.xwt.utils.LoggerManager");
+
+ private LoggerManager() {
+ }
+
+ public static void log(Throwable e, String message) {
+ logger.log(Level.SEVERE, message, e);
+ }
+
+ public static void log(Throwable e) {
+ log(e, null);
+ }
+
+ public static void log(String message) {
+ log(null, message);
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/NamespaceHelper.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/NamespaceHelper.java
new file mode 100644
index 00000000000..553340a1eb7
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/NamespaceHelper.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.utils;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.ILoadingContext;
+
+public class NamespaceHelper {
+
+ static public Class<?> loadCLRClass(ILoadingContext loadingContext, String name, String namespace) throws ClassNotFoundException {
+ // xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary"
+ if(namespace.startsWith(IConstants.XAML_CLR_NAMESPACE_PROTO)) {
+ String contentSegment = namespace.substring(IConstants.XAML_CLR_NAMESPACE_PROTO.length());
+ String packageName = contentSegment;
+ String assembly = null;
+ int index = contentSegment.indexOf(";");
+ if(index != -1) {
+ packageName = contentSegment.substring(0, index);
+ contentSegment = contentSegment.substring(index + 1);
+ if(contentSegment.startsWith(IConstants.XAML_CLR_ASSEMBLY)) {
+ assembly = contentSegment.substring(IConstants.XAML_CLR_ASSEMBLY.length());
+ } else {
+ throw new IllegalStateException(IConstants.XAML_CLR_ASSEMBLY);
+ }
+ }
+ if(assembly != null) {
+ // TODO Load jar using URLClassLoader
+ }
+ if(packageName != null && packageName.length() > 0) {
+ name = packageName + "." + name;
+ }
+ return ClassLoaderUtil.loadClass(loadingContext, name);
+ }
+ return null;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ObjectUtil.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ObjectUtil.java
new file mode 100644
index 00000000000..227a54ae30d
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ObjectUtil.java
@@ -0,0 +1,399 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.utils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.databinding.conversion.IConverter;
+import org.eclipse.papyrus.xwt.XWT;
+
+/**
+ * Object Tools.
+ *
+ * @author yyang (yves.yang@soyatec.com)
+ * @version 1.0
+ */
+public class ObjectUtil {
+
+ public static final Class<?>[] EMPTY = new Class[0];
+
+ private ObjectUtil() {
+ }
+
+ public static Class<?> normalizedType(Class<?> type) {
+ if(type == int.class) {
+ return Integer.class;
+ }
+ if(type == double.class) {
+ return Double.class;
+ }
+ if(type == float.class) {
+ return Float.class;
+ }
+ if(type == boolean.class) {
+ return Boolean.class;
+ }
+ return type;
+ }
+
+ public static boolean isAssignableFrom(Class<?> source, Class<?> target) {
+ if(normalizedType(source) == normalizedType(target)) {
+ return true;
+ }
+ return source.isAssignableFrom(target);
+ }
+
+ /**
+ * Find the compatible class. This includes superclasses, interfaces and so on.
+ *
+ * @param clazz
+ * the specified class.
+ * @return Returns the class array includes its superclasses, interfaces and itself.
+ */
+ public static final Class<?>[] findCompatibleClasses(Class<?> clazz) {
+ Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
+
+ // Add itself to list.
+ classes.add(clazz);
+
+ // Add primitive compatible type
+ if(clazz == Boolean.class) {
+ classes.add(boolean.class);
+ } else if(clazz == Byte.class) {
+ classes.add(byte.class);
+ } else if(clazz == Short.class) {
+ classes.add(short.class);
+ } else if(clazz == Integer.class) {
+ classes.add(int.class);
+ } else if(clazz == Long.class) {
+ classes.add(long.class);
+ } else if(clazz == Float.class) {
+ classes.add(float.class);
+ } else if(clazz == Double.class) {
+ classes.add(double.class);
+ } else if(clazz == Character.class) {
+ classes.add(char.class);
+ } else if(clazz == boolean.class) {
+ classes.add(Boolean.class);
+ } else if(clazz == byte.class) {
+ classes.add(Byte.class);
+ } else if(clazz == short.class) {
+ classes.add(Short.class);
+ } else if(clazz == int.class) {
+ classes.add(Integer.class);
+ } else if(clazz == long.class) {
+ classes.add(Long.class);
+ } else if(clazz == float.class) {
+ classes.add(Float.class);
+ } else if(clazz == double.class) {
+ classes.add(Double.class);
+ } else if(clazz == char.class) {
+ classes.add(Character.class);
+ }
+
+ // Add its interfaces
+ findInterfaces(classes, clazz);
+
+ // Add its superclasses
+ findSuperClasses(classes, clazz);
+
+ // At last, add Object class.
+ classes.add(Object.class);
+
+ return classes.toArray(EMPTY);
+ }
+
+ public static Object resolveValue(Object value, Class<?> targetType, Object defaultValue) {
+ return resolveValue(value, value.getClass(), targetType, defaultValue);
+ }
+
+ public static Object resolveValue(Object value, Class<?> sourceType, Class<?> targetType, Object defaultValue) {
+ IConverter converter = XWT.findConvertor(sourceType, targetType);
+ if(converter != null) {
+ return converter.convert(value);
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Find compatible constructor for specified class.
+ *
+ * @param clazz
+ * the specified class.
+ * @param argumentTypes
+ * constructor argument types.
+ * @return Returns constructor instance. If snot find, returns null.
+ */
+ public static final Constructor<?> findConstructor(Class<?> clazz, Class<?>... argumentTypes) {
+
+ Class<?>[][] classesArray = new Class[argumentTypes.length][];
+
+ for(int i = 0, len = argumentTypes.length; i < len; i++) {
+ Class<?>[] classes = findCompatibleClasses(argumentTypes[i]);
+ classesArray[i] = classes;
+ }
+
+ int totalPossibles = 1;
+ for(int i = 0; i < classesArray.length; i++) {
+ totalPossibles *= classesArray[i].length;
+ }
+
+ List<Class<?>[]> classList = new ArrayList<Class<?>[]>(totalPossibles);
+ computeArguments(classList, classesArray, new Class[classesArray.length], 0);
+
+ for(Class<?>[] arguments : classList) {
+ try {
+ return clazz.getConstructor(arguments);
+ } catch (NoSuchMethodException e) {
+ continue;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Find compatible public method for specified class.
+ *
+ * @param clazz
+ * the specified class.
+ * @param name
+ * method name.
+ * @param argumentTypes
+ * method argument types. If it is a null value, system will find method without argument types.
+ * @return Returns method instance. If not find, returns null.
+ */
+ public static final Method findMethod(Class<?> clazz, String name, Class<?>... argumentTypes) {
+
+ if(argumentTypes != null && argumentTypes.length > 0) {
+
+ Class<?>[][] classesArray = new Class[argumentTypes.length][];
+
+ for(int i = 0, len = argumentTypes.length; i < len; i++) {
+ Class<?>[] classes = findCompatibleClasses(argumentTypes[i]);
+ classesArray[i] = classes;
+ }
+
+ int totalPossibles = 1;
+ for(int i = 0; i < classesArray.length; i++) {
+ totalPossibles *= classesArray[i].length;
+ }
+
+ List<Class<?>[]> classList = new ArrayList<Class<?>[]>(totalPossibles);
+ computeArguments(classList, classesArray, new Class[classesArray.length], 0);
+
+ for(Class<?>[] arguments : classList) {
+ try {
+ return clazz.getDeclaredMethod(name, arguments);
+ } catch (NoSuchMethodException e) {
+ continue;
+ }
+ }
+ } else {
+
+ // find method without argument types;
+
+ Method[] methods = clazz.getMethods();
+ for(Method method : methods) {
+ if(method.getName().equals(name)) {
+ return method;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Find compatible method for specified class.
+ *
+ * @param clazz
+ * the specified class.
+ * @param name
+ * method name.
+ * @param argumentTypes
+ * method argument types. If it is a null value, system will find method without argument types.
+ * @return Returns method instance. If not find, returns null.
+ */
+ public static final Method findDeclaredMethod(Class<?> clazz, String name, Class<?>... argumentTypes) {
+
+ if(argumentTypes != null && argumentTypes.length > 0) {
+
+ Class<?>[][] classesArray = new Class[argumentTypes.length][];
+
+ for(int i = 0, len = argumentTypes.length; i < len; i++) {
+ Class<?>[] classes = findCompatibleClasses(argumentTypes[i]);
+ classesArray[i] = classes;
+ }
+
+ int totalPossibles = 1;
+ for(int i = 0; i < classesArray.length; i++) {
+ totalPossibles *= classesArray[i].length;
+ }
+
+ List<Class<?>[]> classList = new ArrayList<Class<?>[]>(totalPossibles);
+ computeArguments(classList, classesArray, new Class[classesArray.length], 0);
+
+ for(Class<?>[] arguments : classList) {
+ try {
+ return clazz.getDeclaredMethod(name, arguments);
+ } catch (NoSuchMethodException e) {
+ continue;
+ }
+ }
+ } else {
+
+ // find method without argument types;
+ Method[] methods = clazz.getDeclaredMethods();
+ for(Method method : methods) {
+ if(method.getName().equals(name) && method.getParameterTypes().length == 0) {
+ return method;
+ }
+ }
+ }
+ Class<?> superclass = clazz.getSuperclass();
+ if(superclass != null) {
+ return findDeclaredMethod(superclass, name, argumentTypes);
+ }
+
+ return null;
+ }
+
+ /**
+ * Find property getter method for specified class.
+ *
+ * @param clazz
+ * the specified class.
+ * @param name
+ * property name
+ * @param type
+ * property type. If it is a null value, system will find the suitable method.
+ * @return Returns method instance. If not find, returns null.
+ */
+ public static final Method findGetter(Class<?> clazz, String name, Class<?> type) {
+ if(name == null || name.length() == 0) {
+ throw new IllegalArgumentException("Invalid getter method name, null value found");
+ }
+
+ String getterName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
+
+ Method method;
+ try {
+ if(clazz.isEnum()) {
+ method = clazz.getClass().getMethod(getterName, EMPTY);
+ } else {
+ method = clazz.getMethod(getterName, EMPTY);
+ }
+ } catch (NoSuchMethodException e1) {
+
+ // :Check if it is a boolean getter
+ getterName = "is" + name.substring(0, 1).toUpperCase() + name.substring(1);
+ try {
+ method = clazz.getMethod(getterName, EMPTY);
+ if(method.getReturnType() != Boolean.class && method.getReturnType() != boolean.class) {
+ return null;
+ }
+ } catch (NoSuchMethodException e2) {
+ method = findCaseIgnoreGetter(clazz, name, type);
+ }
+ // :~
+ }
+
+ if(type == null) {
+ return method;
+ } else {
+ if(method != null) {
+ Class<?> returnType = method.getReturnType();
+ Class<?>[] types = findCompatibleClasses(type);
+ for(Class<?> t : types) {
+ if(t == returnType) {
+ return method;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static Method findCaseIgnoreGetter(Class<?> clazz, String name, Class<?> type) {
+ String getterName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
+ String isName = "is" + name.substring(0, 1).toUpperCase() + name.substring(1);
+
+ for(Method element : clazz.getMethods()) {
+ if(element.getParameterTypes().length != 0) {
+ continue;
+ }
+ if(element.getName().equalsIgnoreCase(getterName)) {
+ return element;
+ }
+ if(element.getName().equalsIgnoreCase(isName) && element.getReturnType() != Boolean.class && element.getReturnType() != boolean.class) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Find superclasses and add them to list.
+ */
+ private static void findSuperClasses(Set<Class<?>> list, Class<?> clazz) {
+ if(clazz != null) {
+ Class<?> superClass = clazz.getSuperclass();
+
+ if(superClass != Object.class) {
+ list.add(superClass);
+
+ findInterfaces(list, superClass);
+
+ findSuperClasses(list, superClass);
+ }
+ }
+ }
+
+ /**
+ * Find interfaces and add them to list.
+ */
+ private static void findInterfaces(Set<Class<?>> list, Class<?> clazz) {
+ if(clazz != null) {
+ Class<?>[] interfaces = clazz.getInterfaces();
+
+ for(Class<?> interfac1 : interfaces) {
+ list.add(interfac1);
+ findInterfaces(list, interfac1);
+ }
+ }
+ }
+
+ /**
+ * Combine arithmetic.
+ */
+ private static void computeArguments(List<Class<?>[]> list, Class<?>[][] arguments, Class<?>[] buffer, int start) {
+ if(start >= arguments.length) {
+ Class<?>[] classes = new Class<?>[arguments.length];
+ for(int i = 0; i < arguments.length; ++i) {
+ classes[i] = buffer[i];
+ }
+ list.add(classes);
+ return;
+ }
+
+ for(int i = 0; i < arguments[start].length; ++i) {
+ buffer[start] = arguments[start][i];
+ computeArguments(list, arguments, buffer, start + 1);
+ }
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ObservableValueManager.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ObservableValueManager.java
new file mode 100644
index 00000000000..26e8b359e0b
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/ObservableValueManager.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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 API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.utils;
+
+import java.util.HashMap;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.papyrus.xwt.IEventGroup;
+import org.eclipse.papyrus.xwt.IObservableValueListener;
+import org.eclipse.papyrus.xwt.XWT;
+import org.eclipse.papyrus.xwt.javabean.metadata.properties.EventProperty;
+import org.eclipse.papyrus.xwt.metadata.IMetaclass;
+import org.eclipse.papyrus.xwt.metadata.IProperty;
+import org.eclipse.papyrus.xwt.metadata.ModelUtils;
+import org.eclipse.swt.widgets.Event;
+
+public class ObservableValueManager implements IObservableValueListener {
+
+ protected HashMap<String, IObservableValue> map;
+
+ protected Object host;
+
+ public ObservableValueManager(Object host) {
+ this.host = host;
+ }
+
+ public Object getHost() {
+ return host;
+ }
+
+ public void changeValueHandle(Object object, Event event) {
+ // TODO the cast is not clean.
+ EventProperty property = (EventProperty)object;
+ IObservableValue value = map.get(property.getName());
+ if(value != null) {
+ Boolean oldValue = (Boolean)value.getValue();
+ if(oldValue == null) {
+ oldValue = false;
+ }
+ value.setValue(!oldValue);
+ }
+
+ IMetaclass metaclass = XWT.getMetaclass(host);
+
+ // TODO this conversion should be simplied
+ String eventName = ModelUtils.normalizePropertyName(property.getEvent().getName());
+ IEventGroup eventGroup = metaclass.getEventGroup(eventName);
+ if(eventGroup != null) {
+ eventGroup.fireEvent(this, property);
+ }
+ }
+
+ public void registerValue(IProperty property, IObservableValue observableValue) {
+ if(map == null) {
+ map = new HashMap<String, IObservableValue>();
+ }
+ map.put(property.getName(), observableValue);
+
+ IMetaclass metaclass = XWT.getMetaclass(host);
+ // TODO it is not clean.
+ EventProperty eventProperty = (EventProperty)property;
+
+ // TODO this conversion should be simplied
+ String eventName = ModelUtils.normalizePropertyName(eventProperty.getEvent().getName());
+ IEventGroup eventGroup = metaclass.getEventGroup(eventName);
+ if(eventGroup != null) {
+ eventGroup.registerEvent(this, property);
+ }
+ }
+
+ public IObservableValue getValue(IProperty property) {
+ if(map == null) {
+ return null;
+ }
+ return map.get(property.getName());
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/TableEditorHelper.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/TableEditorHelper.java
new file mode 100644
index 00000000000..10c974074a2
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/TableEditorHelper.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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: *
+ * Soyatec - initial API and implementation *
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.utils;
+
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+
+public class TableEditorHelper {
+
+ public static void initEditor(final TableItem tableItem, Control editor, final int column) {
+ if(editor instanceof Text) {
+ final Text text = (Text)editor;
+ text.setText(tableItem.getText(column));
+ text.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ tableItem.setText(column, text.getText());
+ }
+ });
+ } else if(editor instanceof CCombo) {
+ final CCombo combo = (CCombo)editor;
+ combo.setText(tableItem.getText(column));
+ combo.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ tableItem.setText(column, combo.getText());
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ tableItem.setText(column, combo.getItem(combo.getSelectionIndex()));
+ }
+ });
+ } else if(editor instanceof Combo) {
+ final Combo combo = (Combo)editor;
+ combo.setText(tableItem.getText(column));
+ combo.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ tableItem.setText(column, combo.getText());
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ tableItem.setText(column, combo.getItem(combo.getSelectionIndex()));
+ }
+ });
+ }
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/UserData.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/UserData.java
new file mode 100644
index 00000000000..1c7c7e05275
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/utils/UserData.java
@@ -0,0 +1,699 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.utils;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.xwt.IObservableValueListener;
+import org.eclipse.papyrus.xwt.XWT;
+import org.eclipse.papyrus.xwt.core.IUserDataConstants;
+import org.eclipse.papyrus.xwt.core.TriggerBase;
+import org.eclipse.papyrus.xwt.databinding.BindingContext;
+import org.eclipse.papyrus.xwt.databinding.IBindingContext;
+import org.eclipse.papyrus.xwt.internal.core.IEventController;
+import org.eclipse.papyrus.xwt.internal.core.ScopeKeeper;
+import org.eclipse.papyrus.xwt.javabean.Controller;
+import org.eclipse.papyrus.xwt.jface.JFacesHelper;
+import org.eclipse.papyrus.xwt.metadata.IProperty;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.custom.ControlEditor;
+import org.eclipse.swt.custom.TableTreeItem;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.CoolItem;
+import org.eclipse.swt.widgets.ExpandItem;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swt.widgets.ToolTip;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+
+public class UserData {
+
+ private HashMap<Object, Object> dictionary = null;
+
+ private IObservableValueListener observableValueManager;
+
+ protected IObservableValueListener getObservableValueManager() {
+ return observableValueManager;
+ }
+
+ protected void setObservableValueManager(IObservableValueListener observableValueManager) {
+ this.observableValueManager = observableValueManager;
+ }
+
+ public void setData(Object key, Object value) {
+ if(dictionary == null) {
+ dictionary = new HashMap<Object, Object>();
+ }
+ dictionary.put(key, value);
+ if(observableValueManager != null && (key instanceof IProperty)) {
+ IObservableValue observableValue = observableValueManager.getValue((IProperty)key);
+ observableValue.setValue(value);
+ }
+ }
+
+ public Object getData(Object key) {
+ if(dictionary == null) {
+ return null;
+ }
+ return dictionary.get(key);
+ }
+
+ public Object removeData(Object key) {
+ if(dictionary == null) {
+ return null;
+ }
+ return dictionary.remove(key);
+ }
+
+ public boolean containsKey(Object key) {
+ if(dictionary == null) {
+ return false;
+ }
+ return dictionary.containsKey(key);
+ }
+
+ public Collection<Object> keySet() {
+ if(dictionary == null) {
+ return Collections.emptyList();
+ }
+ return dictionary.keySet();
+ }
+
+ public static boolean isUIElementType(Object element) {
+ if(element instanceof Class<?>) {
+ Class<?> elementType = (Class<?>)element;
+ return Widget.class.isAssignableFrom(elementType) || Viewer.class.isAssignableFrom(elementType) || ControlEditor.class.isAssignableFrom(elementType);
+ }
+ return false;
+ }
+
+ public static void bindNameContext(Object element, ScopeKeeper nameContext) {
+ Widget widget = getWidget(element);
+ if(widget == null) {
+ return;
+ }
+ UserData dataDictionary = updateDataDictionary(widget);
+ if(dataDictionary.getData(IUserDataConstants.XWT_NAMECONTEXT_KEY) != null) {
+ throw new IllegalStateException("Name context is already set");
+ }
+ dataDictionary.setData(IUserDataConstants.XWT_NAMECONTEXT_KEY, nameContext);
+ }
+
+ protected static UserData updateDataDictionary(Object target) {
+ Widget widget = getWidget(target);
+ if(widget == null) {
+ return null;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary == null) {
+ dataDictionary = new UserData();
+ widget.setData(IUserDataConstants.XWT_USER_DATA_KEY, dataDictionary);
+ }
+ return dataDictionary;
+ }
+
+ public static Shell findShell(Object element) {
+ Widget widget = getWidget(element);
+ if(widget == null) {
+ return null;
+ }
+ if(widget instanceof Shell) {
+ return (Shell)widget;
+ }
+ Control parent = (Control)findParent(widget, Control.class);
+ if(parent != null) {
+ return parent.getShell();
+ }
+ return null;
+ }
+
+ /**
+ * Find the root widget used by XWT. In fact, it tries to find the root
+ * ScopeKeeper
+ *
+ * @param element
+ * @return
+ */
+ public static Widget findRootWidget(Object element) {
+ Widget root = null;
+ Widget current = getWidget(element);
+ while(current != null) {
+ ScopeKeeper scopeKeeper = findScopeKeeper(current);
+ if(scopeKeeper != null) {
+ root = current;
+ }
+ current = getTreeParent(current);
+ }
+
+ return root;
+ }
+
+ public static Composite findCompositeParent(Object element) {
+ Widget widget = getWidget(element);
+ if(widget == null) {
+ return null;
+ }
+ Control control = getParent(widget);
+ while(control != null && !(control instanceof Composite)) {
+ control = getParent(control);
+ }
+ return (Composite)control;
+ }
+
+ public static Object findParent(Widget element, Class<?> type) {
+ Widget widget = getTreeParent(element);
+ while(widget != null && !(type.isInstance(widget))) {
+ widget = getTreeParent(widget);
+ }
+ return widget;
+ }
+
+ public static ScopeKeeper findScopeKeeper(Object element) {
+ ScopeKeeper scopeKeeper = getLocalScopeKeeper(element);
+ if(scopeKeeper != null) {
+ return scopeKeeper;
+ }
+ Widget parent = getTreeParent(element);
+ if(parent != null && !parent.isDisposed()) {
+ return findScopeKeeper(parent);
+ }
+ return null;
+ }
+
+ public static Widget findScopeRoot(Object element) {
+ Widget widget = getWidget(element);
+ if(widget == null) {
+ return null;
+ }
+
+ Widget current = widget;
+ while(current != null) {
+ UserData dataDictionary = (UserData)current.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ Object data = dataDictionary.getData(IUserDataConstants.XWT_NAMECONTEXT_KEY);
+ if(data != null) {
+ return current;
+ }
+ }
+
+ current = getTreeParent(current);
+ }
+
+ return null;
+ }
+
+ public static ScopeKeeper getLocalScopeKeeper(Object element) {
+ Widget widget = getWidget(element);
+ if(widget == null) {
+ return null;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ Object data = dataDictionary.getData(IUserDataConstants.XWT_NAMECONTEXT_KEY);
+ if(data != null) {
+ return (ScopeKeeper)data;
+ }
+ }
+ return null;
+ }
+
+ public static Object findElementByName(Object context, String name) {
+ Widget widget = getWidget(context);
+ if(widget == null) {
+ return null;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ ScopeKeeper nameContext = (ScopeKeeper)dataDictionary.getData(IUserDataConstants.XWT_NAMECONTEXT_KEY);
+ if(nameContext != null) {
+ Object element = nameContext.getNamedObject(name);
+ if(element != null) {
+ return element;
+ }
+ }
+ }
+ Widget parent = getTreeParent(widget);
+ if(parent != null) {
+ return findElementByName(parent, name);
+ }
+ return null;
+ }
+
+ public static String getElementName(Object object) {
+ Widget widget = getWidget(object);
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ return (String)dataDictionary.getData(IUserDataConstants.XWT_NAME_KEY);
+ }
+ return null;
+ }
+
+ public static void setElementName(Object object, String name, boolean updateScope) {
+ Widget widget = getWidget(object);
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ dataDictionary.setData(IUserDataConstants.XWT_NAME_KEY, name);
+ if(updateScope) {
+ ScopeKeeper keeper = findScopeKeeper(object);
+ if(keeper != null) {
+ keeper.addNamedObject(name, object);
+ }
+ }
+ }
+ }
+
+ public static void setCLR(Object widget, Object type) {
+ setLocalData(widget, IUserDataConstants.XWT_CLR_KEY, type);
+ }
+
+ public static Object getCLR(Object element) {
+ Widget widget = getWidget(element);
+ if(widget == null) {
+ return null;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ Object data = dataDictionary.getData(IUserDataConstants.XWT_CLR_KEY);
+ if(data != null) {
+ return data;
+ }
+ }
+ Widget parent = getParent(widget);
+ if(parent != null) {
+ return getCLR(parent);
+ }
+ return null;
+ }
+
+ public static Widget getTreeParent(Object element) {
+ Widget widget = getWidget(element);
+ if(widget == null) {
+ return null;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ widget = (Widget)dataDictionary.getData(IUserDataConstants.XWT_PARENT_KEY);
+ if(widget != null) {
+ return widget;
+ }
+ }
+ return getParent(element);
+ }
+
+ public static Control getParent(Object element) {
+ Widget widget = getWidget(element);
+ if(widget instanceof Control) {
+ Control control = (Control)widget;
+ return control.getParent();
+ } else if(widget instanceof Menu) {
+ Menu item = (Menu)widget;
+ return item.getParent();
+ } else if(widget instanceof MenuItem) {
+ MenuItem item = (MenuItem)widget;
+ Menu menu = item.getParent();
+ if(menu == null) {
+ return null;
+ }
+ return menu.getParent();
+ } else if(widget instanceof ScrollBar) {
+ ScrollBar item = (ScrollBar)widget;
+ return item.getParent();
+ } else if(widget instanceof ToolTip) {
+ ToolTip item = (ToolTip)widget;
+ return item.getParent();
+ } else if(widget instanceof CoolItem) {
+ CoolItem item = (CoolItem)widget;
+ return item.getParent();
+ } else if(widget instanceof CTabItem) {
+ CTabItem item = (CTabItem)widget;
+ return item.getParent();
+ } else if(widget instanceof ExpandItem) {
+ ExpandItem item = (ExpandItem)widget;
+ return item.getParent();
+ } else if(widget instanceof TabItem) {
+ TabItem item = (TabItem)widget;
+ return item.getParent();
+ } else if(widget instanceof TableColumn) {
+ TableColumn item = (TableColumn)widget;
+ return item.getParent();
+ } else if(widget instanceof TableItem) {
+ TableItem item = (TableItem)widget;
+ return item.getParent();
+ } else if(widget instanceof TableTreeItem) {
+ TableTreeItem item = (TableTreeItem)widget;
+ return item.getParent();
+ } else if(widget instanceof ToolItem) {
+ ToolItem item = (ToolItem)widget;
+ return item.getParent();
+ } else if(widget instanceof TreeColumn) {
+ TreeColumn item = (TreeColumn)widget;
+ return item.getParent();
+ } else if(widget instanceof TreeItem) {
+ TreeItem item = (TreeItem)widget;
+ return item.getParent();
+ } else if(widget instanceof Caret) {
+ Caret item = (Caret)widget;
+ return item.getParent();
+ }
+ return null;
+ }
+
+ public static IEventController findEventController(Object widget) {
+ return (IEventController)findData(widget, IUserDataConstants.XWT_CONTROLLER_KEY);
+ }
+
+ public static Object getDataContext(Object widget) {
+ return findData(widget, IUserDataConstants.XWT_DATACONTEXT_KEY);
+ }
+
+ public static IBindingContext getBindingContext(Object widget) {
+ return (IBindingContext)findData(widget, IUserDataConstants.XWT_BINDING_CONTEXT_KEY);
+ }
+
+ public static TriggerBase[] getTriggers(Object element) {
+ Widget widget = getWidget(element);
+ if(widget == null) {
+ return TriggerBase.EMPTY_ARRAY;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ TriggerBase[] triggers = (TriggerBase[])dataDictionary.getData(IUserDataConstants.XWT_TRIGGERS_KEY);
+ if(triggers != null) {
+ return triggers;
+ }
+ }
+ return TriggerBase.EMPTY_ARRAY;
+ }
+
+ public static void setTriggers(Object widget, TriggerBase[] triggers) {
+ setLocalData(widget, IUserDataConstants.XWT_TRIGGERS_KEY, triggers);
+ }
+
+ public static Widget getDataContextHost(Object element) {
+ Widget widget = getWidget(element);
+ if(widget == null) {
+ return null;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ Object host = null;
+ if(dataDictionary != null) {
+ host = dataDictionary.getData(IUserDataConstants.XWT_DATACONTEXT_KEY);
+ if(host != null) {
+ return widget;
+ }
+ }
+ Widget parent = widget;
+ while(parent != null) {
+ dataDictionary = (UserData)parent.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ host = dataDictionary.getData(IUserDataConstants.XWT_DATACONTEXT_KEY);
+ if(host != null) {
+ return parent;
+ }
+ parent = (Widget)dataDictionary.getData(IUserDataConstants.XWT_PARENT_KEY);
+ } else {
+ parent = getParent(parent);
+ }
+ }
+ return null;
+ }
+
+ public static void setBindingContext(Object widget, Object bindingContext) {
+ setLocalData(widget, IUserDataConstants.XWT_BINDING_CONTEXT_KEY, bindingContext);
+ }
+
+ public static void setDataContext(Object widget, Object dataContext) {
+ setLocalData(widget, IUserDataConstants.XWT_DATACONTEXT_KEY, dataContext);
+ }
+
+ public static Widget getWidget(Object target) {
+ if(JFacesHelper.isViewer(target)) {
+ return JFacesHelper.getControl(target);
+ } else if(target instanceof Widget) {
+ return (Widget)target;
+ } else if(target instanceof TableViewerColumn) {
+ return ((TableViewerColumn)target).getColumn();
+ } else if(target instanceof ControlEditor) {
+ return ((ControlEditor)target).getEditor();
+ }
+ return null;
+ }
+
+ public static Viewer getLocalViewer(Object object) {
+ return (Viewer)getLocalData(object, IUserDataConstants.XWT_VIEWER_KEY);
+ }
+
+ public static Object getLocalDataContext(Object object) {
+ return getLocalData(object, IUserDataConstants.XWT_DATACONTEXT_KEY);
+ }
+
+ public static boolean hasLocalDataContext(Object object) {
+ return hasLocalData(object, IUserDataConstants.XWT_DATACONTEXT_KEY);
+ }
+
+ public static Object getLocalData(Object object, IProperty property) {
+ Widget widget = getWidget(object);
+ if(widget == null) {
+ return null;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary == null) {
+ return null;
+ }
+ return dataDictionary.getData(property);
+ }
+
+ public static Object getLocalData(Object object, String key) {
+ Widget widget = getWidget(object);
+ if(widget == null) {
+ return null;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary == null) {
+ return null;
+ }
+ return dataDictionary.getData(key);
+ }
+
+ public static boolean hasLocalData(Object object, String propertyName) {
+ Widget widget = getWidget(object);
+ if(widget == null) {
+ return false;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary == null) {
+ return false;
+ }
+ return dataDictionary.containsKey(propertyName);
+ }
+
+ public static boolean hasLocalData(Object object, IProperty property) {
+ Widget widget = getWidget(object);
+ if(widget == null) {
+ return false;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary == null) {
+ return false;
+ }
+ return dataDictionary.containsKey(property);
+ }
+
+ public static void removeLocalData(Object object, IProperty property) {
+ Widget widget = getWidget(object);
+ if(widget == null) {
+ return;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary == null) {
+ return;
+ }
+ dataDictionary.removeData(property);
+ }
+
+ public static void removeLocalData(Object object, String key) {
+ Widget widget = getWidget(object);
+ if(widget == null) {
+ return;
+ }
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary == null) {
+ return;
+ }
+ dataDictionary.removeData(key);
+ }
+
+ public static Map<String, Object> getLocalResources(Object object) {
+ return (Map<String, Object>)getLocalData(object, IUserDataConstants.XWT_RESOURCES_KEY);
+ }
+
+ public static Object findResource(Object object, String key) {
+ Map<String, Object> map = (Map<String, Object>)getLocalData(object, IUserDataConstants.XWT_RESOURCES_KEY);
+ if(map.containsKey(key)) {
+ return map.get(key);
+ }
+
+ Object parent = getTreeParent(object);
+ if(parent != null) {
+ return findResource(parent, key);
+ }
+ return null;
+ }
+
+ public static void setResources(Object object, Map<?, ?> resources) {
+ setLocalData(object, IUserDataConstants.XWT_RESOURCES_KEY, resources);
+ }
+
+ public static void setParent(Object object, Object parent) {
+ setLocalData(object, IUserDataConstants.XWT_PARENT_KEY, parent);
+ }
+
+ public static void setViewer(Object object, Object parent) {
+ setLocalData(object, IUserDataConstants.XWT_VIEWER_KEY, parent);
+ }
+
+ public static void setEventController(Object object, IEventController controller) {
+ setLocalData(object, IUserDataConstants.XWT_CONTROLLER_KEY, controller);
+ }
+
+ public static IEventController updateEventController(Object object) {
+ UserData dataDictionary = updateDataDictionary(object);
+ IEventController controller = (IEventController)dataDictionary.getData(IUserDataConstants.XWT_CONTROLLER_KEY);
+ if(controller == null) {
+ controller = new Controller();
+ dataDictionary.setData(IUserDataConstants.XWT_CONTROLLER_KEY, controller);
+ }
+ return controller;
+ }
+
+ public static void setLocalData(Object object, String key, Object value) {
+ UserData dataDictionary = updateDataDictionary(object);
+ dataDictionary.setData(key, value);
+ }
+
+ public static void setLocalData(Object object, IProperty property, Object value) {
+ UserData dataDictionary = updateDataDictionary(object);
+ dataDictionary.setData(property, value);
+ }
+
+ public static IObservableValueListener getObservableValueManager(Object object) {
+ Widget widget = getWidget(object);
+ if(widget == null) {
+ return null;
+ }
+
+ UserData userData = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(userData != null) {
+ return userData.getObservableValueManager();
+ }
+ return null;
+ }
+
+ public static void setObservableValueManager(Object object, IObservableValueListener eventManager) {
+ Widget widget = getWidget(object);
+ if(widget == null) {
+ throw new IllegalStateException("Not SWT Widget");
+ }
+ UserData userData = updateDataDictionary(object);
+ userData.setObservableValueManager(eventManager);
+ }
+
+ public static Object findData(Object object, String key) {
+ Widget widget = getWidget(object);
+ if(widget == null) {
+ return Collections.EMPTY_MAP;
+ }
+
+ UserData dataDictionary = (UserData)widget.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ Object resources = null;
+ if(dataDictionary != null) {
+ resources = dataDictionary.getData(key);
+ if(resources != null) {
+ return resources;
+ }
+ }
+ Widget parent = widget;
+ while(parent != null) {
+ dataDictionary = (UserData)parent.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ resources = dataDictionary.getData(key);
+ if(resources != null) {
+ return resources;
+ }
+ parent = (Widget)dataDictionary.getData(IUserDataConstants.XWT_PARENT_KEY);
+ } else {
+ parent = getParent(parent);
+ }
+ }
+ return null;
+ }
+
+ public static Map<?, ?> getResources(Object object) {
+ return (Map<?, ?>)findData(object, IUserDataConstants.XWT_RESOURCES_KEY);
+ }
+
+ public static void setObjectName(Object object, String name) {
+ Widget widget = getWidget(object);
+ ScopeKeeper nameScoped;
+ if(UserData.findElementByName(widget, name) != null) {
+ // throw an exception or log a message?
+ return;
+ }
+ Widget parent = UserData.getTreeParent(widget);
+ UserData dataDictionary = (UserData)parent.getData(IUserDataConstants.XWT_USER_DATA_KEY);
+ if(dataDictionary != null) {
+ if(dataDictionary.getData(IUserDataConstants.XWT_NAMECONTEXT_KEY) != null) {
+ nameScoped = (ScopeKeeper)dataDictionary.getData(IUserDataConstants.XWT_NAMECONTEXT_KEY);
+ } else {
+ ScopeKeeper parentNameScope = findScopeKeeper(parent);
+ nameScoped = new ScopeKeeper(parentNameScope, widget);
+ bindNameContext(parent, nameScoped);
+ }
+ nameScoped.addNamedObject(name, widget);
+ }
+ // throw an exception or log a message?
+ }
+
+ public static IBindingContext createBindingContext(Object host) {
+ Widget widget = getWidget(host);
+ final IBindingContext dataBindingContext = new BindingContext(widget);
+ dataBindingContext.setRealm(XWT.getRealm());
+ widget.addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ dataBindingContext.dispose();
+ }
+ });
+
+ UserData.setLocalData(host, IUserDataConstants.XWT_BINDING_CONTEXT_KEY, dataBindingContext);
+
+ return dataBindingContext;
+ }
+
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/Attribute.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/Attribute.java
new file mode 100644
index 00000000000..6cd357207f4
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/Attribute.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.xml;
+
+import java.util.Collection;
+
+/**
+ * @author yyang
+ * @version 1.0
+ */
+public class Attribute extends Element {
+
+ protected String namePrefix;
+
+ /**
+ * @param manager
+ * @param namespace
+ * @param name
+ * @param id
+ */
+ public Attribute(String namespace, String name, String id) {
+ super(namespace, name, null);
+ assert id != null;
+ setId(id);
+ }
+
+ public Attribute(String namespace, String name, String path, String id, Collection<Attribute> attributes) {
+ super(namespace, name, path, attributes, null);
+ assert id != null;
+ setId(id);
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ Attribute attribute = (Attribute)super.clone();
+ attribute.setId(getId());
+ return attribute;
+ }
+
+ public String getNamePrefix() {
+ return namePrefix;
+ }
+
+ public void setNamePrefix(String namePrefix) {
+ this.namePrefix = namePrefix;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DocumentObject.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DocumentObject.java
new file mode 100644
index 00000000000..dbe01377726
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DocumentObject.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Observable;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.xml.sax.SAXException;
+
+/**
+ * @author yyang
+ * @version 1.0
+ */
+public class DocumentObject extends Observable implements Cloneable {
+
+ private String id;
+
+ private String name;
+
+ private String namespace;
+
+ private String content;
+
+ private List<DocumentObject> children;
+
+ protected DocumentObject parent;
+
+ /**
+ * @param manager
+ * @param namespace
+ * @param name
+ */
+ public DocumentObject(String namespace, String name) {
+ assert namespace != null;
+ assert name != null;
+ this.children = new LinkedList<DocumentObject>();
+ setNamespace(namespace);
+ setName(name);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#addChild(org.soyatec.xaml.IDocumentObject )
+ */
+ public void addChild(DocumentObject child) {
+ assert child != null;
+
+ if(children.add(child)) {
+ DocumentObject oParent = (DocumentObject)(child).getParent();
+ if(oParent != null) {
+ oParent.delChild(child);
+ }
+ // Assign the new parent.
+ ((DocumentObject)child).setParent(this);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#getChildren()
+ */
+ public DocumentObject[] getChildren() {
+ return children.toArray(IConstants.EMPTY_DOCOBJ_ARRAY);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#getContent()
+ */
+ public String getContent() {
+ return content;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#getId()
+ */
+ public String getId() {
+ return id;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#getName()
+ */
+ public String getName() {
+ return name;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#getNamespace()
+ */
+ public String getNamespace() {
+ return namespace;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#hasCildren()
+ */
+ public boolean hasChildren() {
+ return !children.isEmpty();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#include(java.io.InputStream)
+ */
+ public void include(ElementManager elementManager, InputStream input) throws IOException {
+ try {
+ elementManager.load(input, this);
+ } catch (SAXException e) {
+ throw new IOException(e.getLocalizedMessage());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#include(java.lang.String)
+ */
+ public void include(ElementManager elementManager, String path) throws IOException {
+ InputStream input = elementManager.getDocumentRoot().openStream(path);
+ if(input != null) {
+ include(elementManager, input);
+ }
+ input.close();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentObject#setContent(java.lang.String)
+ */
+ public void setContent(String text) {
+ this.content = text;
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ DocumentObject docobj = (DocumentObject)super.clone();
+
+ // Clear object id.
+ docobj.id = null;
+
+ // Clone children.
+ for(DocumentObject child : getChildren()) {
+ DocumentObject nChild = (DocumentObject)child.clone();
+ docobj.addChild(nChild);
+ }
+
+ return docobj;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ protected void setId(String id) {
+ if(this.id != null) {
+ throw new IllegalStateException("Element id is already defined");
+ }
+
+ assert id != null;
+
+ this.id = id;
+ }
+
+ /**
+ * @param namespace
+ * the namespace to set
+ * @uml.property name="namespace"
+ */
+ protected void setNamespace(String namespace) {
+ assert namespace != null : "Element namespace is null";
+ assert this.namespace != null : "Element namepsace is defined";
+
+ this.namespace = namespace;
+ }
+
+ /**
+ * @param name
+ * the name to set
+ * @uml.property name="name"
+ */
+ protected void setName(String name) {
+ assert name != null : "Element name is null";
+ assert this.name != null : "Element name is defined";
+
+ this.name = name;
+ }
+
+ /**
+ * Remove child from parent.
+ *
+ * @param child
+ * the removed parent.
+ */
+ protected void delChild(DocumentObject child) {
+ assert child != null;
+
+ if(child instanceof Element) {
+ DocumentObject parent = ((Element)child).getParent();
+ if(parent != null && parent.equals(this)) {
+ children.remove(child);
+ ((Element)child).setParent(null);
+ }
+ }
+ }
+
+ public DocumentObject getParent() {
+ return parent;
+ }
+
+ public void setParent(DocumentObject parent) {
+ this.parent = parent;
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DocumentRoot.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DocumentRoot.java
new file mode 100644
index 00000000000..f8ac63bb79d
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DocumentRoot.java
@@ -0,0 +1,463 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.xml;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.XWTException;
+
+/**
+ * @author yyang
+ * @since 1.0
+ */
+public class DocumentRoot {
+
+ /**
+ * The file type(Can be resolved by java.io.File)
+ */
+ public static final int TYPE_FILE = 0;
+
+ /**
+ * The path type(Can be resolved by java.net.URL)
+ */
+ public static final int TYPE_PATH = 1;
+
+ /**
+ * The zip format.
+ */
+ public static final int FORMAT_ZIP = 2;
+
+ /**
+ * The gzip format.
+ */
+ public static final int FORMAT_GZIP = 3;
+
+ /**
+ * The plain format.
+ */
+ public static final int FORMAT_NONE = 4;
+
+ private int type = TYPE_PATH;
+
+ private int format = FORMAT_NONE;
+
+ /**
+ * The absolute path.
+ */
+ private String basePath;
+
+ /**
+ * The relative path.
+ */
+ private URL baseURL;
+
+ /**
+ * The main file name.
+ */
+ private String baseFile;
+
+ private static URL DOCUMENT_ROOT;
+
+ static {
+ try {
+ DOCUMENT_ROOT = new File(System.getProperty("user.dir")).toURI().toURL();
+ } catch (MalformedURLException e) {
+ DOCUMENT_ROOT = null;
+ }
+ }
+
+ public DocumentRoot() {
+ reset();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentRoot#getFormat()
+ */
+ public int getFormat() {
+ return format;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentRoot#getType()
+ */
+ public int getType() {
+ return type;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentRoot#getPath()
+ */
+ public URL getPath() {
+ return baseURL;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentRoot#getFile()
+ */
+ public String getFile() {
+ return baseFile;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentRoot#openStream()
+ */
+ public InputStream openStream() throws IOException {
+ switch(format) {
+ case FORMAT_GZIP:
+ return new GZIPInputStream(new URL(basePath + "/" + baseFile).openStream());
+ default:
+ return new URL(basePath + "/" + baseFile).openStream();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IDocumentRoot#openStream(java.lang.String)
+ */
+ public InputStream openStream(String path) throws IOException {
+ assert path != null;
+ InputStream in = null;
+
+ if(path.indexOf(':') < 0) {
+ if(format == FORMAT_ZIP) {
+ // If it is zip format, that means all directories and files in
+ // zip file are extracted to temporary directory.
+ File file = new File(basePath + "/" + path);
+ in = new FileInputStream(file);
+ } else {
+ // Else, maybe the file parent or url path.
+ switch(type) {
+ case TYPE_FILE:
+ File file;
+ if(path.startsWith("/")) {
+ // Use absolute path
+ file = new File(path);
+ } else {
+ // Use relative path
+ file = new File(basePath + "/" + path);
+ }
+ in = new FileInputStream(file);
+ break;
+ case TYPE_PATH:
+ URL url = new URL(basePath + "/" + path);
+ in = url.openStream();
+ break;
+ }
+ }
+ } else {
+ if(path.startsWith("classpath:")) {
+ // Use class path
+ String p = path.substring(10);
+ in = getClass().getResourceAsStream(p);
+ if(in == null) {
+ in = String.class.getResourceAsStream(p);
+ }
+ if(in == null) {
+ in = Thread.currentThread().getClass().getResourceAsStream(p);
+ }
+ if(in == null) {
+ throw new IOException("File not found in classpath: " + p);
+ }
+ } else {
+ File file = new File(path);
+ if(file.exists()) {
+ // Use Windows File path. For example, G:\\somefile.txt
+ in = new FileInputStream(file);
+ } else {
+ // Use URL path
+ in = new URL(path).openStream();
+ }
+ }
+ }
+
+ // Automatically select the stream type
+ PushbackInputStream pis = new PushbackInputStream(in, 4);
+ if(Format.isGZIP(pis)) {
+ return new GZIPInputStream(pis);
+ } else if(Format.isZIP(pis)) {
+ ZipInputStream zis = new ZipInputStream(pis);
+ // Skip entry of directory or file which contains directory
+ // path("someDirectory/someFile.suffix").
+ for(ZipEntry entry = zis.getNextEntry(); entry != null && (entry.isDirectory() || entry.getName().indexOf('/') != -1); entry = zis.getNextEntry());
+ return zis;
+ } else {
+ return pis;
+ }
+ }
+
+ /**
+ * This method is used in <code>ModelLoader</code>
+ *
+ * @param file
+ * the xaml file path.
+ */
+ protected void init(InputStream inputStream, String path) throws IOException {
+ path = path.replace('\\', '/');
+ File file = new File(path);
+ if(inputStream == null && file.exists()) {
+ // Is file
+ init(file);
+ } else {
+ // Is URL
+ basePath = null;
+ baseURL = new URL(path);
+ PushbackInputStream pis = null;
+ boolean shouldClose_pis = false;
+ if(inputStream instanceof PushbackInputStream) {
+ pis = (PushbackInputStream)inputStream;
+ } else {
+ if(inputStream == null) {
+ pis = new PushbackInputStream(baseURL.openStream(), 4);
+ shouldClose_pis = true;
+ } else {
+ pis = new PushbackInputStream(inputStream, 4);
+ }
+ }
+ if(Format.isGZIP(pis)) {
+ format = FORMAT_GZIP;
+ } else if(Format.isZIP(pis)) {
+ format = FORMAT_ZIP;
+ File tempDir = extractZipToTemporary(pis);
+ basePath = "file:/" + tempDir.getAbsolutePath();
+ baseFile = getMainFile(tempDir);
+ }
+ if(shouldClose_pis) {
+ pis.close();
+ }
+
+ if(basePath == null) {
+ while(path.endsWith("/")) {
+ path = path.substring(0, path.length() - 1);
+ }
+
+ int lastIndex = path.lastIndexOf("/");
+ if(lastIndex > 0) {
+ basePath = path.substring(0, lastIndex);
+ baseFile = path.substring(lastIndex + 1);
+ baseURL = new URL(basePath);
+ } else {
+ basePath = System.getProperty("user.dir");
+ baseURL = new File(basePath).toURI().toURL();
+ baseFile = path;
+ }
+ }
+
+ type = TYPE_PATH;
+ }
+ }
+
+ /**
+ * This method is used in <code>ModelLoader</code>
+ */
+ protected void reset() {
+ type = TYPE_PATH;
+ format = FORMAT_NONE;
+ baseURL = DOCUMENT_ROOT;
+ basePath = DOCUMENT_ROOT.toString();
+ baseFile = null;
+ }
+
+ /**
+ * This method is used in <code>ModelLoader</code>
+ *
+ * @param file
+ * the XAML file.
+ */
+ private void init(File file) throws IOException {
+ FileInputStream fis = new FileInputStream(file);
+ PushbackInputStream pis = new PushbackInputStream(fis, 4);
+ baseURL = file.getParentFile().toURI().toURL();
+ basePath = baseURL.toString();
+ baseFile = file.getName();
+ if(Format.isGZIP(pis)) {
+ format = FORMAT_GZIP;
+ } else if(Format.isZIP(pis)) {
+ format = FORMAT_ZIP;
+ File tempDir = extractZipToTemporary(pis);
+ basePath = "file:/" + tempDir.getAbsolutePath();
+ baseFile = getMainFile(tempDir);
+ baseURL = file.toURI().toURL();
+ }
+
+ type = TYPE_FILE;
+ }
+
+ private String getMainFile(File tempDir) {
+ File[] tempFiles = tempDir.listFiles(new FileFilter() {
+
+ public boolean accept(File pathname) {
+ return pathname.isFile() && pathname.getName().toLowerCase().endsWith(IConstants.XWT_EXTENSION_SUFFIX);
+ }
+ });
+ for(File tempFile : tempFiles) {
+ return tempFile.getName();
+ }
+ return null;
+ }
+
+ /**
+ * Extract zip stream to temporary directory.
+ *
+ * @param stream
+ * zip stream.
+ * @return Returns the directory file the zip stream extracted.
+ */
+ private File extractZipToTemporary(InputStream stream) throws IOException {
+ File file = new File(System.getProperty("java.io.tmpdir") + "/cb" + System.currentTimeMillis() + Math.random());
+ if(!file.mkdir()) {
+ throw new XWTException("Folder creation fails: " + file.toString());
+ }
+ file.deleteOnExit();
+
+ String directory = file.getAbsolutePath();
+ ZipInputStream in = new ZipInputStream(stream);
+ ZipEntry z;
+ while((z = in.getNextEntry()) != null) {
+ if(z.isDirectory()) {
+ String name = z.getName();
+ name = name.substring(0, name.length() - 1);
+ File f = new File(directory + File.separator + name);
+ if(!f.mkdir()) {
+ throw new XWTException("Folder creation fails: " + f.toString());
+ }
+ f.deleteOnExit();
+ } else {
+ File f = new File(directory + File.separator + z.getName());
+ if(!f.createNewFile()) {
+ throw new XWTException("File creation fails: " + f.toString());
+ }
+ f.deleteOnExit();
+ FileOutputStream out = new FileOutputStream(f);
+ byte[] cache = new byte[4096];
+ for(int i = in.read(cache); i != -1; i = in.read(cache)) {
+ out.write(cache, 0, i);
+ }
+ out.close();
+ }
+ }
+ in.close();
+
+ return file;
+ }
+
+ /**
+ * File format uitility.
+ * <p>
+ * To check the format of file or stream.
+ * </p>
+ *
+ */
+ static class Format {
+
+ /**
+ * Check the stream is a gzip format or not.
+ *
+ * @param stream
+ * the checked stream.
+ * @return Returns true is the stream is a gzip format.
+ */
+ public static boolean isGZIP(PushbackInputStream stream) throws IOException {
+ assert stream != null;
+
+ byte[] cachedBytes = new byte[2];
+ if(stream.read(cachedBytes) != cachedBytes.length) {
+ throw new RuntimeException("data content wrong.");
+ }
+ stream.unread(cachedBytes);
+ // GZIP's header data starts with two bytes{1F,8B},
+ if((cachedBytes[0] & 0xff) == 0x1f && (cachedBytes[1] & 0xff) == 0x8b) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Check the file is a gzip format or not.
+ *
+ * @param file
+ * the checked file.
+ * @return Returns true is the file is a gzip format.
+ */
+ public static boolean isGZIP(File file) throws IOException {
+ assert file != null;
+
+ FileInputStream fis = new FileInputStream(file);
+ PushbackInputStream pis = new PushbackInputStream(fis, 2);
+ boolean returnValue = isGZIP(pis);
+ pis.close();
+ return returnValue;
+ }
+
+ /**
+ * Check the stream is a zip format or not.
+ *
+ * @param stream
+ * the checked stream.
+ * @return Returns true is the stream is a zip format.
+ */
+ public static boolean isZIP(PushbackInputStream stream) throws IOException {
+ assert stream != null;
+
+ byte[] cachedBytes = new byte[4];
+ if(stream.read(cachedBytes) != cachedBytes.length) {
+ throw new RuntimeException("data content wrong.");
+ }
+ stream.unread(cachedBytes);
+ // ZIP's header data starts with four bytes{0x50, 0x4b, 0x03, 0x04},
+ if((cachedBytes[0] & 0xff) == 0x50 && (cachedBytes[1] & 0xff) == 0x4b && (cachedBytes[2] & 0xff) == 0x03 && (cachedBytes[3] & 0xff) == 0x04) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Check the file is a zip format or not.
+ *
+ * @param file
+ * the checked file.
+ * @return Returns true is the file is a zip format.
+ */
+ public static boolean isZIP(File file) throws IOException {
+ assert file != null;
+
+ FileInputStream fis = new FileInputStream(file);
+ PushbackInputStream pis = new PushbackInputStream(fis, 4);
+ boolean returnValue = isZIP(pis);
+ pis.close();
+ return returnValue;
+ }
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/Element.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/Element.java
new file mode 100644
index 00000000000..8f5f6f5dadb
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/Element.java
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.xml;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.internal.core.Core;
+
+/**
+ * @since 1.0
+ * @author yyang
+ */
+public class Element extends DocumentObject {
+
+ private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+ private String path;
+
+ private Map<String, Attribute> originalAttributes;
+
+ private Map<String, Map<String, Attribute>> externalAttributes;
+
+ private String[] xmlnsMapping;
+
+ /**
+ * @return the path of this element, i.e. indexes of this element and its parents in XML.
+ */
+ public String getPath() {
+ return path;
+ }
+
+ public String getXmlns(String prefix) {
+ if(prefix == null) {
+ prefix = "";
+ }
+ if(xmlnsMapping != null) {
+ for(int i = 0; i < xmlnsMapping.length; i++) {
+ if(prefix.equals(xmlnsMapping[i++])) {
+ return xmlnsMapping[i];
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Default constructor
+ *
+ * @param context
+ * bundle context
+ * @param namespace
+ * element namespace
+ * @param name
+ * element name
+ * @param originalAttributes
+ * element arributes
+ */
+ public Element(String namespace, String name, Map<String, String> xmlnsMapping) {
+ this(namespace, name, null, null, xmlnsMapping);
+ }
+
+ public Element(String namespace, String name, String path, Collection<Attribute> attributes, Map<String, String> xmlnsMapping) {
+ super(namespace, name);
+ this.path = path;
+ if(xmlnsMapping != null) {
+ this.xmlnsMapping = new String[xmlnsMapping.size() * 2];
+ int i = 0;
+ for(Map.Entry<String, String> entry : xmlnsMapping.entrySet()) {
+ String key = entry.getKey();
+ if(key == null) {
+ key = "";
+ }
+ this.xmlnsMapping[i++] = key;
+ this.xmlnsMapping[i++] = entry.getValue();
+ }
+ }
+
+ this.originalAttributes = Collections.emptyMap();
+ this.externalAttributes = Collections.emptyMap();
+
+ if(attributes != null) {
+ for(Attribute attribute : attributes) {
+ setInternalAttribute(attribute);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.soyatec.eface.core.IElement#attributeNames()
+ */
+ public String[] attributeNames() {
+ return originalAttributes.keySet().toArray(EMPTY_STRING_ARRAY);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.soyatec.eface.core.IElement#attributeNamespaces()
+ */
+ public String[] attributeNamespaces() {
+ return externalAttributes.keySet().toArray(EMPTY_STRING_ARRAY);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seecom.soyatec.eface.core.IElement#setAttribute(com.soyatec.eface.core. IAttribute)
+ */
+ public void setAttribute(Attribute attribute) {
+ setInternalAttribute(attribute);
+ firePropertyChanged(attribute);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.soyatec.eface.IElement#attributeNames(java.lang.String)
+ */
+ public String[] attributeNames(String namespace) {
+ if(getNamespace().equals(namespace)) {
+ return attributeNames();
+ }
+ Map<String, Attribute> externalAttribute = externalAttributes.get(namespace);
+ if(externalAttribute != null) {
+ return externalAttribute.keySet().toArray(EMPTY_STRING_ARRAY);
+ } else {
+ return Core.EMPTY_STRING_ARRAY;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.soyatec.eface.core.IElement#getAttribute(java.lang.String)
+ */
+ public Attribute getAttribute(String name) {
+ assert name != null;
+ return originalAttributes.get(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.soyatec.eface.core.IElement#getAttribute(java.lang.String, java.lang.String)
+ */
+ public Attribute getAttribute(String namespace, String name) {
+ Map<String, Attribute> externalAttribute = externalAttributes.get(namespace);
+ if(externalAttribute != null) {
+ return externalAttribute.get(name);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ Element element = (Element)super.clone();
+
+ element.parent = null;
+
+ if(originalAttributes.isEmpty()) {
+ originalAttributes = Collections.emptyMap();
+ } else {
+ element.originalAttributes = new LinkedHashMap<String, Attribute>(originalAttributes.size());
+ for(String attrName : originalAttributes.keySet()) {
+ Attribute attrValue = (Attribute)originalAttributes.get(attrName).clone();
+ element.originalAttributes.put(attrName, attrValue);
+ }
+ }
+
+ if(externalAttributes.isEmpty()) {
+ element.originalAttributes = Collections.emptyMap();
+ } else {
+ element.externalAttributes = new LinkedHashMap<String, Map<String, Attribute>>(externalAttributes.size());
+ for(String ns : externalAttributes.keySet()) {
+ Map<String, Attribute> oAttributes = externalAttributes.get(ns);
+ Map<String, Attribute> nAttributes = new LinkedHashMap<String, Attribute>(oAttributes.size());
+ for(Map.Entry<String, Attribute> entry : oAttributes.entrySet()) {
+ String attrName = entry.getKey();
+ Attribute attrValue = (Attribute)entry.getValue().clone();
+ nAttributes.put(attrName, attrValue);
+ }
+ element.externalAttributes.put(ns, nAttributes);
+ }
+ }
+
+ return element;
+ }
+
+ protected void setAttributes(Collection<Attribute> attributes) {
+ for(Attribute attribute : attributes) {
+ setInternalAttribute(attribute);
+ }
+ firePropertyChanged(attributes);
+ }
+
+ private void firePropertyChanged(Attribute attribute) {
+ notifyObservers(attribute);
+ }
+
+ private void firePropertyChanged(Collection<Attribute> attributes) {
+ notifyObservers(attributes);
+ }
+
+ private boolean isXWTNamespace(String namespace) {
+ String scopeNamespace = getNamespace();
+ if(namespace == null || "".equals(namespace)) {
+ return true;
+ }
+ if(scopeNamespace.startsWith(IConstants.XAML_CLR_NAMESPACE_PROTO) || scopeNamespace.equals(IConstants.XWT_NAMESPACE)) {
+ return namespace.equalsIgnoreCase(scopeNamespace) || namespace.equals(IConstants.XWT_NAMESPACE);
+ }
+ return false;
+ }
+
+ /**
+ * Set attribute without notifying event.
+ *
+ * @param attribute
+ * the modified attribute.
+ */
+ private void setInternalAttribute(Attribute attribute) {
+ assert attribute != null;
+
+ String namespace = attribute.getNamespace();
+ String name = attribute.getName();
+
+ if(isXWTNamespace(namespace)) {
+ if(originalAttributes == Collections.EMPTY_MAP) {
+ originalAttributes = new LinkedHashMap<String, Attribute>();
+ }
+ originalAttributes.put(name, attribute);
+ } else {
+ Map<String, Attribute> externalAttribute = externalAttributes.get(namespace);
+ if(externalAttribute == null) {
+ externalAttribute = new HashMap<String, Attribute>();
+ }
+ if(externalAttributes == Collections.EMPTY_MAP) {
+ externalAttributes = new LinkedHashMap<String, Map<String, Attribute>>();
+ }
+ externalAttribute.put(name, attribute);
+ externalAttributes.put(namespace, externalAttribute);
+ }
+ ((DocumentObject)attribute).setParent(this);
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/ElementHandler.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/ElementHandler.java
new file mode 100644
index 00000000000..bb65bc61ea7
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/ElementHandler.java
@@ -0,0 +1,797 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.xml;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.XWT;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.Locator2;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * XAML-DOM handler.
+ *
+ * @author yyang
+ * @version 1.0
+ */
+class ElementHandler extends DefaultHandler implements ContentHandler {
+
+ private Stack<StringBuffer> bufferStack = new Stack<StringBuffer>();
+
+ private static final String[] BINDING_PROPERTIES = new String[]{ "path", "validationRule", "converter" };
+
+
+ /**
+ * Temporary element hierarchy
+ */
+ private Stack<DocumentObject> elementStack = new Stack<DocumentObject>();
+
+ private Stack<Integer> elementIndexStack;
+
+ private Stack<Boolean> switchStack;
+
+ private StringBuffer textBuffer = null;
+
+ private Locator locator;
+
+ private boolean ignoreSystemProcession;
+
+ private boolean hasSetDefaultEncoding;
+
+ private ElementManager elementManager;
+
+ private String defaultNamespace;
+
+ private ExtensionParser extensionParser = new ExtensionParser();
+
+ private HashMap<String, String> namespaceMapping = new HashMap<String, String>();
+
+ private boolean needNormalizeName = true;
+
+ /**
+ * Parse the XAML extension Markup: {StaticResource test} {StaticResource RessourceKey=test} {DynamicResource {x:Static
+ * SystemColors.ControlBrushKey}}
+ *
+ * @author yyang
+ *
+ */
+ private class ExtensionParser {
+
+ private Element root;
+
+ private DocumentObject current;
+
+ public void parse(DocumentObject element, String text) {
+ if(root != null) {
+ ExtensionParser parser = new ExtensionParser();
+ parser.parse(element, text);
+ return;
+ }
+
+ StringTokenizer stringTokenizer = new StringTokenizer(text, "{}", true);
+ String previous = null;
+ String nextPrevious = null;
+ while(stringTokenizer.hasMoreTokens()) {
+ String token = stringTokenizer.nextToken();
+
+ if(previous != null) {
+ if(previous.equals("{")) {
+ if(token.equals("}")) {
+ // escape sequence
+ if(stringTokenizer.hasMoreTokens()) {
+ handleBlock(stringTokenizer.nextToken(" \t\n\r\f"), false);
+ }
+ } else {
+ startBlock();
+ }
+ } else if(previous.equals("}")) {
+ endBlock();
+ } else {
+ StringBuilder builder = new StringBuilder();
+ builder.append(previous);
+ if(token.equals("{")) {
+ int level = 1;
+ builder.append(token);
+ while(stringTokenizer.hasMoreTokens() && level >= 0) {
+ String value = stringTokenizer.nextToken();
+ if(value.equals("{")) {
+ level++;
+ } else if(value.equals("}")) {
+ level--;
+ }
+ if(level >= 0) {
+ builder.append(value);
+ }
+ }
+ }
+ handleBlock(builder.toString(), (nextPrevious == null || !nextPrevious.equals("}")));
+ }
+ }
+ nextPrevious = previous;
+ previous = token;
+ }
+ element.addChild(root);
+ root = null;
+ current = null;
+ }
+
+ protected void startBlock() {
+ }
+
+ protected void endBlock() {
+ if(current != null) {
+ current = current.getParent().getParent();
+ }
+ }
+
+ protected Element createElement(String token) {
+ int index = token.indexOf(':');
+ String namespace = null;
+ String name = token;
+ if(index != -1) {
+ String prefix = token.substring(0, index);
+ name = token.substring(index + 1);
+ namespace = namespaceMapping.get(prefix);
+ }
+ if(namespace == null) {
+ namespace = defaultNamespace;
+ }
+ Element element = new Element(namespace, name, namespaceMapping);
+ element.setId(ElementManager.generateID(name));
+ if(current != null) {
+ current.addChild(element);
+ } else {
+ if(root == null) {
+ root = element;
+ }
+ }
+ current = element;
+ return element;
+ }
+
+ protected void handleBlock(String content, boolean newElement) {
+ String rootPattern = " \t\n\r\f=,";
+ StringTokenizer tokenizer = new StringTokenizer(content, rootPattern, true);
+ String attributeName = null;
+ String attributeValue = null;
+ boolean equals = false;
+ Element element = null;
+ if(!newElement && current instanceof Element) {
+ element = (Element)current;
+ }
+
+ boolean skip = false;
+ String token = null;
+ while(skip || tokenizer.hasMoreTokens()) {
+ if(!skip) {
+ token = tokenizer.nextToken(rootPattern).trim();
+ }
+ skip = false;
+ if(token.length() == 0) {
+ continue;
+ }
+ if(element == null) {
+ element = createElement(token);
+ } else {
+ if(token.equals("=")) {
+ equals = true;
+ if("xpath".equalsIgnoreCase(attributeName)) {
+ attributeValue = tokenizer.nextToken(",");
+ }
+ continue;
+ }
+ if(token.equals(",")) {
+ if(attributeName != null) {
+ if(attributeValue != null) {
+ Attribute attribute = new Attribute(normalizeAttrNamespace(current.getNamespace()), attributeName, ElementManager.generateID(current.getName()));
+ if(isExpendedProperty(attributeName) && "Binding".equalsIgnoreCase(element.getName())) {
+ attributeValue = expandNamespaces(element, attributeValue);
+ }
+ handleContent(attribute, attributeValue);
+ element.setAttribute(attribute);
+ current = attribute;
+ } else {
+ element.setContent(attributeName);
+ }
+ attributeName = null;
+ attributeValue = null;
+ equals = false;
+ }
+ } else {
+ if(attributeName == null) {
+ attributeName = token;
+ } else {
+ StringBuilder builder = new StringBuilder();
+ builder.append(token);
+ if(token.startsWith("{")) {
+ int level = 1;
+ while(tokenizer.hasMoreTokens() && level > 0) {
+ String value = tokenizer.nextToken("{}");
+ if(value.equals("{")) {
+ level++;
+ } else if(value.equals("}")) {
+ level--;
+ }
+ builder.append(value);
+ }
+ }
+ attributeValue = builder.toString();
+
+ try {
+ token = tokenizer.nextToken(rootPattern).trim();
+ skip = true;
+ continue;
+ } catch (NoSuchElementException e) {
+ }
+ }
+ }
+ }
+ skip = false;
+ }
+
+ if(equals) {
+ Attribute attribute = new Attribute(normalizeAttrNamespace(current.getNamespace()), attributeName, ElementManager.generateID(current.getName()));
+ if(isExpendedProperty(attributeName) && "Binding".equalsIgnoreCase(element.getName())) {
+ attributeValue = expandNamespaces(element, attributeValue);
+ }
+
+ if(attributeValue != null) {
+ handleContent(attribute, attributeValue);
+ element.setAttribute(attribute);
+ } else {
+ element.setAttribute(attribute);
+ current = attribute;
+ }
+ } else if(attributeName != null) {
+ int index = attributeName.indexOf(":");
+ if(index != -1) {
+ element = createElement(attributeName);
+ current = current.getParent();
+ } else {
+ current.setContent(attributeName);
+ }
+ }
+ }
+ };
+
+ static boolean isExpendedProperty(String name) {
+ // TODO need a generic solution for each property of Binding
+ for(String propertyName : BINDING_PROPERTIES) {
+ if(propertyName.equalsIgnoreCase(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected String expandNamespaces(DocumentObject element, String value) {
+ if(value.startsWith("{") || (value.indexOf(':') == -1)) {
+ return value;
+ }
+ int length = IConstants.XAML_CLR_NAMESPACE_PROTO.length();
+ for(String prefix : namespaceMapping.keySet()) {
+ String namespace = namespaceMapping.get(prefix);
+ if(namespace.startsWith(IConstants.XAML_CLR_NAMESPACE_PROTO)) {
+ String packageName = namespace.substring(length);
+ value = value.replace(prefix + ":", packageName + '.');
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Default constructor.
+ *
+ * @param manager
+ * loader instance.
+ */
+ public ElementHandler(ElementManager elementManager) {
+ this.ignoreSystemProcession = false;
+ this.hasSetDefaultEncoding = false;
+ this.elementManager = elementManager;
+ }
+
+ /**
+ * Internal constructor.
+ *
+ * @param loader
+ * loader instance.
+ * @param parent
+ * the parent element of loading stream.
+ */
+ public ElementHandler(DocumentObject parent, ElementManager elementManager) {
+ if(parent != null) {
+ elementStack.push(parent);
+ bufferStack.push(textBuffer);
+ }
+ ignoreSystemProcession = true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
+ */
+ @Override
+ public void setDocumentLocator(Locator locator) {
+ this.locator = locator;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#startDocument()
+ */
+ @Override
+ public void startDocument() throws SAXException {
+ elementIndexStack = new Stack<Integer>();
+ elementIndexStack.push(0);
+ switchStack = new Stack<Boolean>();
+ defaultNamespace = IConstants.XWT_NAMESPACE;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#startPrefixMapping(java.lang.String, java.lang.String)
+ */
+ @Override
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ if(prefix.length() == 0 && !ignoreSystemProcession) {
+ defaultNamespace = uri;
+ }
+ namespaceMapping.put(prefix, uri);
+ }
+
+ @Override
+ public void endPrefixMapping(String prefix) throws SAXException {
+ namespaceMapping.remove(prefix);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#endDocument()
+ */
+ @Override
+ public void endDocument() throws SAXException {
+ elementStack.clear();
+ bufferStack.clear();
+ switchStack.clear();
+ switchStack = null;
+ defaultNamespace = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
+ */
+ @Override
+ public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
+
+ if(!switchStack.isEmpty() && !switchStack.peek()) {
+ return;
+ }
+
+ String string = new String(arg0, arg1, arg2);
+ if(string.length() > 0) {
+ if(textBuffer == null) {
+ textBuffer = new StringBuffer(string);
+ } else {
+ textBuffer.append(string);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#skippedEntity(java.lang.String)
+ */
+ @Override
+ public void skippedEntity(String name) throws SAXException {
+ super.skippedEntity(name);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+ */
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
+
+ // Set xml's encoding to default.
+ if(!ignoreSystemProcession && !hasSetDefaultEncoding) {
+ if(locator instanceof Locator2) {
+ Locator2 locator2 = (Locator2)locator;
+ String encoding = locator2.getEncoding();
+ if(encoding != null && encoding.length() > 0) {
+ elementManager.setEncoding(encoding);
+ }
+ }
+ hasSetDefaultEncoding = true;
+ }
+
+ uri = normalizeNamespace(uri);
+
+ // If super condition does not allow parse children, ignore it.
+ if(!switchStack.isEmpty() && !switchStack.peek()) {
+ if(uri.equalsIgnoreCase(IConstants.XWT_NAMESPACE)) {
+ if("Switch".equals(localName)) {
+ // If children is switch element, than set false to it.
+ switchStack.push(false);
+ }
+ }
+ return;
+ }
+
+ if(localName.indexOf('.') > 0) {
+ preProperty(uri, localName, attrs);
+ } else {
+ preElement(uri, localName, attrs);
+ }
+
+ elementIndexStack.push(0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+ */
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+
+ elementIndexStack.pop();
+ if(!elementIndexStack.isEmpty()) {
+ int nextIndex = elementIndexStack.pop();
+ elementIndexStack.push(nextIndex + 1);
+ }
+
+ uri = normalizeNamespace(uri);
+
+ // If super condition does not allow parse children, ignore it.
+ if(!switchStack.isEmpty() && !switchStack.peek()) {
+ if(uri.equalsIgnoreCase(IConstants.XWT_NAMESPACE)) {
+ if("Switch".equals(localName)) {
+ switchStack.pop();
+ }
+ }
+ return;
+ }
+
+ if(!elementStack.isEmpty()) {
+ // remove current node from stack
+ DocumentObject element = elementStack.peek();
+
+ if(element instanceof Attribute) {
+ postProperty(uri, localName);
+ } else {
+ postElement(uri, localName);
+ }
+ }
+ }
+
+ private void preElement(String namespace, String name, Attributes attrs) throws SAXException {
+
+ // Process element ID
+
+ namespace = normalizeNamespace(namespace);
+ name = normalizeName(name);
+ if(name.equalsIgnoreCase("xdata")) {
+ needNormalizeName = false;
+ }
+ // Check the reference element.
+ String id = ElementManager.generateID(name);
+
+ // Check the same id elements.
+ if(elementManager.hasElement(id)) {
+ throw new SAXException(getFormattedMessage("Element already exists: ", id));
+ }
+
+ // Process attributes: original, external
+ Set<Attribute> attributes = new HashSet<Attribute>();
+ for(int i = 0, len = attrs.getLength(); i < len; i++) {
+ String attrUri = normalizeAttrNamespace(attrs.getURI(i));
+ String attrName = attrs.getLocalName(i);
+
+ Attribute attribute;
+ int index = attrName.lastIndexOf('.');
+ if(index != -1) {
+ String prefix = normalizeName(attrName.substring(0, index));
+ String attributeName = (XWT.isXWTNamespace(attrUri) ? normalizeName(attrName.substring(index + 1)) : attrName);
+
+ attribute = new Attribute(attrUri, attributeName, id);
+ attribute.setNamePrefix(prefix);
+ } else {
+ attribute = new Attribute(attrUri, (XWT.isXWTNamespace(attrUri) ? normalizeName(attrName) : attrName), id);
+ }
+ handleContent(attribute, attrs.getValue(i));
+ attributes.add(attribute);
+ }
+
+ // Create or reference element.
+ Element element = new Element(namespace, name, getIndexPath(), attributes, namespaceMapping);
+ element.setId(id);
+
+ // Add current node to stack
+ if(!elementStack.isEmpty()) {
+ elementStack.peek().addChild(element);
+ }
+
+ elementStack.push(element);
+ bufferStack.push(textBuffer);
+ textBuffer = null;
+
+ // Register to the element registry
+ elementManager.preElement(element);
+ }
+
+ private void postElement(String namespace, String name) throws SAXException {
+
+ // : The same as postReference : //
+
+ if(!elementStack.isEmpty()) {
+ // remove current node from stack
+ DocumentObject element = elementStack.pop();
+
+ // Setting element text content
+ if(textBuffer != null) {
+ String text = textBuffer.toString().trim();
+ if(text.length() > 0) {
+ handleContent(element, text);
+ }
+ }
+ textBuffer = bufferStack.pop();
+
+ // Post the element registration.
+ elementManager.postElement((Element)element);
+ }
+
+ if(name.equalsIgnoreCase("xdata")) {
+ needNormalizeName = true;
+ }
+ }
+
+ protected void handleContent(DocumentObject element, String text) {
+ if(text.startsWith("{") && text.endsWith("}")) {
+ extensionParser.parse(element, text);
+ return;
+ } else {
+ // handle the case: <x:Array Type="ns:Type" >
+ if(IConstants.XAML_X_TYPE.equals(element.getName()) || IConstants.XAML_X_STATIC.equals(element.getName())) {
+ int index = text.indexOf(':');
+ if(index != -1) {
+ String ns = text.substring(0, index);
+ String content = text.substring(index + 1);
+ String namespace = namespaceMapping.get(ns);
+ if(namespace != null) {
+ Element childElement = new Element(namespace, content, namespaceMapping);
+ childElement.setId(ElementManager.generateID(element.getName()));
+ element.addChild(childElement);
+ return;
+ }
+ }
+ }
+ }
+ if(element instanceof Attribute && IConstants.XWT_X_NAMESPACE.equals(element.getNamespace())) {
+ if(IConstants.XAML_STYLE.equalsIgnoreCase(element.getName()) || IConstants.XAML_X_CLASS.equalsIgnoreCase(element.getName()) || IConstants.XAML_X_CLASS_FACTORY.equalsIgnoreCase(element.getName())) {
+ // handle the expansion of x:Style = "(j:class).variable"
+ // and handle the expansion of x:Class = "(j:class).variable"
+ text = expandNamespaces(element, text);
+ }
+ }
+ element.setContent(text);
+ }
+
+ /**
+ * It is compatible with XAML.
+ * <p>
+ * It must support the following features:
+ *
+ * 1. <Panel> <Button> <Button.Content>Hello World</Button.Content> </Button> </Panel>
+ *
+ * 2. <Panel> <Panel.Composite> <Button Content="Hello World" /> </Panel.Composite> </Panel>
+ *
+ * 3. <Panel> <Panel.Composite> <Button> <Button.Content>Hello World</Button.Content> </Button> </Panel.Composite> </Panel>
+ *
+ * 4. <Panel> <Panel.Composite> <Button> <Button.Content>Hello</Button.Content> </Button> <Button> <Button.Content>World</Button.Content>
+ * </Button> </Panel.Composite> </Panel>
+ * </p>
+ *
+ * @param namespace
+ * attribute namespace
+ * @param name
+ * attribute full name. like: Button.Content
+ */
+ private void preProperty(String namespace, String name, Attributes attrs) throws SAXException {
+ String elementTag = normalizeName(name.substring(0, name.indexOf('.')));
+ String attributeName = (XWT.isXWTNamespace(namespace) ? normalizeName(name.substring(name.indexOf('.') + 1)) : name);
+ String elementId = null;
+
+ // Search the owner element and get the ID.
+ for(int i = elementStack.size() - 1; i >= 0; i--) {
+ DocumentObject element = elementStack.get(i);
+ if(element instanceof Element && element.getName().equals(elementTag)) {
+ elementId = element.getId();
+ break;
+ }
+ }
+
+ if(elementId == null) {
+ preElement(namespace, name, attrs);
+ } else {
+ namespace = normalizeNamespace(namespace);
+ // Process attributes: original, external
+ Collection<Attribute> collection = new ArrayList<Attribute>();
+ for(int i = 0, len = attrs.getLength(); i < len; i++) {
+
+ String attrUri = normalizeNamespace(attrs.getURI(i));
+ String attrName = attrs.getLocalName(i);
+
+ Attribute attr;
+ int index = attrName.lastIndexOf('.');
+ if(index != -1) {
+ String prefix = normalizeName(attrName.substring(0, index));
+ String aName = (XWT.isXWTNamespace(namespace) ? normalizeName(attrName.substring(index + 1)) : attrName);
+ attr = new Attribute(attrUri, aName, elementId);
+ attr.setNamePrefix(prefix);
+ } else {
+ attr = new Attribute(attrUri, (XWT.isXWTNamespace(namespace) ? normalizeName(attrName) : attrName), elementId);
+ }
+ handleContent(attr, attrs.getValue(i));
+ collection.add(attr);
+ }
+
+ Attribute attribute = new Attribute(normalizeAttrNamespace(namespace), attributeName, getIndexPath(), elementId, collection);
+ elementStack.push(attribute);
+ bufferStack.push(textBuffer);
+ textBuffer = null;
+ }
+ }
+
+ /**
+ * @see #preProperty(String, String)
+ */
+ private void postProperty(String namespace, String name) throws SAXException {
+ if(!elementStack.isEmpty()) {
+ // remove current node from stack
+ Attribute attribute = (Attribute)elementStack.pop();
+
+ // Setting attribute content
+ if(textBuffer != null) {
+ String text = textBuffer.toString().trim();
+ if(text.length() > 0) {
+ handleContent(attribute, text);
+ }
+ }
+ textBuffer = bufferStack.pop();
+
+ Element element = elementManager.getElement(attribute.getId());
+ element.setAttribute(attribute);
+ }
+ }
+
+ /**
+ * Normalize the namespace string. If uri is null or length is zero, returns default namespace.
+ *
+ * @param uri
+ * The namespace which to normalize.
+ * @return Returns the normalized namespace.
+ */
+ private String normalizeNamespace(String uri) {
+ if(uri == null || uri.length() == 0) {
+ uri = defaultNamespace;
+ }
+ if(uri.startsWith(IConstants.XAML_CLR_NAMESPACE_PROTO)) {
+ return uri;
+ }
+ return uri.toLowerCase();
+ }
+
+ /**
+ * Normalize the namespace string. If uri is null or length is zero, returns default namespace.
+ *
+ * @param uri
+ * The namespace which to normalize.
+ * @return Returns the normalized namespace.
+ */
+ private String normalizeAttrNamespace(String uri) {
+ if(uri == null || uri.length() == 0) {
+ uri = defaultNamespace;
+ }
+ if(uri.startsWith(IConstants.XAML_CLR_NAMESPACE_PROTO)) {
+ uri = defaultNamespace;
+ }
+ return uri.toLowerCase();
+ }
+
+ /**
+ * <p>
+ * Normalize the tag name to class-formal format.
+ * </p>
+ * <p>
+ * e.g. Normalize &quot;font-face-name&quot; to &quot;FontFaceName&quot;
+ * </p>
+ *
+ * @param tagName
+ * The tag name which to normalize.
+ * @return the normalized tag name.
+ */
+ private String normalizeName(String tagName) {
+ if(!needNormalizeName) {
+ return tagName;
+ }
+ StringBuffer buffer = new StringBuffer();
+
+ boolean isH = false;
+ for(int i = 0, len = tagName.length(); i < len; i++) {
+ char c = tagName.charAt(i);
+ if(i == 0) {
+ buffer.append(Character.toUpperCase(c));
+ } else {
+ switch(c) {
+ case '-':
+ isH = true;
+ break;
+ case '.':
+ isH = true;
+ buffer.append(c);
+ break;
+ default:
+ if(isH) {
+ buffer.append(Character.toUpperCase(c));
+ isH = false;
+ } else {
+ buffer.append(c);
+ }
+ break;
+ }
+ }
+ }
+ return buffer.toString();
+ }
+
+ private String getFormattedMessage(String msg, Object... args) {
+ StringBuffer buffer = new StringBuffer("[" + locator.getLineNumber() + "," + locator.getColumnNumber() + "] ");
+ buffer.append(msg);
+ return MessageFormat.format(buffer.toString(), args);
+ }
+
+ /**
+ * @return the '/' separated, zero based, path of current {@link Element}.
+ */
+ private String getIndexPath() {
+ StringBuilder sb = new StringBuilder();
+ for(Integer index : elementIndexStack) {
+ if(sb.length() != 0) {
+ sb.append('/');
+ }
+ sb.append(index.intValue());
+ }
+ return sb.toString();
+ }
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/ElementManager.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/ElementManager.java
new file mode 100644
index 00000000000..7de6221dbd5
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/ElementManager.java
@@ -0,0 +1,413 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.papyrus.xwt.IConstants;
+import org.eclipse.papyrus.xwt.XWT;
+import org.eclipse.papyrus.xwt.callback.IBeforeParsingCallback;
+import org.eclipse.papyrus.xwt.internal.core.Core;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * @author yyang
+ * @since 1.0
+ */
+public class ElementManager {
+
+ private DocumentRoot documentRoot;
+
+ private SAXParserFactory parserFactory;
+
+ private ErrorHandler errorHandler;
+
+ private String encoding;
+
+ /**
+ * Cache all elements.
+ */
+ private Map<String, Element> elements;
+
+ /**
+ * Only cache root elements.
+ */
+ private Element rootElement;
+
+ private Element xDataElement;
+
+ private static Random RANDOM = new Random();
+
+ public static String generateID(String typeName) {
+ return typeName + RANDOM.nextInt(Integer.MAX_VALUE);
+ }
+
+ public ElementManager() {
+ this(null);
+ }
+
+ public ElementManager(URL url) {
+ this.documentRoot = new DocumentRoot();
+ this.elements = new HashMap<String, Element>();
+ this.encoding = System.getProperty("file.encoding");
+
+ this.parserFactory = SAXParserFactory.newInstance();
+ this.parserFactory.setNamespaceAware(true);
+ this.parserFactory.setValidating(true);
+ if(url != null) {
+ try {
+ documentRoot.init(null, url.toString());
+ } catch (IOException e) {
+ }
+ }
+
+ this.errorHandler = new ErrorHandler() {
+
+ // IFrameworkAdaptor adaptor =
+ // FrameworkUtil.getFrameworkAdaptor(context);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
+ */
+ public void error(SAXParseException exception) throws SAXException {
+ Exception cause = exception.getException();
+ try {
+ if(cause != null) {
+ XWT.getLogger().error(cause);
+ } else {
+ XWT.getLogger().error(exception);
+ }
+ } catch (Exception e) {
+ if(cause != null) {
+ throw new SAXException(exception.getLocalizedMessage(), cause);
+ } else {
+ throw new SAXException(exception);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException
+ * )
+ */
+ public void fatalError(SAXParseException exception) throws SAXException {
+ Exception cause = exception.getException();
+ try {
+ if(cause != null) {
+ XWT.getLogger().error(cause);
+ } else {
+ XWT.getLogger().error(exception);
+ }
+ } catch (Exception e) {
+ if(cause != null) {
+ throw new SAXException(exception.getLocalizedMessage(), cause);
+ } else {
+ throw new SAXException(exception);
+ }
+ }
+ throw new RuntimeException();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
+ */
+ public void warning(SAXParseException exception) throws SAXException {
+ Exception cause = exception.getException();
+ try {
+ if(cause != null) {
+ XWT.getLogger().error(cause);
+ } else {
+ XWT.getLogger().error(exception);
+ }
+ } catch (Exception e) {
+ if(cause != null) {
+ throw new SAXException(exception.getLocalizedMessage(), cause);
+ } else {
+ throw new SAXException(exception);
+ }
+ }
+ }
+ };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IElementManager#getDocumentRoot()
+ */
+ public DocumentRoot getDocumentRoot() {
+ return documentRoot;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IElementManager#getElement(java.lang.String)
+ */
+ public Element getElement(String id) {
+ assert id != null;
+ return elements.get(id);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IElementManager#getElements()
+ */
+ public String[] getElements() {
+ return elements.keySet().toArray(IConstants.EMPTY_STRING_ARRAY);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IElementManager#getEncoding()
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IElementManager#getRootElement()
+ */
+ public Element getRootElement() {
+ return rootElement;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.soyatec.xaml.IElementManager#hasElement(java.lang.String)
+ */
+ public boolean hasElement(String id) {
+ assert id != null;
+ return elements.containsKey(id);
+ }
+
+ protected void setEncoding(String encoding) {
+ assert encoding != null;
+ this.encoding = encoding;
+ }
+
+ /**
+ * @see Core
+ */
+ public Element load(URL url, IBeforeParsingCallback callback) throws Exception {
+
+ reset();
+
+ if(callback == null) {
+ // Initialize document root
+ documentRoot.init(null, url.toString());
+
+ InputStream input = url.openStream();
+ try {
+ doLoad(input);
+ } finally {
+ input.close();
+ }
+
+ input = documentRoot.openStream();
+ try {
+ loadXData(input);
+ } finally {
+ input.close();
+ }
+ } else {
+ String content = callback.onParsing(url.toString());
+
+ documentRoot.init(null, content);
+
+ InputStream input = new ByteArrayInputStream(content.getBytes());
+ try {
+ doLoad(input);
+ } finally {
+ input.close();
+ }
+
+ input = documentRoot.openStream();
+ try {
+ loadXData(input);
+ } finally {
+ input.close();
+ }
+ }
+ return rootElement;
+ }
+
+ /**
+ * @see Core
+ */
+ public Element load(InputStream stream, URL url) throws Exception {
+
+ reset();
+
+ // Initialize document root
+ PushbackInputStream pis = null;
+ if(stream != null) {
+ if(stream instanceof PushbackInputStream) {
+ pis = (PushbackInputStream)stream;
+ } else {
+ pis = new PushbackInputStream(stream, 4);
+ }
+ }
+
+ documentRoot.init(pis, url.toString());
+
+ InputStream input = pis;
+ if(pis == null) {
+ input = documentRoot.openStream();
+ }
+ doLoad(input);
+
+ input = documentRoot.openStream();
+ loadXData(input);
+ input.close();
+ return rootElement;
+ }
+
+ /**
+ * @see ElementHandler
+ */
+ public void load(InputStream stream, DocumentObject parent) throws SAXException {
+ assert stream != null;
+
+ ElementHandler contentHandler = new ElementHandler(parent, this);
+ try {
+ SAXParser parser = parserFactory.newSAXParser();
+ parser.getXMLReader().setErrorHandler(errorHandler);
+ parser.parse(stream, contentHandler);
+ } catch (ParserConfigurationException pce) {
+ throw new SAXException(pce.getLocalizedMessage(), pce);
+ } catch (IOException ioe) {
+ throw new SAXException(ioe.getLocalizedMessage(), ioe);
+ }
+ }
+
+ private void loadXData(InputStream stream) {
+ if(xDataElement != null) {
+ try {
+ SAXParser parser = parserFactory.newSAXParser();
+ parser.getXMLReader().setErrorHandler(errorHandler);
+ StringBuilder out = new StringBuilder();
+ parser.parse(stream, new XDataHandler(out));
+ String content = out.toString();
+ xDataElement.setContent(content);
+ } catch (ParserConfigurationException e) {
+ } catch (SAXException e) {
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * @see ElementHandler
+ */
+ protected void preElement(Element element) {
+ assert element != null;
+ assert elements.containsKey(element.getId()) : "Element already exists in registry: " + element.getId();
+
+ // Add to cache.
+ elements.put(element.getId(), element);
+
+ // If it is a runnable element, add to top-level cache.
+ if(element.getParent() == null && rootElement == null) {
+ rootElement = element;
+ }
+ }
+
+ /**
+ * @see ElementHandler
+ */
+ protected void postElement(Element element) {
+ assert element != null;
+ assert !elements.containsKey(element.getId()) : "Element not found in registry: " + element.getId();
+ if("xdata".equalsIgnoreCase(element.getName()) && IConstants.XWT_X_NAMESPACE.equals(element.getNamespace())) {
+ xDataElement = element;
+ }
+ }
+
+ /**
+ * @see #load(File)
+ * @see #load(URL)
+ */
+ private void doLoad(InputStream stream) throws Exception {
+ assert stream != null;
+ ElementHandler contentHandler = new ElementHandler(this);
+ try {
+ SAXParser parser = parserFactory.newSAXParser();
+ parser.getXMLReader().setErrorHandler(errorHandler);
+ parser.parse(stream, contentHandler);
+ } catch (SAXException saxe) {
+ // Exception cause = saxe.getException();
+ // try {
+ // if (cause != null) {
+ // XWT.getLogger().error(cause);
+ // } else {
+ // XWT.getLogger().error(saxe);
+ // }
+ // } catch (Exception e) {
+ // // e.printStackTrace();
+ // }
+ throw saxe;
+ } catch (ParserConfigurationException pce) {
+ try {
+ XWT.getLogger().error(pce);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ throw pce;
+ } catch (IOException ioe) {
+ try {
+ XWT.getLogger().error(ioe);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ throw ioe;
+ }
+ }
+
+ /**
+ * @see #load(File)
+ * @see #load(URL)
+ */
+ private void reset() {
+
+ // Reset code base.
+ documentRoot.reset();
+ }
+
+}
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/XDataHandler.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/XDataHandler.java
new file mode 100644
index 00000000000..592bf0ec309
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/XDataHandler.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
+ * Soyatec - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.xwt.internal.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * @author jliu jin.liu@soyatec.com
+ */
+public class XDataHandler extends DefaultHandler implements ContentHandler {
+
+ private boolean namespaceBegin = false;
+
+ private String currentNamespace;
+
+ private String currentNamespaceUri;
+
+ private StringBuilder out;
+
+ private boolean started;
+
+ public XDataHandler(StringBuilder out) {
+ this.out = out;
+ }
+
+ public void startPrefixMapping(String prefix, String uri) {
+ namespaceBegin = true;
+ currentNamespace = prefix;
+ currentNamespaceUri = uri;
+ }
+
+ public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
+ if(started) {
+ out.append("<" + qName);
+ if(namespaceBegin) {
+ out.append(" xmlns:" + currentNamespace + "=\"" + currentNamespaceUri + "\"");
+ namespaceBegin = false;
+ }
+ for(int i = 0; i < atts.getLength(); i++) {
+ out.append(" " + atts.getQName(i) + "=\"" + atts.getValue(i) + "\"");
+ }
+ out.append(">");
+ }
+ if(localName.equalsIgnoreCase("xdata")) {
+ started = true;
+ }
+ }
+
+ public void endElement(String namespaceURI, String localName, String qName) {
+ if(localName.equalsIgnoreCase("xdata")) {
+ started = false;
+ }
+ if(started) {
+ out.append("</" + qName + ">");
+ }
+ }
+
+ public void characters(char[] ch, int start, int length) {
+ if(started) {
+ for(int i = start; i < start + length; i++) {
+ out.append(ch[i]);
+ }
+ }
+ }
+
+ public void ignorableWhitespace(char[] ch, int start, int length) {
+ if(started) {
+ for(int i = start; i < start + length; i++) {
+ out.append(ch[i]);
+ }
+ }
+ }
+
+ public void processingInstruction(String target, String data) {
+ if(started) {
+ out.append("<?" + target + " " + data + "?>");
+ }
+ }
+
+ public void skippedEntity(String name) {
+ if(started) {
+ out.append("&" + name + ";");
+ }
+ }
+}

Back to the top