JXTA中定义自己的成员服务

2023-03-13,,

http://blog.csdn.net/neusoftware_20063500/article/details/4302903

——————————————————————————————————————————————————————————————————————————

成员服务:MemberShipService

这个服务是点组用于管理成员的一项服务,既然是服务就可以自己装载和卸载,我们的目的就是定义自己的规则,符合自定义规则的成员可以加入组,否则不可以。所以我们需要实现三个实现类,MemberShipService的实现类、Credential的实现类,Authenticator的实现类。然后需要将成员服务装载到组中,组中的服务继承于父组,所以如果不自定义自己的服务,就继承NetPeerGroup的服务,默认情况下成员服务不做任何验证工作,平台为我们默认实现了PasswdMemberShipService,用于验证密码,那么我们新建自己的组并且装载自己服务的过程如下:

1. 得到父组的ModuleImplAdvertisement

2. StructuredDocument paramDoc = advertisement.getParam()获得参数

3. StdPeerGroupParamAdv paramAdv = new StdPeerGroupParamAdv(paramDoc)封装为标准通告

4. Map services = paramAdv.getServices()得到服务,这些服务就是父组的所有服务

5. services.put(PeerGroup.membershipClassID, moduleAdv);将成员服务替换为自己的成员服务,替换key为membershipClassID的ModuleImplAdvertisement对象,那么如何构建自己服务的ModuleImplAdvertisement对象呢?

6. paramAdv.setServices(services);

7. advertisement.setParam((net.jxta.document.TextElement)paramAdv.getDocument(
                              new net.jxta.document.MimeMediaType(DOCUMENT_MIME_TYPE,
                                                                  DOCUMENT_BASE_TYPE)));还原

8. peerGroup = parent.newGroup(peerGroupID, advertisement, groupName, groupDescription);
peerGroup.init(this.parent,peerGroupID, advertisement);

创建子组然后发布子组。

9. 下面是获得自己的成员服务ModuleImplAdvertisement 的方法

String moduleImplAdvType = ModuleImplAdvertisement.getAdvertisementType();
        ModuleImplAdvertisement implAdvertisement = (ModuleImplAdvertisement)
                    AdvertisementFactory.newAdvertisement(moduleImplAdvType);新建一个空的

implAdvertisement.setModuleSpecID(PeerGroup.refMembershipSpecID);
        implAdvertisement.setCompat(stdCompatStatement);
        implAdvertisement.setCode(code);code是实现MemberShipService的完整类名
        implAdvertisement.setUri(stdUri);
        implAdvertisement.setProvider(stdProvider);
        implAdvertisement.setDescription(descr); 填充信息

那么这样就替换了自己的服务,总体过程是获得父亲组的所有服务,从父亲组的通告(ModuleImplAdvertisement)中获得所有服务,然后将其中的具体某个服务替换成自己的服务(用ModuleImplAdvertisement标示),然后将服务重新设置到通告中,然后根据这个通告创建子组。那么此子组就有自己的成员服务了。

下面是Java P2P程序设计的实例代码:

GroupManager:

package com.sams.jxta.groups;

