11. Apéndice IV: Aplicación del proceso
11.1. Servicio WireAdmin
11.1.5. Reglas de transformación y plantillas de Acceleo
En este caso gran cantidad de código es generada a partir del modelo que en esencia es muy simple, esto muestra un ejemplo donde una herramienta MDA es de gran ayuda en la construcción de aplicaciones. A continuación se presenta el conjunto de reglas de transformación definidas para este problema.
Figura 70: Editor visual para modelar aplicaciones basadas en el servicio WireAdmin Figura 69: Modelo de mapeo GMF para el servicio WireAdmin
Elemento del modelo Código generado Consumer Consumer.java import java.util.Dictionary; import java.util.Hashtable; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import org.osgi.service.wireadmin.Consumer; import org.osgi.service.wireadmin.Wire; import org.osgi.service.wireadmin.WireConstants;
public void stop(BundleContext bundleContext) throws Exception { serviceRegistration.unregister();
}
public void producersConnected(Wire[] wires) { this.wires = wires; } Producer Producer.java import java.util.Hashtable; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.wireadmin.Producer; import org.osgi.service.wireadmin.Wire; context.registerService(Producer.class.getName(), this, ht); public void end() {
this.quit = true; }
public synchronized void consumersConnected(Wire wires[]) { this.wires = wires; } Consumer.acceptsConsumer, Flavor.class Consumer.java import <Flavor.class>;
public void updated(Wire wire, Object obj) { if ( obj instanceof Date )
process<Flavor.class>( (<Flavor.class>) obj ); } properties.put(WireConstants.WIREADMIN_CONSUMER_FLAVORS, new Class[] { <Flavor.class>.class, }); serviceRegistration=bundleContext.registerService(Consumer.class.getName(), this, properties);
public void process<Flavor.class> (<Flavor.class> input) { }
Producer.acceptsProducer, Flavor.class
Producer.java
import <Flavor.class>;
public synchronized void run() {
Hashtable ht = new Hashtable();
ht.put(org.osgi.service.wireadmin.WireConstants.WIREADMIN_PRODUCER_FLAVORS,n ew Class[] {
<Flavor.class>.class, });
Elemento del modelo Código generado
Class clazzes[] = wire.getFlavors(); for (int i = 0; i < clazzes.length; i++) {
Class clazz = clazzes[i];
if (clazz.isAssignableFrom(<Flavor.class>.class)){ <Flavor.class> obj = new <Flavor.class>(); return obj; } } return null; } Consumer.name Consumer.java
public class <Consumer.name>
implements Consumer, BundleActivator { private Wire[] wires = null;
private ServiceRegistration serviceRegistration; public <Consumer.name> ( ) {
}
Producer.name Producer.java
public class <Producer.name> implements Producer, Runnable { private Wire wires[];
private BundleContext context; private ServiceRegistration servreg; private boolean quit;
public <Producer.name>(BundleContext context) { this.context = context;
servreg = null; quit = false;
new Thread(this).start(); }
Producer.active = true Producer.java
while (!quit) try {
for (int i = 0; wires != null && i < wires.length; i++){ Wire wire=wires[i]; if(!wire.isConnected() || !wire.isValid()) continue; wire.update(polled(wire)); } wait(150000);
} catch (InterruptedException ie) { }
Consumer.id Consumer.java
public void start(BundleContext bundleContext) throws Exception { Dictionary properties = new Hashtable();
properties.put( Constants.SERVICE_PID,"<Consumer.id>"); Producer.id Producer.java ht.put(org.osgi.framework.Constants.SERVICE_PID, "<Producer.id>"); Producer.description Producer.java ht.put( org.osgi.framework.Constants.SERVICE_DESCRIPTION, "<Producer.description>");
Tabla 9: Reglas de transformación para el servicio WireAdmin
en código Java, uno para el productor y otro para el consumidor. A continuación se presentan ambas plantillas. Consumer.mt <% metamodel http://www.uam.izt.mx/WA %>
<%script type="WA.Consumer" name="consumer" file="<%name%>.java"%>
package // <%startUserCode%>
// Write the package path // <%endUserCode%> import java.util.Dictionary; import java.util.Hashtable; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration; import org.osgi.service.wireadmin.Consumer; import org.osgi.service.wireadmin.Wire; import org.osgi.service.wireadmin.WireConstants; //<%startUserCode%>
// Here write all the imports that's you require for your code
<%for (acceptsConsumer) {%>
import <%class%>;
<%}%>
//<%endUserCode%>
public class <%name%>
implements Consumer, BundleActivator { private Wire[] wires = null;
private ServiceRegistration serviceRegistration; //<%startUserCode%>
// Here write all the attributes you will required; //<%endUserCode%>
public <%name%> ( ) { //<%startUserCode%>
// Here write all the inicialization code; //<%endUserCode%>
}
public void start(BundleContext bundleContext) throws Exception { Dictionary properties = new Hashtable();
properties.put( Constants.SERVICE_PID,"<%id%>"); properties.put( WireConstants.WIREADMIN_CONSUMER_FLAVORS, new Class[] { <%for (acceptsConsumer) {%> <%class%>.class, <%}%> }); serviceRegistration=bundleContext.registerService(Consumer.class.getName(), this, properties); }
public void stop(BundleContext bundleContext) throws Exception { serviceRegistration.unregister();
}
public void updated(Wire wire, Object obj) {
<%for (acceptsConsumer) {%>
if ( obj instanceof Date )
process<%class%>( (<%class%>) obj );
<%}%>
}
public void producersConnected(Wire[] wires) { this.wires = wires;
}
<%for (acceptsConsumer) {%>
public void process<%class%> (<%class%> input) { // <%startUserCode%>
// Write the code for the manupilation of the object of type <%class%>
// <%endUserCode%>
}
<%}%>
//<%startUserCode%>
// Write your own code; //<%endUserCode%> } Producer.mt <% metamodel http://www.uam.izt.mx/WA %>
<%script type="WA.Producer" name="producer" file="<%name%>.java"%>
package //<%startUserCode%>
//Write the package path //<%endUserCode%> import java.util.Hashtable; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.wireadmin.Producer; import org.osgi.service.wireadmin.Wire; //<%startUserCode%> for import
// Here write all the imports that's you require for your code ;
<%for (acceptsProducer) {%>
import <%class%>;
<%}%>
//<%endUserCode%> for import
public class <%name%> implements Producer, Runnable { private Wire wires[];
private BundleContext context; private ServiceRegistration servreg; private boolean quit;
public <%name%>(BundleContext context) { this.context = context;
servreg = null; quit = false;
new Thread(this).start(); }
Hashtable ht = new Hashtable(); ht.put( org.osgi.service.wireadmin.WireConstants.WIREADMIN_PRODUCER_FLAVORS, new Class[] { <%for (acceptsProducer) {%> <%class%>.class, <%}%> }); ht.put(org.osgi.framework.Constants.SERVICE_PID, "<%id%>"); ht.put( org.osgi.framework.Constants.SERVICE_DESCRIPTION, "<%description%>"); context.registerService(Producer.class.getName(), this, ht);
<%if (active == true) {%>
while (!quit) try {
for (int i = 0; wires != null && i < wires.length; i++){ Wire wire=wires[i]; if(!wire.isConnected() || !wire.isValid()) continue; wire.update(polled(wire)); } wait(150000);
} catch (InterruptedException ie) { }
<%}%>
}
public synchronized void consumersConnected(Wire wires[]) { this.wires = wires;
}
public Object polled(Wire wire) {
Class clazzes[] = wire.getFlavors(); for (int i = 0; i < clazzes.length; i++) {
Class clazz = clazzes[i];
<%for ( acceptsProducer){%>
if (clazz.isAssignableFrom(<%class%>.class)) {
<%class%> obj = new <%class%>(); //<%startUserCode%>
// Here write your code for this type; //<%endUserCode%> return obj; } <%}%> } return null; }
public void end() { this.quit = true; }
}
A continuación se presenta el código generado para el modelo mostrado en la figura 70. Consumidor.java
package // Start of user code
// Write the package path // End of user code
import java.util.Dictionary; import java.util.Hashtable;
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration; import org.osgi.service.wireadmin.Consumer; import org.osgi.service.wireadmin.Wire;
import org.osgi.service.wireadmin.WireConstants;
//Start of user code
// Here write all the imports that's you require for your code
import java.lang.String;
//End of user code
public class Consumidor
implements Consumer, BundleActivator { private Wire[] wires = null;
private ServiceRegistration serviceRegistration;
//Start of user code
// Here write all the attributes you will required; //End of user code
public Consumidor ( ) {
//Start of user code
// Here write all the inicialization code; //End of user code
}
public void start(BundleContext bundleContext) throws Exception { Dictionary properties = new Hashtable();
properties.put(
Constants.SERVICE_PID,"ConID"); properties.put( WireConstants.WIREADMIN_CONSUMER_FLAVORS, new Class[] { java.lang.String.class, }); serviceRegistration=bundleContext.registerService(Consumer.class.getName(), this, properties); }
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister(); }
public void updated(Wire wire, Object obj) { if ( obj instanceof Date )
processjava.lang.String( (java.lang.String) obj ); }
public void producersConnected(Wire[] wires) { this.wires = wires;
}
public void processjava.lang.String (java.lang.String input) {
// Start of user code
// Write the code for the manupilation of the object of type java.lang.String // End of user code
}
//Start of user code // Write your own code; //End of user code
}
Productor.java
//Write the package path //End of user code
import java.util.Hashtable;
import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.wireadmin.Producer; import org.osgi.service.wireadmin.Wire;
//Start of user code for import
// Here write all the imports that's you require for your code ;
import java.lang.String;
import org.osgi.util.position.Position;
//End of user code for import
public class Productor implements Producer, Runnable { private Wire wires[];
private BundleContext context; private ServiceRegistration servreg; private boolean quit;
public Productor(BundleContext context) { this.context = context;
servreg = null;
quit = false;
new Thread(this).start(); }
public synchronized void run() { Hashtable ht = new Hashtable(); ht.put( org.osgi.service.wireadmin.WireConstants.WIREADMIN_PRODUCER_FLAVORS, new Class[] { java.lang.String.class, org.osgi.util.position.Position.class, }); ht.put(org.osgi.framework.Constants.SERVICE_PID, "ProdID");
ht.put( org.osgi.framework.Constants.SERVICE_DESCRIPTION,
"ProductorEjemplo");
context.registerService(Producer.class.getName(), this, ht); while (!quit)
try {
for (int i = 0; wires != null && i < wires.length; i++){ Wire wire=wires[i]; if(!wire.isConnected() || !wire.isValid()) continue; wire.update(polled(wire)); } wait(150000);
} catch (InterruptedException ie) { }
}
public synchronized void consumersConnected(Wire wires[]) { this.wires = wires;
}
public Object polled(Wire wire) {
Class clazzes[] = wire.getFlavors(); for (int i = 0; i < clazzes.length; i++) {
Class clazz = clazzes[i];
if (clazz.isAssignableFrom(java.lang.String.class)) { java.lang.String obj = new java.lang.String();
//Start of user code
// Here write your code for this type; //End of user code
return obj; }
if (clazz.isAssignableFrom(org.osgi.util.position.Position.class)) {
org.osgi.util.position.Position obj = new org.osgi.util.position.Position();
//Start of user code
// Here write your code for this type; //End of user code
return obj; }
}
return null; }
public void end() { this.quit = true; }
}