Hi,

I will expand on this through a little example.
We will put a static HashMap in the MetaDataProvider class, then we will access that HashMap from the DataProvider class, retrieve our related instance and pass to it our DataProvider instance. This flow is needed since LS Kernel initiates the Metadata Adapter before initiating the Data Adapter. This tutorial assumes a basic understanding of Java.

First of all create the adapters.xml file. We will put an additional parameter (match_id) that will help us to make a match between a DataAdapter instance and the MetadataAdapter one. This way, if we have more adapters that share the same class, we just need to give them different match_id to avoid collisions:
Code xml:
  1. <?xml version="1.0"?>
  2.  
  3. <adapters_conf id="ADAPTER_ID">
  4.  
  5.  <metadata_provider>
  6.   <adapter_class>my_package.MyMetadataProvider</adapter_class>
  7.   <param name="match_id">ADAPTER_ID</param>
  8.  </metadata_provider>
  9.  
  10.  <data_provider>
  11.   <adapter_class>my_package.MyDataProvider</adapter_class>
  12.   <param name="match_id">ADAPTER_ID</param>
  13.  </data_provider>
  14.  
  15. </adapters_conf>
So MyMetadataProvider will be our MetadataAdapter class.
To implement this class we will extend the classic LiteralBasedProvider. We will reimplement the init method (to put each instance inside a HashMap) and we will add a method for the setting of the related MyDataProvider instance:
Code java:
  1. package my_package;
  2.  
  3. import java.io.File;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6.  
  7. import com.lightstreamer.adapters.metadata.LiteralBasedProvider;
  8. import com.lightstreamer.interfaces.metadata.MetadataProviderException;
  9.  
  10. public class MyMetadataProvider extends LiteralBasedProvider {
  11.    
  12.     public static HashMap MyDataProviderInstances = new HashMap();
  13.    
  14.     private MyDataAdapter dataAdapter;
  15.    
  16.     public void init(Map params, File configDir) throws MetadataProviderException {
  17.         super.init(params,configDir);
  18.         String adapter_id = (String) params.get("match_id");
  19.         if (adapter_id == null) { throw new MetadataProviderException("match_id for metadata adapter is missing"); }
  20.         MyDataProviderInstances.put(adapter_id,this);
  21.     }
  22.    
  23.     public void setDataAdapter(MyDataAdapter dataAdapter) {
  24.         this.dataAdapter = dataAdapter;
  25.     }
  26.    
  27. }
MyDataProvider will be our DataAdapter class. In the init method of this class we will retrieve the MyMetadataProvider instance from the MyDataProviderInstances HashMap, then we will call its setDataAdapter method. At that point two-way comunication is available. Note that to create a DataProvider implementation you will need to implement a number of methods (like onSubscribe onUnsubscribe etc..) but in this example those are omitted for simplicity:
Code java:
  1. package my_package;
  2.  
  3. import java.io.File;
  4. import java.util.Map;
  5.  
  6. import com.lightstreamer.interfaces.data.DataProvider;
  7. import com.lightstreamer.interfaces.data.DataProviderException;
  8.  
  9. public class MyDataAdapter implements DataProvider {
  10.  
  11.     private MyMetadataProvider metadataAdapter;
  12.    
  13.     public void init(Map params, File configDir) throws DataProviderException {
  14.         String adapter_id = (String) params.get("match_id");
  15.         if (adapter_id == null) { throw new DataProviderException("match_id for data adapter is missing"); }
  16.         metadataAdapter = (MyMetadataProvider) MyMetadataProvider.MyDataProviderInstances.get(adapter_id);
  17.         if (metadataAdapter == null) { throw new DataProviderException("no matching metadata adapter. Check match_id parameters"); }
  18.         metadataAdapter.setDataAdapter(this);
  19.     }
  20. }
Hope that helps.
Mone.