import net.jxta.credential.AuthenticationCredential;
import net.jxta.credential.Credential;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredTextDocument;
import net.jxta.exception.PeerGroupException;
import net.jxta.exception.ProtocolNotSupportedException;
import net.jxta.id.IDFactory;
import net.jxta.impl.id.UUID.UUIDFactory;
import net.jxta.impl.protocol.PeerGroupAdv;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.peergroup.PeerGroupFactory;
import net.jxta.impl.peergroup.StdPeerGroup;
import net.jxta.impl.peergroup.StdPeerGroupParamAdv;
import net.jxta.membership.Authenticator;
import net.jxta.membership.MembershipService;
import net.jxta.peergroup.PeerGroup;
import net.jxta.platform.ModuleClassID;
import net.jxta.protocol.ModuleImplAdvertisement;
import net.jxta.protocol.PeerGroupAdvertisement; import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map; /**
* This class can be used to create a new group with a pluggable
* Membership service.It provides simple APIs for Apply,Join and Resign
* functionalities.
*/ public class GroupManager { private static final org.apache.log4j.Category LOG =
org.apache.log4j.Category.getInstance(GroupManager.class.getName());
protected DiscoveryService disco;
// The parent group of the current peer group
protected PeerGroup parent;
// Net peer for creating advertisements.
protected PeerGroup netPeerGroup;
// The current peer group
protected PeerGroup activeGroup;
// Any module(like a peer group) that is loaded by the parent group,must
// be compatible with the parent.Compatibility is checked by comparision
// with the stdCompactStatement
public StructuredTextDocument stdCompatStatement = // ??? Taken from StdPeerGroup
mkCS();
// An identifier to the implementation used // ??? Is it so ?
public String stdUri = "http://www.jxta.org/download/jxta.jar";// ??? Taken from StdPeerGroup
// The provider of the implementation // ??? Is it so ?
public String stdProvider = "sun.com";// ??? Taken from StdPeerGroup // The mime type of all documents used in this example
public static final String DOCUMENT_MIME_TYPE="text";
// The base type of all documents
public static final String DOCUMENT_BASE_TYPE="xml";
// This is the root element documents created
public static final String DOCUMENT_ROOT_ELEMENT="Comp";
// Key ??? What is this used for ?
private static final String KEY="Efmt";
// Value ??? What is this used for ?
private static final String VALUE="JDK1.4";
// Key used to represent the binding
private static final String BINDING_KEY="Bind";
// Value of the binding key.It represents the binding
// of JXTA that we use.
private static final String BINDING_VALUE="V1.0 Ref Impl"; /**
* The constructor of the Group Manger.Initially
* the parent group is the also the active group.
*/ public GroupManager(PeerGroup netPeerGroup, PeerGroup parent) { this.disco = parent.getDiscoveryService();
this.parent = parent;
this.activeGroup = parent;
this.netPeerGroup = netPeerGroup;
if (netPeerGroup == null){
System.out.println("netPeerGroup :"+netPeerGroup+" - aborting");
throw new NullPointerException("netPeerGroup :"+netPeerGroup+" - aborting");
}
} /*
* Method to add a new peer group and publish it.The
* groupMemebershipClassName is the fully qualified class
* name of the mermbership service class.
*
*/ public PeerGroup addGroup(String groupName,String groupMembershipClassName,
String groupDescription,
ModuleImplAdvertisement advertisement,
boolean conditional){
System.out.println("GroupManager.addGroup Successfully created SecurityDemoGroup");
// The first thing we do is to see if a group already exists by this name.
// If so we get the Group ID of the group. Then depending on the unconditional
// flag we proceed.
// If it is an conditional add ,we create a new group only if no other group
// with the same name already exists otherwise we throw an exception.
// If it is an unconditional add , we always create a group.If the user had previously
// created the group , we use the Old group ID .
PeerGroupID oldPeerGroupID = alreadyExists(groupName);
if(oldPeerGroupID != null && conditional==true)
throw new GroupManagerException("A Group by this name already exists with id :"
+oldPeerGroupID); // If no Advertisement is provided, we create a fresh advertisement.
if (advertisement == null){
LOG.debug("Creating a new Advertisement");
// We use the existing advertisement of the standard peer group
// and add our service along with the other standard services
try{
// This is used as a base to create the new advertisement upon
System.out.println("netPeerGroup :"+netPeerGroup);
advertisement = netPeerGroup.getAllPurposePeerGroupImplAdvertisement();
//advertisement = parent.getAllPurposePeerGroupImplAdvertisement();//<< Did not work in current platform
StructuredDocument paramDoc = advertisement.getParam();
System.out.println("StructuredDocument paramDoc:"+paramDoc);
// The Param document used to make the StandradPeerGroup Advertisement
StdPeerGroupParamAdv paramAdv = new StdPeerGroupParamAdv(paramDoc);
// List of all the available standard services
Map services = paramAdv.getServices();
// Make a ModuleImplAdvertisemnet for the membership service
ModuleImplAdvertisement moduleAdv =
mkImplAdvBuiltin(PeerGroup.refMembershipSpecID,groupMembershipClassName,
groupDescription);
// Add this service along the other standard services
services.put(PeerGroup.membershipClassID, moduleAdv);
paramAdv.setServices(services);
advertisement.setParam((net.jxta.document.TextElement)paramAdv.getDocument(
new net.jxta.document.MimeMediaType(DOCUMENT_MIME_TYPE,
DOCUMENT_BASE_TYPE)));
System.out.println("compat " + advertisement.getCompat());
System.out.println("compat " + StdPeerGroup.STD_COMPAT);
}catch(PeerGroupException peerGroupException){
peerGroupException.printStackTrace();
System.exit(-1);
LOG.error("Error in creating Advertisement",peerGroupException);
throw new GroupManagerException(peerGroupException.getMessage());
}catch(Exception genericException){
genericException.printStackTrace();
LOG.error("Error in creating Advertisement",genericException);
System.exit(-1);
throw new GroupManagerException(genericException.getMessage());
}
}
LOG.debug("Successfullt created ADVERTISEMENT"); // initialize but to no start the application
// this is done by the join command
LOG.debug("Creating the Peer Group");
PeerGroup peerGroup = null;
try {
// create a PeerGroup ID
PeerGroupID peerGroupID = null;
if(oldPeerGroupID != null){
peerGroupID = oldPeerGroupID;
}else{
peerGroupID = IDFactory.newPeerGroupID();
}
// create the PeerGroup
peerGroup = parent.newGroup(peerGroupID, advertisement, groupName, groupDescription);////
// initialize the peergroup
peerGroup.init(this.parent,peerGroupID, advertisement);
} catch (PeerGroupException peerGroupException) {
peerGroupException.printStackTrace();
LOG.error("Unable to create a peer group !",peerGroupException);
throw new GroupManagerException(peerGroupException.getMessage());
}
// For debug purposes, print advertisement to console
//com.sams.jxta.Util.printAdvertismentDoc(advertisement);
// Try to publish the advertisement
LOG.debug("Trying to publish the advertisement");
publish(peerGroup, advertisement/*original advertisement???*/);
LOG.debug("Peer Group Advertisement successfully published");
return peerGroup; } /**
* Will check if a peer group with the same name exists on this peer
*/ public PeerGroupID alreadyExists(String name){ DiscoveryService discovery = parent.getDiscoveryService();
Enumeration enumeration =null;
try{
enumeration =
discovery.getLocalAdvertisements(discovery.GROUP, "Name",name);
} catch(java.io.IOException ioException) {
LOG.debug("Error in getting local advertisements ");
return null;
}
// If the group already exists either the enumeration is null
// or it does not contain any data if(enumeration != null && enumeration.hasMoreElements())
return ((PeerGroupAdv)enumeration.nextElement()).getPeerGroupID();
else
return null;
} // Tries to publish the newly created peer group
// ??? Why do we need the original Advertisement ?
private void publish(PeerGroup child,Advertisement pgAdv
//PeerGroupAdvertisement origAdv
) {
System.out.println("Publishing group");
//get the Discovery for this group
//Publish the New Peer in its group discovery DiscoveryService discovery;
try {
discovery = parent.getDiscoveryService();
discovery.publish(pgAdv);
// let's publish the peer adv
//if (origAdv != null){//?????? Not sure what this does
// we could check if it is indeed ours
// but it does not hurt to publish it any way
// discovery = child.getDiscoveryService();
// discovery.publish(origAdv, DiscoveryService.GROUP);
//}
} catch (java.io.IOException ioException) {
LOG.error("Could not publish the service !",ioException);
throw new GroupManagerException(ioException.getMessage());
}
LOG.debug("Published the group successfully");
} /**
* This is the code that will create a credential to join the group.
* Each group that we are joining has a specific membership requirement.
* Many groups will just be the NullMembership, which is the default.
*
*/ public Credential joinGroup(PeerGroup newGroup,StructuredDocument credentials,
String authenticationMethod)
throws GroupManagerAuthenticationException,
ProtocolNotSupportedException{ MembershipService membership = (MembershipService) newGroup.getMembershipService();
// The first step is to apply to the membership service
Authenticator authenticator;
authenticator = applyToMembershipService(newGroup,credentials,authenticationMethod);
// Next step is to allow the user to "fill up" the authenticator
// by creating a dialog
LOG.debug("Apply process successful");
authenticate(authenticator);
// third , try to join the service
Credential authenticatedCredential =joinMembershipService(authenticator,newGroup); // All is fine ! We can switch to the new group
activeGroup = newGroup;
LOG.debug("JOIN SUCCESSFUL !");
return authenticatedCredential; } /**
* This code demonstrates how to apply to a membership service.
*/ private Authenticator applyToMembershipService(PeerGroup peerGroup,
StructuredDocument credentials,
String authenticationMethod)
throws GroupManagerAuthenticationException,
ProtocolNotSupportedException{
Authenticator authenticator = null;
// Here we create an authentication credential and
// try to apply for a Authenticator.An exception is thrown in case
// this step fails.
try { AuthenticationCredential authenticationCredential =
new AuthenticationCredential(peerGroup,authenticationMethod,credentials );
MembershipService membership = (MembershipService) peerGroup.getMembershipService();
authenticator = (Authenticator)membership.apply( authenticationCredential ); } catch( PeerGroupException peerGroupException ) {
// This denotes a failure in the Apply process.We
// consider this as an Authentication exception.
LOG.error("Apply process failed !! ",peerGroupException);
throw new GroupManagerAuthenticationException(peerGroupException.getMessage());
} catch (ProtocolNotSupportedException protocolNotSupportedException){
LOG.error(protocolNotSupportedException);
throw protocolNotSupportedException;
}
return authenticator;
} /**
* This method will help the user to actually "fill up" the authenticator
* details. It will display a dialog and enable the user to visually
* provide details to each parameter of the Authenticator.The parameters
* of the Authenticator are found by Introspection.
*/ private void authenticate( Authenticator authenticator ){
// The following bean looks for standard bean parameters to create the
// contents to set the authenticator. There is no real spec so this
// will have to do.
AuthenticatorBean viewBean = new AuthenticatorBean(null,
true,authenticator,
"Please Enter Required Group Info");
viewBean.setVisible(true);
} /**
* This code demonstrates how to join a membership service.
*/ private Credential joinMembershipService(Authenticator authenticator,
PeerGroup peerGroup)
throws GroupManagerAuthenticationException { Credential authenticatedCredential = null;
// We check if the user is authentic
if( !authenticator.isReadyForJoin() ) {
LOG.error( "Authenticator is not ready to join");
throw new GroupManagerAuthenticationException("Authenticator is not ready to join !");
} // Since the user is authentic , we allow the
// user to join the service.But the service may reject the
// user as well. try{
MembershipService membership = (MembershipService) peerGroup.getMembershipService();
authenticatedCredential= membership.join(authenticator);
} catch(PeerGroupException peerGroupException) {
LOG.error( "Error in the Join Process",peerGroupException);
throw new GroupManagerAuthenticationException("Error in the Join Process");
}
return authenticatedCredential;
} /**
* Method used to quit the current active group.
*/ public void leaveGroup(){ MembershipService memberShipService = activeGroup.getMembershipService();
try{
memberShipService.resign();
} catch(PeerGroupException peerGroupException){
LOG.error("Exception in resign",peerGroupException);
throw new GroupManagerException(peerGroupException.getMessage());
}
activeGroup = parent;
purgeGroups();
} /*
* The method to renew the membership to the currently active group.
*/ public void renew(Credential credential){
// ??? Seems that the implementation does not have a concept of renewal
} /**
* Purge all groups from the cache. This help prevent us from creating
* a copy of a group with the same ID.
*
*/ public void purgeGroups(){
DiscoveryService discovery = parent.getDiscoveryService();
try{
discovery.flushAdvertisements(null,DiscoveryService.GROUP);
} catch (java.io.IOException ioException) {
LOG.error("Error in purging Groups",ioException);
throw new GroupManagerException(ioException.getMessage());
}
} /**
* Creates an ModuleImplAdvertisement which in this context is a
* MembershipService.
*
*/ private ModuleImplAdvertisement mkImplAdvBuiltin(
net.jxta.platform.ModuleSpecID specID,
String code,String descr) { String moduleImplAdvType = ModuleImplAdvertisement.getAdvertisementType();
ModuleImplAdvertisement implAdvertisement = (ModuleImplAdvertisement)
AdvertisementFactory.newAdvertisement(moduleImplAdvType);
implAdvertisement.setModuleSpecID(specID);
implAdvertisement.setCompat(stdCompatStatement);
implAdvertisement.setCode(code);
implAdvertisement.setUri(stdUri);
implAdvertisement.setProvider(stdProvider);
implAdvertisement.setDescription(descr);
return implAdvertisement;
} /**
* Creates a compatibility segment for a ModuleImplAdvertisement.
* This is needed so that our parent group can load modules of the
* reference implementation also.
*/ //??? Taken from StdPeerGroup because it was private. This should have
//* been in a utility class.
protected StructuredTextDocument mkCS() { StructuredTextDocument doc = (StructuredTextDocument)
net.jxta.document.StructuredDocumentFactory.newStructuredDocument(
new net.jxta.document.MimeMediaType(DOCUMENT_MIME_TYPE,
DOCUMENT_BASE_TYPE),
DOCUMENT_ROOT_ELEMENT);
net.jxta.document.Element e = doc.createElement(KEY, VALUE);
doc.appendChild(e);
e = doc.createElement(BINDING_KEY, BINDING_VALUE);
doc.appendChild(e);
return doc;
} /**
* This method is used for refreshing the peer with remotely published advertisements.
* //???Makes little sense without a listener.Moreover the method is deprecated
*/ public void refreshGroups(){ //disco.getRemoteAdvertisements(null, DiscoveryService.GROUP, null, null,100);
} /*
* Method used to get the currently active group.
*/ public PeerGroup getActiveGroup(){ return activeGroup;
}
}

