Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'target_explorer/plugins')
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java89
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java2
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties2
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/META-INF/MANIFEST.MF3
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/build.properties3
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/plugin.xml6
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/schema/factoryDelegates.exsd221
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate.java21
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java63
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java28
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate.java28
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateManager.java78
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateProxy.java107
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.java2
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.properties2
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistable.java12
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/properties/PropertiesFilePersistenceDelegate.java3
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/MapPersistableAdapter.java14
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java14
19 files changed, 691 insertions, 7 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java
index b1064bbe0..739a76a6f 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java
@@ -26,10 +26,13 @@ import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.util.NLS;
import org.eclipse.tcf.te.core.activator.CoreBundleActivator;
import org.eclipse.tcf.te.core.nls.Messages;
+import org.eclipse.tcf.te.runtime.model.factory.Factory;
+import org.eclipse.tcf.te.runtime.model.interfaces.IContainerModelNode;
import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
import org.eclipse.tcf.te.runtime.persistence.PersistenceDelegateManager;
import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable;
import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistenceDelegate;
+import org.osgi.framework.Bundle;
/**
* Model node persistable adapter implementation.
@@ -67,7 +70,7 @@ public class ModelNodePersistableAdapter implements IPersistable {
IPath path = new Path(node.getStringProperty("Path")); //$NON-NLS-1$
uri = path.toFile().toURI();
}
- // Final fallback is to use the UUID
+ // No name and no explicit path is set -> use the UUID
else if (node.getUUID() != null) {
IPath path = getRoot().append(makeValidFileSystemName(node.getUUID().toString().trim()));
if (!"ini".equals(path.getFileExtension())) path = path.addFileExtension("ini"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -118,6 +121,20 @@ public class ModelNodePersistableAdapter implements IPersistable {
}
/* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#getInterfaceType(java.lang.Object)
+ */
+ @SuppressWarnings("restriction")
+ @Override
+ public String getInterfaceTypeName(Object data) {
+ if (data instanceof IContainerModelNode) {
+ return org.eclipse.tcf.te.runtime.model.activator.CoreBundleActivator.getUniqueIdentifier() + ":" + IContainerModelNode.class.getName(); //$NON-NLS-1$
+ } else if (data instanceof IModelNode) {
+ return org.eclipse.tcf.te.runtime.model.activator.CoreBundleActivator.getUniqueIdentifier() + ":" + IModelNode.class.getName(); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
* @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#exportFrom(java.lang.Object)
*/
@Override
@@ -201,6 +218,7 @@ public class ModelNodePersistableAdapter implements IPersistable {
if (persistable != null) {
String storageID = persistable.getStorageID();
URI uri = persistable.getURI(value);
+ String interfaceTypeName = persistable.getInterfaceTypeName(value);
// Check if the persistable returns complete information to create the reference
if (storageID == null) {
@@ -209,16 +227,20 @@ public class ModelNodePersistableAdapter implements IPersistable {
if (uri == null) {
throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_export_invalidPersistable, value.getClass().getCanonicalName(), "uri")); //$NON-NLS-1$
}
+ if (interfaceTypeName == null) {
+ throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_export_invalidPersistable, value.getClass().getCanonicalName(), "interfaceTypeName")); //$NON-NLS-1$
+ }
// Create a reference object
Map<String, String> reference = new HashMap<String, String>();
reference.put("storageID", storageID); //$NON-NLS-1$
reference.put("uri", uri.toString()); //$NON-NLS-1$
+ reference.put("interfaceType", interfaceTypeName); //$NON-NLS-1$
IPersistenceDelegate delegate = PersistenceDelegateManager.getInstance().getDelegate(storageID, false);
if (delegate != null) {
delegate.write(uri, persistable.exportFrom(value));
- dst.put(key, reference);
+ dst.put("reference:" + key, reference); //$NON-NLS-1$
continue;
}
}
@@ -241,7 +263,68 @@ public class ModelNodePersistableAdapter implements IPersistable {
if (data instanceof IModelNode) {
IModelNode node = (IModelNode) data;
for (String key : external.keySet()) {
- node.setProperty(key, external.get(key));
+ // Get the property value
+ Object value = external.get(key);
+
+ // Check for reference objects
+ if (key.startsWith("reference:") && value instanceof Map<?,?>) { //$NON-NLS-1$
+ // Cut the "reference:" from the key
+ String newKey = key.substring(10);
+
+ @SuppressWarnings("unchecked")
+ Map<String, String> reference = (Map<String, String>)value;
+
+ // Get the storage id and the URI from the reference
+ String storageID = reference.get("storageID"); //$NON-NLS-1$
+ String uri = reference.get("uri"); //$NON-NLS-1$
+ String interfaceTypeName = reference.get("interfaceType"); //$NON-NLS-1$
+
+ // Check if the reference returns complete information to read the referenced storage
+ if (storageID == null) {
+ throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_invalidReference, "storageID")); //$NON-NLS-1$
+ }
+ if (uri == null) {
+ throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_invalidReference, "uri")); //$NON-NLS-1$
+ }
+ if (interfaceTypeName == null) {
+ throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_invalidReference, "interfaceType")); //$NON-NLS-1$
+ }
+
+ // Get the persistence delegate
+ IPersistenceDelegate delegate = PersistenceDelegateManager.getInstance().getDelegate(storageID, false);
+ if (delegate != null) {
+ Map<String, Object> referenceData = delegate.read(URI.create(uri));
+ if (referenceData != null && !referenceData.isEmpty()) {
+ try {
+ // Now, we have to recreate the object
+
+ // Separate the bundleId from the interface name
+ String[] pieces = interfaceTypeName.split(":", 2); //$NON-NLS-1$
+ String bundleId = pieces.length > 1 ? pieces[0] : null;
+ if (pieces.length > 1) interfaceTypeName = pieces[1];
+
+ // Determine the bundle to use for loading the class
+ Bundle bundle = bundleId != null && !"".equals(bundleId.trim()) ? Platform.getBundle(bundleId.trim()) : CoreBundleActivator.getContext().getBundle(); //$NON-NLS-1$
+
+ Class<? extends IModelNode> interfaceType = (Class<? extends IModelNode>)bundle.loadClass(interfaceTypeName);
+ IModelNode referenceNode = Factory.getInstance().newInstance(interfaceType);
+
+ IPersistable persistable = (IPersistable)referenceNode.getAdapter(IPersistable.class);
+ if (persistable == null) persistable = (IPersistable)Platform.getAdapterManager().getAdapter(referenceNode, IPersistable.class);
+ if (persistable != null) {
+ persistable.importTo(referenceNode, referenceData);
+ node.setProperty(newKey, referenceNode);
+ }
+ } catch (ClassNotFoundException e) {
+ throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_import_cannotLoadClass, interfaceTypeName), e);
+ }
+ }
+ }
+ }
+ // Not a reference object -> store the object as is to the node
+ else {
+ node.setProperty(key, value);
+ }
}
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java
index b5f669273..ae2936030 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java
@@ -37,4 +37,6 @@ public class Messages extends NLS {
public static String ModelNodePersistableAdapter_export_invalidPersistable;
public static String ModelNodePersistableAdapter_export_unknownType;
+ public static String ModelNodePersistableAdapter_import_invalidReference;
+ public static String ModelNodePersistableAdapter_import_cannotLoadClass;
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties
index 2c5f058ee..f80734b73 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties
@@ -20,3 +20,5 @@ ConnectStrategyStepExecutor_stepFailed_debugInfo=Debug info:\n{0}
ModelNodePersistableAdapter_export_invalidPersistable=Persistable for object type ''{0}'' provides incomplete information for property ''{1}''.
ModelNodePersistableAdapter_export_unknownType=No strategy to persist an object of type ''{0}'', key = ''{1}''.
+ModelNodePersistableAdapter_import_invalidReference=Reference provides incomplete information for property ''{0}'' to restore the object.
+ModelNodePersistableAdapter_import_cannotLoadClass=Cannot load class for name ''{0}''
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/META-INF/MANIFEST.MF
index 0018cebd8..b4025fdc1 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/META-INF/MANIFEST.MF
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/META-INF/MANIFEST.MF
@@ -12,5 +12,8 @@ Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
Export-Package: org.eclipse.tcf.te.runtime.model,
org.eclipse.tcf.te.runtime.model.activator;x-internal:=true,
+ org.eclipse.tcf.te.runtime.model.factory,
org.eclipse.tcf.te.runtime.model.interfaces,
+ org.eclipse.tcf.te.runtime.model.interfaces.factory,
+ org.eclipse.tcf.te.runtime.model.internal.factory;x-internal:=true,
org.eclipse.tcf.te.runtime.model.nls;x-internal:=true
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/build.properties b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/build.properties
index f4ae97015..73a5119ed 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/build.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/build.properties
@@ -2,4 +2,5 @@ source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
- plugin.properties
+ plugin.properties,\
+ plugin.xml
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/plugin.xml
new file mode 100644
index 000000000..34249eeb3
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/plugin.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension-point id="factoryDelegates" name="Model Node Factory Delegates" schema="schema/factoryDelegates.exsd"/>
+
+</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/schema/factoryDelegates.exsd b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/schema/factoryDelegates.exsd
new file mode 100644
index 000000000..33854922f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/schema/factoryDelegates.exsd
@@ -0,0 +1,221 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tcf.te.runtime.model" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.tcf.te.runtime.model" id="factoryDelegates" name="Model Node Factory Delegates"/>
+ </appinfo>
+ <documentation>
+ This extension point is used to contribute model node factory delegates.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="delegate" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="delegate">
+ <annotation>
+ <documentation>
+ Declares a model node factory delegate contribution.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="class" minOccurs="0" maxOccurs="1"/>
+ <element ref="nodeType" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The unique id of the model node factory delegate contribution.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string">
+ <annotation>
+ <documentation>
+ The label representing the model node factory delegate.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+ The class that implements &lt;code&gt;org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate&lt;/code&gt; or extends &lt;code&gt;org.eclipse.tcf.te.runtime.model.factory.AbstractFactoryDelegate&lt;/code&gt;.
+&lt;p&gt;
+The model node factory delegate implementation class must be specified either by the class attribute or the class child element!
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.tcf.te.runtime.model.factory.AbstractFactoryDelegate:org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="class">
+ <annotation>
+ <documentation>
+ Used when creating an &lt;code&gt;IExecutableExtension&lt;/code&gt; with a named parameter, or more than one.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="parameter" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="class" type="string">
+ <annotation>
+ <documentation>
+ The class that implements &lt;code&gt;org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate&lt;/code&gt; or extends &lt;code&gt;org.eclipse.tcf.te.runtime.model.factory.AbstractFactoryDelegate&lt;/code&gt;.
+&lt;p&gt;
+The model node factory delegate implementation class must be specified either by the class attribute or the class child element!
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.tcf.te.runtime.model.factory.AbstractFactoryDelegate:org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="parameter">
+ <annotation>
+ <documentation>
+ A parameter for an &lt;code&gt;IExecutableExtension&lt;/code&gt;.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ &lt;p&gt;The parameter name.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="value" type="string" use="required">
+ <annotation>
+ <documentation>
+ &lt;p&gt;The parameter value.&lt;/p&gt;
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="nodeType">
+ <annotation>
+ <documentation>
+ The node type interface implemented by nodes created by the factory delegate.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.tcf.te.runtime.model.interfaces.IModelNode"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="bundleId" type="string">
+ <annotation>
+ <documentation>
+ The unique id of the bundle which contains the class loader required to load the node type class. If not specified, the plugin&apos;s own class loader is used.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ Target Explorer 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ This is an example of the extension point usage:
+&lt;p&gt;
+&lt;pre&gt;&lt;code&gt;
+ &lt;extension point=&quot;org.eclipse.tcf.te.runtime.model.factoryDelegates&quot;&gt;
+ &lt;delegate
+ id=&quot;org.eclipse.tcf.te.runtime.model.factory.modelNode&quot;
+ class=&quot;org.eclipse.tcf.te.runtime.model.internal.ModelNodeFactoryDelegate&quot;
+ label=&quot;Model Node Factory Delegate&quot;&gt;
+ &lt;nodeType class=&quot;org.eclipse.tcf.te.runtime.model.interfaces.IModelNode&quot;/&gt;
+ &lt;nodeType class=&quot;org.eclipse.tcf.te.runtime.model.interfaces.IContainerModelNode&quot;/&gt;
+ &lt;/delegate&gt;
+ &lt;/extension&gt;
+&lt;/code&gt;&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ The provider of a model node factory delegate must implement &lt;samp&gt;org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate&lt;/samp&gt;.
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Copyright (c) 2011 Wind River Systems, Inc. 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.
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate.java
new file mode 100644
index 000000000..f2dc3d5ff
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/AbstractFactoryDelegate.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.runtime.model.factory;
+
+import org.eclipse.tcf.te.runtime.extensions.ExecutableExtension;
+import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate;
+
+
+/**
+ * Abstract model node factory delegate implementation.
+ */
+public abstract class AbstractFactoryDelegate extends ExecutableExtension implements IFactoryDelegate {
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java
new file mode 100644
index 000000000..b4c47aad7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/factory/Factory.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.runtime.model.factory;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactory;
+import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate;
+import org.eclipse.tcf.te.runtime.model.internal.factory.FactoryDelegateManager;
+
+/**
+ * Model node factory implementation.
+ */
+public final class Factory extends PlatformObject implements IFactory {
+ private final FactoryDelegateManager manager = new FactoryDelegateManager();
+
+ /*
+ * Thread save singleton instance creation.
+ */
+ private static class LazyInstance {
+ public static Factory instance = new Factory();
+ }
+
+ /**
+ * Returns the singleton instance of the service manager.
+ */
+ public static Factory getInstance() {
+ return LazyInstance.instance;
+ }
+
+ /**
+ * Constructor.
+ */
+ Factory() {
+ super();
+ }
+
+ /**
+ * Creates an new instance of the model node object implementing
+ * the specified node interface.
+ *
+ * @param nodeInterface The node interface to be implemented by the model node object to create.
+ * Must not be <code>null</code>.
+ * @return The model not object implementing the specified node interface or <code>null</code>.
+ */
+ @Override
+ public <V extends IModelNode> V newInstance(Class<V> nodeInterface) {
+ Assert.isNotNull(nodeInterface);
+
+ // Determine the model node factory delegate to use
+ IFactoryDelegate delegate = manager.getFactoryDelegate(nodeInterface);
+ // Return the model node instance
+ return delegate != null ? (V)delegate.newInstance(nodeInterface) : null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java
new file mode 100644
index 000000000..0c1b5b407
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactory.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.runtime.model.interfaces.factory;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+
+/**
+ * Interface to be implemented by model node factories.
+ */
+public interface IFactory extends IAdaptable {
+
+ /**
+ * Creates an new instance of an node object implementing the specified node interface.
+ *
+ * @param nodeInterface The node interface to be implemented by the node object to be created.
+ * Must not be <code>null</code>.
+ * @return The node object implementing the specified node interface or <code>null</code>.
+ */
+ public <V extends IModelNode> V newInstance(Class<V> nodeInterface);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate.java
new file mode 100644
index 000000000..18cead26f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/interfaces/factory/IFactoryDelegate.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.runtime.model.interfaces.factory;
+
+import org.eclipse.tcf.te.runtime.interfaces.extensions.IExecutableExtension;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+
+/**
+ * Interface to be implemented by model node factory delegates.
+ */
+public interface IFactoryDelegate extends IExecutableExtension {
+
+ /**
+ * Returns a new instance of an node object implementing the given node interface.
+ *
+ * @param nodeInterface The node interface to be implemented by the node object to be created.
+ * Must not be <code>null</code>.
+ * @return The node object implementing the specified node interface or <code>null</code>.
+ */
+ public <V extends IModelNode> V newInstance(Class<V> nodeInterface);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateManager.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateManager.java
new file mode 100644
index 000000000..1e5e00354
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateManager.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.runtime.model.internal.factory;
+
+import java.util.Collection;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager;
+import org.eclipse.tcf.te.runtime.extensions.ExecutableExtensionProxy;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate;
+
+
+/**
+ * Model node factory delegate extension point manager implementation.
+ */
+public class FactoryDelegateManager extends AbstractExtensionPointManager<IFactoryDelegate> {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#getExtensionPointId()
+ */
+ @Override
+ protected String getExtensionPointId() {
+ return "org.eclipse.tcf.te.runtime.model.factoryDelegates"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#getConfigurationElementName()
+ */
+ @Override
+ protected String getConfigurationElementName() {
+ return "delegate"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.extensions.AbstractExtensionPointManager#doCreateExtensionProxy(org.eclipse.core.runtime.IConfigurationElement)
+ */
+ @Override
+ protected ExecutableExtensionProxy<IFactoryDelegate> doCreateExtensionProxy(IConfigurationElement element) throws CoreException {
+ return new FactoryDelegateProxy(element);
+ }
+
+ /**
+ * Returns the model node factory delegate for the given node type.
+ * <p>
+ * <b>Note:</b> The first factory delegate declaring the given node type
+ * as supported will be returned.
+ *
+ * @param nodeType The node type. Must not be <code>null</code>.
+ * @return The model node factory delegate or <code>null</code>.
+ */
+ public IFactoryDelegate getFactoryDelegate(Class<? extends IModelNode> nodeType) {
+ Assert.isNotNull(nodeType);
+
+ IFactoryDelegate delegate = null;
+
+ Collection<ExecutableExtensionProxy<IFactoryDelegate>> delegates = getExtensions().values();
+ for (ExecutableExtensionProxy<IFactoryDelegate> candidate : delegates) {
+ if (!(candidate instanceof FactoryDelegateProxy)) continue;
+ if (((FactoryDelegateProxy)candidate).getNodeTypes().contains(nodeType)) {
+ delegate = candidate.getInstance();
+ break;
+ }
+ }
+
+ return delegate;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateProxy.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateProxy.java
new file mode 100644
index 000000000..05af0cc82
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/internal/factory/FactoryDelegateProxy.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.runtime.model.internal.factory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.te.runtime.activator.CoreBundleActivator;
+import org.eclipse.tcf.te.runtime.extensions.ExecutableExtensionProxy;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.runtime.model.interfaces.factory.IFactoryDelegate;
+import org.eclipse.tcf.te.runtime.model.nls.Messages;
+import org.osgi.framework.Bundle;
+
+/**
+ * Model node factory delegate executable extension proxy implementation.
+ */
+public class FactoryDelegateProxy extends ExecutableExtensionProxy<IFactoryDelegate> {
+ // The list of node types supported by the model node factory delegate
+ private final List<Class<? extends IModelNode>> nodeTypes = new ArrayList<Class<? extends IModelNode>>();
+ // Flag to mark if the node types has been loaded
+ private boolean nodeTypesLoaded = false;
+
+ /**
+ * Constructor.
+ *
+ * @param element The configuration element. Must not be <code>null</code>.
+ * @throws CoreException In case the configuration element attribute <i>id</i> is <code>null</code> or empty.
+ */
+ public FactoryDelegateProxy(IConfigurationElement element) throws CoreException {
+ super(element);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param id The id for this instance.
+ * @param instance The instance to add to proxy.
+ */
+ public FactoryDelegateProxy(String id, IFactoryDelegate instance) {
+ super(id, instance);
+ }
+
+ /**
+ * Returns the list of node types supported by the model node factory.
+ *
+ * @return The unmodifiable list of node types.
+ */
+ public List<Class<? extends IModelNode>> getNodeTypes() {
+ if (!nodeTypesLoaded) loadNodeTypes();
+ return Collections.unmodifiableList(nodeTypes);
+ }
+
+ /**
+ * Load the node types.
+ */
+ protected void loadNodeTypes() {
+ IConfigurationElement element = getConfigurationElement();
+ Assert.isNotNull(element);
+
+ nodeTypes.clear();
+
+ IConfigurationElement[] nodeTypeElements = element.getChildren("nodeType"); //$NON-NLS-1$
+ if (nodeTypeElements != null && nodeTypeElements.length > 0) {
+ for (IConfigurationElement nodeTypeElement : nodeTypeElements) {
+ try {
+ String type = nodeTypeElement.getAttribute("class"); //$NON-NLS-1$
+ String bundleId = nodeTypeElement.getAttribute("bundleId"); //$NON-NLS-1$
+
+ // If a bundle id got specified, use the specified bundle to load the node type class
+ Bundle bundle = bundleId != null ? bundle = Platform.getBundle(bundleId) : null;
+ // If we don't have a bundle to load from yet, fallback to the declaring bundle
+ if (bundle == null) bundle = Platform.getBundle(element.getDeclaringExtension().getNamespaceIdentifier());
+ // And finally, use our own bundle to load the class.
+ // This fallback is expected to never be used.
+ if (bundle == null) bundle = CoreBundleActivator.getContext().getBundle();
+
+ // Try to load the node type class now.
+ Class<? extends IModelNode> typeClass = (Class<? extends IModelNode>)(bundle != null ? bundle.loadClass(type) : Class.forName(type));
+ this.nodeTypes.add(typeClass);
+ }
+ catch (Exception e) {
+ IStatus status = new Status(IStatus.WARNING, CoreBundleActivator.getUniqueIdentifier(),
+ NLS.bind(Messages.FactoryDelegateProxy_warning_failedToLoadNodeType, nodeTypeElement.getAttribute("class"), element.getDeclaringExtension().getUniqueIdentifier()), e); //$NON-NLS-1$
+ Platform.getLog(CoreBundleActivator.getContext().getBundle()).log(status);
+ }
+ }
+ }
+
+ nodeTypesLoaded = true;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.java
index eccd6a288..b739d0ce9 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.java
@@ -30,4 +30,6 @@ public class Messages extends NLS {
// **** Declare externalized string id's down here *****
public static String PendingOperationModelNode_label;
+
+ public static String FactoryDelegateProxy_warning_failedToLoadNodeType;
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.properties
index 9fa4cbffc..74497992b 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/nls/Messages.properties
@@ -4,3 +4,5 @@
#
PendingOperationModelNode_label=Pending...
+
+FactoryDelegateProxy_warning_failedToLoadNodeType=Cannot create node type ''{0}'' for model node factory delegate ''{1}''.
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistable.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistable.java
index d93f862fd..17368c32a 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistable.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/interfaces/IPersistable.java
@@ -41,6 +41,18 @@ public interface IPersistable {
public URI getURI(Object data);
/**
+ * Returns the interface type name to use for recreating the object from the
+ * persisted object representation.
+ * <p>
+ * <b>Note:</b> The returned string is expected in the format <code>&quot;&lt;bundleId&gt;:&lt;full qualified interface type name&gt;&quot;</code>.
+ * If the bundle id is not present, it is very likely that the object recreation will fail with a {@link ClassNotFoundException}.
+ *
+ * @param data The data object. Must not be <code>null</code>.
+ * @return The interface type or <code>null</code>.
+ */
+ public String getInterfaceTypeName(Object data);
+
+ /**
* Exports the given data object to an external representation.
* <p>
* As a general guide line, it is expected that the external representation contains only base
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/properties/PropertiesFilePersistenceDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/properties/PropertiesFilePersistenceDelegate.java
index d18465c6d..8522891c2 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/properties/PropertiesFilePersistenceDelegate.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.persistence/src/org/eclipse/tcf/te/runtime/persistence/properties/PropertiesFilePersistenceDelegate.java
@@ -224,7 +224,8 @@ public class PropertiesFilePersistenceDelegate extends AbstractPersistenceDelega
while (line != null) {
Matcher matcher = SECTION.matcher(line);
if (matcher.matches()) {
- currentSection = matcher.group(1).toLowerCase();
+ // Section names are case-sensitive too
+ currentSection = matcher.group(1);
if (sections.get(currentSection) == null) {
sections.put(currentSection, new HashMap<String, Object>());
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/MapPersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/MapPersistableAdapter.java
index e2695c393..d302d769f 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/MapPersistableAdapter.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/MapPersistableAdapter.java
@@ -18,8 +18,8 @@ import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.tcf.protocol.IPeer;
-import org.eclipse.tcf.te.tcf.locator.activator.CoreBundleActivator;
import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable;
+import org.eclipse.tcf.te.tcf.locator.activator.CoreBundleActivator;
/**
* Persistable implementation handling peer attributes.
@@ -98,6 +98,18 @@ public class MapPersistableAdapter implements IPersistable {
}
/* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#getInterfaceType(java.lang.Object)
+ */
+ @Override
+ public String getInterfaceTypeName(Object data) {
+ if (data instanceof Map) {
+ // No bundle id needed here, it's a POJO
+ return Map.class.getName();
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
* @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#exportFrom(java.lang.Object)
*/
@SuppressWarnings("unchecked")
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java
index fa7ee71ff..adce7db44 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.locator/src/org/eclipse/tcf/te/tcf/locator/internal/adapters/PeerModelPersistableAdapter.java
@@ -16,8 +16,9 @@ import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.Path;
import org.eclipse.tcf.protocol.Protocol;
-import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable;
+import org.eclipse.tcf.te.tcf.locator.activator.CoreBundleActivator;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
/**
* Persistable implementation handling peer attributes.
@@ -64,6 +65,17 @@ public class PeerModelPersistableAdapter implements IPersistable {
return uri;
}
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#getInterfaceType(java.lang.Object)
+ */
+ @Override
+ public String getInterfaceTypeName(Object data) {
+ if (data instanceof IPeerModel) {
+ return CoreBundleActivator.getUniqueIdentifier() + ":" + IPeerModel.class.getName(); //$NON-NLS-1$
+ }
+ return null;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable#exportFrom(java.lang.Object)
*/

Back to the top