Senior Project Design
Jini Service UIs in SORCERAgenda
- SOA, SOOA, Service UI
- UI Descriptors
- Arithmetic Demo
- API Details
- Implications
- Four Ways to Attach Service UI in SORCER
- Yet Another Calculator Demo
- Conclusions
Service Oriented Architecture (SOA)
![](images/soa.png)
Service Object-Oriented Architecture (SOOA)
![](images/serviceRequestor.png)
User Agent and Service UI
![](images/soa-serviceui.png)
Bundles of Functionality
Client UI
Service UI
-
Can give access to full functionality
-
Can be branded
-
Increases accessibility to users
package sorcer.arithmetic;
import java.rmi.RemoteException;
import sorcer.service.Context;
public class ArithmeticProviderImpl implements ArithmeticRemote {
public Context add(Context context) throws RemoteException;
public Context subtract(Context context) throws RemoteException;
public Context multiply(Context context) throws RemoteException;
public Context divide(Context context) throws RemoteException;
}
package sorcer.arithmetic;
import sorcer.arithmetic.Adder;
import sorcer.arithmetic.Divider;
import sorcer.arithmetic.Multiplier;
import sorcer.arithmetic.Subtractor;
public interface ArithmeticRemote extends Adder, Subtractor, Divider, Multiplier, Remote {)
-
To use a service UI, clients need prior knowledge
-
We needed a standard way to:
- Associate UIs with services
- Access those UIs at the client
User Adapters
UI Descriptors
- UI provider describes UIs
- Client decides
Class UIDescriptor
- UI descriptors created by
package sorcer.ui.serviceui.UIDescriptorFactory
in SORCER
package net.jini.lookup.entry;
// imports...
public class UIDescriptor extends AbstractEntry {
public String role;
public String toolkit;
public Set attributes;
public MarshalledObject factory;
//...
}
UI Role
- Describe purpose of UI
- Examples: main, admin, about
- UIDescriptor.role = fully qualified name of role interface
package net.jini.lookup.ui;
public interface MainUI {
String ROLE = "net.jini.lookup.ui.MainUI";
}
The Role Interface
-
UI object implements the role interface
-
MainUI, AdminUI, and AboutUI are tag interfaces
-
Role interfaces can declare methods
package sorcer.arithmetic.ui;
import javax.swing.JFrame;
import net.jini.lookup.ui.MainUI;
public class ArithmeticFrameUI extends JFrame
implements MainUI {
//...
}
UI Attributes
-
UIDescriptor.attributes = a set of objects that describe the UI
-
Four attribute classes defined:
- AccessibleUI
- Locales
- RequiredPackages
- UIFactoryTypes
AccessibleUI Attribute
-
Says two things about the UI:
- Implements
javax.accessibility.Accessible
- Programmer did the necessary work
package net.jini.lookup.ui.attribute;
public class AccessibleUI
implements java.io.Serializable {
public boolean equals(Object o) {}
public int hashCode() {}
}
Locales Attribute
-
Describes supported locales
package net.jini.lookup.ui.attribute;
import java.util.*;
public class Locales
implements java.io.Serializable {
public boolean isLocaleSupported(Locale locale) {}
public Locale getFirstSupportedLocale(
List locales) {}
public Iterator iterator() {}
public Set getLocales() {}
//...
}
RequiredPackages Attribute
- Lists packages required by the UI:
- fully qualified package name
- package version number
package net.jini.lookup.ui.attribute;
import java.util.*;
public class RequiredPackages
implements java.io.Serializable {
public Iterator iterator() {}
public String getVersion(String packageName) {}
public Map getRequiredPackages() {}
}
UI Factories
-
Don't want to serialize UI objects
-
Instead, serialize a UI factory
-
To get the UI, Client invokes factory method
-
Factory methods declared in UI factory interfaces (
net.jini.lookup.ui.factory
):
getJComponent()
declared in interface JComponentFactory
or getPanel()
declared in interface PanelFactory
-
getJFrame()
declared in interface JFrameFactory
or getFrame()
declared in interface FrameFactory
getJDialog()
declared in
JDialogFactory
or getDialog()
declared in DialogFactory
getJWindow()
declared in
JWindowFactory
or getWindow()
declared in
WindowFactory
- Swing versions of these interfaces implemented in
package sorcer.ui.serviceui
UIFactoryTypes Attribute
-
Lists UI factory interfaces implemented by the factory object
- (Factory is stored in
UIDescriptor.factory
)
package net.jini.lookup.ui.attribute;
import java.util.*;
public class UIFactoryTypes
implements java.io.Serializable {
public boolean isAssignableTo(Class classObj) {}
public Iterator iterator() {}
public Set getTypeNames() {}
}
UI Toolkit
-
UIDescriptor.toolkit
= package name of primary UI toolkit used by UI
-
Enables clients to narrow search for services based on UIs offered
UI Factory Interfaces
- Family of interfaces, each with targeted factory methods:
- AWT
DialogFactory
FrameFactory
PanelFactory
WindowFactory
- Swing
JDialogFactory
JFrameFactory
JComponentFactory
JWindowFactory
JFrameFactory
package net.jini.lookup.ui.factory;
import javax.swing.JFrame;
public interface JFrameFactory
extends java.io.Serializable {
String TOOLKIT = "javax.swing";
String TYPE_NAME =
"net.jini.lookup.ui.factory.JFrameFactory";
JFrame getJFrame(Object roleObject);
}
Separating Codebases
- Must not force clients to download JAR files for UI's they'll never use
public String role;
public String toolkit;
public Set attributes;
public MarshalledObject factory;
Marshalling the UI Factory
UIDescriptor descriptor = new UIDescriptor();
Class c = RMIClassLoader.loadClass(
"http://sorcer.cs.ttu.edu:9000/arithmetic-ui.jar",
"package sorcer.ui.serviceui.UIFrameFactory");
Object factory = c.newInstance();
descriptor.factory = new MarshalledObject(factory);
Unmarshalling the UI Factory
- Client can call getUIFactory() on UIDescriptor
public final Object getUIFactory(final ClassLoader parentLoader)
throws IOException, ClassNotFoundException {}
- Must pass a class loader that can load the classes
of the role object
Object uiFactory = selectedDescriptor.getUIFactory(
serviceItem.service.getClass().getClassLoader());
Generating the UI
- Client invokes a factory method, passing in the role object
- package
sorcer.ui.serviceui.UIFrameFactory implements JFrameFactory
JFrameFactory frameFactory = (JFrameFactory) uiFactory;
JFrame jff = frameFactory.getJFrame(serviceItem);
jff.setLocation(100, 100);
jff.setVisible(true);
//...
-
Service UI can be generated by service browsers, Inca X for example
UI Talks to the Service
public class AritmeticUI extends JPanel {
private ArithmeticRemote server;
public AritmeticUI (Object obj) {
this.servcer = (ArithmeticRemote)obj;
//...
Arithmetic Service UI - Component Type
public UIDescriptor getMainUIDescriptor() {
// Associate the service UI as a component
UIDescriptor uiDesc = null;
try {
uiDesc = UIDescriptorFactory.getUIDescriptor(
MainUI.ROLE,
new UIComponentFactory(new URL[]{new URL(urlbase +
"arithmetic-ui.jar")},
"sorcer.arithmetic.ui.ArithmeticUI"));
} catch(Exception ex) {
ex.printStackTrace();
}
return uiDesc;
}
Cataloger Service UI - Frame Type
public UIDescriptor getMainUIDescriptor() {
UIDescriptor uiDesc = null;
try {
uiDesc = UIDescriptorFactory.getUIDescriptor(
MainUI.ROLE,
new UIFrameFactory(new URL[] {new URL(Env.getHttpCodebase() +
"cataloger-ui.jar")},
"sorcer.core.provider.catalog.CatalogerUI"));
} catch (Exception ex) {
ex.printStackTrace();
}
return uiDesc;
}
Cataloger Service UI - Component Type as Frame via a Button
public UIDescriptor getMainUIDescriptor() {
UIDescriptor uiDesc = null;
try {
uiDesc = UIDescriptorFactory.getUIDescriptor(MainUI.ROLE,
new UIComponentFactory(new URL[] { new URL(Env
.getWebsterUrl()
+ "/cataloger-ui.jar") }, CatalogerUI.class
.getName(), true));
} catch (Exception ex) {
ex.printStackTrace();
}
return uiDesc;
}
Arithmetic UI - Configuration Entry
sorcer.core.provider.ServiceProvider {
/* service provider genetic properties */
name = "Smart Arithmetic";
description = "Example of a SORCER smart proxy provider";
interfaces = new String[] { "sorcer.arithmetic.provider.Arithmetic" };
entries = new Entry[] { ArithmeticUI.getUIDescriptor(),
ServiceProvider.getUIDescriptor(),
new Comment("It uses sorcer.arithmetic.Arithmometer for smart proxying"),
new Location("3", "310", "CP TTU") };
// smart proxy
smartProxy = new SmartArithmometer();
}
Conclusion
- Can add new roles, factories, and attributes
- Services can be used by both people and software
- Can create different UIs for different client devices
- More natural UIs than web pages
- UI descriptors created by
package sorcer.ui.serviceui.UIDescriptorFactory
in SORCER