UniversityAdmissionsService

package com.sams.jxta.groups.student;

import net.jxta.membership.MembershipService;
import net.jxta.membership.Authenticator;
import net.jxta.credential.Credential;
import net.jxta.credential.AuthenticationCredential;
import net.jxta.exception.PeerGroupException;
import net.jxta.exception.ProtocolNotSupportedException;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.Element;
import net.jxta.document.Advertisement;
import net.jxta.id.ID;
import net.jxta.impl.membership.passwd.PasswdMembershipService;
import net.jxta.peergroup.PeerGroup;
import net.jxta.protocol.ModuleImplAdvertisement;
import net.jxta.service.Service;
import net.jxta.document.StructuredDocument; import java.util.Vector; import java.util.Enumeration; /*
* A Membership Service designed to represent the Admission Process in a Univeristy.
*/ public class UniversityAdmissionsService extends PasswdMembershipService{ public UniversityAdmissionsService() throws PeerGroupException {
super();
} private static final org.apache.log4j.Category LOG =
org.apache.log4j.Category.getInstance(UniversityAdmissionsService.class.getName());
private PeerGroup peerGroup;
private ModuleImplAdvertisement implAdv;
private ID assignedID;
private Vector invitationLetters = new Vector();
private Vector authenticationCredentials = new Vector(); /*
* This method is called during an apply process.
*/ public Authenticator apply( AuthenticationCredential unsubscribedCredential )
throws PeerGroupException, ProtocolNotSupportedException{ String method = unsubscribedCredential.getMethod(); if( (null != method) && !"PreApplication".equals( method ) )
throw new ProtocolNotSupportedException(
"Authentication method not recognized : Required /"PreApplication/" ");
StructuredDocument preApForm =
(StructuredDocument)unsubscribedCredential.getIdentityInfo();
Enumeration enums = preApForm.getChildren();
Element element = (Element) enums.nextElement();
String departmentAppliedFor =(String) element.getValue();
// Vacancies exist only in the Computer Science Department
if(!departmentAppliedFor.equals(PreApplicationForm.DEPARTMENT_COMPUTER_SCIENCE))
throw new PeerGroupException("No Admissions to this Department(code:"+departmentAppliedFor+")");
ApplicationForm applicationForm = new ApplicationForm(this,unsubscribedCredential);
return applicationForm; } /*
* This method is called when the peer is interested in joining the peer group.
*/ public Credential join(Authenticator authenticated )throws PeerGroupException{ ApplicationForm applicationForm = (ApplicationForm)authenticated;
// We double check that the Authentiction is indeed successful
if(!applicationForm.isReadyForJoin())
throw new PeerGroupException("Application Form rejected !!");
// this means that the person can be taken in
InvitationLetter invitationLetter = new InvitationLetter(this);
invitationLetters.addElement(invitationLetter);
authenticationCredentials.addElement(authenticated.getAuthenticationCredential());
return invitationLetter;
} /*
* This method is called when the peer leaves the group.
* Here we destroy all previous records of Authentication
* Credentials and Credentials
*/
public void resign(){
//Destory all records
invitationLetters = new Vector();
authenticationCredentials = new Vector();
} /*
* Returns all the Credentials for this peer
*/
public Enumeration getCurrentCredentials(){
return invitationLetters.elements();
} /*
* Returns all the Authentication Credentials for this peer
*/
public Enumeration getAuthCredentials(){
return authenticationCredentials.elements();
} /*
* Returns the ModuleImplAdvertisement
*/
public Advertisement getImplAdvertisement(){
return implAdv;
} /*
* This method is called when the module is initialized.
*/
public void init(PeerGroup peerGroup,
ID assignedID,
Advertisement implAdv)
throws PeerGroupException{ this.peerGroup = peerGroup;
this.assignedID=assignedID;
this.implAdv=(ModuleImplAdvertisement)implAdv;
} /*
* Getter method for the peer group
*/
public PeerGroup getPeerGroup(){
return peerGroup;
} /*
* Getter for the Interface.For the sake of simplicity ,
* this object acts as it's own interface.
*/
public Service getInterface() {
return this;
} /*
* Methods to be implemented by virtue of being a module.
* Not used in this example
*/ public int startApp(String[] args){return 0;} public void stopApp(){} /*
* This method is currently not supported .//??? Is this OK ?
*/
public Credential makeCredential( Element element )
throws PeerGroupException, Exception{
return null;
} }

