Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java16
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/IXWTLoader.java39
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/core/Core.java74
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DefaultElementCache.java73
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/ElementManager.java14
-rw-r--r--plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/IElementCache.java56
6 files changed, 251 insertions, 21 deletions
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java b/plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java
index 3e90438af7b..c057263f513 100644
--- a/plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties/src/org/eclipse/papyrus/views/properties/runtime/DefaultDisplayEngine.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2010, 2013 CEA LIST.
+ * Copyright (c) 2010, 2014 CEA LIST and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -9,10 +9,13 @@
* Contributors:
* Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
* Christian W. Damus (CEA) - Use URIs to support non-URL-compatible storage (CDO)
+ * Christian W. Damus (CEA) - bug 417409
+ *
*****************************************************************************/
package org.eclipse.papyrus.views.properties.runtime;
import java.net.URL;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
@@ -34,6 +37,7 @@ import org.eclipse.papyrus.views.properties.util.EMFURLStreamHandler;
import org.eclipse.papyrus.views.properties.xwt.XWTTabDescriptor;
import org.eclipse.papyrus.xwt.DefaultLoadingContext;
import org.eclipse.papyrus.xwt.ILoadingContext;
+import org.eclipse.papyrus.xwt.IXWTLoader;
import org.eclipse.papyrus.xwt.XWT;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
@@ -56,6 +60,8 @@ public class DefaultDisplayEngine implements DisplayEngine {
private Set<Control> controls = new HashSet<Control>();
private boolean allowDuplicate;
+
+ private Object xmlCache;
/**
* Constructs a new DisplayEnginet that doesn't allow the duplication of sections
@@ -183,7 +189,13 @@ public class DefaultDisplayEngine implements DisplayEngine {
try {
ResourceSet rset = section.eResource().getResourceSet();
URL url = new URL(null, sectionFile.toString(), new EMFURLStreamHandler(rset.getURIConverter()));
- control = (Control)XWT.load(parent, url, source);
+
+ Map<String, Object> options = new HashMap<String, Object>();
+ options.put(IXWTLoader.CONTAINER_PROPERTY, parent);
+ options.put(IXWTLoader.DATACONTEXT_PROPERTY, source);
+ options.put(IXWTLoader.XML_CACHE_PROPERTY, (xmlCache != null) ? xmlCache : Boolean.TRUE);
+ control = (Control)XWT.loadWithOptions(url, options);
+ xmlCache = options.get(IXWTLoader.XML_CACHE_PROPERTY);
if(control != null) {
control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/IXWTLoader.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/IXWTLoader.java
index 7dc634dcf44..dd8713bf5be 100644
--- a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/IXWTLoader.java
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/IXWTLoader.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) and others.
+ * Copyright (c) 2006, 2014 Soyatec (http://www.soyatec.com), CEA, and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,8 @@
*
* Contributors:
* Soyatec - initial API and implementation
+ * Christian W. Damus (CEA) - bug 417409
+ *
*******************************************************************************/
package org.eclipse.papyrus.xwt;
@@ -31,6 +33,7 @@ import org.eclipse.papyrus.xwt.core.TriggerBase;
import org.eclipse.papyrus.xwt.databinding.IBindingContext;
import org.eclipse.papyrus.xwt.input.ICommand;
import org.eclipse.papyrus.xwt.internal.core.UpdateSourceTrigger;
+import org.eclipse.papyrus.xwt.internal.xml.IElementCache;
import org.eclipse.papyrus.xwt.metadata.IMetaclass;
import org.eclipse.papyrus.xwt.metadata.IProperty;
import org.eclipse.swt.widgets.Composite;
@@ -122,8 +125,38 @@ public interface IXWTLoader {
*
*/
String BEFORE_PARSING_CALLBACK = IBeforeParsingCallback.class.getName();
-
- String[] ALL_PROPERTIES = { URL_PROPERTY, CONTAINER_PROPERTY, INIT_STYLE_PROPERTY, DATACONTEXT_PROPERTY, BINDING_CONTEXT_PROPERTY, RESOURCE_DICTIONARY_PROPERTY, CLASS_PROPERTY, CLASS_FACTORY_PROPERTY, LOADED_CALLBACK, CREATED_CALLBACK, BEFORE_PARSING_CALLBACK, DESIGN_MODE_PROPERTY };
+
+ /**
+ * Parsed XML element caching option. In the public API, this may be only either a {@link Boolean} indicating whether to cache the XML content
+ * parsed from XWT resources (the cache having some unspecified default size) or a positive {@link Integer} indicating the size of XML cache.
+ * This load option is a bit odd in that, if specified, it is replaced by the actual cache, which then should be supplied as the option value
+ * for subsequent calls. Thus, the following idiom is recommended:
+ *
+ * <pre>
+ * private Object xmlCache; // the XML cache
+ *
+ * // other fields ...
+ *
+ * void whatever() {
+ * Map<String, Object> options = new HashMap&lt;String, Object&gt;();
+ * options.put(IXWTLoader.XML_CACHE_PROPERTY, (xmlCache != null) ? xmlCache : Boolean.TRUE);
+ * // ... set other options as needed ...
+ *
+ * URL url = getResourceURL(); // however this is obtained
+ *
+ * Object ui = XWT.loadWithOptions(url, options);
+ *
+ * // Get the cache to reuse next time
+ * xmlCache = options.get(IXWTLoader.XML_CACHE_PROPERTY);
+ *
+ * doSomethingWithTheUI(ui);
+ * }
+ * </pre>
+ */
+ String XML_CACHE_PROPERTY = IElementCache.class.getName();
+
+
+ String[] ALL_PROPERTIES = { URL_PROPERTY, CONTAINER_PROPERTY, INIT_STYLE_PROPERTY, DATACONTEXT_PROPERTY, BINDING_CONTEXT_PROPERTY, RESOURCE_DICTIONARY_PROPERTY, CLASS_PROPERTY, CLASS_FACTORY_PROPERTY, LOADED_CALLBACK, CREATED_CALLBACK, BEFORE_PARSING_CALLBACK, DESIGN_MODE_PROPERTY, XML_CACHE_PROPERTY };
/**
* Register an Observable IChangeListener for a given UI element. The second
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
index 9873fb8cbb1..f28065ffbc5 100644
--- 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) and others.
+ * Copyright (c) 2006, 2014 Soyatec (http://www.soyatec.com), CEA, 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
@@ -7,9 +7,13 @@
*
* Contributors:
* Soyatec - initial API and implementation
+ * Christian W. Damus (CEA) - bug 417409
+ *
*******************************************************************************/
package org.eclipse.papyrus.xwt.internal.core;
+import static org.eclipse.papyrus.xwt.IXWTLoader.XML_CACHE_PROPERTY;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -48,10 +52,12 @@ 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.DefaultElementCache;
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.internal.xml.IElementCache;
import org.eclipse.papyrus.xwt.javabean.ValueConvertorRegister;
import org.eclipse.papyrus.xwt.metadata.IMetaclass;
import org.eclipse.swt.graphics.Point;
@@ -715,23 +721,39 @@ public class Core {
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);
+ IElementCache cache = getCache(options);
+ element = cache.getElement(input);
+ if(element != null) {
+ manager.setRootElement(element);
+
+ // Got an element from the cache, so we don't need an input stream
+ if(stream != null) {
stream.close();
- content = callback.onParsing(content);
- inputStream = new ByteArrayInputStream(content.getBytes());
- element = manager.load(stream, input);
}
- element = manager.load(inputStream, input);
+ } else {
+ 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);
+ }
+
+ if(cache != null) {
+ cache.cache(input, element);
+ }
}
+
IRenderingContext context = new ExtensionContext(loadingContext, manager, manager.getRootElement().getNamespace());
Object visual = createCLRElement(context, element, options);
if(TRACE_BENCH) {
@@ -773,6 +795,28 @@ public class Core {
return control;
}
+ private IElementCache getCache(Map<String, Object> options) {
+ Object option = (options == null) ? IElementCache.NULL : options.get(XML_CACHE_PROPERTY);
+ if(option instanceof Boolean) {
+ // Enable caching according to the option
+ if(((Boolean)option).booleanValue()) {
+ option = new DefaultElementCache();
+ } else {
+ option = IElementCache.NULL;
+ }
+ options.put(XML_CACHE_PROPERTY, option);
+ } else if(option instanceof Number) {
+ // create a default cache of this size
+ option = new DefaultElementCache(((Number)option).intValue());
+ options.put(XML_CACHE_PROPERTY, option);
+ } else if(!(option instanceof IElementCache)) {
+ option = IElementCache.NULL;
+ options.put(XML_CACHE_PROPERTY, option);
+ }
+
+ return (IElementCache)option;
+ }
+
protected void autoLayout(Control composite, Element element) {
if(element == null) {
return;
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DefaultElementCache.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DefaultElementCache.java
new file mode 100644
index 00000000000..b7c3e1e98cb
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/DefaultElementCache.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014 CEA 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:
+ * Christian W. Damus (CEA) - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.xwt.internal.xml;
+
+import java.net.URL;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+/**
+ * The default implementation of the cache of parsed XML elements for XWT source files.
+ */
+public class DefaultElementCache implements IElementCache {
+
+ /** The default cache size (currently {@value}). */
+ static int DEFAULT_CACHE_SIZE = 128;
+
+ private final int cacheSize;
+
+ private final Map<String, Element> cache = new LinkedHashMap<String, Element>() {
+
+ private static final long serialVersionUID = 1L;
+
+ protected boolean removeEldestEntry(Map.Entry<String, Element> eldest) {
+ return size() > cacheSize;
+ }
+ };
+
+
+ /**
+ * Initializes me with a cache of the {@linkplain #DEFAULT_CACHE_SIZE default size}.
+ */
+ public DefaultElementCache() {
+ this(DEFAULT_CACHE_SIZE);
+ }
+
+ /**
+ * Initializes me with a specific size of cache.
+ *
+ * @param cacheSize
+ * the maximal number of cached XML elements to keep
+ *
+ * @throws IllegalArgumentException
+ * if the {@code cacheSize} is not positive
+ */
+ public DefaultElementCache(int cacheSize) {
+ super();
+
+ if(cacheSize <= 0) {
+ throw new IllegalArgumentException("non-positive cacheSize"); //$NON-NLS-1$
+ }
+
+ this.cacheSize = cacheSize;
+ }
+
+ public Element getElement(URL url) {
+ return cache.get(url.toExternalForm());
+ }
+
+ public void cache(URL url, Element element) {
+ cache.put(url.toExternalForm(), element);
+ }
+}
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
index 51d0d06cf8a..3648cf458a6 100644
--- 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2013 Soyatec (http://www.soyatec.com), CEA, and others.
+ * Copyright (c) 2006, 2014 Soyatec (http://www.soyatec.com), CEA, 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
@@ -8,6 +8,8 @@
* Contributors:
* Soyatec - initial API and implementation
* Christian W. Damus (CEA) - Fix failure to propagate stream handlers of URLs (CDO)
+ * Christian W. Damus (CEA) - bug 417409
+ *
*******************************************************************************/
package org.eclipse.papyrus.xwt.internal.xml;
@@ -205,6 +207,16 @@ public class ElementManager {
public Element getRootElement() {
return rootElement;
}
+
+ /**
+ * Sets my root element (either loaded by me or perhaps obtained from some cache or other source).
+ *
+ * @param rootElement
+ * my root element
+ */
+ public void setRootElement(Element rootElement) {
+ this.rootElement = rootElement;
+ }
/*
* (non-Javadoc)
diff --git a/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/IElementCache.java b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/IElementCache.java
new file mode 100644
index 00000000000..f5f2293024b
--- /dev/null
+++ b/plugins/xwt/org.eclipse.papyrus.xwt/src/org/eclipse/papyrus/xwt/internal/xml/IElementCache.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 CEA 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:
+ * Christian W. Damus (CEA) - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.xwt.internal.xml;
+
+import java.net.URL;
+
+
+/**
+ * A cache of reusable XML elements previously parsed from specific {@code URL}s. Implementations may selectively
+ * cache content, for example caching only elements for <tt>platform:/resource</tt> or OSGi bundle URLs because
+ * others such as HTTP URLs reference potentially changeable resources.
+ */
+public interface IElementCache {
+
+ /** An implementation of the protocol that doesn't actually cache anything. */
+ IElementCache NULL = new IElementCache() {
+
+ public Element getElement(URL url) {
+ return null;
+ }
+
+ public void cache(URL url, Element element) {
+ // Pass
+ }
+ };
+
+ /**
+ * Obtains the previously cached element parsed from the given {@code url}.
+ *
+ * @param url
+ * the URL of an XWT resource
+ *
+ * @return the previously parsed contents of the resource, or {@code null} if the cache has nothing for this {@code url}
+ */
+ Element getElement(URL url);
+
+ /**
+ * Adds an {@code element} parsed from the resource indicated by the given {@code url}.
+ *
+ * @param url
+ * the URL of an XWT resource that was parsed
+ * @param element
+ * the element that was parsed from it
+ */
+ void cache(URL url, Element element);
+}

Back to the top