PreApplicationForm

package com.sams.jxta.groups.student;

import net.jxta.document.Element;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory; /*
* A Pre Application Form is used as an identity info in the
* Authentication Credential.
*
*/ public abstract class PreApplicationForm { public static final String DEPARTMENT_COMPUTER_SCIENCE = "CS";
public static final String DEPARTMENT_MANAGEMENT = "MT";
public static final String DEPARTMENT_ARCHITECTURE = "AT"; /*
* This methods creates a Structured Document representing the PreApp form.
* This serves as an IdentityInfo in the authentication credential.
*/
public static final StructuredDocument createPreAppForm(String department){ MimeMediaType type = new MimeMediaType("text","xml");
StructuredDocument doc =
StructuredDocumentFactory.newStructuredDocument( type,"PreAppForm" );
Element e = doc.createElement( "Department",department);
doc.appendChild( e );
return doc; }
}

InvitationLetter

package com.sams.jxta.groups.student;

import net.jxta.credential.Credential;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.peer.PeerID;
import net.jxta.service.Service;
import net.jxta.id.ID;
import net.jxta.membership.MembershipService;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory;
import net.jxta.document.MimeMediaType;
import net.jxta.document.Element; /*
* This class represents a Credential that is supplied to a
* peer after a successful apply process.
*/
public class InvitationLetter implements Credential {
// Reference to the Membership Service
private UniversityAdmissionsService admissionsService; /*
* Constructor which takes a Membership Service Object
*/
public InvitationLetter(UniversityAdmissionsService admissionsService){ this.admissionsService = admissionsService;
}
/*
* Getter for the Membership Service
*/
public Service getSourceService(){ return admissionsService;
} /*
* This method returns the PeerGroup ID
*/
public ID getPeerGroupID(){
return admissionsService.getPeerGroup().getPeerGroupID();
} /*
* This method returns the Peer ID
*/
public ID getPeerID(){
return admissionsService.getPeerGroup().getPeerID();
} /*
* This method returns a Structured Document representing the Credential
*/
public StructuredDocument getDocument(MimeMediaType as) throws Exception { StructuredDocument doc =
StructuredDocumentFactory.newStructuredDocument( as,"InivtationLetter" ); Element e = doc.createElement( "PeerGroupID",
admissionsService.getPeerGroup().getPeerGroupID() );
doc.appendChild( e );
e = doc.createElement("TimeOfRequest",""+System.currentTimeMillis());
doc.appendChild( e );
return doc;
}
public Object getSubject() {
return null;
}
public boolean isExpired() {
return false;
}
public boolean isValid() {
return false;
}
}

ApplicationForm

package com.sams.jxta.groups.student;

import net.jxta.membership.Authenticator;
import net.jxta.membership.MembershipService;
import net.jxta.credential.AuthenticationCredential; /*
* An Application Form represents an Authenticator.
*
*/
public class ApplicationForm implements Authenticator{ private String studentName;
private float GPA;
private UniversityAdmissionsService admissionsService;
private AuthenticationCredential unsubscribedCredential; /*
* Constructor
*/
public ApplicationForm(UniversityAdmissionsService admissionsService,
AuthenticationCredential unsubscribedCredential){
this.admissionsService = admissionsService;
this.unsubscribedCredential = unsubscribedCredential;
} /*
* Returns a String representing the method Name
*/
public String getMethodName(){
return "ApplicationForm";
} /*
* Returns the Authentication Credential
*/
public AuthenticationCredential getAuthenticationCredential(){
return unsubscribedCredential;
} /*
* Returns the Source Membership Service
*/
public MembershipService getSourceService(){
return admissionsService;
} /*
* This method checks if the Application Form is authenticated properly
* Only if the form is "filled" properly , can the peer join the Membership
* Service. Here we consider an Application Form as ready to join if
* the GPA is greater than 3.0 and a "non blank" name has been provided.
*
*/
public boolean isReadyForJoin(){
if(studentName == null || studentName.trim().equals(""))
return false;
if(GPA >3.0f)
return true;
else
return false;
} /*
* Setter for the GPA
*/
public void setGPA(float GPA){
this.GPA = GPA;
} /*
* Setter for the Student Name
*/
public void setStudentName(String studentName){
this.studentName=studentName;
}
}

下面是使用PasswdMemeberShipService的例子

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import net.jxta.credential.AuthenticationCredential;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.Element;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory;
import net.jxta.document.StructuredTextDocument;
import net.jxta.document.TextElement;
import net.jxta.exception.PeerGroupException;
import net.jxta.id.ID;
import net.jxta.id.IDFactory;
import net.jxta.impl.membership.PasswdMembershipService;
import net.jxta.membership.Authenticator;
import net.jxta.membership.MembershipService;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupFactory;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.platform.ModuleSpecID;
import net.jxta.protocol.ModuleImplAdvertisement;
import net.jxta.protocol.PeerGroupAdvertisement;
import net.jxta.impl.peergroup.StdPeerGroupParamAdv; public class PrivatePeerGroup {
private PeerGroup myNetPeerGroup = null, satellaPeerGroup = null,
discoveredSatellaPeerGroup = null;
private final static PeerGroupID satellaPeerGroupID = PeerGroupID
.create(URI.create("jxta:uuid-4d6172676572696e204272756e6f202002")); /** Creates new RootWS */
public PrivatePeerGroup() {
// Starts the JXTA Platform
myNetPeerGroup = this.startJxta();
if (myNetPeerGroup != null) {
System.out.println("JXTA platform Started ...");
} else {
System.err.println("Failed to start JXTA : myNetPeerGroup is null");
System.exit(1);
}
// Generate the parameters:
// login, passwd, peer group name and peer group id
// for creating the Peer Group
String login = "PrivatePeerGroups";
String passwd = "RULE";
String groupName = "SatellaGroup";
// create The Passwd Authenticated Peer Group
satellaPeerGroup = this.createPeerGroup(myNetPeerGroup, groupName,
login, passwd);
// join the satellaPeerGroup
if (satellaPeerGroup != null) {
System.out.println(" Peer Group Created ...");
discoveredSatellaPeerGroup = this.discoverPeerGroup(myNetPeerGroup,
satellaPeerGroupID);
if (discoveredSatellaPeerGroup != null) {
System.out.println(" Peer Group Found ...");
this.joinPeerGroup(discoveredSatellaPeerGroup, login, passwd);
}
}
System.out.println(" Peer Group Joined ...");
// Print the Peer Group Adverstisement on sdt out.
this.printXmlAdvertisement(
"XML Advertisement forPeer Group Advertisement",
satellaPeerGroup.getPeerGroupAdvertisement());
} private PeerGroup createPeerGroup(PeerGroup rootPeerGroup,
String groupName, String login, String passwd) {
// create the Peer Group by doing the following:
// - Create a Peer Group Module Implementation Advertisement and publish
// it
// - Create a Peer Group Adv and publish it
// - Create a Peer Group from the Peer Group Adv and return this object
PeerGroup satellaPeerGroup = null;
PeerGroupAdvertisement satellaPeerGroupAdvertisement;
// Create the PeerGroup Module Implementation Adv
ModuleImplAdvertisement passwdMembershipModuleImplAdv;
passwdMembershipModuleImplAdv = this
.createPasswdMembershipPeerGroupModuleImplAdv(rootPeerGroup);
// Publish it in the parent peer group
DiscoveryService rootPeerGroupDiscoveryService = rootPeerGroup
.getDiscoveryService();
try {
rootPeerGroupDiscoveryService.publish(
passwdMembershipModuleImplAdv, PeerGroup.DEFAULT_LIFETIME,
PeerGroup.DEFAULT_EXPIRATION);
rootPeerGroupDiscoveryService
.remotePublish(passwdMembershipModuleImplAdv,
PeerGroup.DEFAULT_EXPIRATION);
} catch (java.io.IOException e) {
System.err.println("Can't Publish passwdMembershipModuleImplAdv");
System.exit(1);
}
// Now, Create the Peer Group Advertisement
satellaPeerGroupAdvertisement = this.createPeerGroupAdvertisement(
passwdMembershipModuleImplAdv, groupName, login, passwd);
// Publish it in the parent peer group
try {
rootPeerGroupDiscoveryService.publish(
satellaPeerGroupAdvertisement, PeerGroup.DEFAULT_LIFETIME,
PeerGroup.DEFAULT_EXPIRATION);
rootPeerGroupDiscoveryService
.remotePublish(satellaPeerGroupAdvertisement,
PeerGroup.DEFAULT_EXPIRATION);
} catch (java.io.IOException e) {
System.err.println("Can't Publish satellaPeerGroupAdvertisement");
System.exit(1);
}
// Finally Create the Peer Group
if (satellaPeerGroupAdvertisement == null) {
System.err.println("satellaPeerGroupAdvertisement is null");
}
try {
satellaPeerGroup = rootPeerGroup
.newGroup(satellaPeerGroupAdvertisement);
} catch (net.jxta.exception.PeerGroupException e) {
System.err
.println("Can't create Satella Peer Group from Advertisement");
e.printStackTrace();
return null;
}
return satellaPeerGroup;
} private PeerGroupAdvertisement createPeerGroupAdvertisement(
ModuleImplAdvertisement passwdMembershipModuleImplAdv,
String groupName, String login, String passwd) {
// Create a PeerGroupAdvertisement for the peer group
PeerGroupAdvertisement satellaPeerGroupAdvertisement = (PeerGroupAdvertisement) AdvertisementFactory
.newAdvertisement(PeerGroupAdvertisement.getAdvertisementType());
// Instead of creating a new group ID each time, by using the
// line below
// satellaPeerGroupAdvertisement.setPeerGroupID
// (IDFactory.newPeerGroupID());
// I use a fixed ID so that each time I start PrivatePeerGroup,
// it creates the same Group
satellaPeerGroupAdvertisement.setPeerGroupID(satellaPeerGroupID);
satellaPeerGroupAdvertisement
.setModuleSpecID(passwdMembershipModuleImplAdv
.getModuleSpecID());
satellaPeerGroupAdvertisement.setName(groupName);
satellaPeerGroupAdvertisement
.setDescription("Peer Group using Password Authentication");
// Now create the Structured Document Containing the login and
// passwd informations. Login and passwd are put into the Param
// section of the peer Group
if (login != null) {
StructuredTextDocument loginAndPasswd = (StructuredTextDocument) StructuredDocumentFactory
.newStructuredDocument(new MimeMediaType("text/xml"),
"Parm");
String loginAndPasswdString = login + ":"
+ PasswdMembershipService.makePsswd(passwd) + ":";
TextElement loginElement = loginAndPasswd.createElement("login",
loginAndPasswdString);
loginAndPasswd.appendChild(loginElement);
// All Right, now that loginAndPasswdElement
// (The strucuted document
// that is the Param Element for The PeerGroup Adv
// is done, include it in the Peer Group Advertisement
satellaPeerGroupAdvertisement.putServiceParam(
PeerGroup.membershipClassID, loginAndPasswd);
}
return satellaPeerGroupAdvertisement;
} private ModuleImplAdvertisement createPasswdMembershipPeerGroupModuleImplAdv(
PeerGroup rootPeerGroup) {
// Create a ModuleImpl Advertisement for the Passwd
// Membership Service Take a allPurposePeerGroupImplAdv
// ModuleImplAdvertisement parameter to
// Clone some of its fields. It is easier than to recreate
// everything from scratch
// Try to locate where the PasswdMembership is within this
// ModuleImplAdvertisement.
// For a PeerGroup Module Impl, the list of the services
// (including Membership) are located in the Param section
ModuleImplAdvertisement allPurposePeerGroupImplAdv = null;
try {
allPurposePeerGroupImplAdv = rootPeerGroup
.getAllPurposePeerGroupImplAdvertisement();
} catch (java.lang.Exception e) {
System.err
.println("Can't Execute: getAllPurposePeerGroupImplAdvertisement();");
System.exit(1);
}
ModuleImplAdvertisement passwdMembershipPeerGroupModuleImplAdv = allPurposePeerGroupImplAdv;
ModuleImplAdvertisement passwdMembershipServiceModuleImplAdv = null;
StdPeerGroupParamAdv passwdMembershipPeerGroupParamAdv = null;
passwdMembershipPeerGroupParamAdv = new StdPeerGroupParamAdv(
allPurposePeerGroupImplAdv.getParam());
Hashtable allPurposePeerGroupServicesHashtable = (Hashtable) passwdMembershipPeerGroupParamAdv
.getServices();
Enumeration allPurposePeerGroupServicesEnumeration = allPurposePeerGroupServicesHashtable
.keys();
boolean membershipServiceFound = false;
while ((!membershipServiceFound)
&& (allPurposePeerGroupServicesEnumeration.hasMoreElements())) {
Object allPurposePeerGroupServiceID = allPurposePeerGroupServicesEnumeration
.nextElement();
if (allPurposePeerGroupServiceID
.equals(PeerGroup.membershipClassID)) {
// allPurposePeerGroupMemershipServiceModuleImplAdv is
// the all Purpose Mermbership Service for the all
// purpose Peer Group Module Impl adv
ModuleImplAdvertisement allPurposePeerGroupMemershipServiceModuleImplAdv = (ModuleImplAdvertisement) allPurposePeerGroupServicesHashtable
.get(allPurposePeerGroupServiceID);
// Create the passwdMembershipServiceModuleImplAdv
passwdMembershipServiceModuleImplAdv = this
.createPasswdMembershipServiceModuleImplAdv(allPurposePeerGroupMemershipServiceModuleImplAdv);
// Remove the All purpose Membership Service implementation
allPurposePeerGroupServicesHashtable
.remove(allPurposePeerGroupServiceID);
// And Replace it by the Passwd Membership Service
// Implementation
allPurposePeerGroupServicesHashtable.put(
PeerGroup.membershipClassID,
passwdMembershipServiceModuleImplAdv);
membershipServiceFound = true;
// Now the Service Advertisements are complete. Let's
// update the passwdMembershipPeerGroupModuleImplAdv by
// Updating its param
passwdMembershipPeerGroupModuleImplAdv
.setParam((Element) passwdMembershipPeerGroupParamAdv
.getDocument(MimeMediaType.XMLUTF8));
// Update its Spec ID This comes from the
// Instant P2P PeerGroupManager Code (Thanks !!!!)
if (!passwdMembershipPeerGroupModuleImplAdv.getModuleSpecID()
.equals(PeerGroup.allPurposePeerGroupSpecID)) {
passwdMembershipPeerGroupModuleImplAdv
.setModuleSpecID(IDFactory
.newModuleSpecID(passwdMembershipPeerGroupModuleImplAdv
.getModuleSpecID().getBaseClass()));
} else {
ID passwdGrpModSpecID = ID.create(URI.create("urn"
+ "jxta:uuid-" + "DeadBeefDeafBabaFeedBabe00000001"
+ "04" + "06"));
passwdMembershipPeerGroupModuleImplAdv
.setModuleSpecID((ModuleSpecID) passwdGrpModSpecID);
} // End Else
membershipServiceFound = true;
} // end if (allPurposePeerGroupServiceID.
// equals(PeerGroup.membershipClassID))
}// end While
return passwdMembershipPeerGroupModuleImplAdv;
} private ModuleImplAdvertisement createPasswdMembershipServiceModuleImplAdv(
ModuleImplAdvertisement allPurposePeerGroupMemershipServiceModuleImplAdv) {
// Create a new ModuleImplAdvertisement for the
// Membership Service
ModuleImplAdvertisement passwdMembershipServiceModuleImplAdv = (ModuleImplAdvertisement) AdvertisementFactory
.newAdvertisement(ModuleImplAdvertisement
.getAdvertisementType());
passwdMembershipServiceModuleImplAdv
.setModuleSpecID(PasswdMembershipService.passwordMembershipSpecID);
passwdMembershipServiceModuleImplAdv
.setCode(PasswdMembershipService.class.getName());
passwdMembershipServiceModuleImplAdv
.setDescription(" Module Impl Advertisement for the PasswdMembership Service");
passwdMembershipServiceModuleImplAdv
.setCompat(allPurposePeerGroupMemershipServiceModuleImplAdv
.getCompat());
passwdMembershipServiceModuleImplAdv
.setUri(allPurposePeerGroupMemershipServiceModuleImplAdv
.getUri());
passwdMembershipServiceModuleImplAdv
.setProvider(allPurposePeerGroupMemershipServiceModuleImplAdv
.getProvider());
return passwdMembershipServiceModuleImplAdv;
} private PeerGroup discoverPeerGroup(PeerGroup myNetPeerGroup,
PeerGroupID satellaPeerGroupID) {
// First discover the peer group
// In most cases we should use discovery listeners so that
// we can do the discovery asynchroneously.
// Here I won't, for increased simplicity and because
// The Peer Group Advertisement is in the local cache for
// sure
PeerGroup satellaPeerGroup;
DiscoveryService myNetPeerGroupDiscoveryService = null;
if (myNetPeerGroup != null) {
myNetPeerGroupDiscoveryService = myNetPeerGroup
.getDiscoveryService();
} else {
System.err
.println("Can't join Peer Group since it's parent is null");
System.exit(1);
}
boolean isGroupFound = false;
Enumeration localPeerGroupAdvertisementEnumeration = null;
PeerGroupAdvertisement satellaPeerGroupAdvertisement = null;
while (!isGroupFound) {
try {
localPeerGroupAdvertisementEnumeration = myNetPeerGroupDiscoveryService
.getLocalAdvertisements(DiscoveryService.GROUP, "GID",
satellaPeerGroupID.toString());
} catch (java.io.IOException e) {
System.out.println("Can't Discover Local Adv");
}
if (localPeerGroupAdvertisementEnumeration != null) {
while (localPeerGroupAdvertisementEnumeration.hasMoreElements()) {
PeerGroupAdvertisement pgAdv = null;
pgAdv = (PeerGroupAdvertisement) localPeerGroupAdvertisementEnumeration
.nextElement();
if (pgAdv.getPeerGroupID().equals(satellaPeerGroupID)) {
satellaPeerGroupAdvertisement = pgAdv;
isGroupFound = true;
break;
}
}
}
try {
Thread.sleep(5 * 1000);
} catch (Exception e) {
}
}
try {
satellaPeerGroup = myNetPeerGroup
.newGroup(satellaPeerGroupAdvertisement);
} catch (net.jxta.exception.PeerGroupException e) {
System.err.println("Can't create Peer Group from Advertisement");
e.printStackTrace();
return null;
}
return satellaPeerGroup;
} private void joinPeerGroup(PeerGroup satellaPeerGroup, String login,
String passwd) {
// Get the Heavy Weight Paper for the resume
// Alias define the type of credential to be provided
StructuredDocument creds = null;
try {
// Create the resume to apply for the Job
// Alias generate the credentials for the Peer Group
AuthenticationCredential authCred = new AuthenticationCredential(
satellaPeerGroup, null, creds);
// Create the resume to apply for the Job
// Alias generate the credentials for the Peer Group
MembershipService membershipService = satellaPeerGroup
.getMembershipService();
// Send the resume and get the Job application form
// Alias get the Authenticator from the Authentication creds
Authenticator auth = membershipService.apply(authCred);
// Fill in the Job Application Form
// Alias complete the authentication
completeAuth(auth, login, passwd);
// Check if I got the Job
// Alias Check if the authentication that was submitted was
// accepted.
if (!auth.isReadyForJoin()) {
System.out.println("Failure in authentication.");
System.out
.println("Group was not joined. Does not know how to complete authenticator");
}
// I got the Job, Join the company
// Alias I the authentication I completed was accepted,
// therefore join the Peer Group accepted.
membershipService.join(auth);
} catch (Exception e) {
System.out.println("Failure in authentication.");
System.out.println("Group was not joined. Login was incorrect.");
e.printStackTrace();
}
} private void completeAuth(Authenticator auth, String login, String passwd)
throws Exception {
Method[] methods = auth.getClass().getMethods();
Vector authMethods = new Vector();
// Find out with fields of the application needs to be
// filled
// Alias Go through the methods of the Authenticator
// class and
// copy them sorted by name into a vector.
for (int eachMethod = 0; eachMethod < methods.length; eachMethod++) {
if (methods[eachMethod].getName().startsWith("setAuth")) {
if (Modifier.isPublic(methods[eachMethod].getModifiers())) {
// sorted insertion.
for (int doInsert = 0; doInsert <= authMethods.size(); doInsert++) {
int insertHere = -1;
if (doInsert == authMethods.size())
insertHere = doInsert;
else {
if (methods[eachMethod].getName().compareTo(
((Method) authMethods.elementAt(doInsert))
.getName()) <= 0)
insertHere = doInsert;
} // end else
if (-1 != insertHere) {
authMethods.insertElementAt(methods[eachMethod],
insertHere);
break;
} // end if ( -1 != insertHere)
} // end for (int doInsert=0
} // end if (modifier.isPublic
} // end if (methods[eachMethod]
} // end for (int eachMethod)
Object[] AuthId = { login };
Object[] AuthPasswd = { passwd };
for (int eachAuthMethod = 0; eachAuthMethod < authMethods.size(); eachAuthMethod++) {
Method doingMethod = (Method) authMethods.elementAt(eachAuthMethod);
String authStepName = doingMethod.getName().substring(7);
if (doingMethod.getName().equals("setAuth1Identity")) {
// Found identity Method, providing identity
doingMethod.invoke(auth, AuthId);
} else if (doingMethod.getName().equals("setAuth2_Password")) {
// Found Passwd Method, providing passwd
doingMethod.invoke(auth, AuthPasswd);
}
}
} private void printXmlAdvertisement(String title, Advertisement adv) {
// First, Let's print a "nice" Title
String separator = "";
for (int i = 0; i < title.length() + 4; i++) {
separator = separator + "-";
}
System.out.println(separator);
System.out.println("| " + title + " |");
System.out.println(separator);
// Now let's print the Advertisement
System.out.println(adv.toString());
// Let's end up with a line
System.out.println(separator);
} /** Starts the jxta platform */
private PeerGroup startJxta() {
PeerGroup myNetPeerGroup = null;
try {
myNetPeerGroup = PeerGroupFactory.newNetPeerGroup();
} catch (PeerGroupException e) {
// could not instantiate the group, print the stack
// and exit
System.out.println("fatal error : group creation failure");
e.printStackTrace();
System.exit(1);
}
return myNetPeerGroup;
} public static void main(String args[]) {
PrivatePeerGroup satellaRoot = new PrivatePeerGroup();
System.exit(0);
}
}

这段代码是基于旧版本的jxta实现,所以运行起来需要旧版本的jxta支持,下载地址:www.samspublishing.com中,搜索jxta并且点击download

我还没有弄出新版本的实现,总是出现兼容问题,让我很郁闷,希望得到帮组啊

CSDN 下载地址:http://download.csdn.net/source/1442761

JXTA中定义自己的成员服务的相关教程结束。

《JXTA中定义自己的成员服务.doc》

下载本文的Word格式文档,以方便收藏与打印。